|
@@ -270,6 +270,9 @@ static inline int is_module_addr(void *addr)
|
|
|
#define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
|
|
|
#define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INVALID)
|
|
|
|
|
|
+#define _REGION3_ENTRY_ORIGIN_LARGE ~0x7fffffffUL /* large page address */
|
|
|
+#define _REGION3_ENTRY_ORIGIN ~0x7ffUL/* region third table origin */
|
|
|
+
|
|
|
#define _REGION3_ENTRY_DIRTY 0x2000 /* SW region dirty bit */
|
|
|
#define _REGION3_ENTRY_YOUNG 0x1000 /* SW region young bit */
|
|
|
#define _REGION3_ENTRY_LARGE 0x0400 /* RTTE-format control, large page */
|
|
@@ -525,6 +528,16 @@ static inline int pud_large(pud_t pud)
|
|
|
return !!(pud_val(pud) & _REGION3_ENTRY_LARGE);
|
|
|
}
|
|
|
|
|
|
+static inline unsigned long pud_pfn(pud_t pud)
|
|
|
+{
|
|
|
+ unsigned long origin_mask;
|
|
|
+
|
|
|
+ origin_mask = _REGION3_ENTRY_ORIGIN;
|
|
|
+ if (pud_large(pud))
|
|
|
+ origin_mask = _REGION3_ENTRY_ORIGIN_LARGE;
|
|
|
+ return (pud_val(pud) & origin_mask) >> PAGE_SHIFT;
|
|
|
+}
|
|
|
+
|
|
|
static inline int pud_bad(pud_t pud)
|
|
|
{
|
|
|
/*
|
|
@@ -1020,20 +1033,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
|
|
|
#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
|
|
|
#define pte_unmap(pte) do { } while (0)
|
|
|
|
|
|
-#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)
|
|
|
-static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
|
|
|
-{
|
|
|
- /*
|
|
|
- * pgprot is PAGE_NONE, PAGE_READ, or PAGE_WRITE (see __Pxxx / __Sxxx)
|
|
|
- * Convert to segment table entry format.
|
|
|
- */
|
|
|
- if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE))
|
|
|
- return pgprot_val(SEGMENT_NONE);
|
|
|
- if (pgprot_val(pgprot) == pgprot_val(PAGE_READ))
|
|
|
- return pgprot_val(SEGMENT_READ);
|
|
|
- return pgprot_val(SEGMENT_WRITE);
|
|
|
-}
|
|
|
-
|
|
|
static inline pmd_t pmd_wrprotect(pmd_t pmd)
|
|
|
{
|
|
|
pmd_val(pmd) &= ~_SEGMENT_ENTRY_WRITE;
|
|
@@ -1070,6 +1069,56 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd)
|
|
|
return pmd;
|
|
|
}
|
|
|
|
|
|
+static inline pud_t pud_wrprotect(pud_t pud)
|
|
|
+{
|
|
|
+ pud_val(pud) &= ~_REGION3_ENTRY_WRITE;
|
|
|
+ pud_val(pud) |= _REGION_ENTRY_PROTECT;
|
|
|
+ return pud;
|
|
|
+}
|
|
|
+
|
|
|
+static inline pud_t pud_mkwrite(pud_t pud)
|
|
|
+{
|
|
|
+ pud_val(pud) |= _REGION3_ENTRY_WRITE;
|
|
|
+ if (pud_large(pud) && !(pud_val(pud) & _REGION3_ENTRY_DIRTY))
|
|
|
+ return pud;
|
|
|
+ pud_val(pud) &= ~_REGION_ENTRY_PROTECT;
|
|
|
+ return pud;
|
|
|
+}
|
|
|
+
|
|
|
+static inline pud_t pud_mkclean(pud_t pud)
|
|
|
+{
|
|
|
+ if (pud_large(pud)) {
|
|
|
+ pud_val(pud) &= ~_REGION3_ENTRY_DIRTY;
|
|
|
+ pud_val(pud) |= _REGION_ENTRY_PROTECT;
|
|
|
+ }
|
|
|
+ return pud;
|
|
|
+}
|
|
|
+
|
|
|
+static inline pud_t pud_mkdirty(pud_t pud)
|
|
|
+{
|
|
|
+ if (pud_large(pud)) {
|
|
|
+ pud_val(pud) |= _REGION3_ENTRY_DIRTY |
|
|
|
+ _REGION3_ENTRY_SOFT_DIRTY;
|
|
|
+ if (pud_val(pud) & _REGION3_ENTRY_WRITE)
|
|
|
+ pud_val(pud) &= ~_REGION_ENTRY_PROTECT;
|
|
|
+ }
|
|
|
+ return pud;
|
|
|
+}
|
|
|
+
|
|
|
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)
|
|
|
+static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * pgprot is PAGE_NONE, PAGE_READ, or PAGE_WRITE (see __Pxxx / __Sxxx)
|
|
|
+ * Convert to segment table entry format.
|
|
|
+ */
|
|
|
+ if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE))
|
|
|
+ return pgprot_val(SEGMENT_NONE);
|
|
|
+ if (pgprot_val(pgprot) == pgprot_val(PAGE_READ))
|
|
|
+ return pgprot_val(SEGMENT_READ);
|
|
|
+ return pgprot_val(SEGMENT_WRITE);
|
|
|
+}
|
|
|
+
|
|
|
static inline pmd_t pmd_mkyoung(pmd_t pmd)
|
|
|
{
|
|
|
if (pmd_large(pmd)) {
|