KVM: x86: avoid write-tearing of TDP
authorNadav Amit <nadav.amit@gmail.com>
Wed, 11 May 2016 15:04:29 +0000 (08:04 -0700)
committerRadim Krčmář <rkrcmar@redhat.com>
Thu, 2 Jun 2016 15:38:50 +0000 (17:38 +0200)
In theory, nothing prevents the compiler from write-tearing PTEs, or
split PTE writes. These partially-modified PTEs can be fetched by other
cores and cause mayhem. I have not really encountered such case in
real-life, but it does seem possible.

For example, the compiler may try to do something creative for
kvm_set_pte_rmapp() and perform multiple writes to the PTE.

Signed-off-by: Nadav Amit <nadav.amit@gmail.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
arch/x86/kvm/mmu.c

index 24e800116ab4a25d750dca67023633b16f648972..def97b3a392b52bd004b9b8e60d8bf70c018bc0c 100644 (file)
@@ -336,12 +336,12 @@ static gfn_t pse36_gfn_delta(u32 gpte)
 #ifdef CONFIG_X86_64
 static void __set_spte(u64 *sptep, u64 spte)
 {
-       *sptep = spte;
+       WRITE_ONCE(*sptep, spte);
 }
 
 static void __update_clear_spte_fast(u64 *sptep, u64 spte)
 {
-       *sptep = spte;
+       WRITE_ONCE(*sptep, spte);
 }
 
 static u64 __update_clear_spte_slow(u64 *sptep, u64 spte)
@@ -390,7 +390,7 @@ static void __set_spte(u64 *sptep, u64 spte)
         */
        smp_wmb();
 
-       ssptep->spte_low = sspte.spte_low;
+       WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
 }
 
 static void __update_clear_spte_fast(u64 *sptep, u64 spte)
@@ -400,7 +400,7 @@ static void __update_clear_spte_fast(u64 *sptep, u64 spte)
        ssptep = (union split_spte *)sptep;
        sspte = (union split_spte)spte;
 
-       ssptep->spte_low = sspte.spte_low;
+       WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
 
        /*
         * If we map the spte from present to nonpresent, we should clear