debuggers.hg
changeset 18074:f40c310dca31
x86: allow control domain to limit machine addresses given to a particular guest
This allows domains which make buggy assumptions about the maximum
possible MFN to be worked around.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
This allows domains which make buggy assumptions about the maximum
possible MFN to be worked around.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Fri Jul 11 12:51:26 2008 +0100 (2008-07-11) |
parents | bcef824afe1a |
children | 3e563929f17a |
files | tools/libxc/xc_domain.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/create.py xen/arch/x86/domctl.c xen/arch/x86/x86_64/mm.c xen/include/public/domctl.h xen/include/xsm/xsm.h xen/xsm/dummy.c |
line diff
1.1 --- a/tools/libxc/xc_domain.c Fri Jul 11 12:49:14 2008 +0100 1.2 +++ b/tools/libxc/xc_domain.c Fri Jul 11 12:51:26 2008 +0100 1.3 @@ -993,6 +993,35 @@ int xc_domain_subscribe_for_suspend( 1.4 return do_domctl(xc_handle, &domctl); 1.5 } 1.6 1.7 +int xc_domain_set_machine_address_size(int xc, 1.8 + uint32_t domid, 1.9 + unsigned int width) 1.10 +{ 1.11 + DECLARE_DOMCTL; 1.12 + 1.13 + memset(&domctl, 0, sizeof(domctl)); 1.14 + domctl.domain = domid; 1.15 + domctl.cmd = XEN_DOMCTL_set_machine_address_size; 1.16 + domctl.u.address_size.size = width; 1.17 + 1.18 + return do_domctl(xc, &domctl); 1.19 +} 1.20 + 1.21 + 1.22 +int xc_domain_get_machine_address_size(int xc, uint32_t domid) 1.23 +{ 1.24 + DECLARE_DOMCTL; 1.25 + int rc; 1.26 + 1.27 + memset(&domctl, 0, sizeof(domctl)); 1.28 + domctl.domain = domid; 1.29 + domctl.cmd = XEN_DOMCTL_get_machine_address_size; 1.30 + 1.31 + rc = do_domctl(xc, &domctl); 1.32 + 1.33 + return rc == 0 ? domctl.u.address_size.size : rc; 1.34 +} 1.35 + 1.36 /* 1.37 * Local variables: 1.38 * mode: C
2.1 --- a/tools/libxc/xenctrl.h Fri Jul 11 12:49:14 2008 +0100 2.2 +++ b/tools/libxc/xenctrl.h Fri Jul 11 12:51:26 2008 +0100 2.3 @@ -1076,6 +1076,12 @@ int xc_domain_bind_pt_isa_irq(int xc_han 2.4 uint32_t domid, 2.5 uint8_t machine_irq); 2.6 2.7 +int xc_domain_set_machine_address_size(int handle, 2.8 + uint32_t domid, 2.9 + unsigned int width); 2.10 +int xc_domain_get_machine_address_size(int handle, 2.11 + uint32_t domid); 2.12 + 2.13 /* Set the target domain */ 2.14 int xc_domain_set_target(int xc_handle, 2.15 uint32_t domid,
3.1 --- a/tools/python/xen/lowlevel/xc/xc.c Fri Jul 11 12:49:14 2008 +0100 3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Fri Jul 11 12:51:26 2008 +0100 3.3 @@ -843,6 +843,22 @@ static PyObject *pyxc_dom_set_cpuid(XcOb 3.4 return pyxc_create_cpuid_dict(regs_transform); 3.5 } 3.6 3.7 +static PyObject *pyxc_dom_set_machine_address_size(XcObject *self, 3.8 + PyObject *args, 3.9 + PyObject *kwds) 3.10 +{ 3.11 + uint32_t dom, width; 3.12 + 3.13 + if (!PyArg_ParseTuple(args, "ii", &dom, &width)) 3.14 + return NULL; 3.15 + 3.16 + if (xc_domain_set_machine_address_size(self->xc_handle, dom, width) != 0) 3.17 + return pyxc_error_to_exception(); 3.18 + 3.19 + Py_INCREF(zero); 3.20 + return zero; 3.21 +} 3.22 + 3.23 #endif /* __i386__ || __x86_64__ */ 3.24 3.25 static PyObject *pyxc_hvm_build(XcObject *self, 3.26 @@ -1889,6 +1905,13 @@ static PyMethodDef pyxc_methods[] = { 3.27 "Set the default cpuid policy for a domain.\n" 3.28 " dom [int]: Identifier of domain.\n\n" 3.29 "Returns: [int] 0 on success; exception on error.\n" }, 3.30 + 3.31 + { "domain_set_machine_address_size", 3.32 + (PyCFunction)pyxc_dom_set_machine_address_size, 3.33 + METH_VARARGS, "\n" 3.34 + "Set maximum machine address size for this domain.\n" 3.35 + " dom [int]: Identifier of domain.\n" 3.36 + " width [int]: Maximum machine address width.\n" }, 3.37 #endif 3.38 3.39 { NULL, NULL, 0, NULL }
4.1 --- a/tools/python/xen/xend/XendConfig.py Fri Jul 11 12:49:14 2008 +0100 4.2 +++ b/tools/python/xen/xend/XendConfig.py Fri Jul 11 12:51:26 2008 +0100 4.3 @@ -207,6 +207,7 @@ XENAPI_CFG_TYPES = { 4.4 'pci': str, 4.5 'cpuid' : dict, 4.6 'cpuid_check' : dict, 4.7 + 'machine_address_size': int, 4.8 } 4.9 4.10 # List of legacy configuration keys that have no equivalent in the
5.1 --- a/tools/python/xen/xend/XendDomainInfo.py Fri Jul 11 12:49:14 2008 +0100 5.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Jul 11 12:51:26 2008 +0100 5.3 @@ -2223,6 +2223,11 @@ class XendDomainInfo: 5.4 shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024) 5.5 self.info['shadow_memory'] = shadow_cur 5.6 5.7 + # machine address size 5.8 + if self.info.has_key('machine_address_size'): 5.9 + log.debug("_initDomain: setting maximum machine address size %d" % self.info['machine_address_size']) 5.10 + xc.domain_set_machine_address_size(self.domid, self.info['machine_address_size']) 5.11 + 5.12 self._createChannels() 5.13 5.14 channel_details = self.image.createImage()
6.1 --- a/tools/python/xen/xm/create.py Fri Jul 11 12:49:14 2008 +0100 6.2 +++ b/tools/python/xen/xm/create.py Fri Jul 11 12:51:26 2008 +0100 6.3 @@ -563,6 +563,10 @@ gopts.var('cpuid_check', val="IN[,SIN]:e 6.4 fn=append_value, default=[], 6.5 use="""Cpuid check description.""") 6.6 6.7 +gopts.var('machine_address_size', val='BITS', 6.8 + fn=set_int, default=None, 6.9 + use="""Maximum machine address size""") 6.10 + 6.11 def err(msg): 6.12 """Print an error to stderr and exit. 6.13 """ 6.14 @@ -611,6 +615,9 @@ def configure_image(vals): 6.15 if vals.vhpt != 0: 6.16 config_image.append(['vhpt', vals.vhpt]) 6.17 6.18 + if vals.machine_address_size: 6.19 + config_image.append(['machine_address_size', vals.machine_address_size]) 6.20 + 6.21 return config_image 6.22 6.23 def configure_disks(config_devs, vals): 6.24 @@ -863,7 +870,7 @@ def make_config(vals): 6.25 'restart', 'on_poweroff', 6.26 'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features', 6.27 'on_xend_start', 'on_xend_stop', 'target', 'cpuid', 6.28 - 'cpuid_check']) 6.29 + 'cpuid_check', 'machine_address_size']) 6.30 6.31 if vals.uuid is not None: 6.32 config.append(['uuid', vals.uuid])
7.1 --- a/xen/arch/x86/domctl.c Fri Jul 11 12:49:14 2008 +0100 7.2 +++ b/xen/arch/x86/domctl.c Fri Jul 11 12:51:26 2008 +0100 7.3 @@ -490,6 +490,57 @@ long arch_do_domctl( 7.4 } 7.5 break; 7.6 7.7 + case XEN_DOMCTL_set_machine_address_size: 7.8 + { 7.9 + struct domain *d; 7.10 + 7.11 + ret = -ESRCH; 7.12 + if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) 7.13 + break; 7.14 + 7.15 + ret = xsm_machine_address_size(d, domctl->cmd); 7.16 + if ( ret ) 7.17 + rcu_unlock_domain(d); 7.18 + 7.19 + ret = -EBUSY; 7.20 + if ( d->tot_pages > 0 ) 7.21 + goto set_machine_address_size_out; 7.22 + 7.23 + d->arch.physaddr_bitsize = domctl->u.address_size.size; 7.24 + 7.25 + ret = 0; 7.26 + set_machine_address_size_out: 7.27 + rcu_unlock_domain(d); 7.28 + } 7.29 + break; 7.30 + 7.31 + case XEN_DOMCTL_get_machine_address_size: 7.32 + { 7.33 + struct domain *d; 7.34 + 7.35 + ret = -ESRCH; 7.36 + if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) 7.37 + break; 7.38 + 7.39 + ret = xsm_machine_address_size(d, domctl->cmd); 7.40 + if ( ret ) 7.41 + { 7.42 + rcu_unlock_domain(d); 7.43 + break; 7.44 + } 7.45 + 7.46 + domctl->u.address_size.size = d->arch.physaddr_bitsize; 7.47 + 7.48 + ret = 0; 7.49 + rcu_unlock_domain(d); 7.50 + 7.51 + if ( copy_to_guest(u_domctl, domctl, 1) ) 7.52 + ret = -EFAULT; 7.53 + 7.54 + 7.55 + } 7.56 + break; 7.57 + 7.58 case XEN_DOMCTL_sendtrigger: 7.59 { 7.60 struct domain *d;
8.1 --- a/xen/arch/x86/x86_64/mm.c Fri Jul 11 12:49:14 2008 +0100 8.2 +++ b/xen/arch/x86/x86_64/mm.c Fri Jul 11 12:51:26 2008 +0100 8.3 @@ -475,7 +475,8 @@ int check_descriptor(const struct domain 8.4 void domain_set_alloc_bitsize(struct domain *d) 8.5 { 8.6 if ( !is_pv_32on64_domain(d) || 8.7 - (MACH2PHYS_COMPAT_NR_ENTRIES(d) >= max_page) ) 8.8 + (MACH2PHYS_COMPAT_NR_ENTRIES(d) >= max_page) || 8.9 + d->arch.physaddr_bitsize > 0 ) 8.10 return; 8.11 d->arch.physaddr_bitsize = 8.12 /* 2^n entries can be contained in guest's p2m mapping space */
9.1 --- a/xen/include/public/domctl.h Fri Jul 11 12:49:14 2008 +0100 9.2 +++ b/xen/include/public/domctl.h Fri Jul 11 12:51:26 2008 +0100 9.3 @@ -607,6 +607,14 @@ struct xen_domctl_subscribe { 9.4 typedef struct xen_domctl_subscribe xen_domctl_subscribe_t; 9.5 DEFINE_XEN_GUEST_HANDLE(xen_domctl_subscribe_t); 9.6 9.7 +/* 9.8 + * Define the maximum machine address size which should be allocated 9.9 + * to a guest. 9.10 + */ 9.11 +#define XEN_DOMCTL_set_machine_address_size 51 9.12 +#define XEN_DOMCTL_get_machine_address_size 52 9.13 + 9.14 + 9.15 struct xen_domctl { 9.16 uint32_t cmd; 9.17 uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
10.1 --- a/xen/include/xsm/xsm.h Fri Jul 11 12:49:14 2008 +0100 10.2 +++ b/xen/include/xsm/xsm.h Fri Jul 11 12:51:26 2008 +0100 10.3 @@ -119,6 +119,7 @@ struct xsm_operations { 10.4 int (*hypercall_init) (struct domain *d); 10.5 int (*hvmcontext) (struct domain *d, uint32_t op); 10.6 int (*address_size) (struct domain *d, uint32_t op); 10.7 + int (*machine_address_size) (struct domain *d, uint32_t op); 10.8 int (*hvm_param) (struct domain *d, unsigned long op); 10.9 int (*hvm_set_pci_intx_level) (struct domain *d); 10.10 int (*hvm_set_isa_irq_level) (struct domain *d); 10.11 @@ -448,6 +449,11 @@ static inline int xsm_address_size (stru 10.12 return xsm_call(address_size(d, cmd)); 10.13 } 10.14 10.15 +static inline int xsm_machine_address_size (struct domain *d, uint32_t cmd) 10.16 +{ 10.17 + return xsm_call(machine_address_size(d, cmd)); 10.18 +} 10.19 + 10.20 static inline int xsm_hvm_param (struct domain *d, unsigned long op) 10.21 { 10.22 return xsm_call(hvm_param(d, op));
11.1 --- a/xen/xsm/dummy.c Fri Jul 11 12:49:14 2008 +0100 11.2 +++ b/xen/xsm/dummy.c Fri Jul 11 12:51:26 2008 +0100 11.3 @@ -467,6 +467,7 @@ void xsm_fixup_ops (struct xsm_operation 11.4 set_to_dummy_if_null(ops, hypercall_init); 11.5 set_to_dummy_if_null(ops, hvmcontext); 11.6 set_to_dummy_if_null(ops, address_size); 11.7 + set_to_dummy_if_null(ops, machine_address_size); 11.8 set_to_dummy_if_null(ops, hvm_param); 11.9 set_to_dummy_if_null(ops, hvm_set_pci_intx_level); 11.10 set_to_dummy_if_null(ops, hvm_set_isa_irq_level);