ia64/xen-unstable
changeset 19090:39517e863cc8
x86_64: Widen page counts to avoid overflow.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
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