diff options
author | Avi Kivity <avi@qumranet.com> | 2007-06-07 12:18:30 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-07-16 05:05:46 -0400 |
commit | d9e368d61263055eceac2966bb7ea31b89da3425 (patch) | |
tree | 9d507b851ea7bd667cdd50dde640e47e0d4773e9 /drivers/kvm/svm.c | |
parent | 39c3b86e5c193e09f69f0e99c93600a4999ffc60 (diff) |
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>
Diffstat (limited to 'drivers/kvm/svm.c')
-rw-r--r-- | drivers/kvm/svm.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 70f386e04cbe..eb175c5cd499 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -1470,6 +1470,11 @@ static void load_db_regs(unsigned long *db_regs) | |||
1470 | asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3])); | 1470 | asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3])); |
1471 | } | 1471 | } |
1472 | 1472 | ||
1473 | static void svm_flush_tlb(struct kvm_vcpu *vcpu) | ||
1474 | { | ||
1475 | force_new_asid(vcpu); | ||
1476 | } | ||
1477 | |||
1473 | static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 1478 | static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
1474 | { | 1479 | { |
1475 | u16 fs_selector; | 1480 | u16 fs_selector; |
@@ -1487,6 +1492,11 @@ again: | |||
1487 | 1492 | ||
1488 | clgi(); | 1493 | clgi(); |
1489 | 1494 | ||
1495 | vcpu->guest_mode = 1; | ||
1496 | if (vcpu->requests) | ||
1497 | if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests)) | ||
1498 | svm_flush_tlb(vcpu); | ||
1499 | |||
1490 | pre_svm_run(vcpu); | 1500 | pre_svm_run(vcpu); |
1491 | 1501 | ||
1492 | save_host_msrs(vcpu); | 1502 | save_host_msrs(vcpu); |
@@ -1618,6 +1628,8 @@ again: | |||
1618 | #endif | 1628 | #endif |
1619 | : "cc", "memory" ); | 1629 | : "cc", "memory" ); |
1620 | 1630 | ||
1631 | vcpu->guest_mode = 0; | ||
1632 | |||
1621 | if (vcpu->fpu_active) { | 1633 | if (vcpu->fpu_active) { |
1622 | fx_save(vcpu->guest_fx_image); | 1634 | fx_save(vcpu->guest_fx_image); |
1623 | fx_restore(vcpu->host_fx_image); | 1635 | fx_restore(vcpu->host_fx_image); |
@@ -1682,11 +1694,6 @@ again: | |||
1682 | return r; | 1694 | return r; |
1683 | } | 1695 | } |
1684 | 1696 | ||
1685 | static void svm_flush_tlb(struct kvm_vcpu *vcpu) | ||
1686 | { | ||
1687 | force_new_asid(vcpu); | ||
1688 | } | ||
1689 | |||
1690 | static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) | 1697 | static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) |
1691 | { | 1698 | { |
1692 | vcpu->svm->vmcb->save.cr3 = root; | 1699 | vcpu->svm->vmcb->save.cr3 = root; |