Ian Campbell
2008-Oct-15 12:40 UTC
[Xen-devel] make injection of spurious page faults configurable per domain
make injection of spurious page faults configurable per domain Some distro kernels do not handle spurious page faults so allow these to be supressed on a per VM basis. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> diff -r a26194601c8f tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Mon Oct 13 13:15:20 2008 +0100 +++ b/tools/libxc/xc_domain.c Tue Oct 14 14:13:42 2008 +0100 @@ -1049,6 +1049,18 @@ int xc_domain_get_machine_address_size(i return rc == 0 ? domctl.u.address_size.size : rc; } +int xc_domain_suppress_spurious_page_faults(int xc, uint32_t domid) +{ + DECLARE_DOMCTL; + + memset(&domctl, 0, sizeof(domctl)); + domctl.domain = domid; + domctl.cmd = XEN_DOMCTL_suppress_spurious_page_faults; + + return do_domctl(xc, &domctl); + +} + /* * Local variables: * mode: C diff -r a26194601c8f tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Oct 13 13:15:20 2008 +0100 +++ b/tools/libxc/xenctrl.h Tue Oct 14 14:13:42 2008 +0100 @@ -1103,6 +1103,9 @@ int xc_domain_get_machine_address_size(i int xc_domain_get_machine_address_size(int handle, uint32_t domid); +int xc_domain_suppress_spurious_page_faults(int handle, + uint32_t domid); + /* Set the target domain */ int xc_domain_set_target(int xc_handle, uint32_t domid, diff -r a26194601c8f tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Mon Oct 13 13:15:20 2008 +0100 +++ b/tools/python/xen/lowlevel/xc/xc.c Tue Oct 14 14:13:42 2008 +0100 @@ -859,6 +859,21 @@ static PyObject *pyxc_dom_set_machine_ad return zero; } +static PyObject *pyxc_dom_suppress_spurious_page_faults(XcObject *self, + PyObject *args, + PyObject *kwds) +{ + uint32_t dom; + + if (!PyArg_ParseTuple(args, "i", &dom)) + return NULL; + + if (xc_domain_suppress_spurious_page_faults(self->xc_handle, dom) != 0) + return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; +} #endif /* __i386__ || __x86_64__ */ static PyObject *pyxc_hvm_build(XcObject *self, @@ -1911,6 +1926,12 @@ static PyMethodDef pyxc_methods[] = { "Set maximum machine address size for this domain.\n" " dom [int]: Identifier of domain.\n" " width [int]: Maximum machine address width.\n" }, + + { "domain_suppress_spurious_page_faults", + (PyCFunction)pyxc_dom_suppress_spurious_page_faults, + METH_VARARGS, "\n" + "Do not propagate spurious page faults to this guest.\n" + " dom [int]: Identifier of domain.\n" }, #endif { NULL, NULL, 0, NULL } diff -r a26194601c8f tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Mon Oct 13 13:15:20 2008 +0100 +++ b/tools/python/xen/xend/XendConfig.py Tue Oct 14 14:13:42 2008 +0100 @@ -208,6 +208,7 @@ XENAPI_CFG_TYPES = { ''cpuid'' : dict, ''cpuid_check'' : dict, ''machine_address_size'': int, + ''suppress_spurious_page_faults'': bool0, } # List of legacy configuration keys that have no equivalent in the diff -r a26194601c8f tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Oct 13 13:15:20 2008 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Oct 15 10:00:19 2008 +0100 @@ -2236,6 +2236,10 @@ class XendDomainInfo: if self.info.has_key(''machine_address_size''): log.debug("_initDomain: setting maximum machine address size %d" % self.info[''machine_address_size'']) xc.domain_set_machine_address_size(self.domid, self.info[''machine_address_size'']) + + if self.info.has_key(''suppress_spurious_page_faults'') and self.info[''suppress_spurious_page_faults'']: + log.debug("_initDomain: suppressing spurious page faults") + xc.domain_suppress_spurious_page_faults(self.domid) self._createChannels() diff -r a26194601c8f tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Mon Oct 13 13:15:20 2008 +0100 +++ b/tools/python/xen/xm/create.py Tue Oct 14 14:13:42 2008 +0100 @@ -578,6 +578,10 @@ gopts.var(''machine_address_size'', val=''B fn=set_int, default=None, use="""Maximum machine address size""") +gopts.var(''suppress_spurious_page_faults'', val=''yes|no'', + fn=set_bool, default=None, + use="""Do not inject spurious page faults into this guest""") + def err(msg): """Print an error to stderr and exit. """ @@ -628,6 +632,9 @@ def configure_image(vals): if vals.machine_address_size: config_image.append([''machine_address_size'', vals.machine_address_size]) + + if vals.suppress_spurious_page_faults: + config_image.append([''suppress_spurious_page_faults'', vals.suppress_spurious_page_faults]) return config_image @@ -881,7 +888,7 @@ def make_config(vals): ''restart'', ''on_poweroff'', ''on_reboot'', ''on_crash'', ''vcpus'', ''vcpu_avail'', ''features'', ''on_xend_start'', ''on_xend_stop'', ''target'', ''cpuid'', - ''cpuid_check'', ''machine_address_size'']) + ''cpuid_check'', ''machine_address_size'', ''suppress_spurious_page_faults'']) if vals.uuid is not None: config.append([''uuid'', vals.uuid]) diff -r a26194601c8f xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Mon Oct 13 13:15:20 2008 +0100 +++ b/xen/arch/x86/domctl.c Tue Oct 14 14:13:42 2008 +0100 @@ -1028,6 +1028,21 @@ long arch_do_domctl( } break; + case XEN_DOMCTL_suppress_spurious_page_faults: + { + struct domain *d; + + ret = -ESRCH; + d = rcu_lock_domain_by_id(domctl->domain); + if ( d != NULL ) + { + d->arch.suppress_spurious_page_faults = 1; + rcu_unlock_domain(d); + ret = 0; + } + } + break; + default: ret = -ENOSYS; break; diff -r a26194601c8f xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Mon Oct 13 13:15:20 2008 +0100 +++ b/xen/arch/x86/traps.c Wed Oct 15 10:02:15 2008 +0100 @@ -1229,6 +1229,10 @@ asmlinkage void do_page_fault(struct cpu "Faulting linear address: %p\n", regs->error_code, _p(addr)); } + + if ( unlikely(current->domain->arch.suppress_spurious_page_faults + && spurious_page_fault(addr, regs)) ) + return; propagate_page_fault(addr, regs->error_code); } diff -r a26194601c8f xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Mon Oct 13 13:15:20 2008 +0100 +++ b/xen/include/asm-x86/domain.h Tue Oct 14 14:13:42 2008 +0100 @@ -250,6 +250,8 @@ struct arch_domain bool_t is_32bit_pv; /* Is shared-info page in 32-bit format? */ bool_t has_32bit_shinfo; + /* Domain cannot handle spurious page faults? */ + bool_t suppress_spurious_page_faults; /* Continuable domain_relinquish_resources(). */ enum { diff -r a26194601c8f xen/include/public/domctl.h --- a/xen/include/public/domctl.h Mon Oct 13 13:15:20 2008 +0100 +++ b/xen/include/public/domctl.h Tue Oct 14 14:13:42 2008 +0100 @@ -614,6 +614,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_subsc #define XEN_DOMCTL_set_machine_address_size 51 #define XEN_DOMCTL_get_machine_address_size 52 +/* + * Do not inject spurious page faults into this domain. + */ +#define XEN_DOMCTL_suppress_spurious_page_faults 53 struct xen_domctl { uint32_t cmd; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel