KVM: Flush remote tlbs when reducing shadow pte permissions
When a vcpu causes a shadow tlb entry to have reduced permissions, it
must also clear the tlb on remote vcpus. We do that by:
- setting a bit on the vcpu that requests a tlb flush before the next entry
- if the vcpu is currently executing, we send an ipi to make sure it
exits before we continue
Signed-off-by: Avi Kivity <avi@qumranet.com>
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 70f386e..eb175c5 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1470,6 +1470,11 @@
asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3]));
}
+static void svm_flush_tlb(struct kvm_vcpu *vcpu)
+{
+ force_new_asid(vcpu);
+}
+
static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
u16 fs_selector;
@@ -1487,6 +1492,11 @@
clgi();
+ vcpu->guest_mode = 1;
+ if (vcpu->requests)
+ if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
+ svm_flush_tlb(vcpu);
+
pre_svm_run(vcpu);
save_host_msrs(vcpu);
@@ -1618,6 +1628,8 @@
#endif
: "cc", "memory" );
+ vcpu->guest_mode = 0;
+
if (vcpu->fpu_active) {
fx_save(vcpu->guest_fx_image);
fx_restore(vcpu->host_fx_image);
@@ -1682,11 +1694,6 @@
return r;
}
-static void svm_flush_tlb(struct kvm_vcpu *vcpu)
-{
- force_new_asid(vcpu);
-}
-
static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
{
vcpu->svm->vmcb->save.cr3 = root;