]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/mm/pageattr.c
x86: remove suprious ifdefs from pageattr.c
[linux-2.6-omap-h63xx.git] / arch / x86 / mm / pageattr.c
index 42ca3d8effad96a045aa537800651acb442a1712..8493c855582bf56a5a36d2e6e64266332c9d26c0 100644 (file)
@@ -16,6 +16,9 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 
+/*
+ * The current flushing context - we pass it instead of 5 arguments:
+ */
 struct cpa_data {
        unsigned long   vaddr;
        pgprot_t        mask_set;
@@ -24,11 +27,6 @@ struct cpa_data {
        int             flushtlb;
 };
 
-enum {
-       CPA_NO_SPLIT = 0,
-       CPA_SPLIT,
-};
-
 static inline int
 within(unsigned long addr, unsigned long start, unsigned long end)
 {
@@ -169,8 +167,6 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address)
        if (within(address, virt_to_highmap(_text), virt_to_highmap(_etext)))
                pgprot_val(forbidden) |= _PAGE_NX;
 
-
-#ifdef CONFIG_DEBUG_RODATA
        /* The .rodata section needs to be read-only */
        if (within(address, (unsigned long)__start_rodata,
                                (unsigned long)__end_rodata))
@@ -181,7 +177,6 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address)
        if (within(address, virt_to_highmap(__start_rodata),
                                virt_to_highmap(__end_rodata)))
                pgprot_val(forbidden) |= _PAGE_RW;
-#endif
 
        prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
 
@@ -206,6 +201,7 @@ pte_t *lookup_address(unsigned long address, int *level)
 
        if (pgd_none(*pgd))
                return NULL;
+
        pud = pud_offset(pgd, address);
        if (pud_none(*pud))
                return NULL;
@@ -223,9 +219,13 @@ pte_t *lookup_address(unsigned long address, int *level)
                return (pte_t *)pmd;
 
        *level = PG_LEVEL_4K;
+
        return pte_offset_kernel(pmd, address);
 }
 
+/*
+ * Set the new pmd in all the pgds we know about:
+ */
 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
 {
        /* change init_mm */
@@ -248,24 +248,14 @@ static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
 #endif
 }
 
-static int try_preserve_large_page(pte_t *kpte, unsigned long address,
-                                  struct cpa_data *cpa)
+static int
+try_preserve_large_page(pte_t *kpte, unsigned long address,
+                       struct cpa_data *cpa)
 {
        unsigned long nextpage_addr, numpages, pmask, psize, flags;
        pte_t new_pte, old_pte, *tmp;
        pgprot_t old_prot, new_prot;
-       int level, res = CPA_SPLIT;
-
-       /*
-        * An Athlon 64 X2 showed hard hangs if we tried to preserve
-        * largepages and changed the PSE entry from RW to RO.
-        *
-        * As AMD CPUs have a long series of erratas in this area,
-        * (and none of the known ones seem to explain this hang),
-        * disable this code until the hang can be debugged:
-        */
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
-               return res;
+       int level, do_split = 1;
 
        spin_lock_irqsave(&pgd_lock, flags);
        /*
@@ -288,7 +278,7 @@ static int try_preserve_large_page(pte_t *kpte, unsigned long address,
                break;
 #endif
        default:
-               res = -EINVAL;
+               do_split = -EINVAL;
                goto out_unlock;
        }
 
@@ -316,7 +306,7 @@ static int try_preserve_large_page(pte_t *kpte, unsigned long address,
         * above:
         */
        if (pgprot_val(new_prot) == pgprot_val(old_prot)) {
-               res = CPA_NO_SPLIT;
+               do_split = 0;
                goto out_unlock;
        }
 
@@ -336,22 +326,23 @@ static int try_preserve_large_page(pte_t *kpte, unsigned long address,
                new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot));
                __set_pmd_pte(kpte, address, new_pte);
                cpa->flushtlb = 1;
-               res = CPA_NO_SPLIT;
+               do_split = 0;
        }
 
 out_unlock:
        spin_unlock_irqrestore(&pgd_lock, flags);
-       return res;
+
+       return do_split;
 }
 
 static int split_large_page(pte_t *kpte, unsigned long address)
 {
-       pgprot_t ref_prot;
+       unsigned long flags, pfn, pfninc = 1;
        gfp_t gfp_flags = GFP_KERNEL;
-       unsigned long flags, addr, pfn, pfninc = 1;
+       unsigned int i, level;
        pte_t *pbase, *tmp;
+       pgprot_t ref_prot;
        struct page *base;
-       unsigned int i, level;
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
        gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
@@ -369,8 +360,6 @@ static int split_large_page(pte_t *kpte, unsigned long address)
        if (tmp != kpte)
                goto out_unlock;
 
-       address = __pa(address);
-       addr = address & PMD_PAGE_MASK;
        pbase = (pte_t *)page_address(base);
 #ifdef CONFIG_X86_32
        paravirt_alloc_pt(&init_mm, page_to_pfn(base));
@@ -381,7 +370,6 @@ static int split_large_page(pte_t *kpte, unsigned long address)
        if (level == PG_LEVEL_1G) {
                pfninc = PMD_PAGE_SIZE >> PAGE_SHIFT;
                pgprot_val(ref_prot) |= _PAGE_PSE;
-               addr &= PUD_PAGE_MASK;
        }
 #endif
 
@@ -418,8 +406,8 @@ out_unlock:
 
 static int __change_page_attr(unsigned long address, struct cpa_data *cpa)
 {
+       int level, do_split, err;
        struct page *kpte_page;
-       int level, res;
        pte_t *kpte;
 
 repeat:
@@ -470,26 +458,25 @@ repeat:
         * Check, whether we can keep the large page intact
         * and just change the pte:
         */
-       res = try_preserve_large_page(kpte, address, cpa);
-       if (res < 0)
-               return res;
-
+       do_split = try_preserve_large_page(kpte, address, cpa);
        /*
         * When the range fits into the existing large page,
         * return. cp->numpages and cpa->tlbflush have been updated in
         * try_large_page:
         */
-       if (res == CPA_NO_SPLIT)
-               return 0;
+       if (do_split <= 0)
+               return do_split;
 
        /*
         * We have to split the large page:
         */
-       res = split_large_page(kpte, address);
-       if (res)
-               return res;
-       cpa->flushtlb = 1;
-       goto repeat;
+       err = split_large_page(kpte, address);
+       if (!err) {
+               cpa->flushtlb = 1;
+               goto repeat;
+       }
+
+       return err;
 }
 
 /**
@@ -505,7 +492,6 @@ repeat:
  *
  * Modules and drivers should use the set_memory_* APIs instead.
  */
-
 static int change_page_attr_addr(struct cpa_data *cpa)
 {
        int err;