]> err.no Git - linux-2.6/blobdiff - include/asm-powerpc/pgtable-64k.h
[POWERPC] Provide a way to protect 4k subpages when using 64k pages
[linux-2.6] / include / asm-powerpc / pgtable-64k.h
index 31cbd3d7fce82b24690e4ed4e0fa6a7b84d5ceda..1cbd6b377eead96c093d4ce48975d69b8f57585c 100644 (file)
@@ -9,6 +9,7 @@
 #define PUD_INDEX_SIZE 0
 #define PGD_INDEX_SIZE  4
 
+#ifndef __ASSEMBLY__
 #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
 #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
 #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
 #define PTRS_PER_PMD   (1 << PMD_INDEX_SIZE)
 #define PTRS_PER_PGD   (1 << PGD_INDEX_SIZE)
 
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+/*
+ * For the sub-page protection option, we extend the PGD with one of
+ * these.  Basically we have a 3-level tree, with the top level being
+ * the protptrs array.  To optimize speed and memory consumption when
+ * only addresses < 4GB are being protected, pointers to the first
+ * four pages of sub-page protection words are stored in the low_prot
+ * array.
+ * Each page of sub-page protection words protects 1GB (4 bytes
+ * protects 64k).  For the 3-level tree, each page of pointers then
+ * protects 8TB.
+ */
+struct subpage_prot_table {
+       unsigned long maxaddr;  /* only addresses < this are protected */
+       unsigned int **protptrs[2];
+       unsigned int *low_prot[4];
+};
+
+#undef PGD_TABLE_SIZE
+#define PGD_TABLE_SIZE         ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \
+                                sizeof(struct subpage_prot_table))
+
+#define SBP_L1_BITS            (PAGE_SHIFT - 2)
+#define SBP_L2_BITS            (PAGE_SHIFT - 3)
+#define SBP_L1_COUNT           (1 << SBP_L1_BITS)
+#define SBP_L2_COUNT           (1 << SBP_L2_BITS)
+#define SBP_L2_SHIFT           (PAGE_SHIFT + SBP_L1_BITS)
+#define SBP_L3_SHIFT           (SBP_L2_SHIFT + SBP_L2_BITS)
+
+extern void subpage_prot_free(pgd_t *pgd);
+
+static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
+{
+       return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD);
+}
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
+#endif /* __ASSEMBLY__ */
+
 /* With 4k base page size, hugepage PTEs go at the PMD level */
 #define MIN_HUGEPTE_SHIFT      PAGE_SHIFT
 
 
 /* Shift to put page number into pte.
  *
- * That gives us a max RPN of 32 bits, which means a max of 48 bits
- * of addressable physical space.
- * We could get 3 more bits here by setting PTE_RPN_SHIFT to 29 but
- * 32 makes PTEs more readable for debugging for now :)
+ * That gives us a max RPN of 34 bits, which means a max of 50 bits
+ * of addressable physical space, or 46 bits for the special 4k PFNs.
  */
-#define PTE_RPN_SHIFT  (32)
+#define PTE_RPN_SHIFT  (30)
 #define PTE_RPN_MAX    (1UL << (64 - PTE_RPN_SHIFT))
 #define PTE_RPN_MASK   (~((1UL<<PTE_RPN_SHIFT)-1))