xcp-1.6-updates/xen-4.1.hg

changeset 23270:c7729c73fefc

x86: make the pv-only e820 array be dynamic.

During creation of the PV domain we allocate the E820 structure to
have the amount of E820 entries on the machine, plus the number three.

This will allow the tool stack to fill the E820 with more than three
entries. Specifically the use cases is , where the toolstack retrieves
the E820, sanitizes it, and then sets it for the PV guest (for PCI
passthrough), this dynamic number of E820 is just right.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Keir Fraser <keir@xen.org>
xen-unstable changeset: 23225:3f00c5faa12a
xen-unstable date: Wed Apr 13 16:10:26 2011 +0100
author Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
date Thu Mar 29 10:19:56 2012 +0100 (2012-03-29)
parents d67e4d12723f
children 13741fd6253b
files xen/arch/x86/domain.c xen/arch/x86/mm.c xen/include/asm-x86/domain.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Fri Mar 23 14:01:05 2012 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Thu Mar 29 10:19:56 2012 +0100
     1.3 @@ -557,6 +557,8 @@ int arch_domain_create(struct domain *d,
     1.4          /* 32-bit PV guest by default only if Xen is not 64-bit. */
     1.5          d->arch.is_32bit_pv = d->arch.has_32bit_shinfo =
     1.6              (CONFIG_PAGING_LEVELS != 4);
     1.7 +
     1.8 +        spin_lock_init(&d->arch.e820_lock);
     1.9      }
    1.10  
    1.11      memset(d->arch.cpuids, 0, sizeof(d->arch.cpuids));
    1.12 @@ -603,6 +605,8 @@ void arch_domain_destroy(struct domain *
    1.13  
    1.14      if ( is_hvm_domain(d) )
    1.15          hvm_domain_destroy(d);
    1.16 +    else
    1.17 +        xfree(d->arch.e820);
    1.18  
    1.19      vmce_destroy_msr(d);
    1.20      free_domain_pirqs(d);
     2.1 --- a/xen/arch/x86/mm.c	Fri Mar 23 14:01:05 2012 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Thu Mar 29 10:19:56 2012 +0100
     2.3 @@ -99,6 +99,7 @@
     2.4  #include <xen/event.h>
     2.5  #include <xen/iocap.h>
     2.6  #include <xen/guest_access.h>
     2.7 +#include <xen/xmalloc.h>
     2.8  #include <asm/paging.h>
     2.9  #include <asm/shadow.h>
    2.10  #include <asm/page.h>
    2.11 @@ -4667,11 +4668,12 @@ long arch_memory_op(int op, XEN_GUEST_HA
    2.12      {
    2.13          struct xen_foreign_memory_map fmap;
    2.14          struct domain *d;
    2.15 +        struct e820entry *e820;
    2.16  
    2.17          if ( copy_from_guest(&fmap, arg, 1) )
    2.18              return -EFAULT;
    2.19  
    2.20 -        if ( fmap.map.nr_entries > ARRAY_SIZE(d->arch.e820) )
    2.21 +        if ( fmap.map.nr_entries > E820MAX )
    2.22              return -EINVAL;
    2.23  
    2.24          rc = rcu_lock_target_domain_by_id(fmap.domid, &d);
    2.25 @@ -4685,9 +4687,25 @@ long arch_memory_op(int op, XEN_GUEST_HA
    2.26              return rc;
    2.27          }
    2.28  
    2.29 -        rc = copy_from_guest(d->arch.e820, fmap.map.buffer,
    2.30 -                             fmap.map.nr_entries) ? -EFAULT : 0;
    2.31 +        e820 = xmalloc_array(e820entry_t, fmap.map.nr_entries);
    2.32 +        if ( e820 == NULL )
    2.33 +        {
    2.34 +            rcu_unlock_domain(d);
    2.35 +            return -ENOMEM;
    2.36 +        }
    2.37 +
    2.38 +        if ( copy_from_guest(e820, fmap.map.buffer, fmap.map.nr_entries) )
    2.39 +        {
    2.40 +            xfree(e820);
    2.41 +            rcu_unlock_domain(d);
    2.42 +            return -EFAULT;
    2.43 +        }
    2.44 +
    2.45 +        spin_lock(&d->arch.e820_lock);
    2.46 +        xfree(d->arch.e820);
    2.47 +        d->arch.e820 = e820;
    2.48          d->arch.nr_e820 = fmap.map.nr_entries;
    2.49 +	spin_unlock(&d->arch.e820_lock);
    2.50  
    2.51          rcu_unlock_domain(d);
    2.52          return rc;
    2.53 @@ -4698,18 +4716,28 @@ long arch_memory_op(int op, XEN_GUEST_HA
    2.54          struct xen_memory_map map;
    2.55          struct domain *d = current->domain;
    2.56  
    2.57 -        /* Backwards compatibility. */
    2.58 -        if ( d->arch.nr_e820 == 0 )
    2.59 -            return -ENOSYS;
    2.60 -
    2.61          if ( copy_from_guest(&map, arg, 1) )
    2.62              return -EFAULT;
    2.63  
    2.64 +        spin_lock(&d->arch.e820_lock);
    2.65 +
    2.66 +        /* Backwards compatibility. */
    2.67 +        if ( (d->arch.nr_e820 == 0) ||
    2.68 +             (d->arch.e820 == NULL) )
    2.69 +        {
    2.70 +            spin_unlock(&d->arch.e820_lock);
    2.71 +            return -ENOSYS;
    2.72 +        }
    2.73 +
    2.74          map.nr_entries = min(map.nr_entries, d->arch.nr_e820);
    2.75          if ( copy_to_guest(map.buffer, d->arch.e820, map.nr_entries) ||
    2.76               copy_to_guest(arg, &map, 1) )
    2.77 +        {
    2.78 +            spin_unlock(&d->arch.e820_lock);
    2.79              return -EFAULT;
    2.80 -
    2.81 +        }
    2.82 +
    2.83 +        spin_unlock(&d->arch.e820_lock);
    2.84          return 0;
    2.85      }
    2.86  
     3.1 --- a/xen/include/asm-x86/domain.h	Fri Mar 23 14:01:05 2012 +0000
     3.2 +++ b/xen/include/asm-x86/domain.h	Thu Mar 29 10:19:56 2012 +0100
     3.3 @@ -270,7 +270,8 @@ struct arch_domain
     3.4      unsigned long pirq_eoi_map_mfn;
     3.5  
     3.6      /* Pseudophysical e820 map (XENMEM_memory_map).  */
     3.7 -    struct e820entry e820[3];
     3.8 +    spinlock_t e820_lock;
     3.9 +    struct e820entry *e820;
    3.10      unsigned int nr_e820;
    3.11  
    3.12      /* Maximum physical-address bitwidth supported by this guest. */