|
@@ -155,3 +155,107 @@ extern struct page *empty_zero_page;
|
|
|
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|
|
|
|
|
/* to find an entry in a page-table-directory */
|
|
|
+#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
|
|
|
+
|
|
|
+#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
|
|
|
+
|
|
|
+/* to find an entry in a kernel page-table-directory */
|
|
|
+#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
|
|
|
+
|
|
|
+#define pmd_none(pmd) (!pmd_val(pmd))
|
|
|
+#define pmd_present(pmd) (pmd_val(pmd))
|
|
|
+
|
|
|
+static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
|
|
+{
|
|
|
+ return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
|
|
|
+}
|
|
|
+
|
|
|
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
|
|
|
+
|
|
|
+#ifndef CONFIG_HIGHPTE
|
|
|
+#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
|
|
|
+#define __pte_unmap(pte) do { } while (0)
|
|
|
+#else
|
|
|
+#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd)))
|
|
|
+#define __pte_unmap(pte) kunmap_atomic(pte)
|
|
|
+#endif
|
|
|
+
|
|
|
+#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
|
|
+
|
|
|
+#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr))
|
|
|
+
|
|
|
+#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
|
|
|
+#define pte_unmap(pte) __pte_unmap(pte)
|
|
|
+
|
|
|
+#define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
|
|
|
+#define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
|
|
|
+
|
|
|
+#define pte_page(pte) pfn_to_page(pte_pfn(pte))
|
|
|
+#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
|
|
|
+
|
|
|
+#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
|
|
|
+
|
|
|
+#define pte_none(pte) (!pte_val(pte))
|
|
|
+#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
|
|
|
+#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
|
|
|
+#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
|
|
|
+#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
|
|
|
+#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
|
|
|
+#define pte_special(pte) (0)
|
|
|
+
|
|
|
+#define pte_present_user(pte) (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
|
|
|
+
|
|
|
+#if __LINUX_ARM_ARCH__ < 6
|
|
|
+static inline void __sync_icache_dcache(pte_t pteval)
|
|
|
+{
|
|
|
+}
|
|
|
+#else
|
|
|
+extern void __sync_icache_dcache(pte_t pteval);
|
|
|
+#endif
|
|
|
+
|
|
|
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
|
|
+ pte_t *ptep, pte_t pteval)
|
|
|
+{
|
|
|
+ unsigned long ext = 0;
|
|
|
+
|
|
|
+ if (addr < TASK_SIZE && pte_present_user(pteval)) {
|
|
|
+ __sync_icache_dcache(pteval);
|
|
|
+ ext |= PTE_EXT_NG;
|
|
|
+ }
|
|
|
+
|
|
|
+ set_pte_ext(ptep, pteval, ext);
|
|
|
+}
|
|
|
+
|
|
|
+#define PTE_BIT_FUNC(fn,op) \
|
|
|
+static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
|
|
|
+
|
|
|
+PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY);
|
|
|
+PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY);
|
|
|
+PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
|
|
|
+PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
|
|
|
+PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
|
|
|
+PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
|
|
|
+
|
|
|
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
|
|
|
+
|
|
|
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|
|
+{
|
|
|
+ const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER |
|
|
|
+ L_PTE_NONE | L_PTE_VALID;
|
|
|
+ pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
|
|
|
+ return pte;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Encode and decode a swap entry. Swap entries are stored in the Linux
|
|
|
+ * page tables as follows:
|
|
|
+ *
|
|
|
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
|
|
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
|
|
+ * <--------------- offset ----------------------> < type -> 0 0 0
|
|
|
+ *
|
|
|
+ * This gives us up to 31 swap files and 64GB per swap file. Note that
|
|
|
+ * the offset field is always non-zero.
|
|
|
+ */
|
|
|
+#define __SWP_TYPE_SHIFT 3
|
|
|
+#define __SWP_TYPE_BITS 5
|