linux/x86: revert the effect of xen_limit_pages_to_max_mfn()
Subsystems (4)
PATCH 1/1 linux/x86: revert the effect of xen_limit_pages_to_max_mfn()
As usual, written and tested on 2.6.27.7 and made apply to the 2.6.18 tree without further testing.
Signed-off-by Jan Beulich <[email protected]>
arch/i386/mm/hypervisor.c +38 -5
@@ -437,6 +437,15 @@ void xen_destroy_contiguous_region(unsig }EXPORT_SYMBOL_GPL (xen_destroy_contiguous_region); +static void undo_limit_pages (struct page *pages,unsigned int order) +{ +BUG_ON (xen_feature (XENFEAT_auto_translated_physmap)); +BUG_ON (order >MAX_CONTIG_ORDER ); +xen_limit_pages_to_max_mfn (pages, order,0 ); +ClearPageForeign (pages); +__free_pages (pages, order); +} +int xen_limit_pages_to_max_mfn (struct page *pages,unsigned int order,unsigned int address_bits) {
@@ -465,16 +474,28 @@ int xen_limit_pages_to_max_mfn(if (unlikely (order >MAX_CONTIG_ORDER ))return -ENOMEM ; -bitmap_zero (limit_map,1U << order); +if (address_bits) { +if (address_bits <PAGE_SHIFT ) +return -EINVAL ; +bitmap_zero (limit_map,1U << order); + }else if (order) { +BUILD_BUG_ON (sizeof (pages->index) !=sizeof (*limit_map)); +for (i =0 ; i <BITS_TO_LONGS (1U << order); ++i) + limit_map[i] = pages[i +1 ].index; + }else +__set_bit (0 , limit_map); +set_xen_guest_handle (exchange.in.extent_start, in_frames);set_xen_guest_handle (exchange.out.extent_start, out_frames);/* 0. Scrub the pages. */ for (i =0 , n =0 ; i <1U <<order ; i++) { page = &pages[i]; -if (!(pfn_to_mfn (page_to_pfn (page)) >> (address_bits -PAGE_SHIFT ))) -continue ; -__set_bit (i, limit_map); +if (address_bits) { +if (!(pfn_to_mfn (page_to_pfn (page)) >> (address_bits -PAGE_SHIFT ))) +continue ; +__set_bit (i, limit_map); + }if (!PageHighMem (page))scrub_pages (page_address (page),1 );
@@ -560,7 +581,19 @@ int xen_limit_pages_to_max_mfn(balloon_unlock (flags); -return success ?0 : -ENOMEM ; +if (!success) +return -ENOMEM ; + +if (address_bits) { +if (order) { +BUILD_BUG_ON (sizeof (*limit_map) !=sizeof (pages->index)); +for (i =0 ; i <BITS_TO_LONGS (1U << order); ++i) + pages[i +1 ].index = limit_map[i]; + } +SetPageForeign (pages, undo_limit_pages); + } + +return 0 ; }EXPORT_SYMBOL_GPL (xen_limit_pages_to_max_mfn);
arch/i386/mm/pgtable-xen.c +7 -1
@@ -146,6 +146,12 @@ pte_t *pte_alloc_one_kernel(struct mm_streturn pte; } +static void _pte_free (struct page *page,unsigned int order) +{ +BUG_ON (order); +pte_free (page); +} +struct page *pte_alloc_one (struct mm_struct *mm,unsigned long address) {struct page *pte;
@@ -156,7 +162,7 @@ struct page *pte_alloc_one(struct mm_struct pte =alloc_pages (GFP_KERNEL |__GFP_REPEAT|__GFP_ZERO,0 );#endif if (pte) { -SetPageForeign (pte, pte_free); +SetPageForeign (pte, _pte_free);init_page_count (pte); }return pte;
arch/x86_64/mm/pageattr-xen.c +7 -1
@@ -216,6 +216,12 @@ void _arch_exit_mmap(struct mm_struct *mm_unpin (mm); } +static void _pte_free (struct page *page,unsigned int order) +{ +BUG_ON (order); +pte_free (page); +} +struct page *pte_alloc_one (struct mm_struct *mm,unsigned long address) {struct page *pte;
@@ -222,7 +228,7 @@ struct page *pte_alloc_one(struct mm_struct pte =alloc_pages (GFP_KERNEL |__GFP_REPEAT|__GFP_ZERO,0 );if (pte) { -SetPageForeign (pte, pte_free); +SetPageForeign (pte, _pte_free);init_page_count (pte); }return pte;
drivers/xen/core/gnttab.c +2 -1
@@ -506,8 +506,9 @@ static int gnttab_map(unsigned int startreturn 0 ; } -static void gnttab_page_free (struct page *page) +static void gnttab_page_free (struct page *page,unsigned int order) { +BUG_ON (order);ClearPageForeign (page);gnttab_reset_grant_page (page);put_page (page);
drivers/xen/netback/netback.c +2 -2
@@ -55,7 +55,6 @@ struct netbk_tx_pending_inuse { };static void netif_idx_release (u16 pending_idx); -static void netif_page_release (struct page *page);static void make_tx_response (netif_t *netif,netif_tx_request_t *txp,s8 st);
@@ -1453,8 +1452,9 @@ static void netif_idx_release(u16 pendintasklet_schedule (&net_tx_tasklet); } -static void netif_page_release (struct page *page) +static void netif_page_release (struct page *page,unsigned int order) { +BUG_ON (order);netif_idx_release (netif_page_index (page)); }
include/linux/page-flags.h +3 -3
@@ -285,15 +285,15 @@#define PageForeign (page) test_bit(PG_foreign, &(page)->flags)#define SetPageForeign (_page, dtor) do { \ set_bit(PG_foreign, &(_page)->flags); \ - BUG_ON((dtor) == (void (*)(struct page *))0); \ + BUG_ON((dtor) == (void (*)(struct page *, unsigned int))0); \ (_page)->index = (long)(dtor); \ } while (0)#define ClearPageForeign (page) do { \ clear_bit(PG_foreign, &(page)->flags); \ (page)->index = 0; \ } while (0) -#define PageForeignDestructor (_page) \ - ((void (*)(struct page *))(_page)->index)(_page) +#define PageForeignDestructor (_page, order) \ + ((void (*)(struct page *, unsigned int))(_page)->index)(_page, order)struct page ;/* forward declaration */
mm/page_alloc.c +2 -2
@@ -505,7 +505,7 @@ static void __free_pages_ok(struct page#ifdef CONFIG_XEN if (PageForeign (page)) { -PageForeignDestructor (page); +PageForeignDestructor (page, order);return ; }#endif
@@ -803,7 +803,7 @@ static void free_hot_cold_page(struct pa#ifdef CONFIG_XEN if (PageForeign (page)) { -PageForeignDestructor (page); +PageForeignDestructor (page,0 );return ; }#endif