]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.xen/xen-x86-dcr-fallback
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.xen / xen-x86-dcr-fallback
CommitLineData
2cb7cef9
BS
1Subject: Add fallback when XENMEM_exchange fails to replace contiguous region
2From: jbeulich@novell.com
3Patch-mainline: obsolete
4References: 181869
5
6This avoids losing precious special memory in places where any memory can be
7used.
8
9--- sle11-2009-06-29.orig/arch/x86/mm/hypervisor.c 2009-03-16 16:17:45.000000000 +0100
10+++ sle11-2009-06-29/arch/x86/mm/hypervisor.c 2009-03-30 12:18:24.000000000 +0200
11@@ -42,6 +42,7 @@
12 #include <xen/interface/memory.h>
13 #include <linux/module.h>
14 #include <linux/percpu.h>
15+#include <linux/highmem.h>
16 #include <asm/tlbflush.h>
17 #include <linux/highmem.h>
18
19@@ -712,6 +713,83 @@ void xen_destroy_contiguous_region(unsig
20 BUG();
21
22 balloon_unlock(flags);
23+
24+ if (unlikely(!success)) {
25+ /* Try hard to get the special memory back to Xen. */
26+ exchange.in.extent_order = 0;
27+ set_xen_guest_handle(exchange.in.extent_start, &in_frame);
28+
29+ for (i = 0; i < (1U<<order); i++) {
30+ struct page *page = alloc_page(__GFP_HIGHMEM|__GFP_COLD);
31+ unsigned long pfn;
32+ mmu_update_t mmu;
33+ unsigned int j = 0;
34+
35+ if (!page) {
36+ printk(KERN_WARNING "Xen and kernel out of memory "
37+ "while trying to release an order %u "
38+ "contiguous region\n", order);
39+ break;
40+ }
41+ pfn = page_to_pfn(page);
42+
43+ balloon_lock(flags);
44+
45+ if (!PageHighMem(page)) {
46+ void *v = __va(pfn << PAGE_SHIFT);
47+
48+ scrub_pages(v, 1);
49+ MULTI_update_va_mapping(cr_mcl + j, (unsigned long)v,
50+ __pte_ma(0), UVMF_INVLPG|UVMF_ALL);
51+ ++j;
52+ }
53+#ifdef CONFIG_XEN_SCRUB_PAGES
54+ else {
55+ scrub_pages(kmap(page), 1);
56+ kunmap(page);
57+ kmap_flush_unused();
58+ }
59+#endif
60+
61+ frame = pfn_to_mfn(pfn);
62+ set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
63+
64+ MULTI_update_va_mapping(cr_mcl + j, vstart,
65+ pfn_pte_ma(frame, PAGE_KERNEL),
66+ UVMF_INVLPG|UVMF_ALL);
67+ ++j;
68+
69+ pfn = __pa(vstart) >> PAGE_SHIFT;
70+ set_phys_to_machine(pfn, frame);
71+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
72+ mmu.ptr = ((uint64_t)frame << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
73+ mmu.val = pfn;
74+ cr_mcl[j].op = __HYPERVISOR_mmu_update;
75+ cr_mcl[j].args[0] = (unsigned long)&mmu;
76+ cr_mcl[j].args[1] = 1;
77+ cr_mcl[j].args[2] = 0;
78+ cr_mcl[j].args[3] = DOMID_SELF;
79+ ++j;
80+ }
81+
82+ cr_mcl[j].op = __HYPERVISOR_memory_op;
83+ cr_mcl[j].args[0] = XENMEM_decrease_reservation;
84+ cr_mcl[j].args[1] = (unsigned long)&exchange.in;
85+
86+ if (HYPERVISOR_multicall(cr_mcl, j + 1))
87+ BUG();
88+ BUG_ON(cr_mcl[j].result != 1);
89+ while (j--)
90+ BUG_ON(cr_mcl[j].result != 0);
91+
92+ balloon_unlock(flags);
93+
94+ free_empty_pages(&page, 1);
95+
96+ in_frame++;
97+ vstart += PAGE_SIZE;
98+ }
99+ }
100 }
101 EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
102
103--- sle11-2009-06-29.orig/drivers/xen/balloon/balloon.c 2009-06-29 15:44:49.000000000 +0200
104+++ sle11-2009-06-29/drivers/xen/balloon/balloon.c 2009-06-29 15:46:09.000000000 +0200
105@@ -665,7 +665,7 @@ struct page **alloc_empty_pages_and_page
106 goto out;
107 }
108
109-void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
110+static void _free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages, int free_vec)
111 {
112 unsigned long flags;
113 int i;
114@@ -678,13 +678,26 @@ void free_empty_pages_and_pagevec(struct
115 BUG_ON(page_count(pagevec[i]) != 1);
116 balloon_append(pagevec[i]);
117 }
118+ if (!free_vec)
119+ totalram_pages = bs.current_pages -= nr_pages;
120 balloon_unlock(flags);
121
122- kfree(pagevec);
123+ if (free_vec)
124+ kfree(pagevec);
125
126 schedule_work(&balloon_worker);
127 }
128
129+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
130+{
131+ _free_empty_pages_and_pagevec(pagevec, nr_pages, 1);
132+}
133+
134+void free_empty_pages(struct page **pagevec, int nr_pages)
135+{
136+ _free_empty_pages_and_pagevec(pagevec, nr_pages, 0);
137+}
138+
139 void balloon_release_driver_page(struct page *page)
140 {
141 unsigned long flags;
142--- sle11-2009-06-29.orig/include/xen/balloon.h 2009-03-16 16:38:05.000000000 +0100
143+++ sle11-2009-06-29/include/xen/balloon.h 2009-03-16 16:40:33.000000000 +0100
144@@ -47,6 +47,10 @@ void balloon_update_driver_allowance(lon
145 struct page **alloc_empty_pages_and_pagevec(int nr_pages);
146 void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages);
147
148+/* Free an empty page range (not allocated through
149+ alloc_empty_pages_and_pagevec), adding to the balloon. */
150+void free_empty_pages(struct page **pagevec, int nr_pages);
151+
152 void balloon_release_driver_page(struct page *page);
153
154 /*