|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/altp2m: Added xc_altp2m_set_mem_access_multi()
For the default EPT view we have xc_set_mem_access_multi(), which
is able to set an array of pages to an array of access rights with
a single hypercall. However, this functionality was lacking for the
altp2m subsystem, which could only set page restrictions for one
page at a time. This patch addresses the gap.
Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
---
tools/libxc/include/xenctrl.h | 3 +++
tools/libxc/xc_altp2m.c | 41 +++++++++++++++++++++++++++++++++++++++++
xen/arch/x86/hvm/hvm.c | 30 +++++++++++++++++++++++++++---
xen/include/public/hvm/hvm_op.h | 28 +++++++++++++++++++++++-----
4 files changed, 94 insertions(+), 8 deletions(-)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index a48981a..645b5bd 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1903,6 +1903,9 @@ int xc_altp2m_switch_to_view(xc_interface *handle,
domid_t domid,
int xc_altp2m_set_mem_access(xc_interface *handle, domid_t domid,
uint16_t view_id, xen_pfn_t gfn,
xenmem_access_t access);
+int xc_altp2m_set_mem_access_multi(xc_interface *handle, domid_t domid,
+ uint16_t view_id, uint8_t *access,
+ uint64_t *pages, uint32_t nr);
int xc_altp2m_change_gfn(xc_interface *handle, domid_t domid,
uint16_t view_id, xen_pfn_t old_gfn,
xen_pfn_t new_gfn);
diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c
index 0639632..f202ca1 100644
--- a/tools/libxc/xc_altp2m.c
+++ b/tools/libxc/xc_altp2m.c
@@ -188,6 +188,47 @@ int xc_altp2m_set_mem_access(xc_interface *handle, domid_t
domid,
return rc;
}
+int xc_altp2m_set_mem_access_multi(xc_interface *xch, domid_t domid,
+ uint16_t view_id, uint8_t *access,
+ uint64_t *pages, uint32_t nr)
+{
+ int rc;
+
+ DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
+ DECLARE_HYPERCALL_BOUNCE(access, nr, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+ DECLARE_HYPERCALL_BOUNCE(pages, nr * sizeof(uint64_t),
+ XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+ arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
+ if ( arg == NULL )
+ return -1;
+
+ arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
+ arg->cmd = HVMOP_altp2m_set_mem_access_multi;
+ arg->domain = domid;
+ arg->u.set_mem_access_multi.view = view_id;
+ arg->u.set_mem_access_multi.nr = nr;
+
+ if ( xc_hypercall_bounce_pre(xch, pages) ||
+ xc_hypercall_bounce_pre(xch, access) )
+ {
+ PERROR("Could not bounce memory for
HVMOP_altp2m_set_mem_access_multi");
+ return -1;
+ }
+
+ set_xen_guest_handle(arg->u.set_mem_access_multi.pfn_list, pages);
+ set_xen_guest_handle(arg->u.set_mem_access_multi.access_list, access);
+
+ rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+ HYPERCALL_BUFFER_AS_ARG(arg));
+
+ xc_hypercall_buffer_free(xch, arg);
+ xc_hypercall_bounce_post(xch, access);
+ xc_hypercall_bounce_post(xch, pages);
+
+ return rc;
+}
+
int xc_altp2m_change_gfn(xc_interface *handle, domid_t domid,
uint16_t view_id, xen_pfn_t old_gfn,
xen_pfn_t new_gfn)
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index ccfae4f..cc9b207 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4394,11 +4394,13 @@ static int hvmop_get_param(
}
static int do_altp2m_op(
+ unsigned long cmd,
XEN_GUEST_HANDLE_PARAM(void) arg)
{
struct xen_hvm_altp2m_op a;
struct domain *d = NULL;
- int rc = 0;
+ long rc = 0;
+ unsigned long start_iter = cmd & ~MEMOP_CMD_MASK;
if ( !hvm_altp2m_supported() )
return -EOPNOTSUPP;
@@ -4419,6 +4421,7 @@ static int do_altp2m_op(
case HVMOP_altp2m_destroy_p2m:
case HVMOP_altp2m_switch_p2m:
case HVMOP_altp2m_set_mem_access:
+ case HVMOP_altp2m_set_mem_access_multi:
case HVMOP_altp2m_change_gfn:
break;
default:
@@ -4535,6 +4538,25 @@ static int do_altp2m_op(
a.u.set_mem_access.view);
break;
+ case HVMOP_altp2m_set_mem_access_multi:
+ if ( a.u.set_mem_access_multi.pad )
+ {
+ rc = -EINVAL;
+ break;
+ }
+ rc = p2m_set_mem_access_multi(d, a.u.set_mem_access_multi.pfn_list,
+ a.u.set_mem_access_multi.access_list,
+ a.u.set_mem_access_multi.nr, start_iter,
+ MEMOP_CMD_MASK,
+ a.u.set_mem_access_multi.view);
+ if ( rc > 0 )
+ {
+ ASSERT(!(rc & MEMOP_CMD_MASK));
+ rc = hypercall_create_continuation(__HYPERVISOR_hvm_op, "lh",
+ HVMOP_altp2m | rc, arg);
+ }
+ break;
+
case HVMOP_altp2m_change_gfn:
if ( a.u.change_gfn.pad1 || a.u.change_gfn.pad2 )
rc = -EINVAL;
@@ -4608,10 +4630,12 @@ static int hvmop_get_mem_type(
return rc;
}
-long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
+long do_hvm_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
{
long rc = 0;
+ unsigned long op = cmd & MEMOP_CMD_MASK;
+
switch ( op )
{
case HVMOP_set_evtchn_upcall_vector:
@@ -4693,7 +4717,7 @@ long do_hvm_op(unsigned long op,
XEN_GUEST_HANDLE_PARAM(void) arg)
break;
case HVMOP_altp2m:
- rc = do_altp2m_op(arg);
+ rc = do_altp2m_op(cmd, arg);
break;
default:
diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h
index bc00ef0..e226758 100644
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -231,6 +231,21 @@ struct xen_hvm_altp2m_set_mem_access {
typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access_t;
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t);
+struct xen_hvm_altp2m_set_mem_access_multi {
+ /* view */
+ uint16_t view;
+ uint16_t pad;
+ /* Number of pages */
+ uint32_t nr;
+ /* List of pfns to set access for */
+ XEN_GUEST_HANDLE(const_uint64) pfn_list;
+ /* Corresponding list of access settings for pfn_list */
+ XEN_GUEST_HANDLE(const_uint8) access_list;
+};
+typedef struct xen_hvm_altp2m_set_mem_access_multi
+ xen_hvm_altp2m_set_mem_access_multi_t;
+DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_multi_t);
+
struct xen_hvm_altp2m_change_gfn {
/* view */
uint16_t view;
@@ -262,15 +277,18 @@ struct xen_hvm_altp2m_op {
#define HVMOP_altp2m_set_mem_access 7
/* Change a p2m entry to have a different gfn->mfn mapping */
#define HVMOP_altp2m_change_gfn 8
+/* Set access for an array of pages */
+#define HVMOP_altp2m_set_mem_access_multi 9
domid_t domain;
uint16_t pad1;
uint32_t pad2;
union {
- struct xen_hvm_altp2m_domain_state domain_state;
- struct xen_hvm_altp2m_vcpu_enable_notify enable_notify;
- struct xen_hvm_altp2m_view view;
- struct xen_hvm_altp2m_set_mem_access set_mem_access;
- struct xen_hvm_altp2m_change_gfn change_gfn;
+ struct xen_hvm_altp2m_domain_state domain_state;
+ struct xen_hvm_altp2m_vcpu_enable_notify enable_notify;
+ struct xen_hvm_altp2m_view view;
+ struct xen_hvm_altp2m_set_mem_access set_mem_access;
+ struct xen_hvm_altp2m_change_gfn change_gfn;
+ struct xen_hvm_altp2m_set_mem_access_multi set_mem_access_multi;
uint8_t pad[64];
} u;
};
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |