diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown index a130452462..4002eab08b 100644 --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -133,13 +133,6 @@ resume. `s3_mode` instructs Xen to set up the boot time (option `vga=`) video mode during S3 resume. -### allowsuperpage -> `= ` - -> Default: `true` - -Permit Xen to use superpages when performing memory management. - ### altp2m (Intel) > `= ` diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index dd8bf1302f..1ce804b05f 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1782,8 +1782,6 @@ static int relinquish_memory( BUG(); } - clear_superpage_mark(page); - if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) put_page(page); diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 51c93c168f..97b3b4ba2c 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -150,18 +150,11 @@ struct rangeset *__read_mostly mmio_ro_ranges; #define PAGE_CACHE_ATTRS (_PAGE_PAT|_PAGE_PCD|_PAGE_PWT) -bool __read_mostly opt_allow_superpage; -boolean_param("allowsuperpage", opt_allow_superpage); - -static void put_superpage(unsigned long mfn); - static uint32_t base_disallow_mask; /* Global bit is allowed to be set on L1 PTEs. Intended for user mappings. */ #define L1_DISALLOW_MASK ((base_disallow_mask | _PAGE_GNTTAB) & ~_PAGE_GLOBAL) -#define L2_DISALLOW_MASK (unlikely(opt_allow_superpage) \ - ? base_disallow_mask & ~_PAGE_PSE \ - : base_disallow_mask) +#define L2_DISALLOW_MASK base_disallow_mask #define l3_disallow_mask(d) (!is_pv_32bit_domain(d) ? \ base_disallow_mask : 0xFFFFF198U) @@ -219,15 +212,6 @@ static void __init init_frametable_chunk(void *start, void *end) memset(end, -1, s - e); } -static void __init init_spagetable(void) -{ - BUILD_BUG_ON(XEN_VIRT_END > SPAGETABLE_VIRT_START); - - init_frametable_chunk(spage_table, - mem_hotplug ? spage_table + SPAGETABLE_NR - : pdx_to_spage(max_pdx - 1) + 1); -} - void __init init_frametable(void) { unsigned int sidx, eidx, nidx; @@ -252,9 +236,6 @@ void __init init_frametable(void) : end_pg; init_frametable_chunk(pdx_to_page(sidx * PDX_GROUP_COUNT), top_pg); memset(end_pg, -1, (unsigned long)top_pg - (unsigned long)end_pg); - - if (opt_allow_superpage) - init_spagetable(); } #ifndef NDEBUG @@ -1129,20 +1110,7 @@ get_page_from_l2e( return rc; } - if ( !opt_allow_superpage ) - { - gdprintk(XENLOG_WARNING, "PV superpages disabled in hypervisor\n"); - return -EINVAL; - } - - if ( mfn & (L1_PAGETABLE_ENTRIES - 1) ) - { - gdprintk(XENLOG_WARNING, - "Unaligned superpage map attempt mfn %" PRI_mfn "\n", mfn); - return -EINVAL; - } - - return get_superpage(mfn, d); + return -EINVAL; } @@ -1315,8 +1283,13 @@ static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn) return 1; if ( l2e_get_flags(l2e) & _PAGE_PSE ) - put_superpage(l2e_get_pfn(l2e)); - else + { + struct page_info *page = mfn_to_page(l2e_get_pfn(l2e)); + unsigned int i; + + for ( i = 0; i < (1u << PAGETABLE_ORDER); i++, page++ ) + put_page_and_type(page); + } else put_page_and_type(l2e_get_page(l2e)); return 0; @@ -2676,197 +2649,6 @@ int get_page_type_preemptible(struct page_info *page, unsigned long type) return __get_page_type(page, type, 1); } -static int get_spage_pages(struct page_info *page, struct domain *d) -{ - unsigned int i; - - for ( i = 0; i < (1u << PAGETABLE_ORDER); i++, page++ ) - { - if ( !get_page_and_type(page, d, PGT_writable_page) ) - { - while ( i-- > 0 ) - put_page_and_type(--page); - return 0; - } - } - return 1; -} - -static void put_spage_pages(struct page_info *page) -{ - unsigned int i; - - for ( i = 0; i < (1u << PAGETABLE_ORDER); i++, page++ ) - put_page_and_type(page); -} - -static int mark_superpage(struct spage_info *spage, struct domain *d) -{ - unsigned long x, nx, y = spage->type_info; - int pages_done = 0; - - ASSERT(opt_allow_superpage); - - do { - x = y; - nx = x + 1; - if ( (x & SGT_type_mask) == SGT_mark ) - { - gdprintk(XENLOG_WARNING, - "Duplicate superpage mark attempt mfn %" PRI_mfn "\n", - spage_to_mfn(spage)); - if ( pages_done ) - put_spage_pages(spage_to_page(spage)); - return -EINVAL; - } - if ( (x & SGT_type_mask) == SGT_dynamic ) - { - if ( pages_done ) - { - put_spage_pages(spage_to_page(spage)); - pages_done = 0; - } - } - else if ( !pages_done ) - { - if ( !get_spage_pages(spage_to_page(spage), d) ) - { - gdprintk(XENLOG_WARNING, - "Superpage type conflict in mark attempt mfn %" PRI_mfn "\n", - spage_to_mfn(spage)); - return -EINVAL; - } - pages_done = 1; - } - nx = (nx & ~SGT_type_mask) | SGT_mark; - - } while ( (y = cmpxchg(&spage->type_info, x, nx)) != x ); - - return 0; -} - -static int unmark_superpage(struct spage_info *spage) -{ - unsigned long x, nx, y = spage->type_info; - unsigned long do_pages = 0; - - ASSERT(opt_allow_superpage); - - do { - x = y; - nx = x - 1; - if ( (x & SGT_type_mask) != SGT_mark ) - { - gdprintk(XENLOG_WARNING, - "Attempt to unmark unmarked superpage mfn %" PRI_mfn "\n", - spage_to_mfn(spage)); - return -EINVAL; - } - if ( (nx & SGT_count_mask) == 0 ) - { - nx = (nx & ~SGT_type_mask) | SGT_none; - do_pages = 1; - } - else - { - nx = (nx & ~SGT_type_mask) | SGT_dynamic; - } - } while ( (y = cmpxchg(&spage->type_info, x, nx)) != x ); - - if ( do_pages ) - put_spage_pages(spage_to_page(spage)); - - return 0; -} - -void clear_superpage_mark(struct page_info *page) -{ - struct spage_info *spage; - - if ( !opt_allow_superpage ) - return; - - spage = page_to_spage(page); - if ((spage->type_info & SGT_type_mask) == SGT_mark) - unmark_superpage(spage); - -} - -int get_superpage(unsigned long mfn, struct domain *d) -{ - struct spage_info *spage; - unsigned long x, nx, y; - int pages_done = 0; - - ASSERT(opt_allow_superpage); - - if ( !mfn_valid(_mfn(mfn | (L1_PAGETABLE_ENTRIES - 1))) ) - return -EINVAL; - - spage = mfn_to_spage(mfn); - y = spage->type_info; - do { - x = y; - nx = x + 1; - if ( (x & SGT_type_mask) != SGT_none ) - { - if ( pages_done ) - { - put_spage_pages(spage_to_page(spage)); - pages_done = 0; - } - } - else - { - if ( !get_spage_pages(spage_to_page(spage), d) ) - { - gdprintk(XENLOG_WARNING, - "Type conflict on superpage mapping mfn %" PRI_mfn "\n", - spage_to_mfn(spage)); - return -EINVAL; - } - pages_done = 1; - nx = (nx & ~SGT_type_mask) | SGT_dynamic; - } - } while ( (y = cmpxchg(&spage->type_info, x, nx)) != x ); - - return 0; -} - -static void put_superpage(unsigned long mfn) -{ - struct spage_info *spage; - unsigned long x, nx, y; - unsigned long do_pages = 0; - - if ( !opt_allow_superpage ) - { - put_spage_pages(mfn_to_page(mfn)); - return; - } - - spage = mfn_to_spage(mfn); - y = spage->type_info; - do { - x = y; - nx = x - 1; - if ((x & SGT_type_mask) == SGT_dynamic) - { - if ((nx & SGT_count_mask) == 0) - { - nx = (nx & ~SGT_type_mask) | SGT_none; - do_pages = 1; - } - } - - } while ((y = cmpxchg(&spage->type_info, x, nx)) != x); - - if (do_pages) - put_spage_pages(spage_to_page(spage)); - - return; -} - int put_old_guest_table(struct vcpu *v) { int rc; @@ -3599,27 +3381,8 @@ long do_mmuext_op( case MMUEXT_MARK_SUPER: case MMUEXT_UNMARK_SUPER: - { - unsigned long mfn = op.arg1.mfn; - - if ( !opt_allow_superpage ) - rc = -EOPNOTSUPP; - else if ( unlikely(currd != pg_owner) ) - rc = -EPERM; - else if ( mfn & (L1_PAGETABLE_ENTRIES - 1) ) - { - gdprintk(XENLOG_WARNING, - "Unaligned superpage mfn %" PRI_mfn "\n", mfn); - rc = -EINVAL; - } - else if ( !mfn_valid(_mfn(mfn | (L1_PAGETABLE_ENTRIES - 1))) ) - rc = -EINVAL; - else if ( op.cmd == MMUEXT_MARK_SUPER ) - rc = mark_superpage(mfn_to_spage(mfn), currd); - else - rc = unmark_superpage(mfn_to_spage(mfn)); + rc = -EOPNOTSUPP; break; - } default: rc = -ENOSYS; diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 18c19a256f..e67ffdd7b8 100644 --- a/xen/arch/x86/pv/dom0_build.c +++ b/xen/arch/x86/pv/dom0_build.c @@ -181,8 +181,6 @@ static __init void setup_pv_physmap(struct domain *d, unsigned long pgtbl_pfn, 0)) != NULL ) { *pl2e = l2e_from_page(page, L1_PROT|_PAGE_DIRTY|_PAGE_PSE); - if ( opt_allow_superpage ) - get_superpage(page_to_mfn(page), d); vphysmap_start += 1UL << L2_PAGETABLE_SHIFT; continue; } diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index dc424f99e4..bc0730fd9d 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -143,19 +143,15 @@ extern unsigned char boot_edid_info[128]; * 0xffff82d080000000 - 0xffff82d0bfffffff [1GB, 2^30 bytes, PML4:261] * Xen text, static data, bss. #ifndef CONFIG_BIGMEM - * 0xffff82d0c0000000 - 0xffff82dffbffffff [61GB - 64MB, PML4:261] + * 0xffff82d0c0000000 - 0xffff82dfffffffff [61GB, PML4:261] * Reserved for future use. - * 0xffff82dffc000000 - 0xffff82dfffffffff [64MB, 2^26 bytes, PML4:261] - * Super-page information array. * 0xffff82e000000000 - 0xffff82ffffffffff [128GB, 2^37 bytes, PML4:261] * Page-frame information array. * 0xffff830000000000 - 0xffff87ffffffffff [5TB, 5*2^40 bytes, PML4:262-271] * 1:1 direct mapping of all physical memory. #else - * 0xffff82d0c0000000 - 0xffff82ffdfffffff [188.5GB, PML4:261] + * 0xffff82d0c0000000 - 0xffff82ffffffffff [189GB, PML4:261] * Reserved for future use. - * 0xffff82ffe0000000 - 0xffff82ffffffffff [512MB, 2^29 bytes, PML4:261] - * Super-page information array. * 0xffff830000000000 - 0xffff847fffffffff [1.5TB, 3*2^39 bytes, PML4:262-264] * Page-frame information array. * 0xffff848000000000 - 0xffff87ffffffffff [3.5TB, 7*2^39 bytes, PML4:265-271] @@ -230,14 +226,6 @@ extern unsigned char boot_edid_info[128]; #define XEN_VIRT_START (HIRO_COMPAT_MPT_VIRT_END) #define XEN_VIRT_END (XEN_VIRT_START + GB(1)) -/* Slot 261: superpage information array (64MB or 512MB). */ -#define SPAGETABLE_VIRT_END FRAMETABLE_VIRT_START -#define SPAGETABLE_NR (((FRAMETABLE_NR - 1) >> (SUPERPAGE_SHIFT - \ - PAGE_SHIFT)) + 1) -#define SPAGETABLE_SIZE (SPAGETABLE_NR * sizeof(struct spage_info)) -#define SPAGETABLE_VIRT_START ((SPAGETABLE_VIRT_END - SPAGETABLE_SIZE) & \ - (_AC(-1,UL) << SUPERPAGE_SHIFT)) - #ifndef CONFIG_BIGMEM /* Slot 261: page-frame information array (128GB). */ #define FRAMETABLE_SIZE GB(128) diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 2550e35f85..2bf3f335ad 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -233,21 +233,6 @@ struct page_info #define PGC_count_width PG_shift(9) #define PGC_count_mask ((1UL<count_info & PGC_xen_heap) #define is_xen_heap_mfn(mfn) \ (__mfn_valid(mfn) && is_xen_heap_page(__mfn_to_page(mfn))) @@ -282,8 +267,6 @@ extern void share_xen_page_with_privileged_guests( extern void free_shared_domheap_page(struct page_info *page); #define frame_table ((struct page_info *)FRAMETABLE_VIRT_START) -#define spage_table ((struct spage_info *)SPAGETABLE_VIRT_START) -int get_superpage(unsigned long mfn, struct domain *d); extern unsigned long max_page; extern unsigned long total_pages; void init_frametable(void); @@ -329,8 +312,6 @@ void zap_ro_mpt(unsigned long mfn); bool is_iomem_page(mfn_t mfn); -void clear_superpage_mark(struct page_info *page); - const unsigned long *get_platform_badpages(unsigned int *array_size); /* Per page locks: * page_lock() is used for two purposes: pte serialization, and memory sharing. @@ -403,7 +384,6 @@ static inline int get_page_and_type(struct page_info *page, int check_descriptor(const struct domain *, struct desc_struct *d); -extern bool opt_allow_superpage; extern paddr_t mem_hotplug; /****************************************************************************** diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index 474b9bde78..0f843c2a46 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -239,15 +239,6 @@ void copy_page_sse2(void *, const void *); #define __pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT) #define __paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT)) - -/* Convert between machine frame numbers and spage-info structures. */ -#define __mfn_to_spage(mfn) (spage_table + pfn_to_sdx(mfn)) -#define __spage_to_mfn(pg) sdx_to_pfn((unsigned long)((pg) - spage_table)) - -/* Convert between page-info structures and spage-info structures. */ -#define page_to_spage(page) (spage_table+(((page)-frame_table)>>(SUPERPAGE_SHIFT-PAGE_SHIFT))) -#define spage_to_page(spage) (frame_table+(((spage)-spage_table)<<(SUPERPAGE_SHIFT-PAGE_SHIFT))) - /* * We define non-underscored wrappers for above conversion functions. These are * overridden in various source files while underscored versions remain intact. @@ -259,8 +250,6 @@ void copy_page_sse2(void *, const void *); #define maddr_to_virt(ma) __maddr_to_virt((unsigned long)(ma)) #define mfn_to_page(mfn) __mfn_to_page(mfn) #define page_to_mfn(pg) __page_to_mfn(pg) -#define mfn_to_spage(mfn) __mfn_to_spage(mfn) -#define spage_to_mfn(pg) __spage_to_mfn(pg) #define maddr_to_page(ma) __maddr_to_page(ma) #define page_to_maddr(pg) __page_to_maddr(pg) #define virt_to_page(va) __virt_to_page(va) diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h index 44e86d6a1f..64bf2f968a 100644 --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -371,8 +371,7 @@ static inline unsigned int paging_max_paddr_bits(const struct domain *d) { unsigned int bits = paging_mode_hap(d) ? hap_paddr_bits : paddr_bits; - if ( !IS_ENABLED(BIGMEM) && paging_mode_shadow(d) && - (!is_pv_domain(d) || opt_allow_superpage) ) + if ( !IS_ENABLED(BIGMEM) && paging_mode_shadow(d) && !is_pv_domain(d) ) { /* Shadowed superpages store GFNs in 32-bit page_info fields. */ bits = min(bits, 32U + PAGE_SHIFT); diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h index 31ba975e3d..1b48309363 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h @@ -41,8 +41,6 @@ extern unsigned long xen_virt_end; -#define spage_to_pdx(spg) (((spg) - spage_table)<<(SUPERPAGE_SHIFT-PAGE_SHIFT)) -#define pdx_to_spage(pdx) (spage_table + ((pdx)>>(SUPERPAGE_SHIFT-PAGE_SHIFT))) /* * Note: These are solely for the use by page_{get,set}_owner(), and * therefore don't need to handle the XEN_VIRT_{START,END} range.