aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-08 06:24:29 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 06:24:29 -0400
commit6236af82d8a989e150a02800c210eb61cb1e17be (patch)
treed5e83e66b09fc405ac70925f9b83152abaf48a03 /arch/x86
parente3ae0acf59244ecf5b023ec99cef4b6b29d649bc (diff)
parent8b7ef4ec5b1ac8b6feebf5ae9cda85a7514728f8 (diff)
Merge branch 'x86/fixmap' into x86/devel
Conflicts: arch/x86/mm/init_64.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/paravirt.c2
-rw-r--r--arch/x86/mm/init_64.c21
-rw-r--r--arch/x86/mm/pgtable.c20
-rw-r--r--arch/x86/mm/pgtable_32.c20
-rw-r--r--arch/x86/xen/enlighten.c29
5 files changed, 59 insertions, 33 deletions
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index f1ab0f727007..e9b504537212 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -420,6 +420,8 @@ struct pv_mmu_ops pv_mmu_ops = {
420 .enter = paravirt_nop, 420 .enter = paravirt_nop,
421 .leave = paravirt_nop, 421 .leave = paravirt_nop,
422 }, 422 },
423
424 .set_fixmap = native_set_fixmap,
423}; 425};
424 426
425EXPORT_SYMBOL_GPL(pv_time_ops); 427EXPORT_SYMBOL_GPL(pv_time_ops);
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 18c6a006e406..97c2bc741e94 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -148,15 +148,15 @@ static __init void *spp_getpage(void)
148 return ptr; 148 return ptr;
149} 149}
150 150
151static __init void 151void
152set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) 152set_pte_vaddr(unsigned long vaddr, pte_t new_pte)
153{ 153{
154 pgd_t *pgd; 154 pgd_t *pgd;
155 pud_t *pud; 155 pud_t *pud;
156 pmd_t *pmd; 156 pmd_t *pmd;
157 pte_t *pte, new_pte; 157 pte_t *pte;
158 158
159 pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys); 159 pr_debug("set_pte_vaddr %lx to %lx\n", vaddr, native_pte_val(new_pte));
160 160
161 pgd = pgd_offset_k(vaddr); 161 pgd = pgd_offset_k(vaddr);
162 if (pgd_none(*pgd)) { 162 if (pgd_none(*pgd)) {
@@ -183,7 +183,6 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
183 return; 183 return;
184 } 184 }
185 } 185 }
186 new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
187 186
188 pte = pte_offset_kernel(pmd, vaddr); 187 pte = pte_offset_kernel(pmd, vaddr);
189 if (!pte_none(*pte) && pte_val(new_pte) && 188 if (!pte_none(*pte) && pte_val(new_pte) &&
@@ -226,18 +225,6 @@ void __init cleanup_highmap(void)
226 } 225 }
227} 226}
228 227
229/* NOTE: this is meant to be run only at boot */
230void __init __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
231{
232 unsigned long address = __fix_to_virt(idx);
233
234 if (idx >= __end_of_fixed_addresses) {
235 printk(KERN_ERR "Invalid __set_fixmap\n");
236 return;
237 }
238 set_pte_phys(address, phys, prot);
239}
240
241static unsigned long __initdata table_start; 228static unsigned long __initdata table_start;
242static unsigned long __meminitdata table_end; 229static unsigned long __meminitdata table_end;
243 230
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index ee1d6d39edd4..45b99ac39480 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -2,6 +2,7 @@
2#include <asm/pgalloc.h> 2#include <asm/pgalloc.h>
3#include <asm/pgtable.h> 3#include <asm/pgtable.h>
4#include <asm/tlb.h> 4#include <asm/tlb.h>
5#include <asm/fixmap.h>
5 6
6pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 7pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
7{ 8{
@@ -274,3 +275,22 @@ int ptep_clear_flush_young(struct vm_area_struct *vma,
274 275
275 return young; 276 return young;
276} 277}
278
279int fixmaps_set;
280
281void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
282{
283 unsigned long address = __fix_to_virt(idx);
284
285 if (idx >= __end_of_fixed_addresses) {
286 BUG();
287 return;
288 }
289 set_pte_vaddr(address, pte);
290 fixmaps_set++;
291}
292
293void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
294{
295 __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags));
296}
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index 369cf065b6a4..0662f345212f 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -71,7 +71,7 @@ void show_mem(void)
71 * Associate a virtual page frame with a given physical page frame 71 * Associate a virtual page frame with a given physical page frame
72 * and protection flags for that frame. 72 * and protection flags for that frame.
73 */ 73 */
74static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) 74void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
75{ 75{
76 pgd_t *pgd; 76 pgd_t *pgd;
77 pud_t *pud; 77 pud_t *pud;
@@ -94,8 +94,8 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
94 return; 94 return;
95 } 95 }
96 pte = pte_offset_kernel(pmd, vaddr); 96 pte = pte_offset_kernel(pmd, vaddr);
97 if (pgprot_val(flags)) 97 if (pte_val(pteval))
98 set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags)); 98 set_pte_present(&init_mm, vaddr, pte, pteval);
99 else 99 else
100 pte_clear(&init_mm, vaddr, pte); 100 pte_clear(&init_mm, vaddr, pte);
101 101
@@ -145,18 +145,6 @@ static int fixmaps;
145unsigned long __FIXADDR_TOP = 0xfffff000; 145unsigned long __FIXADDR_TOP = 0xfffff000;
146EXPORT_SYMBOL(__FIXADDR_TOP); 146EXPORT_SYMBOL(__FIXADDR_TOP);
147 147
148void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
149{
150 unsigned long address = __fix_to_virt(idx);
151
152 if (idx >= __end_of_fixed_addresses) {
153 BUG();
154 return;
155 }
156 set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
157 fixmaps++;
158}
159
160/** 148/**
161 * reserve_top_address - reserves a hole in the top of kernel address space 149 * reserve_top_address - reserves a hole in the top of kernel address space
162 * @reserve - size of hole to reserve 150 * @reserve - size of hole to reserve
@@ -166,7 +154,7 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
166 */ 154 */
167void reserve_top_address(unsigned long reserve) 155void reserve_top_address(unsigned long reserve)
168{ 156{
169 BUG_ON(fixmaps > 0); 157 BUG_ON(fixmaps_set > 0);
170 printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", 158 printk(KERN_INFO "Reserving virtual address space above 0x%08x\n",
171 (int)-reserve); 159 (int)-reserve);
172 __FIXADDR_TOP = -reserve - PAGE_SIZE; 160 __FIXADDR_TOP = -reserve - PAGE_SIZE;
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index fe60aa9fed0a..316623cf411f 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1013,6 +1013,33 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
1013 return ret; 1013 return ret;
1014} 1014}
1015 1015
1016static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
1017{
1018 pte_t pte;
1019
1020 phys >>= PAGE_SHIFT;
1021
1022 switch (idx) {
1023 case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
1024#ifdef CONFIG_X86_F00F_BUG
1025 case FIX_F00F_IDT:
1026#endif
1027 case FIX_WP_TEST:
1028 case FIX_VDSO:
1029#ifdef CONFIG_X86_LOCAL_APIC
1030 case FIX_APIC_BASE: /* maps dummy local APIC */
1031#endif
1032 pte = pfn_pte(phys, prot);
1033 break;
1034
1035 default:
1036 pte = mfn_pte(phys, prot);
1037 break;
1038 }
1039
1040 __native_set_fixmap(idx, pte);
1041}
1042
1016static const struct pv_info xen_info __initdata = { 1043static const struct pv_info xen_info __initdata = {
1017 .paravirt_enabled = 1, 1044 .paravirt_enabled = 1,
1018 .shared_kernel_pmd = 0, 1045 .shared_kernel_pmd = 0,
@@ -1167,6 +1194,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1167 .enter = paravirt_enter_lazy_mmu, 1194 .enter = paravirt_enter_lazy_mmu,
1168 .leave = xen_leave_lazy, 1195 .leave = xen_leave_lazy,
1169 }, 1196 },
1197
1198 .set_fixmap = xen_set_fixmap,
1170}; 1199};
1171 1200
1172#ifdef CONFIG_SMP 1201#ifdef CONFIG_SMP