/[pkg-src]/trunk/kernel26-xen/patches-2.6.25-r1/1112-2.6.25-xen-include-asm-x86-pgalloc_64.h-pvops-hacks-SPLITME.patch |
Contents of /trunk/kernel26-xen/patches-2.6.25-r1/1112-2.6.25-xen-include-asm-x86-pgalloc_64.h-pvops-hacks-SPLITME.patch
Parent Directory | Revision Log
Revision 606 -
(show annotations)
(download)
Thu May 22 23:13:13 2008 UTC (16 years, 4 months ago) by niro
File size: 6155 byte(s)
Thu May 22 23:13:13 2008 UTC (16 years, 4 months ago) by niro
File size: 6155 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 716ecef49a853ed5a7277c583719a604f181bfb6 Mon Sep 17 00:00:00 2001 |
2 | From: Eduardo Habkost <ehabkost@redhat.com> |
3 | Date: Mon, 14 Jan 2008 20:01:22 -0200 |
4 | Subject: [PATCH] include/asm-x86/pgalloc_64.h pvops hacks (SPLITME) |
5 | |
6 | - Xen-specific: |
7 | - Create __user_pgd() |
8 | - Change pgd allocation to allocate two pages |
9 | - Unpin and mark PGD as read-write on pgd_free() |
10 | |
11 | - Not xen-specific: |
12 | - pagetable allocation hooks |
13 | |
14 | - Maybe other stuff |
15 | |
16 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> |
17 | --- |
18 | arch/x86/xen/mmu.c | 2 +- |
19 | arch/x86/xen/mmu.h | 2 + |
20 | include/asm-x86/pgalloc_64.h | 79 +++++++++++++++++++++++++++++++++++------ |
21 | include/xen/page.h | 3 ++ |
22 | 4 files changed, 73 insertions(+), 13 deletions(-) |
23 | |
24 | diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c |
25 | index eaf9652..e545dee 100644 |
26 | --- a/arch/x86/xen/mmu.c |
27 | +++ b/arch/x86/xen/mmu.c |
28 | @@ -561,7 +561,7 @@ static int unpin_page(struct page *page, enum pt_level level) |
29 | } |
30 | |
31 | /* Release a pagetables pages back as normal RW */ |
32 | -static void xen_pgd_unpin(pgd_t *pgd) |
33 | +void xen_pgd_unpin(pgd_t *pgd) |
34 | { |
35 | xen_mc_batch(); |
36 | |
37 | diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h |
38 | index b25b8e4..28e5225 100644 |
39 | --- a/arch/x86/xen/mmu.h |
40 | +++ b/arch/x86/xen/mmu.h |
41 | @@ -63,4 +63,6 @@ void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); |
42 | void xen_pmd_clear(pmd_t *pmdp); |
43 | #endif |
44 | |
45 | +void xen_pgd_unpin(pgd_t *pgd); |
46 | + |
47 | #endif /* _XEN_MMU_H */ |
48 | diff --git a/include/asm-x86/pgalloc_64.h b/include/asm-x86/pgalloc_64.h |
49 | index b9835d6..94f42d4 100644 |
50 | --- a/include/asm-x86/pgalloc_64.h |
51 | +++ b/include/asm-x86/pgalloc_64.h |
52 | @@ -13,17 +13,39 @@ |
53 | #define arch_remove_exec_range(mm, limit) \ |
54 | do { (void)(mm), (void)(limit); } while (0) |
55 | |
56 | -#define pmd_populate_kernel(mm, pmd, pte) \ |
57 | - set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte))) |
58 | -#define pud_populate(mm, pud, pmd) \ |
59 | - set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd))) |
60 | -#define pgd_populate(mm, pgd, pud) \ |
61 | - set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud))) |
62 | +#ifdef CONFIG_XEN |
63 | + |
64 | +#include <xen/page.h> |
65 | + |
66 | +extern pud_t level3_user_pgt[512]; |
67 | + |
68 | +/*FIXME: use pvops */ |
69 | +static pgd_t *__user_pgd(pgd_t *pgd) |
70 | +{ |
71 | + return pgd + PTRS_PER_PGD; |
72 | +} |
73 | + |
74 | +#endif |
75 | + |
76 | +#define pmd_populate_kernel(mm, pmd, pte) do { \ |
77 | + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \ |
78 | + set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte))); \ |
79 | + } while (0) |
80 | +#define pud_populate(mm, pud, pmd) do { \ |
81 | + paravirt_alloc_pd(mm, __pa(pmd) >> PAGE_SHIFT); \ |
82 | + set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd))); \ |
83 | + } while (0) |
84 | +#define pgd_populate(mm, pgd, pud) do {\ |
85 | + paravirt_alloc_pd(mm, __pa(pud) >> PAGE_SHIFT); \ |
86 | + set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud))); \ |
87 | + set_pgd(__user_pgd(pgd), __pgd(_PAGE_TABLE | __pa(pud))); \ |
88 | + } while (0) |
89 | |
90 | #define pmd_pgtable(pmd) pmd_page(pmd) |
91 | |
92 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) |
93 | { |
94 | + paravirt_alloc_pt(mm, page_to_pfn(pte)); \ |
95 | set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT))); |
96 | } |
97 | |
98 | @@ -35,12 +57,16 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) |
99 | |
100 | static inline pmd_t *pmd_alloc_one (struct mm_struct *mm, unsigned long addr) |
101 | { |
102 | - return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); |
103 | + pmd_t *pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); |
104 | + paravirt_alloc_pd(mm, __pa(pmd) >> PAGE_SHIFT); |
105 | + return pmd; |
106 | } |
107 | |
108 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) |
109 | { |
110 | - return (pud_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); |
111 | + pud_t *pud = (pud_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); |
112 | + paravirt_alloc_pd(mm, __pa(pud) >> PAGE_SHIFT); |
113 | + return pud; |
114 | } |
115 | |
116 | static inline void pud_free(struct mm_struct *mm, pud_t *pud) |
117 | @@ -72,7 +98,7 @@ static inline void pgd_list_del(pgd_t *pgd) |
118 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
119 | { |
120 | unsigned boundary; |
121 | - pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); |
122 | + pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1); |
123 | if (!pgd) |
124 | return NULL; |
125 | pgd_list_add(pgd); |
126 | @@ -86,6 +112,14 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
127 | memcpy(pgd + boundary, |
128 | init_level4_pgt + boundary, |
129 | (PTRS_PER_PGD - boundary) * sizeof(pgd_t)); |
130 | + |
131 | + memset(__user_pgd(pgd), 0, PAGE_SIZE); /* clean up user pgd */ |
132 | + /* |
133 | + * Set level3_user_pgt for vsyscall area |
134 | + */ |
135 | + set_pgd(__user_pgd(pgd) + pgd_index(VSYSCALL_START), |
136 | + mk_kernel_pgd(__pa_symbol(level3_user_pgt))); |
137 | + |
138 | return pgd; |
139 | } |
140 | |
141 | @@ -93,7 +127,18 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) |
142 | { |
143 | BUG_ON((unsigned long)pgd & (PAGE_SIZE-1)); |
144 | pgd_list_del(pgd); |
145 | - free_page((unsigned long)pgd); |
146 | + |
147 | +#ifdef CONFIG_XEN |
148 | + /* Unpin and make it read-write again, in the (likely) case |
149 | + * it was pinned |
150 | + * |
151 | + * FIXME: should be a paravirt_ops hook |
152 | + */ |
153 | + xen_pgd_unpin(pgd); |
154 | + make_lowmem_page_readwrite(pgd); |
155 | +#endif |
156 | + |
157 | + free_pages((unsigned long)pgd, 1); |
158 | } |
159 | |
160 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
161 | @@ -132,10 +177,20 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) |
162 | #define __pte_free_tlb(tlb,pte) \ |
163 | do { \ |
164 | pgtable_page_dtor((pte)); \ |
165 | + paravirt_release_pt(page_to_pfn(pte)); \ |
166 | tlb_remove_page((tlb), (pte)); \ |
167 | } while (0) |
168 | |
169 | -#define __pmd_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) |
170 | -#define __pud_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) |
171 | +#define __pmd_free_tlb(tlb,x) \ |
172 | +do { \ |
173 | + paravirt_release_pd(page_to_pfn(virt_to_page(x))); \ |
174 | + tlb_remove_page((tlb),virt_to_page(x)); \ |
175 | +} while (0) |
176 | + |
177 | +#define __pud_free_tlb(tlb,x) \ |
178 | +do { \ |
179 | + paravirt_release_pd(page_to_pfn(virt_to_page(x))); \ |
180 | + tlb_remove_page((tlb),virt_to_page(x)); \ |
181 | +} while (0) |
182 | |
183 | #endif /* _X86_64_PGALLOC_H */ |
184 | diff --git a/include/xen/page.h b/include/xen/page.h |
185 | index 158fb60..1eb4721 100644 |
186 | --- a/include/xen/page.h |
187 | +++ b/include/xen/page.h |
188 | @@ -179,4 +179,7 @@ xmaddr_t arbitrary_virt_to_machine(unsigned long address); |
189 | void make_lowmem_page_readonly(void *vaddr); |
190 | void make_lowmem_page_readwrite(void *vaddr); |
191 | |
192 | +extern void xen_pgd_unpin(pgd_t *pgd); |
193 | + |
194 | + |
195 | #endif /* __XEN_PAGE_H */ |
196 | -- |
197 | 1.5.4.1 |
198 |