summaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/hyperv.c
diff options
context:
space:
mode:
authorVitaly Kuznetsov <vkuznets@redhat.com>2022-11-01 15:53:55 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2022-11-18 12:59:10 -0500
commit53ca765a041d5a24650d3f01bced791be5d72df7 (patch)
tree32275d47843885562cf06fd7f99e46b2622d5b1a /arch/x86/kvm/hyperv.c
parentb6c2c22fa7012616b3039c9f559bf01195137b9d (diff)
downloadlinux-53ca765a041d5a24650d3f01bced791be5d72df7.tar.bz2
KVM: x86: hyper-v: Create a separate fifo for L2 TLB flush
To handle L2 TLB flush requests, KVM needs to use a separate fifo from regular (L1) Hyper-V TLB flush requests: e.g. when a request to flush something in L2 is made, the target vCPU can transition from L2 to L1, receive a request to flush a GVA for L1 and then try to enter L2 back. The first request needs to be processed at this point. Similarly, requests to flush GVAs in L1 must wait until L2 exits to L1. No functional change as KVM doesn't handle L2 TLB flush requests from L2 yet. Reviewed-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20221101145426.251680-18-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/hyperv.c')
-rw-r--r--arch/x86/kvm/hyperv.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 0bfa59838e0a..989846310303 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -956,8 +956,10 @@ int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu)
hv_vcpu->vp_index = vcpu->vcpu_idx;
- INIT_KFIFO(hv_vcpu->tlb_flush_fifo.entries);
- spin_lock_init(&hv_vcpu->tlb_flush_fifo.write_lock);
+ for (i = 0; i < HV_NR_TLB_FLUSH_FIFOS; i++) {
+ INIT_KFIFO(hv_vcpu->tlb_flush_fifo[i].entries);
+ spin_lock_init(&hv_vcpu->tlb_flush_fifo[i].write_lock);
+ }
return 0;
}
@@ -1839,7 +1841,8 @@ static void hv_tlb_flush_enqueue(struct kvm_vcpu *vcpu, u64 *entries, int count)
if (!hv_vcpu)
return;
- tlb_flush_fifo = &hv_vcpu->tlb_flush_fifo;
+ /* kvm_hv_flush_tlb() is not ready to handle requests for L2s yet */
+ tlb_flush_fifo = &hv_vcpu->tlb_flush_fifo[HV_L1_TLB_FLUSH_FIFO];
spin_lock(&tlb_flush_fifo->write_lock);
@@ -1874,7 +1877,7 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu)
if (!tdp_enabled || !hv_vcpu)
return -EINVAL;
- tlb_flush_fifo = &hv_vcpu->tlb_flush_fifo;
+ tlb_flush_fifo = kvm_hv_get_tlb_flush_fifo(vcpu, is_guest_mode(vcpu));
count = kfifo_out(&tlb_flush_fifo->entries, entries, KVM_HV_TLB_FLUSH_FIFO_SIZE);