|
|
@@ -175,18 +175,15 @@ static inline pmd_t kvm_s2pmd_mkwrite(pmd_t pmd)
|
|
|
|
|
|
static inline void kvm_set_s2pte_readonly(pte_t *pte)
|
|
|
{
|
|
|
- pteval_t pteval;
|
|
|
- unsigned long tmp;
|
|
|
-
|
|
|
- asm volatile("// kvm_set_s2pte_readonly\n"
|
|
|
- " prfm pstl1strm, %2\n"
|
|
|
- "1: ldxr %0, %2\n"
|
|
|
- " and %0, %0, %3 // clear PTE_S2_RDWR\n"
|
|
|
- " orr %0, %0, %4 // set PTE_S2_RDONLY\n"
|
|
|
- " stxr %w1, %0, %2\n"
|
|
|
- " cbnz %w1, 1b\n"
|
|
|
- : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*pte))
|
|
|
- : "L" (~PTE_S2_RDWR), "L" (PTE_S2_RDONLY));
|
|
|
+ pteval_t old_pteval, pteval;
|
|
|
+
|
|
|
+ pteval = READ_ONCE(pte_val(*pte));
|
|
|
+ do {
|
|
|
+ old_pteval = pteval;
|
|
|
+ pteval &= ~PTE_S2_RDWR;
|
|
|
+ pteval |= PTE_S2_RDONLY;
|
|
|
+ pteval = cmpxchg_relaxed(&pte_val(*pte), old_pteval, pteval);
|
|
|
+ } while (pteval != old_pteval);
|
|
|
}
|
|
|
|
|
|
static inline bool kvm_s2pte_readonly(pte_t *pte)
|