ia64/xen-unstable

changeset 19090:39517e863cc8

x86_64: Widen page counts to avoid overflow.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Jan 26 16:19:42 2009 +0000 (2009-01-26)
parents 055c589f4791
children fa5887d90110
files xen/arch/x86/domain.c xen/arch/x86/mm.c xen/arch/x86/mm/hap/hap.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/private.h xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_64/mm.c xen/common/xenoprof.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Mon Jan 26 14:56:19 2009 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Mon Jan 26 16:19:42 2009 +0000
     1.3 @@ -143,7 +143,7 @@ void dump_pageframe_info(struct domain *
     1.4      {
     1.5          list_for_each_entry ( page, &d->page_list, list )
     1.6          {
     1.7 -            printk("    DomPage %p: caf=%08x, taf=%" PRtype_info "\n",
     1.8 +            printk("    DomPage %p: caf=%08lx, taf=%" PRtype_info "\n",
     1.9                     _p(page_to_mfn(page)),
    1.10                     page->count_info, page->u.inuse.type_info);
    1.11          }
    1.12 @@ -156,7 +156,7 @@ void dump_pageframe_info(struct domain *
    1.13  
    1.14      list_for_each_entry ( page, &d->xenpage_list, list )
    1.15      {
    1.16 -        printk("    XenPage %p: caf=%08x, taf=%" PRtype_info "\n",
    1.17 +        printk("    XenPage %p: caf=%08lx, taf=%" PRtype_info "\n",
    1.18                 _p(page_to_mfn(page)),
    1.19                 page->count_info, page->u.inuse.type_info);
    1.20      }
     2.1 --- a/xen/arch/x86/mm.c	Mon Jan 26 14:56:19 2009 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Mon Jan 26 16:19:42 2009 +0000
     2.3 @@ -739,8 +739,8 @@ get_page_from_l1e(
     2.4      else if ( pte_flags_to_cacheattr(l1f) !=
     2.5                ((page->count_info >> PGC_cacheattr_base) & 7) )
     2.6      {
     2.7 -        uint32_t x, nx, y = page->count_info;
     2.8 -        uint32_t cacheattr = pte_flags_to_cacheattr(l1f);
     2.9 +        unsigned long x, nx, y = page->count_info;
    2.10 +        unsigned long cacheattr = pte_flags_to_cacheattr(l1f);
    2.11  
    2.12          if ( is_xen_heap_page(page) )
    2.13          {
    2.14 @@ -1909,7 +1909,7 @@ static int mod_l4_entry(l4_pgentry_t *pl
    2.15  
    2.16  void put_page(struct page_info *page)
    2.17  {
    2.18 -    u32 nx, x, y = page->count_info;
    2.19 +    unsigned long nx, x, y = page->count_info;
    2.20  
    2.21      do {
    2.22          x  = y;
    2.23 @@ -1927,7 +1927,7 @@ void put_page(struct page_info *page)
    2.24  
    2.25  int get_page(struct page_info *page, struct domain *domain)
    2.26  {
    2.27 -    u32 x, y = page->count_info;
    2.28 +    unsigned long x, y = page->count_info;
    2.29  
    2.30      do {
    2.31          x = y;
    2.32 @@ -1946,7 +1946,7 @@ int get_page(struct page_info *page, str
    2.33   fail:
    2.34      if ( !_shadow_mode_refcounts(domain) && !domain->is_dying )
    2.35          gdprintk(XENLOG_INFO,
    2.36 -                 "Error pfn %lx: rd=%p, od=%p, caf=%08x, taf=%" PRtype_info,
    2.37 +                 "Error pfn %lx: rd=%p, od=%p, caf=%08lx, taf=%" PRtype_info,
    2.38                   page_to_mfn(page), domain, page_get_owner(page),
    2.39                   y, page->u.inuse.type_info);
    2.40      return 0;
    2.41 @@ -1962,7 +1962,7 @@ int get_page(struct page_info *page, str
    2.42   */
    2.43  static void get_page_light(struct page_info *page)
    2.44  {
    2.45 -    u32 x, nx, y = page->count_info;
    2.46 +    unsigned long x, nx, y = page->count_info;
    2.47  
    2.48      do {
    2.49          x  = y;
    2.50 @@ -2003,7 +2003,7 @@ static int alloc_page_type(struct page_i
    2.51          rc = alloc_segdesc_page(page);
    2.52          break;
    2.53      default:
    2.54 -        printk("Bad type in alloc_page_type %lx t=%" PRtype_info " c=%x\n", 
    2.55 +        printk("Bad type in alloc_page_type %lx t=%" PRtype_info " c=%lx\n", 
    2.56                 type, page->u.inuse.type_info,
    2.57                 page->count_info);
    2.58          rc = -EINVAL;
    2.59 @@ -2027,7 +2027,7 @@ static int alloc_page_type(struct page_i
    2.60      {
    2.61          ASSERT(rc < 0);
    2.62          MEM_LOG("Error while validating mfn %lx (pfn %lx) for type %"
    2.63 -                PRtype_info ": caf=%08x taf=%" PRtype_info,
    2.64 +                PRtype_info ": caf=%08lx taf=%" PRtype_info,
    2.65                  page_to_mfn(page), get_gpfn_from_mfn(page_to_mfn(page)),
    2.66                  type, page->count_info, page->u.inuse.type_info);
    2.67          page->u.inuse.type_info = 0;
    2.68 @@ -3184,7 +3184,7 @@ static int create_grant_pte_mapping(
    2.69      void *va;
    2.70      unsigned long gmfn, mfn;
    2.71      struct page_info *page;
    2.72 -    u32 type;
    2.73 +    unsigned long type;
    2.74      l1_pgentry_t ol1e;
    2.75      struct domain *d = v->domain;
    2.76  
    2.77 @@ -3245,7 +3245,7 @@ static int destroy_grant_pte_mapping(
    2.78      void *va;
    2.79      unsigned long gmfn, mfn;
    2.80      struct page_info *page;
    2.81 -    u32 type;
    2.82 +    unsigned long type;
    2.83      l1_pgentry_t ol1e;
    2.84  
    2.85      gmfn = addr >> PAGE_SHIFT;
    2.86 @@ -3471,7 +3471,7 @@ int replace_grant_host_mapping(
    2.87  int steal_page(
    2.88      struct domain *d, struct page_info *page, unsigned int memflags)
    2.89  {
    2.90 -    u32 x, y;
    2.91 +    unsigned long x, y;
    2.92  
    2.93      spin_lock(&d->page_alloc_lock);
    2.94  
    2.95 @@ -3508,7 +3508,7 @@ int steal_page(
    2.96  
    2.97   fail:
    2.98      spin_unlock(&d->page_alloc_lock);
    2.99 -    MEM_LOG("Bad page %p: ed=%p(%u), sd=%p, caf=%08x, taf=%" PRtype_info,
   2.100 +    MEM_LOG("Bad page %p: ed=%p(%u), sd=%p, caf=%08lx, taf=%" PRtype_info,
   2.101              (void *)page_to_mfn(page), d, d->domain_id,
   2.102              page_get_owner(page), page->count_info, page->u.inuse.type_info);
   2.103      return -1;
     3.1 --- a/xen/arch/x86/mm/hap/hap.c	Mon Jan 26 14:56:19 2009 +0000
     3.2 +++ b/xen/arch/x86/mm/hap/hap.c	Mon Jan 26 16:19:42 2009 +0000
     3.3 @@ -166,7 +166,7 @@ void hap_free_p2m_page(struct domain *d,
     3.4      ASSERT(page_get_owner(pg) == d);
     3.5      /* Should have just the one ref we gave it in alloc_p2m_page() */
     3.6      if ( (pg->count_info & PGC_count_mask) != 1 )
     3.7 -        HAP_ERROR("Odd p2m page count c=%#x t=%"PRtype_info"\n",
     3.8 +        HAP_ERROR("Odd p2m page count c=%#lx t=%"PRtype_info"\n",
     3.9                    pg->count_info, pg->u.inuse.type_info);
    3.10      pg->count_info = 0;
    3.11      /* Free should not decrement domain's total allocation, since
     4.1 --- a/xen/arch/x86/mm/shadow/common.c	Mon Jan 26 14:56:19 2009 +0000
     4.2 +++ b/xen/arch/x86/mm/shadow/common.c	Mon Jan 26 16:19:42 2009 +0000
     4.3 @@ -1715,7 +1715,7 @@ shadow_free_p2m_page(struct domain *d, s
     4.4      /* Should have just the one ref we gave it in alloc_p2m_page() */
     4.5      if ( (pg->count_info & PGC_count_mask) != 1 )
     4.6      {
     4.7 -        SHADOW_ERROR("Odd p2m page count c=%#x t=%"PRtype_info"\n",
     4.8 +        SHADOW_ERROR("Odd p2m page count c=%#lx t=%"PRtype_info"\n",
     4.9                       pg->count_info, pg->u.inuse.type_info);
    4.10      }
    4.11      pg->count_info = 0;
    4.12 @@ -2593,7 +2593,7 @@ int sh_remove_all_mappings(struct vcpu *
    4.13                 && (page->u.inuse.type_info & PGT_count_mask) == 0) )
    4.14          {
    4.15              SHADOW_ERROR("can't find all mappings of mfn %lx: "
    4.16 -                          "c=%08x t=%08lx\n", mfn_x(gmfn), 
    4.17 +                          "c=%08lx t=%08lx\n", mfn_x(gmfn), 
    4.18                            page->count_info, page->u.inuse.type_info);
    4.19          }
    4.20      }
     5.1 --- a/xen/arch/x86/mm/shadow/private.h	Mon Jan 26 14:56:19 2009 +0000
     5.2 +++ b/xen/arch/x86/mm/shadow/private.h	Mon Jan 26 16:19:42 2009 +0000
     5.3 @@ -247,8 +247,13 @@ struct shadow_page_info
     5.4                  unsigned int type:5;   /* What kind of shadow is this? */
     5.5                  unsigned int pinned:1; /* Is the shadow pinned? */
     5.6                  unsigned int count:26; /* Reference count */
     5.7 -                u32 mbz;               /* Must be zero: this is where the
     5.8 +#ifdef __x86_64__
     5.9 +                u32 pad;
    5.10 +                u64 mbz;               /* Must be zero: this is where the
    5.11                                          * owner field lives in page_info */
    5.12 +#else
    5.13 +                u32 mbz;
    5.14 +#endif
    5.15              } __attribute__((packed));
    5.16              union {
    5.17                  /* For unused shadow pages, a list of pages of this order; for 
     6.1 --- a/xen/arch/x86/x86_32/mm.c	Mon Jan 26 14:56:19 2009 +0000
     6.2 +++ b/xen/arch/x86/x86_32/mm.c	Mon Jan 26 16:19:42 2009 +0000
     6.3 @@ -159,15 +159,6 @@ void __init subarch_init_memory(void)
     6.4      unsigned long m2p_start_mfn;
     6.5      unsigned int i, j;
     6.6  
     6.7 -    /*
     6.8 -     * We are rather picky about the layout of 'struct page_info'. The
     6.9 -     * count_info and domain fields must be adjacent, as we perform atomic
    6.10 -     * 64-bit operations on them. Also, just for sanity, we assert the size
    6.11 -     * of the structure here.
    6.12 -     */
    6.13 -    BUILD_BUG_ON(offsetof(struct page_info, u.inuse._domain) != 
    6.14 -                 (offsetof(struct page_info, count_info) + sizeof(u32)));
    6.15 -    BUILD_BUG_ON((offsetof(struct page_info, count_info) & 7) != 0);
    6.16      BUILD_BUG_ON(sizeof(struct page_info) != 24);
    6.17  
    6.18      /* M2P table is mappable read-only by privileged domains. */
     7.1 --- a/xen/arch/x86/x86_64/mm.c	Mon Jan 26 14:56:19 2009 +0000
     7.2 +++ b/xen/arch/x86/x86_64/mm.c	Mon Jan 26 16:19:42 2009 +0000
     7.3 @@ -225,15 +225,6 @@ void __init subarch_init_memory(void)
     7.4      l3_pgentry_t l3e;
     7.5      l2_pgentry_t l2e;
     7.6  
     7.7 -    /*
     7.8 -     * We are rather picky about the layout of 'struct page_info'. The
     7.9 -     * count_info and domain fields must be adjacent, as we perform atomic
    7.10 -     * 64-bit operations on them.
    7.11 -     */
    7.12 -    BUILD_BUG_ON(offsetof(struct page_info, u.inuse._domain) != 
    7.13 -                 (offsetof(struct page_info, count_info) + sizeof(u32)));
    7.14 -    BUILD_BUG_ON((offsetof(struct page_info, count_info) & 7) != 0);
    7.15 -
    7.16      /* M2P table is mappable read-only by privileged domains. */
    7.17      for ( v  = RDWR_MPT_VIRT_START;
    7.18            v != RDWR_MPT_VIRT_END;
     8.1 --- a/xen/common/xenoprof.c	Mon Jan 26 14:56:19 2009 +0000
     8.2 +++ b/xen/common/xenoprof.c	Mon Jan 26 16:19:42 2009 +0000
     8.3 @@ -142,8 +142,8 @@ share_xenoprof_page_with_guest(struct do
     8.4         struct page_info *page = mfn_to_page(mfn + i);
     8.5         if ( (page->count_info & (PGC_allocated|PGC_count_mask)) != 0 )
     8.6         {
     8.7 -           gdprintk(XENLOG_INFO, "mfn 0x%lx page->count_info 0x%x\n",
     8.8 -                    mfn + i, page->count_info);
     8.9 +           gdprintk(XENLOG_INFO, "mfn 0x%lx page->count_info 0x%lx\n",
    8.10 +                    mfn + i, (unsigned long)page->count_info);
    8.11             return -EBUSY;
    8.12         }
    8.13         page_set_owner(page, NULL);
     9.1 --- a/xen/include/asm-x86/mm.h	Mon Jan 26 14:56:19 2009 +0000
     9.2 +++ b/xen/include/asm-x86/mm.h	Mon Jan 26 16:19:42 2009 +0000
     9.3 @@ -23,7 +23,7 @@ struct page_info
     9.4      struct list_head list;
     9.5  
     9.6      /* Reference count and various PGC_xxx flags and fields. */
     9.7 -    u32 count_info;
     9.8 +    unsigned long count_info;
     9.9  
    9.10      /* Context-dependent fields follow... */
    9.11      union {
    9.12 @@ -31,7 +31,7 @@ struct page_info
    9.13          /* Page is in use: ((count_info & PGC_count_mask) != 0). */
    9.14          struct {
    9.15              /* Owner of this page (NULL if page is anonymous). */
    9.16 -            u32 _domain; /* pickled format */
    9.17 +            unsigned long _domain; /* pickled format */
    9.18              /* Type reference count and various PGT_xxx flags and fields. */
    9.19              unsigned long type_info;
    9.20          } __attribute__ ((packed)) inuse;
    9.21 @@ -102,52 +102,57 @@ struct page_info
    9.22      };
    9.23  };
    9.24  
    9.25 +#define PG_shift(idx)   (BITS_PER_LONG - (idx))
    9.26 +#define PG_mask(x, idx) (x ## UL << PG_shift(idx))
    9.27 +
    9.28   /* The following page types are MUTUALLY EXCLUSIVE. */
    9.29 -#define PGT_none            (0U<<29) /* no special uses of this page */
    9.30 -#define PGT_l1_page_table   (1U<<29) /* using this page as an L1 page table? */
    9.31 -#define PGT_l2_page_table   (2U<<29) /* using this page as an L2 page table? */
    9.32 -#define PGT_l3_page_table   (3U<<29) /* using this page as an L3 page table? */
    9.33 -#define PGT_l4_page_table   (4U<<29) /* using this page as an L4 page table? */
    9.34 -#define PGT_seg_desc_page   (5U<<29) /* using this page in a GDT/LDT? */
    9.35 -#define PGT_writable_page   (7U<<29) /* has writable mappings of this page? */
    9.36 -#define PGT_type_mask       (7U<<29) /* Bits 29-31. */
    9.37 +#define PGT_none          PG_mask(0, 3) /* no special uses of this page */
    9.38 +#define PGT_l1_page_table PG_mask(1, 3) /* using as an L1 page table? */
    9.39 +#define PGT_l2_page_table PG_mask(2, 3) /* using as an L2 page table? */
    9.40 +#define PGT_l3_page_table PG_mask(3, 3) /* using as an L3 page table? */
    9.41 +#define PGT_l4_page_table PG_mask(4, 3) /* using as an L4 page table? */
    9.42 +#define PGT_seg_desc_page PG_mask(5, 3) /* using this page in a GDT/LDT? */
    9.43 +#define PGT_writable_page PG_mask(7, 3) /* has writable mappings? */
    9.44 +#define PGT_type_mask     PG_mask(7, 3) /* Bits 29-31. */
    9.45  
    9.46   /* Owning guest has pinned this page to its current type? */
    9.47 -#define _PGT_pinned         28
    9.48 -#define PGT_pinned          (1U<<_PGT_pinned)
    9.49 +#define _PGT_pinned       PG_shift(4)
    9.50 +#define PGT_pinned        PG_mask(1, 4)
    9.51   /* Has this page been validated for use as its current type? */
    9.52 -#define _PGT_validated      27
    9.53 -#define PGT_validated       (1U<<_PGT_validated)
    9.54 +#define _PGT_validated    PG_shift(5)
    9.55 +#define PGT_validated     PG_mask(1, 5)
    9.56   /* PAE only: is this an L2 page directory containing Xen-private mappings? */
    9.57 -#define _PGT_pae_xen_l2     26
    9.58 -#define PGT_pae_xen_l2      (1U<<_PGT_pae_xen_l2)
    9.59 +#define _PGT_pae_xen_l2   PG_shift(6)
    9.60 +#define PGT_pae_xen_l2    PG_mask(1, 6)
    9.61  /* Has this page been *partially* validated for use as its current type? */
    9.62 -#define _PGT_partial        25
    9.63 -#define PGT_partial         (1U<<_PGT_partial)
    9.64 +#define _PGT_partial      PG_shift(7)
    9.65 +#define PGT_partial       PG_mask(1, 7)
    9.66  
    9.67 - /* 25-bit count of uses of this frame as its current type. */
    9.68 -#define PGT_count_mask      ((1U<<25)-1)
    9.69 + /* Count of uses of this frame as its current type. */
    9.70 +#define PGT_count_width   PG_shift(7)
    9.71 +#define PGT_count_mask    ((1UL<<PGT_count_width)-1)
    9.72  
    9.73   /* Cleared when the owning guest 'frees' this page. */
    9.74 -#define _PGC_allocated      31
    9.75 -#define PGC_allocated       (1U<<_PGC_allocated)
    9.76 +#define _PGC_allocated    PG_shift(1)
    9.77 +#define PGC_allocated     PG_mask(1, 1)
    9.78  #if defined(__i386__)
    9.79   /* Page is locked? */
    9.80 -# define _PGC_locked        30
    9.81 -# define PGC_locked         (1U<<_PGC_out_of_sync)
    9.82 +# define _PGC_locked      PG_shift(2)
    9.83 +# define PGC_locked       PG_mask(1, 2)
    9.84  #else
    9.85   /* Page is Xen heap? */
    9.86 -# define _PGC_xen_heap      30
    9.87 -# define PGC_xen_heap       (1U<<_PGC_xen_heap)
    9.88 +# define _PGC_xen_heap    PG_shift(2)
    9.89 +# define PGC_xen_heap     PG_mask(1, 2)
    9.90  #endif
    9.91   /* Set when is using a page as a page table */
    9.92 -#define _PGC_page_table     29
    9.93 -#define PGC_page_table      (1U<<_PGC_page_table)
    9.94 +#define _PGC_page_table   PG_shift(3)
    9.95 +#define PGC_page_table    PG_mask(1, 3)
    9.96   /* 3-bit PAT/PCD/PWT cache-attribute hint. */
    9.97 -#define PGC_cacheattr_base  26
    9.98 -#define PGC_cacheattr_mask  (7U<<PGC_cacheattr_base)
    9.99 - /* 26-bit count of references to this frame. */
   9.100 -#define PGC_count_mask      ((1U<<26)-1)
   9.101 +#define PGC_cacheattr_base PG_shift(6)
   9.102 +#define PGC_cacheattr_mask PG_mask(7, 6)
   9.103 + /* Count of references to this frame. */
   9.104 +#define PGC_count_width   PG_shift(6)
   9.105 +#define PGC_count_mask    ((1UL<<PGC_count_width)-1)
   9.106  
   9.107  #if defined(__i386__)
   9.108  #define is_xen_heap_page(page) is_xen_heap_mfn(page_to_mfn(page))
   9.109 @@ -166,10 +171,8 @@ static inline struct domain *unpickle_do
   9.110  { return (_domain & 1) ? NULL : (void *)_domain; }
   9.111  #define PRtype_info "08lx" /* should only be used for printk's */
   9.112  #elif defined(__x86_64__)
   9.113 -static inline struct domain *unpickle_domptr(u32 _domain)
   9.114 -{ return ((_domain == 0) || (_domain & 1)) ? NULL : __va(_domain); }
   9.115 -static inline u32 pickle_domptr(struct domain *domain)
   9.116 -{ return (domain == NULL) ? 0 : (u32)__pa(domain); }
   9.117 +#define unpickle_domptr(d) ((struct domain *)(d))
   9.118 +#define pickle_domptr(d) ((unsigned long)(d))
   9.119  #define PRtype_info "016lx"/* should only be used for printk's */
   9.120  #endif
   9.121