All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] linux/x86: revert the effect of xen_limit_pages_to_max_mfn()
@ 2008-11-28 10:16 Jan Beulich
  0 siblings, 0 replies; only message in thread
From: Jan Beulich @ 2008-11-28 10:16 UTC (permalink / raw)
  To: xen-devel

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 <jbeulich@novell.com>

Index: head-2008-11-25/arch/i386/mm/hypervisor.c
===================================================================
--- head-2008-11-25.orig/arch/i386/mm/hypervisor.c	2008-11-17 14:07:20.000000000 +0100
+++ head-2008-11-25/arch/i386/mm/hypervisor.c	2008-11-26 15:01:10.000000000 +0100
@@ -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);
 
Index: head-2008-11-25/arch/i386/mm/pgtable-xen.c
===================================================================
--- head-2008-11-25.orig/arch/i386/mm/pgtable-xen.c	2008-11-17 14:07:20.000000000 +0100
+++ head-2008-11-25/arch/i386/mm/pgtable-xen.c	2008-11-26 10:48:36.000000000 +0100
@@ -146,6 +146,12 @@ pte_t *pte_alloc_one_kernel(struct mm_st
 	return 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;
Index: head-2008-11-25/arch/x86_64/mm/pageattr-xen.c
===================================================================
--- head-2008-11-25.orig/arch/x86_64/mm/pageattr-xen.c	2008-11-17 14:07:20.000000000 +0100
+++ head-2008-11-25/arch/x86_64/mm/pageattr-xen.c	2008-11-26 10:48:36.000000000 +0100
@@ -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;
Index: head-2008-11-25/drivers/xen/core/gnttab.c
===================================================================
--- head-2008-11-25.orig/drivers/xen/core/gnttab.c	2008-11-26 11:39:29.000000000 +0100
+++ head-2008-11-25/drivers/xen/core/gnttab.c	2008-11-26 10:41:13.000000000 +0100
@@ -506,8 +506,9 @@ static int gnttab_map(unsigned int start
 	return 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);
Index: head-2008-11-25/drivers/xen/netback/netback.c
===================================================================
--- head-2008-11-25.orig/drivers/xen/netback/netback.c	2008-11-06 09:53:04.000000000 +0100
+++ head-2008-11-25/drivers/xen/netback/netback.c	2008-11-26 13:39:51.000000000 +0100
@@ -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 pendin
 	tasklet_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));
 }
 
Index: head-2008-11-25/include/linux/page-flags.h
===================================================================
--- head-2008-11-25.orig/include/linux/page-flags.h	2008-11-26 11:37:58.000000000 +0100
+++ head-2008-11-25/include/linux/page-flags.h	2008-11-26 10:40:38.000000000 +0100
@@ -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 */
 
Index: head-2008-11-25/mm/page_alloc.c
===================================================================
--- head-2008-11-25.orig/mm/page_alloc.c	2008-11-26 11:37:58.000000000 +0100
+++ head-2008-11-25/mm/page_alloc.c	2008-11-26 10:38:38.000000000 +0100
@@ -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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-11-28 10:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-28 10:16 [PATCH] linux/x86: revert the effect of xen_limit_pages_to_max_mfn() Jan Beulich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.