x86: add tizen_qemu_x86_defconfig & tizen_qemu_x86_64_defconfig
[platform/kernel/linux-rpi.git] / mm / highmem.c
index 4212ad0..4f94267 100644 (file)
@@ -504,16 +504,22 @@ static inline int kmap_local_calc_idx(int idx)
 
 static pte_t *__kmap_pte;
 
-static pte_t *kmap_get_pte(void)
+static pte_t *kmap_get_pte(unsigned long vaddr, int idx)
 {
+       if (IS_ENABLED(CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY))
+               /*
+                * Set by the arch if __kmap_pte[-idx] does not produce
+                * the correct entry.
+                */
+               return virt_to_kpte(vaddr);
        if (!__kmap_pte)
                __kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
-       return __kmap_pte;
+       return &__kmap_pte[-idx];
 }
 
 void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
 {
-       pte_t pteval, *kmap_pte = kmap_get_pte();
+       pte_t pteval, *kmap_pte;
        unsigned long vaddr;
        int idx;
 
@@ -525,9 +531,10 @@ void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
        preempt_disable();
        idx = arch_kmap_local_map_idx(kmap_local_idx_push(), pfn);
        vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-       BUG_ON(!pte_none(*(kmap_pte - idx)));
+       kmap_pte = kmap_get_pte(vaddr, idx);
+       BUG_ON(!pte_none(*kmap_pte));
        pteval = pfn_pte(pfn, prot);
-       arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte - idx, pteval);
+       arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte, pteval);
        arch_kmap_local_post_map(vaddr, pteval);
        current->kmap_ctrl.pteval[kmap_local_idx()] = pteval;
        preempt_enable();
@@ -560,7 +567,7 @@ EXPORT_SYMBOL(__kmap_local_page_prot);
 void kunmap_local_indexed(void *vaddr)
 {
        unsigned long addr = (unsigned long) vaddr & PAGE_MASK;
-       pte_t *kmap_pte = kmap_get_pte();
+       pte_t *kmap_pte;
        int idx;
 
        if (addr < __fix_to_virt(FIX_KMAP_END) ||
@@ -585,8 +592,9 @@ void kunmap_local_indexed(void *vaddr)
        idx = arch_kmap_local_unmap_idx(kmap_local_idx(), addr);
        WARN_ON_ONCE(addr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 
+       kmap_pte = kmap_get_pte(addr, idx);
        arch_kmap_local_pre_unmap(addr);
-       pte_clear(&init_mm, addr, kmap_pte - idx);
+       pte_clear(&init_mm, addr, kmap_pte);
        arch_kmap_local_post_unmap(addr);
        current->kmap_ctrl.pteval[kmap_local_idx()] = __pte(0);
        kmap_local_idx_pop();
@@ -608,7 +616,7 @@ EXPORT_SYMBOL(kunmap_local_indexed);
 void __kmap_local_sched_out(void)
 {
        struct task_struct *tsk = current;
-       pte_t *kmap_pte = kmap_get_pte();
+       pte_t *kmap_pte;
        int i;
 
        /* Clear kmaps */
@@ -619,7 +627,7 @@ void __kmap_local_sched_out(void)
 
                /* With debug all even slots are unmapped and act as guard */
                if (IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL) && !(i & 0x01)) {
-                       WARN_ON_ONCE(!pte_none(pteval));
+                       WARN_ON_ONCE(pte_val(pteval) != 0);
                        continue;
                }
                if (WARN_ON_ONCE(pte_none(pteval)))
@@ -635,8 +643,9 @@ void __kmap_local_sched_out(void)
                idx = arch_kmap_local_map_idx(i, pte_pfn(pteval));
 
                addr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+               kmap_pte = kmap_get_pte(addr, idx);
                arch_kmap_local_pre_unmap(addr);
-               pte_clear(&init_mm, addr, kmap_pte - idx);
+               pte_clear(&init_mm, addr, kmap_pte);
                arch_kmap_local_post_unmap(addr);
        }
 }
@@ -644,7 +653,7 @@ void __kmap_local_sched_out(void)
 void __kmap_local_sched_in(void)
 {
        struct task_struct *tsk = current;
-       pte_t *kmap_pte = kmap_get_pte();
+       pte_t *kmap_pte;
        int i;
 
        /* Restore kmaps */
@@ -655,7 +664,7 @@ void __kmap_local_sched_in(void)
 
                /* With debug all even slots are unmapped and act as guard */
                if (IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL) && !(i & 0x01)) {
-                       WARN_ON_ONCE(!pte_none(pteval));
+                       WARN_ON_ONCE(pte_val(pteval) != 0);
                        continue;
                }
                if (WARN_ON_ONCE(pte_none(pteval)))
@@ -664,7 +673,8 @@ void __kmap_local_sched_in(void)
                /* See comment in __kmap_local_sched_out() */
                idx = arch_kmap_local_map_idx(i, pte_pfn(pteval));
                addr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-               set_pte_at(&init_mm, addr, kmap_pte - idx, pteval);
+               kmap_pte = kmap_get_pte(addr, idx);
+               set_pte_at(&init_mm, addr, kmap_pte, pteval);
                arch_kmap_local_post_map(addr, pteval);
        }
 }