ia64/xen-unstable

changeset 18039: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>
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);