|
@@ -133,7 +133,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
|
|
|
|
|
#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
|
|
|
|
|
|
-#define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL))
|
|
|
+#ifdef CONFIG_XPA
|
|
|
+# define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL))
|
|
|
+#else
|
|
|
+# define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
|
|
|
+#endif
|
|
|
+
|
|
|
#define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT)
|
|
|
#define pte_no_exec(pte) ((pte).pte_low & _PAGE_NO_EXEC)
|
|
|
|
|
@@ -143,14 +148,21 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
|
|
|
smp_wmb();
|
|
|
ptep->pte_low = pte.pte_low;
|
|
|
|
|
|
+#ifdef CONFIG_XPA
|
|
|
if (pte.pte_high & _PAGE_GLOBAL) {
|
|
|
+#else
|
|
|
+ if (pte.pte_low & _PAGE_GLOBAL) {
|
|
|
+#endif
|
|
|
pte_t *buddy = ptep_buddy(ptep);
|
|
|
/*
|
|
|
* Make sure the buddy is global too (if it's !none,
|
|
|
* it better already be global)
|
|
|
*/
|
|
|
- if (pte_none(*buddy))
|
|
|
+ if (pte_none(*buddy)) {
|
|
|
+ if (!config_enabled(CONFIG_XPA))
|
|
|
+ buddy->pte_low |= _PAGE_GLOBAL;
|
|
|
buddy->pte_high |= _PAGE_GLOBAL;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -160,8 +172,13 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
|
|
|
|
|
|
htw_stop();
|
|
|
/* Preserve global status for the pair */
|
|
|
- if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL)
|
|
|
- null.pte_high = _PAGE_GLOBAL;
|
|
|
+ if (config_enabled(CONFIG_XPA)) {
|
|
|
+ if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL)
|
|
|
+ null.pte_high = _PAGE_GLOBAL;
|
|
|
+ } else {
|
|
|
+ if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL)
|
|
|
+ null.pte_low = null.pte_high = _PAGE_GLOBAL;
|
|
|
+ }
|
|
|
|
|
|
set_pte_at(mm, addr, ptep, null);
|
|
|
htw_start();
|
|
@@ -302,6 +319,8 @@ static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; }
|
|
|
static inline pte_t pte_wrprotect(pte_t pte)
|
|
|
{
|
|
|
pte.pte_low &= ~_PAGE_WRITE;
|
|
|
+ if (!config_enabled(CONFIG_XPA))
|
|
|
+ pte.pte_low &= ~_PAGE_SILENT_WRITE;
|
|
|
pte.pte_high &= ~_PAGE_SILENT_WRITE;
|
|
|
return pte;
|
|
|
}
|
|
@@ -309,6 +328,8 @@ static inline pte_t pte_wrprotect(pte_t pte)
|
|
|
static inline pte_t pte_mkclean(pte_t pte)
|
|
|
{
|
|
|
pte.pte_low &= ~_PAGE_MODIFIED;
|
|
|
+ if (!config_enabled(CONFIG_XPA))
|
|
|
+ pte.pte_low &= ~_PAGE_SILENT_WRITE;
|
|
|
pte.pte_high &= ~_PAGE_SILENT_WRITE;
|
|
|
return pte;
|
|
|
}
|
|
@@ -316,6 +337,8 @@ static inline pte_t pte_mkclean(pte_t pte)
|
|
|
static inline pte_t pte_mkold(pte_t pte)
|
|
|
{
|
|
|
pte.pte_low &= ~_PAGE_ACCESSED;
|
|
|
+ if (!config_enabled(CONFIG_XPA))
|
|
|
+ pte.pte_low &= ~_PAGE_SILENT_READ;
|
|
|
pte.pte_high &= ~_PAGE_SILENT_READ;
|
|
|
return pte;
|
|
|
}
|
|
@@ -323,24 +346,33 @@ static inline pte_t pte_mkold(pte_t pte)
|
|
|
static inline pte_t pte_mkwrite(pte_t pte)
|
|
|
{
|
|
|
pte.pte_low |= _PAGE_WRITE;
|
|
|
- if (pte.pte_low & _PAGE_MODIFIED)
|
|
|
+ if (pte.pte_low & _PAGE_MODIFIED) {
|
|
|
+ if (!config_enabled(CONFIG_XPA))
|
|
|
+ pte.pte_low |= _PAGE_SILENT_WRITE;
|
|
|
pte.pte_high |= _PAGE_SILENT_WRITE;
|
|
|
+ }
|
|
|
return pte;
|
|
|
}
|
|
|
|
|
|
static inline pte_t pte_mkdirty(pte_t pte)
|
|
|
{
|
|
|
pte.pte_low |= _PAGE_MODIFIED;
|
|
|
- if (pte.pte_low & _PAGE_WRITE)
|
|
|
+ if (pte.pte_low & _PAGE_WRITE) {
|
|
|
+ if (!config_enabled(CONFIG_XPA))
|
|
|
+ pte.pte_low |= _PAGE_SILENT_WRITE;
|
|
|
pte.pte_high |= _PAGE_SILENT_WRITE;
|
|
|
+ }
|
|
|
return pte;
|
|
|
}
|
|
|
|
|
|
static inline pte_t pte_mkyoung(pte_t pte)
|
|
|
{
|
|
|
pte.pte_low |= _PAGE_ACCESSED;
|
|
|
- if (!(pte.pte_low & _PAGE_NO_READ))
|
|
|
+ if (!(pte.pte_low & _PAGE_NO_READ)) {
|
|
|
+ if (!config_enabled(CONFIG_XPA))
|
|
|
+ pte.pte_low |= _PAGE_SILENT_READ;
|
|
|
pte.pte_high |= _PAGE_SILENT_READ;
|
|
|
+ }
|
|
|
return pte;
|
|
|
}
|
|
|
#else
|
|
@@ -438,7 +470,7 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
|
|
|
*/
|
|
|
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
|
|
|
|
|
|
-#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
|
|
|
+#if defined(CONFIG_XPA)
|
|
|
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|
|
{
|
|
|
pte.pte_low &= (_PAGE_MODIFIED | _PAGE_ACCESSED | _PFNX_MASK);
|
|
@@ -447,6 +479,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|
|
pte.pte_high |= pgprot_val(newprot) & ~_PFN_MASK;
|
|
|
return pte;
|
|
|
}
|
|
|
+#elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
|
|
|
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|
|
+{
|
|
|
+ pte.pte_low &= _PAGE_CHG_MASK;
|
|
|
+ pte.pte_high &= (_PFN_MASK | _CACHE_MASK);
|
|
|
+ pte.pte_low |= pgprot_val(newprot);
|
|
|
+ pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK);
|
|
|
+ return pte;
|
|
|
+}
|
|
|
#else
|
|
|
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|
|
{
|