|
@@ -125,12 +125,16 @@ static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot)
|
|
|
|
|
|
|
|
static inline pte_t pte_wrprotect(pte_t pte)
|
|
static inline pte_t pte_wrprotect(pte_t pte)
|
|
|
{
|
|
{
|
|
|
- return clear_pte_bit(pte, __pgprot(PTE_WRITE));
|
|
|
|
|
|
|
+ pte = clear_pte_bit(pte, __pgprot(PTE_WRITE));
|
|
|
|
|
+ pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
|
|
|
|
|
+ return pte;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static inline pte_t pte_mkwrite(pte_t pte)
|
|
static inline pte_t pte_mkwrite(pte_t pte)
|
|
|
{
|
|
{
|
|
|
- return set_pte_bit(pte, __pgprot(PTE_WRITE));
|
|
|
|
|
|
|
+ pte = set_pte_bit(pte, __pgprot(PTE_WRITE));
|
|
|
|
|
+ pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY));
|
|
|
|
|
+ return pte;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static inline pte_t pte_mkclean(pte_t pte)
|
|
static inline pte_t pte_mkclean(pte_t pte)
|
|
@@ -169,16 +173,6 @@ static inline pte_t pte_mknoncont(pte_t pte)
|
|
|
return clear_pte_bit(pte, __pgprot(PTE_CONT));
|
|
return clear_pte_bit(pte, __pgprot(PTE_CONT));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static inline pte_t pte_clear_rdonly(pte_t pte)
|
|
|
|
|
-{
|
|
|
|
|
- return clear_pte_bit(pte, __pgprot(PTE_RDONLY));
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static inline pte_t pte_set_rdonly(pte_t pte)
|
|
|
|
|
-{
|
|
|
|
|
- return set_pte_bit(pte, __pgprot(PTE_RDONLY));
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
static inline pte_t pte_mkpresent(pte_t pte)
|
|
static inline pte_t pte_mkpresent(pte_t pte)
|
|
|
{
|
|
{
|
|
|
return set_pte_bit(pte, __pgprot(PTE_VALID));
|
|
return set_pte_bit(pte, __pgprot(PTE_VALID));
|
|
@@ -226,14 +220,8 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
|
|
|
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
|
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
|
|
pte_t *ptep, pte_t pte)
|
|
pte_t *ptep, pte_t pte)
|
|
|
{
|
|
{
|
|
|
- if (pte_present(pte)) {
|
|
|
|
|
- if (pte_sw_dirty(pte) && pte_write(pte))
|
|
|
|
|
- pte_val(pte) &= ~PTE_RDONLY;
|
|
|
|
|
- else
|
|
|
|
|
- pte_val(pte) |= PTE_RDONLY;
|
|
|
|
|
- if (pte_user_exec(pte) && !pte_special(pte))
|
|
|
|
|
- __sync_icache_dcache(pte, addr);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
|
|
|
|
|
+ __sync_icache_dcache(pte, addr);
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* If the existing pte is valid, check for potential race with
|
|
* If the existing pte is valid, check for potential race with
|
|
@@ -659,12 +647,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
|
|
|
old_pte = pte;
|
|
old_pte = pte;
|
|
|
/*
|
|
/*
|
|
|
* If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY
|
|
* If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY
|
|
|
- * clear), set the PTE_DIRTY and PTE_RDONLY bits.
|
|
|
|
|
|
|
+ * clear), set the PTE_DIRTY bit.
|
|
|
*/
|
|
*/
|
|
|
- if (pte_hw_dirty(pte)) {
|
|
|
|
|
|
|
+ if (pte_hw_dirty(pte))
|
|
|
pte = pte_mkdirty(pte);
|
|
pte = pte_mkdirty(pte);
|
|
|
- pte = pte_set_rdonly(pte);
|
|
|
|
|
- }
|
|
|
|
|
pte = pte_wrprotect(pte);
|
|
pte = pte_wrprotect(pte);
|
|
|
pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
|
|
pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
|
|
|
pte_val(old_pte), pte_val(pte));
|
|
pte_val(old_pte), pte_val(pte));
|