kvm: arm64: Convert kvm_set_s2pte_readonly() from inline asm to cmpxchg()
authorCatalin Marinas <catalin.marinas@arm.com>
Thu, 6 Jul 2017 10:46:39 +0000 (11:46 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 21 Aug 2017 10:12:39 +0000 (11:12 +0100)
To take advantage of the LSE atomic instructions and also make the code
cleaner, convert the kvm_set_s2pte_readonly() function to use the more
generic cmpxchg().

Cc: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/kvm_mmu.h

index a89cc22..672c868 100644 (file)
@@ -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)