aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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 74f0c5ea2a03..cf06670349dc 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -416,6 +416,8 @@ struct pv_mmu_ops pv_mmu_ops = {
416 .enter = paravirt_nop, 416 .enter = paravirt_nop,
417 .leave = paravirt_nop, 417 .leave = paravirt_nop,
418 }, 418 },
419
420 .set_fixmap = native_set_fixmap,
419}; 421};
420 422
421EXPORT_SYMBOL_GPL(pv_time_ops); 423EXPORT_SYMBOL_GPL(pv_time_ops);
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 156e6d7b0e32..74fae8335128 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -135,15 +135,15 @@ static __init void *spp_getpage(void)
135 return ptr; 135 return ptr;
136} 136}
137 137
138static void 138void
139set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) 139set_pte_vaddr(unsigned long vaddr, pte_t new_pte)
140{ 140{
141 pgd_t *pgd; 141 pgd_t *pgd;
142 pud_t *pud; 142 pud_t *pud;
143 pmd_t *pmd; 143 pmd_t *pmd;
144 pte_t *pte, new_pte; 144 pte_t *pte;
145 145
146 pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys); 146 pr_debug("set_pte_vaddr %lx to %lx\n", vaddr, native_pte_val(new_pte));
147 147
148 pgd = pgd_offset_k(vaddr); 148 pgd = pgd_offset_k(vaddr);
149 if (pgd_none(*pgd)) { 149 if (pgd_none(*pgd)) {
@@ -170,7 +170,6 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
170 return; 170 return;
171 } 171 }
172 } 172 }
173 new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
174 173
175 pte = pte_offset_kernel(pmd, vaddr); 174 pte = pte_offset_kernel(pmd, vaddr);
176 if (!pte_none(*pte) && pte_val(new_pte) && 175 if (!pte_none(*pte) && pte_val(new_pte) &&
@@ -213,18 +212,6 @@ void __init cleanup_highmap(void)
213 } 212 }
214} 213}
215 214
216/* NOTE: this is meant to be run only at boot */
217void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
218{
219 unsigned long address = __fix_to_virt(idx);
220
221 if (idx >= __end_of_fixed_addresses) {
222 printk(KERN_ERR "Invalid __set_fixmap\n");
223 return;
224 }
225 set_pte_phys(address, phys, prot);
226}
227
228static unsigned long __initdata table_start; 215static unsigned long __initdata table_start;
229static unsigned long __meminitdata table_end; 216static unsigned long __meminitdata table_end;
230 217
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 50159764f694..892fd1892b8d 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 f09c1c69c37a..2d19382e6555 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -947,6 +947,33 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
947 return ret; 947 return ret;
948} 948}
949 949
950static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
951{
952 pte_t pte;
953
954 phys >>= PAGE_SHIFT;
955
956 switch (idx) {
957 case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
958#ifdef CONFIG_X86_F00F_BUG
959 case FIX_F00F_IDT:
960#endif
961 case FIX_WP_TEST:
962 case FIX_VDSO:
963#ifdef CONFIG_X86_LOCAL_APIC
964 case FIX_APIC_BASE: /* maps dummy local APIC */
965#endif
966 pte = pfn_pte(phys, prot);
967 break;
968
969 default:
970 pte = mfn_pte(phys, prot);
971 break;
972 }
973
974 __native_set_fixmap(idx, pte);
975}
976
950static const struct pv_info xen_info __initdata = { 977static const struct pv_info xen_info __initdata = {
951 .paravirt_enabled = 1, 978 .paravirt_enabled = 1,
952 .shared_kernel_pmd = 0, 979 .shared_kernel_pmd = 0,
@@ -1097,6 +1124,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
1097 .enter = paravirt_enter_lazy_mmu, 1124 .enter = paravirt_enter_lazy_mmu,
1098 .leave = xen_leave_lazy, 1125 .leave = xen_leave_lazy,
1099 }, 1126 },
1127
1128 .set_fixmap = xen_set_fixmap,
1100}; 1129};
1101 1130
1102#ifdef CONFIG_SMP 1131#ifdef CONFIG_SMP