Magellan Linux

Contents of /trunk/kernel26-xen/patches-2.6.25-r1/1065-2.6.25-xen-Trying-to-make-the-pagetable-initialization-code-wor.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 606 - (show annotations) (download)
Thu May 22 23:13:13 2008 UTC (15 years, 11 months ago) by niro
File size: 8557 byte(s)
-ver bump to 2.6.25-magellan-r1:
- linux-2.6.25.4
- fbcondecor-0.9.4
- squashfs-3.3
- unionfs-2.3.3
- tuxonice-3.0-rc7
- linux-phc-0.3.0
- acpi-dstd-0.9a
- reiser4
- xen-3.2.0
. ipw3945-1.2.2

1 From 0e9f82c8cfc17b0fb15ca0e0951687cc7c2df281 Mon Sep 17 00:00:00 2001
2 From: Eduardo Habkost <ehabkost@redhat.com>
3 Date: Wed, 12 Dec 2007 16:26:56 -0200
4 Subject: [PATCH] Trying to make the pagetable initialization code work under Xen
5
6 To be fixed:
7
8 - Lots of #ifdef CONFIG_XEN that will break bare metal
9 - Make it actually work
10
11 Wrt. pse_available() in pgtable_64.h:
12
13 - Probably we may use the CPU feature code to handle this
14 - We need it to be variable (not constant 0) if Xen is supported
15
16 Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
17 ---
18 arch/x86/mm/init_64.c | 153 ++++++++++++++++++++++++++++++++++++++++--
19 include/asm-x86/paravirt.h | 10 +++
20 include/asm-x86/pgalloc_64.h | 1 +
21 include/asm-x86/pgtable.h | 4 +
22 4 files changed, 161 insertions(+), 7 deletions(-)
23
24 diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
25 index b5f1f6e..69d1056 100644
26 --- a/arch/x86/mm/init_64.c
27 +++ b/arch/x86/mm/init_64.c
28 @@ -47,6 +47,22 @@
29 #include <asm/numa.h>
30 #include <asm/cacheflush.h>
31
32 +#ifdef CONFIG_XEN
33 +/*FIXME: ouch. */
34 +#include <xen/features.h>
35 +#include <xen/page.h>
36 +#include <xen/hvc-console.h>
37 +#include <asm/xen/hypercall.h>
38 +#include "../xen/init.h"
39 +#include "../xen/xen-ops.h"
40 +#endif
41 +
42 +#ifdef CONFIG_XEN
43 +/*FIXME: ouch again */
44 +#define PTE_SIZE PAGE_SIZE
45 +#else
46 +#endif
47 +
48 const struct dma_mapping_ops *dma_ops;
49 EXPORT_SYMBOL(dma_ops);
50
51 @@ -102,6 +118,9 @@ void show_mem(void)
52
53 int after_bootmem;
54
55 +static unsigned long __initdata table_start;
56 +static unsigned long __meminitdata table_end;
57 +
58 static __init void *spp_getpage(void)
59 {
60 void *ptr;
61 @@ -232,8 +251,75 @@ native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
62 __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, prot));
63 }
64
65 -static unsigned long __initdata table_start;
66 -static unsigned long __meminitdata table_end;
67 +
68 +#ifdef CONFIG_XEN
69 +
70 +/*FIXME: this code should be enabled at runtime, somehow */
71 +
72 +unsigned long start_pfn;
73 +
74 +static __meminit void *alloc_low_page(unsigned long *phys)
75 +{
76 + unsigned long pfn;
77 + void *adr;
78 +
79 + if (after_bootmem) {
80 + adr = (void *)get_zeroed_page(GFP_ATOMIC);
81 + *phys = __pa(adr);
82 + return adr;
83 + }
84 +
85 + pfn = start_pfn++;
86 + *phys = pfn << PAGE_SHIFT;
87 +
88 + /* The address returned by __va() is not available yet.
89 + * This function is used by init_memory_mapping(). We will
90 + * use the mapping that was set by Xen for us.
91 + */
92 + adr = (void*)((*phys) + __START_KERNEL_map);
93 + memset(adr, 0, PAGE_SIZE);
94 +
95 + return adr;
96 +}
97 +
98 +
99 +static inline void __set_pte(pte_t *dst, pte_t val)
100 +{
101 + *dst = val;
102 +}
103 +
104 +
105 +int make_readonly(unsigned long paddr)
106 +{
107 + extern char __vsyscall_0;
108 + int readonly = 0;
109 +
110 + /* Make new page tables read-only. */
111 + if (!xen_feature(XENFEAT_writable_page_tables)
112 + && (paddr >= (table_start << PAGE_SHIFT))
113 + && (paddr < (table_end << PAGE_SHIFT)))
114 + readonly = 1;
115 + /* Make old page tables read-only. */
116 + if (!xen_feature(XENFEAT_writable_page_tables)
117 + && (paddr >= (xen_start_info->pt_base - __START_KERNEL_map))
118 + && (paddr < (start_pfn << PAGE_SHIFT)))
119 + readonly = 1;
120 +
121 + /*
122 + * No need for writable mapping of kernel image. This also ensures that
123 + * page and descriptor tables embedded inside don't have writable
124 + * mappings. Exclude the vsyscall area here, allowing alternative
125 + * instruction patching to work.
126 + */
127 + if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end))
128 + && !(paddr >= __pa_symbol(&__vsyscall_0)
129 + && paddr < __pa_symbol(&__vsyscall_0) + PAGE_SIZE))
130 + readonly = 1;
131 +
132 + return readonly;
133 +}
134 +
135 +#else /* !XEN */
136
137 static __meminit void *alloc_low_page(unsigned long *phys)
138 {
139 @@ -256,12 +342,18 @@ static __meminit void *alloc_low_page(unsigned long *phys)
140 return adr;
141 }
142
143 +#endif /* !XEN */
144 +
145 +
146 static __meminit void unmap_low_page(void *adr)
147 {
148 if (after_bootmem)
149 return;
150
151 +#ifndef CONFIG_XEN
152 + /*FIXME: this behaviour should be changed in runtime, also */
153 early_iounmap(adr, PAGE_SIZE);
154 +#endif
155 }
156
157 /* Must run before zap_low_mappings */
158 @@ -284,8 +376,9 @@ __meminit void *early_ioremap(unsigned long addr, unsigned long size)
159 vaddr += addr & ~PMD_MASK;
160 addr &= PMD_MASK;
161
162 - for (i = 0; i < pmds; i++, addr += PMD_SIZE)
163 + for (i = 0; i < pmds; i++, addr += PMD_SIZE) {
164 set_pmd(pmd+i, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
165 + } /* for pmds */
166 __flush_tlb_all();
167
168 return (void *)vaddr;
169 @@ -321,7 +414,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
170 {
171 int i = pmd_index(address);
172
173 - for (; i < PTRS_PER_PMD; i++, address += PMD_SIZE) {
174 + for (; i < PTRS_PER_PMD; i++) {
175 pmd_t *pmd = pmd_page + pmd_index(address);
176
177 if (address >= end) {
178 @@ -335,8 +428,46 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
179 if (pmd_val(*pmd))
180 continue;
181
182 - set_pte((pte_t *)pmd,
183 - pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
184 + if (pse_available()) {
185 + /* Lucky us :) */
186 + set_pte((pte_t *)pmd,
187 + pfn_pte(address >> PAGE_SHIFT,
188 + PAGE_KERNEL_LARGE));
189 + address += PMD_SIZE;
190 + } else {
191 + /* No PSE support. Must make lots of PTEs */
192 + unsigned long pte_phys;
193 + pte_t *pte, *pte_save;
194 + int k;
195 +
196 + pte = alloc_low_page(&pte_phys);
197 + pte_save = pte;
198 + for (k = 0; k < PTRS_PER_PTE; pte++, k++, address += PTE_SIZE) {
199 + pteval_t attrs;
200 + if ((address >= end)) {
201 + __set_pte(pte, __pte(0));
202 + continue;
203 + }
204 +
205 + /*FIXME: _PAGE_GLOBAL is skipped here,
206 + * but this is Xen-specific. Use pvops
207 + * to handle this
208 + */
209 + attrs = __PAGE_KERNEL;
210 +
211 + /*FIXME: somehow we need to make those
212 + * pages readonly on some other place
213 + */
214 + if (make_readonly(address))
215 + attrs &= ~_PAGE_RW;
216 + __set_pte(pte, __pte(address | attrs));
217 + }
218 + pte = pte_save;
219 +
220 + /*FIXME: this should be done somewhere else */
221 + early_make_page_readonly(pte, XENFEAT_writable_page_tables);
222 + set_pmd(pmd, pfn_pmd(pte_phys>>PAGE_SHIFT, PAGE_KERNEL));
223 + } /* !pse_available() */
224 }
225 }
226
227 @@ -363,11 +494,14 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
228 if (addr >= end)
229 break;
230
231 +#ifndef CONFIG_XEN
232 + /*FIXME: how to make this enabled on runtime */
233 if (!after_bootmem &&
234 !e820_any_mapped(addr, addr+PUD_SIZE, 0)) {
235 set_pud(pud, __pud(0));
236 continue;
237 }
238 +#endif
239
240 if (pud_val(*pud)) {
241 phys_pmd_update(pud, addr, end);
242 @@ -375,6 +509,8 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
243 }
244
245 pmd = alloc_low_page(&pmd_phys);
246 + /*FIXME: this (making page readonly) should be done somewhere else */
247 + early_make_page_readonly(pmd, XENFEAT_writable_page_tables);
248
249 spin_lock(&init_mm.page_table_lock);
250 set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
251 @@ -440,8 +576,11 @@ void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
252
253 if (after_bootmem)
254 pud = pud_offset(pgd, start & PGDIR_MASK);
255 - else
256 + else {
257 pud = alloc_low_page(&pud_phys);
258 + /*FIXME: this (making page readonly) should be done somewhere else */
259 + early_make_page_readonly(pud, XENFEAT_writable_page_tables);
260 + }
261
262 next = start + PGDIR_SIZE;
263 if (next > end)
264 diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
265 index c7c4e34..7edbeda 100644
266 --- a/include/asm-x86/paravirt.h
267 +++ b/include/asm-x86/paravirt.h
268 @@ -153,6 +153,16 @@ struct pv_cpu_ops {
269 struct pv_lazy_ops lazy_mode;
270 };
271
272 +
273 +#ifdef CONFIG_XEN
274 +/*FIXME: return 0 only if we are really running under Xen */
275 +#define pse_available() (0)
276 +#else
277 +/* No Xen support, PSE is always available */
278 +#define pse_available() (1)
279 +#endif
280 +
281 +
282 struct pv_irq_ops {
283 void (*init_IRQ)(void);
284
285 diff --git a/include/asm-x86/pgalloc_64.h b/include/asm-x86/pgalloc_64.h
286 index 982e1cb..b9835d6 100644
287 --- a/include/asm-x86/pgalloc_64.h
288 +++ b/include/asm-x86/pgalloc_64.h
289 @@ -2,6 +2,7 @@
290 #define _X86_64_PGALLOC_H
291
292 #include <asm/pda.h>
293 +#include <asm/vsyscall.h>
294 #include <linux/threads.h>
295 #include <linux/mm.h>
296
297 diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
298 index 9cf472a..6b3979e 100644
299 --- a/include/asm-x86/pgtable.h
300 +++ b/include/asm-x86/pgtable.h
301 @@ -232,6 +232,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
302
303 #define pte_update(mm, addr, ptep) do { } while (0)
304 #define pte_update_defer(mm, addr, ptep) do { } while (0)
305 +
306 +/*FIXME: this have a better place than here */
307 +#define pse_available() (1)
308 +
309 #endif /* CONFIG_PARAVIRT */
310
311 #endif /* __ASSEMBLY__ */
312 --
313 1.5.4.1
314