aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@cn.fujitsu.com>2010-11-19 04:02:35 -0500
committerAvi Kivity <avi@redhat.com>2011-01-12 04:29:45 -0500
commitb330aa0c7df1ece45f45566c45ea44f01e379ab0 (patch)
tree898c047105adaf74793e2f9a9293f5082049cc9f /arch
parent30bfb3c4256422221cc763ff6e749ce8aca8e5c9 (diff)
KVM: MMU: don't drop spte if overwrite it from W to RO
We just need flush tlb if overwrite a writable spte with a read-only one. And we should move this operation to set_spte() for sync_page path Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/mmu.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index ab100a7e0c49..29b2ec46bf1e 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1960,7 +1960,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1960 gfn_t gfn, pfn_t pfn, bool speculative, 1960 gfn_t gfn, pfn_t pfn, bool speculative,
1961 bool can_unsync, bool reset_host_protection) 1961 bool can_unsync, bool reset_host_protection)
1962{ 1962{
1963 u64 spte; 1963 u64 spte, entry = *sptep;
1964 int ret = 0; 1964 int ret = 0;
1965 1965
1966 /* 1966 /*
@@ -2031,6 +2031,14 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
2031 2031
2032set_pte: 2032set_pte:
2033 update_spte(sptep, spte); 2033 update_spte(sptep, spte);
2034 /*
2035 * If we overwrite a writable spte with a read-only one we
2036 * should flush remote TLBs. Otherwise rmap_write_protect
2037 * will find a read-only spte, even though the writable spte
2038 * might be cached on a CPU's TLB.
2039 */
2040 if (is_writable_pte(entry) && !is_writable_pte(*sptep))
2041 kvm_flush_remote_tlbs(vcpu->kvm);
2034done: 2042done:
2035 return ret; 2043 return ret;
2036} 2044}
@@ -2069,16 +2077,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
2069 spte_to_pfn(*sptep), pfn); 2077 spte_to_pfn(*sptep), pfn);
2070 drop_spte(vcpu->kvm, sptep, shadow_trap_nonpresent_pte); 2078 drop_spte(vcpu->kvm, sptep, shadow_trap_nonpresent_pte);
2071 kvm_flush_remote_tlbs(vcpu->kvm); 2079 kvm_flush_remote_tlbs(vcpu->kvm);
2072 /*
2073 * If we overwrite a writable spte with a read-only one,
2074 * drop it and flush remote TLBs. Otherwise rmap_write_protect
2075 * will find a read-only spte, even though the writable spte
2076 * might be cached on a CPU's TLB.
2077 */
2078 } else if (is_writable_pte(*sptep) &&
2079 (!(pte_access & ACC_WRITE_MASK) || !dirty)) {
2080 drop_spte(vcpu->kvm, sptep, shadow_trap_nonpresent_pte);
2081 kvm_flush_remote_tlbs(vcpu->kvm);
2082 } else 2080 } else
2083 was_rmapped = 1; 2081 was_rmapped = 1;
2084 } 2082 }