summaryrefslogtreecommitdiff
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorJunaid Shahid <junaids@google.com>2018-06-27 14:59:20 -0700
committerPaolo Bonzini <pbonzini@redhat.com>2018-08-06 17:59:02 +0200
commitb94742c958f0b97d304d4aecb4603a20ee9a2df3 (patch)
tree98dd56c5f03449587af3c9f34d75e560a78662e1 /arch/x86/kvm/vmx.c
parentfaff87588d8bfd9e56e9203412f0bb80455da7b9 (diff)
kvm: x86: Add multi-entry LRU cache for previous CR3s
Adds support for storing multiple previous CR3/root_hpa pairs maintained as an LRU cache, so that the lockless CR3 switch path can be used when switching back to any of them. Signed-off-by: Junaid Shahid <junaids@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 5aea5af02386..97e4d71431a1 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -8788,6 +8788,8 @@ static int handle_invpcid(struct kvm_vcpu *vcpu)
bool pcid_enabled;
gva_t gva;
struct x86_exception e;
+ unsigned i;
+ unsigned long roots_to_free = 0;
struct {
u64 pcid;
u64 gla;
@@ -8846,12 +8848,14 @@ static int handle_invpcid(struct kvm_vcpu *vcpu)
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
}
- if (kvm_get_pcid(vcpu, vcpu->arch.mmu.prev_root.cr3)
- == operand.pcid)
- kvm_mmu_free_roots(vcpu, KVM_MMU_ROOT_PREVIOUS);
+ for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++)
+ if (kvm_get_pcid(vcpu, vcpu->arch.mmu.prev_roots[i].cr3)
+ == operand.pcid)
+ roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);
+ kvm_mmu_free_roots(vcpu, roots_to_free);
/*
- * If neither the current cr3 nor the prev_root.cr3 use the
+ * If neither the current cr3 nor any of the prev_roots use the
* given PCID, then nothing needs to be done here because a
* resync will happen anyway before switching to any other CR3.
*/