|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 11/20] xen/domctl: Merge set_gnttab_limits into createdomain
XEN_DOMCTL_set_gnttab_limits is a fairly new hypercall, and is strictly
mandatory. Adding support for it introduced a state where a domain has a
mostly un-constructed grant table, and there were cases where mis-ordering of
toolstack hypercalls could cause a NULL pointer deference in the hypervisor.
In fixing this, the grant table initialisation code became very tangled.
As the settings are mandatory, delete XEN_DOMCTL_set_gnttab_limits (including
XSM hooks and libxc wrappers) and retain the functionality in
XEN_DOMCTL_createdomain.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CC: Wei Liu <wei.liu2@xxxxxxxxxx>
CC: Christian Lindig <christian.lindig@xxxxxxxxxx>
CC: David Scott <dave@xxxxxxxxxx>
CC: Jon Ludlam <jonathan.ludlam@xxxxxxxxxxxxx>
CC: Rob Hoes <Rob.Hoes@xxxxxxxxxx>
CC: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
CC: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Hypervisor side cleanup is present in later patchs
---
tools/flask/policy/modules/dom0.te | 2 +-
tools/flask/policy/modules/xen.if | 2 +-
tools/helpers/init-xenstore-domain.c | 19 ++++++++-----------
tools/libxc/include/xenctrl.h | 13 -------------
tools/libxc/xc_domain.c | 13 -------------
tools/libxl/libxl_create.c | 2 ++
tools/libxl/libxl_dom.c | 6 ------
tools/ocaml/libs/xc/xenctrl.ml | 2 ++
tools/ocaml/libs/xc/xenctrl.mli | 2 ++
tools/ocaml/libs/xc/xenctrl_stubs.c | 8 +++++++-
tools/python/xen/lowlevel/xc/xc.c | 2 ++
xen/common/domctl.c | 34 ++++++++++++++++++++++++++--------
xen/include/public/domctl.h | 10 +++-------
xen/xsm/flask/hooks.c | 3 ---
xen/xsm/flask/policy/access_vectors | 2 --
15 files changed, 54 insertions(+), 66 deletions(-)
diff --git a/tools/flask/policy/modules/dom0.te
b/tools/flask/policy/modules/dom0.te
index 4eb3843..dfdcdcd 100644
--- a/tools/flask/policy/modules/dom0.te
+++ b/tools/flask/policy/modules/dom0.te
@@ -39,7 +39,7 @@ allow dom0_t dom0_t:domain {
};
allow dom0_t dom0_t:domain2 {
set_cpuid gettsc settsc setscheduler set_vnumainfo
- get_vnumainfo psr_cmt_op psr_alloc set_gnttab_limits
+ get_vnumainfo psr_cmt_op psr_alloc
};
allow dom0_t dom0_t:resource { add remove };
diff --git a/tools/flask/policy/modules/xen.if
b/tools/flask/policy/modules/xen.if
index 7dc25be..5af984c 100644
--- a/tools/flask/policy/modules/xen.if
+++ b/tools/flask/policy/modules/xen.if
@@ -52,7 +52,7 @@ define(`create_domain_common', `
settime setdomainhandle getvcpucontext set_misc_info };
allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim
set_vnumainfo get_vnumainfo cacheflush
- psr_cmt_op psr_alloc soft_reset set_gnttab_limits };
+ psr_cmt_op psr_alloc soft_reset };
allow $1 $2:security check_context;
allow $1 $2:shadow enable;
allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage
mmuext_op updatemp };
diff --git a/tools/helpers/init-xenstore-domain.c
b/tools/helpers/init-xenstore-domain.c
index 89c329c..4771750 100644
--- a/tools/helpers/init-xenstore-domain.c
+++ b/tools/helpers/init-xenstore-domain.c
@@ -67,6 +67,14 @@ static int build(xc_interface *xch)
.ssidref = SECINITSID_DOMU,
.flags = XEN_DOMCTL_CDF_xs_domain,
.max_evtchn_port = -1, /* No limit. */
+
+ /*
+ * 1 grant frame is enough: we don't need many grants.
+ * Mini-OS doesn't like less than 4, though, so use 4.
+ * 128 maptrack frames: 256 entries per frame, enough for 32768
domains.
+ */
+ .max_grant_frames = 4,
+ .max_maptrack_frames = 128,
};
xs_fd = open("/dev/xen/xenbus_backend", O_RDWR);
@@ -104,17 +112,6 @@ static int build(xc_interface *xch)
fprintf(stderr, "xc_domain_setmaxmem failed\n");
goto err;
}
- /*
- * 1 grant frame is enough: we don't need many grants.
- * Mini-OS doesn't like less than 4, though, so use 4.
- * 128 maptrack frames: 256 entries per frame, enough for 32768 domains.
- */
- rv = xc_domain_set_gnttab_limits(xch, domid, 4, 128);
- if ( rv )
- {
- fprintf(stderr, "xc_domain_set_gnttab_limits failed\n");
- goto err;
- }
rv = xc_domain_set_memmap_limit(xch, domid, limit_kb);
if ( rv )
{
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 88a175f..0c7c07c 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1071,19 +1071,6 @@ int xc_domain_set_access_required(xc_interface *xch,
*/
int xc_domain_set_virq_handler(xc_interface *xch, uint32_t domid, int virq);
-/**
- * Set the maximum number of grant frames and maptrack frames a domain
- * can have. Must be used at domain setup time and only then.
- *
- * @param xch a handle to an open hypervisor interface
- * @param domid the domain id
- * @param grant_frames max. number of grant frames
- * @param maptrack_frames max. number of maptrack frames
- */
-int xc_domain_set_gnttab_limits(xc_interface *xch, uint32_t domid,
- uint32_t grant_frames,
- uint32_t maptrack_frames);
-
/*
* CPUPOOL MANAGEMENT FUNCTIONS
*/
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 2bc695c..e8d0734 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -2256,19 +2256,6 @@ int xc_domain_set_virq_handler(xc_interface *xch,
uint32_t domid, int virq)
return do_domctl(xch, &domctl);
}
-int xc_domain_set_gnttab_limits(xc_interface *xch, uint32_t domid,
- uint32_t grant_frames,
- uint32_t maptrack_frames)
-{
- DECLARE_DOMCTL;
-
- domctl.cmd = XEN_DOMCTL_set_gnttab_limits;
- domctl.domain = domid;
- domctl.u.set_gnttab_limits.grant_frames = grant_frames;
- domctl.u.set_gnttab_limits.maptrack_frames = maptrack_frames;
- return do_domctl(xch, &domctl);
-}
-
/* Plumbing Xen with vNUMA topology */
int xc_domain_setvnuma(xc_interface *xch,
uint32_t domid,
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 2cb3460..c8eb59c 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -566,6 +566,8 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config
*d_config,
struct xen_domctl_createdomain create = {
.ssidref = info->ssidref,
.max_evtchn_port = b_info->event_channels,
+ .max_grant_frames = b_info->max_grant_frames,
+ .max_maptrack_frames = b_info->max_maptrack_frames,
};
if (info->type != LIBXL_DOMAIN_TYPE_PV) {
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 227e6cf..9194109 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -358,12 +358,6 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
return ERROR_FAIL;
}
- if (xc_domain_set_gnttab_limits(ctx->xch, domid, info->max_grant_frames,
- info->max_maptrack_frames) != 0) {
- LOG(ERROR, "Couldn't set grant table limits");
- return ERROR_FAIL;
- }
-
/*
* Check if the domain has any CPU or node affinity already. If not, try
* to build up the latter via automatic NUMA placement. In fact, in case
diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
index 6dc0dd7..7c8d6ab 100644
--- a/tools/ocaml/libs/xc/xenctrl.ml
+++ b/tools/ocaml/libs/xc/xenctrl.ml
@@ -64,6 +64,8 @@ type domctl_create_config =
handle: string;
flags: domain_create_flag list;
max_evtchn_port: int32;
+ max_grant_frames: int32;
+ max_maptrack_frames: int32;
arch: arch_domainconfig;
}
diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli
index b0fec24..f150a5d 100644
--- a/tools/ocaml/libs/xc/xenctrl.mli
+++ b/tools/ocaml/libs/xc/xenctrl.mli
@@ -56,6 +56,8 @@ type domctl_create_config = {
handle: string;
flags: domain_create_flag list;
max_evtchn_port: int32;
+ max_grant_frames: int32;
+ max_maptrack_frames: int32;
arch: arch_domainconfig;
}
diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
b/tools/ocaml/libs/xc/xenctrl_stubs.c
index c022de9..882828f 100644
--- a/tools/ocaml/libs/xc/xenctrl_stubs.c
+++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
@@ -128,7 +128,9 @@ CAMLprim value stub_xc_domain_create(value xch, value
config)
#define VAL_HANDLE Field(config, 1)
#define VAL_FLAGS Field(config, 2)
#define VAL_MAX_EVTCHN_PORT Field(config, 3)
-#define VAL_ARCH Field(config, 4)
+#define VAL_MAX_GRANT_FRAMES Field(config, 4)
+#define VAL_MAX_MAPTRACK_FRAMES Field(config, 5)
+#define VAL_ARCH Field(config, 6)
uint32_t domid = 0;
int result;
@@ -136,6 +138,8 @@ CAMLprim value stub_xc_domain_create(value xch, value
config)
struct xen_domctl_createdomain cfg = {
.ssidref = Int32_val(VAL_SSIDREF),
.max_evtchn_port = Int32_val(VAL_MAX_EVTCHN_PORT),
+ .max_grant_frames = Int32_val(VAL_MAX_GRANT_FRAMES),
+ .max_maptrack_frames = Int32_val(VAL_MAX_MAPTRACK_FRAMES),
};
domain_handle_of_uuid_string(cfg.handle, String_val(VAL_HANDLE));
@@ -164,6 +168,8 @@ CAMLprim value stub_xc_domain_create(value xch, value
config)
}
#undef VAL_ARCH
+#undef VAL_MAX_MAPTRACK_FRAMES
+#undef VAL_MAX_GRANT_FRAMES
#undef VAL_MAX_EVTCHN_PORT
#undef VAL_FLAGS
#undef VAL_HANDLE
diff --git a/tools/python/xen/lowlevel/xc/xc.c
b/tools/python/xen/lowlevel/xc/xc.c
index a307de7..db99a52 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -126,6 +126,8 @@ static PyObject *pyxc_domain_create(XcObject *self,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
},
.max_evtchn_port = -1, /* No limit. */
+ .max_grant_frames = 32,
+ .max_maptrack_frames = 1024,
};
static char *kwd_list[] = { "domid", "ssidref", "handle", "flags",
"target", NULL };
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 14dab56..d8ba461 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -539,14 +539,37 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
u_domctl)
break;
}
+ /* Stash the new domid for the toolstack. */
+ op->domain = d->domain_id;
+ copyback = true;
+
d->max_evtchn_port =
min_t(unsigned int, op->u.createdomain.max_evtchn_port, INT_MAX);
- ret = 0;
- op->domain = d->domain_id;
- copyback = 1;
+ ret = grant_table_set_limits(d, op->u.createdomain.max_grant_frames,
+ op->u.createdomain.max_maptrack_frames);
+ if ( !ret )
+ goto createdomain_fail_late;
+
d = NULL;
break;
+
+ createdomain_fail_late:
+ /*
+ * We've hit an error after putting the domain into the domain list,
+ * meaning that other entities in the system can refer to it.
+ *
+ * Unwinding is substantially more complicated, and without
+ * returning success, the toolstack wont know to clean up.
+ *
+ * Reuse the continuation logic to turn this hypercall into a
+ * destroydomain on behalf of the toolstack.
+ */
+ op->cmd = XEN_DOMCTL_destroydomain;
+ d = NULL;
+
+ ret = hypercall_create_continuation(__HYPERVISOR_domctl, "h",
u_domctl);
+ break;
}
case XEN_DOMCTL_max_vcpus:
@@ -1114,11 +1137,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
u_domctl)
copyback = 1;
break;
- case XEN_DOMCTL_set_gnttab_limits:
- ret = grant_table_set_limits(d, op->u.set_gnttab_limits.grant_frames,
- op->u.set_gnttab_limits.maptrack_frames);
- break;
-
default:
ret = arch_do_domctl(op, d, u_domctl);
break;
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 515671e..424f0a8 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -71,6 +71,8 @@ struct xen_domctl_createdomain {
* mapping space, xenheap, etc) a guest may consume.
*/
uint32_t max_evtchn_port;
+ uint32_t max_grant_frames;
+ uint32_t max_maptrack_frames;
struct xen_arch_domainconfig arch;
};
@@ -1065,11 +1067,6 @@ struct xen_domctl_psr_alloc {
uint64_t data; /* IN/OUT */
};
-struct xen_domctl_set_gnttab_limits {
- uint32_t grant_frames; /* IN */
- uint32_t maptrack_frames; /* IN */
-};
-
/* XEN_DOMCTL_vuart_op */
struct xen_domctl_vuart_op {
#define XEN_DOMCTL_VUART_OP_INIT 0
@@ -1168,7 +1165,7 @@ struct xen_domctl {
#define XEN_DOMCTL_monitor_op 77
#define XEN_DOMCTL_psr_alloc 78
#define XEN_DOMCTL_soft_reset 79
-#define XEN_DOMCTL_set_gnttab_limits 80
+/* #define XEN_DOMCTL_set_gnttab_limits 80 - Moved into
XEN_DOMCTL_createdomain */
#define XEN_DOMCTL_vuart_op 81
#define XEN_DOMCTL_gdbsx_guestmemio 1000
#define XEN_DOMCTL_gdbsx_pausevcpu 1001
@@ -1229,7 +1226,6 @@ struct xen_domctl {
struct xen_domctl_psr_cmt_op psr_cmt_op;
struct xen_domctl_monitor_op monitor_op;
struct xen_domctl_psr_alloc psr_alloc;
- struct xen_domctl_set_gnttab_limits set_gnttab_limits;
struct xen_domctl_vuart_op vuart_op;
uint8_t pad[128];
} u;
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 1978703..cccd1c7 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -740,9 +740,6 @@ static int flask_domctl(struct domain *d, int cmd)
case XEN_DOMCTL_soft_reset:
return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SOFT_RESET);
- case XEN_DOMCTL_set_gnttab_limits:
- return current_has_perm(d, SECCLASS_DOMAIN2,
DOMAIN2__SET_GNTTAB_LIMITS);
-
default:
return avc_unknown_permission("domctl", cmd);
}
diff --git a/xen/xsm/flask/policy/access_vectors
b/xen/xsm/flask/policy/access_vectors
index deecfa2..6f6e969 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -246,8 +246,6 @@ class domain2
mem_sharing
# XEN_DOMCTL_psr_alloc
psr_alloc
-# XEN_DOMCTL_set_gnttab_limits
- set_gnttab_limits
}
# Similar to class domain, but primarily contains domctls related to HVM
domains
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |