]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'x86/fixmap' into x86/devel
authorIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 10:24:29 +0000 (12:24 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 10:24:29 +0000 (12:24 +0200)
Conflicts:

arch/x86/mm/init_64.c

Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/paravirt.c
arch/x86/mm/init_64.c
arch/x86/mm/pgtable.c
arch/x86/mm/pgtable_32.c
arch/x86/xen/enlighten.c
include/asm-x86/fixmap.h
include/asm-x86/fixmap_32.h
include/asm-x86/fixmap_64.h
include/asm-x86/paravirt.h
include/asm-x86/pgtable.h

index f1ab0f727007e5f93f6e4502f7a2e6ef73bec62b..e9b5045372129b15a9edbda594b0296c84843db1 100644 (file)
@@ -420,6 +420,8 @@ struct pv_mmu_ops pv_mmu_ops = {
                .enter = paravirt_nop,
                .leave = paravirt_nop,
        },
+
+       .set_fixmap = native_set_fixmap,
 };
 
 EXPORT_SYMBOL_GPL(pv_time_ops);
index 18c6a006e4061413066692dc3c810c0013a4b8df..97c2bc741e94fc511a6021e19c4e7acef264ed7a 100644 (file)
@@ -148,15 +148,15 @@ static __init void *spp_getpage(void)
        return ptr;
 }
 
-static __init void
-set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
+void
+set_pte_vaddr(unsigned long vaddr, pte_t new_pte)
 {
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
-       pte_t *pte, new_pte;
+       pte_t *pte;
 
-       pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
+       pr_debug("set_pte_vaddr %lx to %lx\n", vaddr, native_pte_val(new_pte));
 
        pgd = pgd_offset_k(vaddr);
        if (pgd_none(*pgd)) {
@@ -183,7 +183,6 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
                        return;
                }
        }
-       new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
 
        pte = pte_offset_kernel(pmd, vaddr);
        if (!pte_none(*pte) && pte_val(new_pte) &&
@@ -226,18 +225,6 @@ void __init cleanup_highmap(void)
        }
 }
 
-/* NOTE: this is meant to be run only at boot */
-void __init __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
-{
-       unsigned long address = __fix_to_virt(idx);
-
-       if (idx >= __end_of_fixed_addresses) {
-               printk(KERN_ERR "Invalid __set_fixmap\n");
-               return;
-       }
-       set_pte_phys(address, phys, prot);
-}
-
 static unsigned long __initdata table_start;
 static unsigned long __meminitdata table_end;
 
index ee1d6d39edd4343e52300a1691049c3976402eb6..45b99ac394802cd28ed9c7014ca8a392a4d5a943 100644 (file)
@@ -2,6 +2,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlb.h>
+#include <asm/fixmap.h>
 
 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
@@ -274,3 +275,22 @@ int ptep_clear_flush_young(struct vm_area_struct *vma,
 
        return young;
 }
+
+int fixmaps_set;
+
+void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
+{
+       unsigned long address = __fix_to_virt(idx);
+
+       if (idx >= __end_of_fixed_addresses) {
+               BUG();
+               return;
+       }
+       set_pte_vaddr(address, pte);
+       fixmaps_set++;
+}
+
+void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
+{
+       __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags));
+}
index 369cf065b6a48f78f9870ddaf9f27e59b6980c0c..0662f345212f048b37b61b7cef478bb49a584733 100644 (file)
@@ -71,7 +71,7 @@ void show_mem(void)
  * Associate a virtual page frame with a given physical page frame 
  * and protection flags for that frame.
  */ 
-static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
+void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
 {
        pgd_t *pgd;
        pud_t *pud;
@@ -94,8 +94,8 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
                return;
        }
        pte = pte_offset_kernel(pmd, vaddr);
-       if (pgprot_val(flags))
-               set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
+       if (pte_val(pteval))
+               set_pte_present(&init_mm, vaddr, pte, pteval);
        else
                pte_clear(&init_mm, vaddr, pte);
 
@@ -145,18 +145,6 @@ static int fixmaps;
 unsigned long __FIXADDR_TOP = 0xfffff000;
 EXPORT_SYMBOL(__FIXADDR_TOP);
 
-void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
-{
-       unsigned long address = __fix_to_virt(idx);
-
-       if (idx >= __end_of_fixed_addresses) {
-               BUG();
-               return;
-       }
-       set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
-       fixmaps++;
-}
-
 /**
  * reserve_top_address - reserves a hole in the top of kernel address space
  * @reserve - size of hole to reserve
@@ -166,7 +154,7 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
  */
 void reserve_top_address(unsigned long reserve)
 {
-       BUG_ON(fixmaps > 0);
+       BUG_ON(fixmaps_set > 0);
        printk(KERN_INFO "Reserving virtual address space above 0x%08x\n",
               (int)-reserve);
        __FIXADDR_TOP = -reserve - PAGE_SIZE;
index fe60aa9fed0a6a73fbed57b1fc63dcfeec39a761..316623cf411fb808249a357bcb0de45cba16b133 100644 (file)
@@ -1013,6 +1013,33 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
        return ret;
 }
 
+static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
+{
+       pte_t pte;
+
+       phys >>= PAGE_SHIFT;
+
+       switch (idx) {
+       case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
+#ifdef CONFIG_X86_F00F_BUG
+       case FIX_F00F_IDT:
+#endif
+       case FIX_WP_TEST:
+       case FIX_VDSO:
+#ifdef CONFIG_X86_LOCAL_APIC
+       case FIX_APIC_BASE:     /* maps dummy local APIC */
+#endif
+               pte = pfn_pte(phys, prot);
+               break;
+
+       default:
+               pte = mfn_pte(phys, prot);
+               break;
+       }
+
+       __native_set_fixmap(idx, pte);
+}
+
 static const struct pv_info xen_info __initdata = {
        .paravirt_enabled = 1,
        .shared_kernel_pmd = 0,
@@ -1167,6 +1194,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
                .enter = paravirt_enter_lazy_mmu,
                .leave = xen_leave_lazy,
        },
+
+       .set_fixmap = xen_set_fixmap,
 };
 
 #ifdef CONFIG_SMP
index 5bd206973dca3cf184b859a1c2031ce6d3501ff3..44d4f82173496d2984b9c6612c4d4fe48341a146 100644 (file)
@@ -7,7 +7,62 @@
 # include "fixmap_64.h"
 #endif
 
+extern int fixmaps_set;
+
+void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
+void native_set_fixmap(enum fixed_addresses idx,
+                      unsigned long phys, pgprot_t flags);
+
+#ifndef CONFIG_PARAVIRT
+static inline void __set_fixmap(enum fixed_addresses idx,
+                               unsigned long phys, pgprot_t flags)
+{
+       native_set_fixmap(idx, phys, flags);
+}
+#endif
+
+#define set_fixmap(idx, phys)                          \
+       __set_fixmap(idx, phys, PAGE_KERNEL)
+
+/*
+ * Some hardware wants to get fixmapped without caching.
+ */
+#define set_fixmap_nocache(idx, phys)                  \
+       __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+
 #define clear_fixmap(idx)                      \
        __set_fixmap(idx, 0, __pgprot(0))
 
+#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)       ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without translation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
+{
+       /*
+        * this branch gets completely eliminated after inlining,
+        * except when someone tries to use fixaddr indices in an
+        * illegal way. (such as mixing up address types or using
+        * out-of-range indices).
+        *
+        * If it doesn't get removed, the linker will complain
+        * loudly with a reasonably clear error message..
+        */
+       if (idx >= __end_of_fixed_addresses)
+               __this_fixmap_does_not_exist();
+
+       return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+       BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+       return __virt_to_fix(vaddr);
+}
 #endif
index f0df7ee968161aabe26c50cd138ac8157b606367..aae2f0501a4006a145ca82e9d65f7999c89aaf5f 100644 (file)
@@ -109,17 +109,8 @@ enum fixed_addresses {
        __end_of_fixed_addresses
 };
 
-extern void __set_fixmap(enum fixed_addresses idx,
-                        unsigned long phys, pgprot_t flags);
 extern void reserve_top_address(unsigned long reserve);
 
-#define set_fixmap(idx, phys)                          \
-       __set_fixmap(idx, phys, PAGE_KERNEL)
-/*
- * Some hardware wants to get fixmapped without caching.
- */
-#define set_fixmap_nocache(idx, phys)                  \
-       __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
 
 #define FIXADDR_TOP    ((unsigned long)__FIXADDR_TOP)
 
@@ -128,38 +119,5 @@ extern void reserve_top_address(unsigned long reserve);
 #define FIXADDR_START          (FIXADDR_TOP - __FIXADDR_SIZE)
 #define FIXADDR_BOOT_START     (FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
 
-#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
-#define __virt_to_fix(x)       ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
-
-extern void __this_fixmap_does_not_exist(void);
-
-/*
- * 'index to address' translation. If anyone tries to use the idx
- * directly without tranlation, we catch the bug with a NULL-deference
- * kernel oops. Illegal ranges of incoming indices are caught too.
- */
-static __always_inline unsigned long fix_to_virt(const unsigned int idx)
-{
-       /*
-        * this branch gets completely eliminated after inlining,
-        * except when someone tries to use fixaddr indices in an
-        * illegal way. (such as mixing up address types or using
-        * out-of-range indices).
-        *
-        * If it doesn't get removed, the linker will complain
-        * loudly with a reasonably clear error message..
-        */
-       if (idx >= __end_of_fixed_addresses)
-               __this_fixmap_does_not_exist();
-
-       return __fix_to_virt(idx);
-}
-
-static inline unsigned long virt_to_fix(const unsigned long vaddr)
-{
-       BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
-       return __virt_to_fix(vaddr);
-}
-
 #endif /* !__ASSEMBLY__ */
 #endif
index 355d26a75a821a87aa298ee52f79617015dc7a8e..626098823a0c5b99afab7fce5226e132c0cbd519 100644 (file)
@@ -52,17 +52,6 @@ enum fixed_addresses {
        __end_of_fixed_addresses
 };
 
-extern void __set_fixmap(enum fixed_addresses idx,
-                        unsigned long phys, pgprot_t flags);
-
-#define set_fixmap(idx, phys)                  \
-       __set_fixmap(idx, phys, PAGE_KERNEL)
-/*
- * Some hardware wants to get fixmapped without caching.
- */
-#define set_fixmap_nocache(idx, phys)                  \
-       __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
-
 #define FIXADDR_TOP    (VSYSCALL_END-PAGE_SIZE)
 #define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
@@ -71,30 +60,4 @@ extern void __set_fixmap(enum fixed_addresses idx,
 #define FIXADDR_USER_START     ((unsigned long)VSYSCALL32_VSYSCALL)
 #define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
 
-#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
-
-extern void __this_fixmap_does_not_exist(void);
-
-/*
- * 'index to address' translation. If anyone tries to use the idx
- * directly without translation, we catch the bug with a NULL-deference
- * kernel oops. Illegal ranges of incoming indices are caught too.
- */
-static __always_inline unsigned long fix_to_virt(const unsigned int idx)
-{
-       /*
-        * this branch gets completely eliminated after inlining,
-        * except when someone tries to use fixaddr indices in an
-        * illegal way. (such as mixing up address types or using
-        * out-of-range indices).
-        *
-        * If it doesn't get removed, the linker will complain
-        * loudly with a reasonably clear error message..
-        */
-       if (idx >= __end_of_fixed_addresses)
-               __this_fixmap_does_not_exist();
-
-       return __fix_to_virt(idx);
-}
-
 #endif
index e9ada314dfc15c8ef2faad180989107a4452ec7b..41f5447efd88490800808fc4efda819e1ac54f7a 100644 (file)
@@ -279,6 +279,13 @@ struct pv_mmu_ops {
 #endif
 
        struct pv_lazy_ops lazy_mode;
+
+       /* dom0 ops */
+
+       /* Sometimes the physical address is a pfn, and sometimes its
+          an mfn.  We can tell which is which from the index. */
+       void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
+                          unsigned long phys, pgprot_t flags);
 };
 
 /* This contains all the paravirt structures: we get a convenient
@@ -1295,6 +1302,12 @@ static inline void arch_flush_lazy_mmu_mode(void)
        }
 }
 
+static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
+                               unsigned long phys, pgprot_t flags)
+{
+       pv_mmu_ops.set_fixmap(idx, phys, flags);
+}
+
 void _paravirt_nop(void);
 #define paravirt_nop   ((void *)_paravirt_nop)
 
index bcb5446a08d1b431b07192d4467c39c50c2db1ba..f048975b31a48c20398980d0479097434b6e00b1 100644 (file)
@@ -313,6 +313,9 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
                               unsigned long size, pgprot_t *vma_prot);
 #endif
 
+/* Install a pte for a particular vaddr in kernel space. */
+void set_pte_vaddr(unsigned long vaddr, pte_t pte);
+
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else  /* !CONFIG_PARAVIRT */