direct-io.hg

changeset 12803:df5fa63490f4

[XEN] Implement XENMEM_set_memory_map, which specifies memory map to
be returned by XENMEM_memory_map. Hook this into the domain builder.

Based on a patch by Glauber de Oliveira Costa <gcosta@redhat.com>

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Dec 08 11:30:30 2006 +0000 (2006-12-08)
parents 8beecb8c5ae2
children 7c3dee5ff185
files tools/libxc/xc_domain.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py xen/arch/x86/mm.c xen/include/asm-x86/domain.h xen/include/public/memory.h
line diff
     1.1 --- a/tools/libxc/xc_domain.c	Fri Dec 08 11:08:26 2006 +0000
     1.2 +++ b/tools/libxc/xc_domain.c	Fri Dec 08 11:30:30 2006 +0000
     1.3 @@ -316,6 +316,52 @@ int xc_domain_setmaxmem(int xc_handle,
     1.4      return do_domctl(xc_handle, &domctl);
     1.5  }
     1.6  
     1.7 +#if defined(__i386__) || defined(__x86_64__)
     1.8 +#include <xen/hvm/e820.h>
     1.9 +int xc_domain_set_memmap_limit(int xc_handle,
    1.10 +                               uint32_t domid,
    1.11 +                               unsigned long map_limitkb)
    1.12 +{
    1.13 +    int rc;
    1.14 +
    1.15 +    struct xen_foreign_memory_map fmap = {
    1.16 +        .domid = domid,
    1.17 +        .map = { .nr_entries = 1 }
    1.18 +    };
    1.19 +
    1.20 +    struct e820entry e820 = {
    1.21 +        .addr = 0,
    1.22 +        .size = (uint64_t)map_limitkb << 10,
    1.23 +        .type = E820_RAM
    1.24 +    };
    1.25 +
    1.26 +    set_xen_guest_handle(fmap.map.buffer, &e820);
    1.27 +
    1.28 +    if ( lock_pages(&fmap, sizeof(fmap)) || lock_pages(&e820, sizeof(e820)) )
    1.29 +    {
    1.30 +        PERROR("Could not lock memory for Xen hypercall");
    1.31 +        rc = -1;
    1.32 +        goto out;
    1.33 +    }
    1.34 +
    1.35 +    rc = xc_memory_op(xc_handle, XENMEM_set_memory_map, &fmap);
    1.36 +
    1.37 + out:
    1.38 +    unlock_pages(&fmap, sizeof(fmap));
    1.39 +    unlock_pages(&e820, sizeof(e820));
    1.40 +    return rc;
    1.41 +}
    1.42 +#else
    1.43 +int xc_domain_set_memmap_limit(int xc_handle,
    1.44 +                               uint32_t domid,
    1.45 +                               unsigned long map_limitkb)
    1.46 +{
    1.47 +    PERROR("Function not implemented");
    1.48 +    errno = ENOSYS;
    1.49 +    return -1;
    1.50 +}
    1.51 +#endif
    1.52 +
    1.53  int xc_domain_set_time_offset(int xc_handle,
    1.54                                uint32_t domid,
    1.55                                int32_t time_offset_seconds)
     2.1 --- a/tools/libxc/xenctrl.h	Fri Dec 08 11:08:26 2006 +0000
     2.2 +++ b/tools/libxc/xenctrl.h	Fri Dec 08 11:30:30 2006 +0000
     2.3 @@ -419,6 +419,10 @@ int xc_domain_setmaxmem(int xc_handle,
     2.4                          uint32_t domid,
     2.5                          unsigned int max_memkb);
     2.6  
     2.7 +int xc_domain_set_memmap_limit(int xc_handle,
     2.8 +                               uint32_t domid,
     2.9 +                               unsigned long map_limitkb);
    2.10 +
    2.11  int xc_domain_set_time_offset(int xc_handle,
    2.12                                uint32_t domid,
    2.13                                int32_t time_offset_seconds);
     3.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Fri Dec 08 11:08:26 2006 +0000
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri Dec 08 11:30:30 2006 +0000
     3.3 @@ -758,6 +758,21 @@ static PyObject *pyxc_domain_setmaxmem(X
     3.4      return zero;
     3.5  }
     3.6  
     3.7 +static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
     3.8 +{
     3.9 +    uint32_t dom;
    3.10 +    unsigned int maplimit_kb;
    3.11 +
    3.12 +    if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
    3.13 +        return NULL;
    3.14 +
    3.15 +    if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
    3.16 +        return pyxc_error_to_exception();
    3.17 +    
    3.18 +    Py_INCREF(zero);
    3.19 +    return zero;
    3.20 +}
    3.21 +
    3.22  static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
    3.23                                                           PyObject *args,
    3.24                                                           PyObject *kwds)
    3.25 @@ -1141,6 +1156,14 @@ static PyMethodDef pyxc_methods[] = {
    3.26        " maxmem_kb [int]: .\n"
    3.27        "Returns: [int] 0 on success; -1 on error.\n" },
    3.28  
    3.29 +    { "domain_set_memmap_limit", 
    3.30 +      (PyCFunction)pyxc_domain_set_memmap_limit, 
    3.31 +      METH_VARARGS, "\n"
    3.32 +      "Set a domain's physical memory mappping limit\n"
    3.33 +      " dom [int]: Identifier of domain.\n"
    3.34 +      " map_limitkb [int]: .\n"
    3.35 +      "Returns: [int] 0 on success; -1 on error.\n" },
    3.36 +
    3.37      { "domain_memory_increase_reservation", 
    3.38        (PyCFunction)pyxc_domain_memory_increase_reservation, 
    3.39        METH_VARARGS | METH_KEYWORDS, "\n"
     4.1 --- a/tools/python/xen/xend/image.py	Fri Dec 08 11:08:26 2006 +0000
     4.2 +++ b/tools/python/xen/xend/image.py	Fri Dec 08 11:30:30 2006 +0000
     4.3 @@ -548,6 +548,14 @@ class X86_HVM_ImageHandler(HVMImageHandl
     4.4          return max(4 * (256 * self.vm.getVCpuCount() + 2 * (maxmem_kb / 1024)),
     4.5                     shadow_mem_kb)
     4.6  
     4.7 +class X86_Linux_ImageHandler(LinuxImageHandler):
     4.8 +
     4.9 +    def buildDomain(self):
    4.10 +        # set physical mapping limit
    4.11 +        # add an 8MB slack to balance backend allocations.
    4.12 +        mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
    4.13 +        xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
    4.14 +        return LinuxImageHandler.buildDomain(self)
    4.15  
    4.16  _handlers = {
    4.17      "powerpc": {
    4.18 @@ -558,7 +566,7 @@ class X86_HVM_ImageHandler(HVMImageHandl
    4.19          "hvm": IA64_HVM_ImageHandler,
    4.20      },
    4.21      "x86": {
    4.22 -        "linux": LinuxImageHandler,
    4.23 +        "linux": X86_Linux_ImageHandler,
    4.24          "hvm": X86_HVM_ImageHandler,
    4.25      },
    4.26  }
     5.1 --- a/xen/arch/x86/mm.c	Fri Dec 08 11:08:26 2006 +0000
     5.2 +++ b/xen/arch/x86/mm.c	Fri Dec 08 11:30:30 2006 +0000
     5.3 @@ -2978,9 +2978,54 @@ long arch_memory_op(int op, XEN_GUEST_HA
     5.4          break;
     5.5      }
     5.6  
     5.7 +    case XENMEM_set_memory_map:
     5.8 +    {
     5.9 +        struct xen_foreign_memory_map fmap;
    5.10 +        struct domain *d;
    5.11 +        int rc;
    5.12 +
    5.13 +        if ( copy_from_guest(&fmap, arg, 1) )
    5.14 +            return -EFAULT;
    5.15 +
    5.16 +        if ( fmap.map.nr_entries > ARRAY_SIZE(d->arch.e820) )
    5.17 +            return -EINVAL;
    5.18 +
    5.19 +        if ( fmap.domid == DOMID_SELF )
    5.20 +        {
    5.21 +            d = current->domain;
    5.22 +            get_knownalive_domain(d);
    5.23 +        }
    5.24 +        else if ( !IS_PRIV(current->domain) )
    5.25 +            return -EPERM;
    5.26 +        else if ( (d = find_domain_by_id(fmap.domid)) == NULL )
    5.27 +            return -ESRCH;
    5.28 +
    5.29 +        rc = copy_from_guest(&d->arch.e820[0], fmap.map.buffer,
    5.30 +                             fmap.map.nr_entries) ? -EFAULT : 0;
    5.31 +        d->arch.nr_e820 = fmap.map.nr_entries;
    5.32 +
    5.33 +        put_domain(d);
    5.34 +        return rc;
    5.35 +    }
    5.36 +
    5.37      case XENMEM_memory_map:
    5.38      {
    5.39 -        return -ENOSYS;
    5.40 +        struct xen_memory_map map;
    5.41 +        struct domain *d = current->domain;
    5.42 +
    5.43 +        /* Backwards compatibility. */
    5.44 +        if ( d->arch.nr_e820 == 0 )
    5.45 +            return -ENOSYS;
    5.46 +
    5.47 +        if ( copy_from_guest(&map, arg, 1) )
    5.48 +            return -EFAULT;
    5.49 +
    5.50 +        map.nr_entries = min(map.nr_entries, d->arch.nr_e820);
    5.51 +        if ( copy_to_guest(map.buffer, &d->arch.e820[0], map.nr_entries) ||
    5.52 +             copy_to_guest(arg, &map, 1) )
    5.53 +            return -EFAULT;
    5.54 +
    5.55 +        return 0;
    5.56      }
    5.57  
    5.58      case XENMEM_machine_memory_map:
     6.1 --- a/xen/include/asm-x86/domain.h	Fri Dec 08 11:08:26 2006 +0000
     6.2 +++ b/xen/include/asm-x86/domain.h	Fri Dec 08 11:30:30 2006 +0000
     6.3 @@ -5,6 +5,7 @@
     6.4  #include <xen/mm.h>
     6.5  #include <asm/hvm/vcpu.h>
     6.6  #include <asm/hvm/domain.h>
     6.7 +#include <asm/e820.h>
     6.8  
     6.9  struct trap_bounce {
    6.10      unsigned long  error_code;
    6.11 @@ -100,11 +101,7 @@ struct arch_domain
    6.12      /* I/O-port admin-specified access capabilities. */
    6.13      struct rangeset *ioport_caps;
    6.14  
    6.15 -    /* HVM stuff */
    6.16 -    struct hvm_domain   hvm_domain;
    6.17 -
    6.18 -    /* Shadow-translated guest: Pseudophys base address of reserved area. */
    6.19 -    unsigned long first_reserved_pfn;
    6.20 +    struct hvm_domain hvm_domain;
    6.21  
    6.22      struct shadow_domain shadow;
    6.23  
    6.24 @@ -113,6 +110,9 @@ struct arch_domain
    6.25      /* Highest guest frame that's ever been mapped in the p2m */
    6.26      unsigned long max_mapped_pfn;
    6.27  
    6.28 +    /* Pseudophysical e820 map (XENMEM_memory_map).  */
    6.29 +    struct e820entry e820[3];
    6.30 +    unsigned int nr_e820;
    6.31  } __cacheline_aligned;
    6.32  
    6.33  #ifdef CONFIG_X86_PAE
     7.1 --- a/xen/include/public/memory.h	Fri Dec 08 11:08:26 2006 +0000
     7.2 +++ b/xen/include/public/memory.h	Fri Dec 08 11:30:30 2006 +0000
     7.3 @@ -222,7 +222,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_translate_gp
     7.4  
     7.5  /*
     7.6   * Returns the pseudo-physical memory map as it was when the domain
     7.7 - * was started.
     7.8 + * was started (specified by XENMEM_set_memory_map).
     7.9 + * arg == addr of xen_memory_map_t.
    7.10   */
    7.11  #define XENMEM_memory_map           9
    7.12  struct xen_memory_map {
    7.13 @@ -245,9 +246,23 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t
    7.14  /*
    7.15   * Returns the real physical memory map. Passes the same structure as
    7.16   * XENMEM_memory_map.
    7.17 + * arg == addr of xen_memory_map_t.
    7.18   */
    7.19  #define XENMEM_machine_memory_map	10
    7.20  
    7.21 +/*
    7.22 + * Set the pseudo-physical memory map of a domain, as returned by
    7.23 + * XENMEM_memory_map.
    7.24 + * arg == addr of xen_foreign_memory_map_t.
    7.25 + */
    7.26 +#define XENMEM_set_memory_map       13
    7.27 +struct xen_foreign_memory_map {
    7.28 +    domid_t domid;
    7.29 +    struct xen_memory_map map;
    7.30 +};
    7.31 +typedef struct xen_foreign_memory_map xen_foreign_memory_map_t;
    7.32 +DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t);
    7.33 +
    7.34  #endif /* __XEN_PUBLIC_MEMORY_H__ */
    7.35  
    7.36  /*