KVM: x86: make several APIC virtualization callbacks optional
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 8 Feb 2022 18:08:19 +0000 (13:08 -0500)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 18 Feb 2022 17:41:23 +0000 (12:41 -0500)
All their invocations are conditional on vcpu->arch.apicv_active,
meaning that they need not be implemented by vendor code: even
though at the moment both vendors implement APIC virtualization,
all of them can be optional.  In fact SVM does not need many of
them, and their implementation can be deleted now.

Reviewed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm-x86-ops.h
arch/x86/kvm/lapic.c
arch/x86/kvm/svm/avic.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h
arch/x86/kvm/x86.c

index 5e3296c07207f75fec117cf4ca52948cfce6f261..c0ec066a85993d94cfdf693915d46d2b7d853022 100644 (file)
@@ -75,11 +75,11 @@ KVM_X86_OP(enable_irq_window)
 KVM_X86_OP_OPTIONAL(update_cr8_intercept)
 KVM_X86_OP(check_apicv_inhibit_reasons)
 KVM_X86_OP(refresh_apicv_exec_ctrl)
-KVM_X86_OP(hwapic_irr_update)
-KVM_X86_OP(hwapic_isr_update)
+KVM_X86_OP_OPTIONAL(hwapic_irr_update)
+KVM_X86_OP_OPTIONAL(hwapic_isr_update)
 KVM_X86_OP_OPTIONAL(guest_apic_has_interrupt)
-KVM_X86_OP(load_eoi_exitmap)
-KVM_X86_OP(set_virtual_apic_mode)
+KVM_X86_OP_OPTIONAL(load_eoi_exitmap)
+KVM_X86_OP_OPTIONAL(set_virtual_apic_mode)
 KVM_X86_OP_OPTIONAL(set_apic_access_page_addr)
 KVM_X86_OP(deliver_interrupt)
 KVM_X86_OP_OPTIONAL(sync_pir_to_irr)
@@ -102,7 +102,7 @@ KVM_X86_OP_OPTIONAL(vcpu_blocking)
 KVM_X86_OP_OPTIONAL(vcpu_unblocking)
 KVM_X86_OP_OPTIONAL(pi_update_irte)
 KVM_X86_OP_OPTIONAL(pi_start_assignment)
-KVM_X86_OP(apicv_post_state_restore)
+KVM_X86_OP_OPTIONAL(apicv_post_state_restore)
 KVM_X86_OP_OPTIONAL(dy_apicv_has_pending_interrupt)
 KVM_X86_OP_OPTIONAL(set_hv_timer)
 KVM_X86_OP_OPTIONAL(cancel_hv_timer)
index dd4e2888c244baf9600d5318f75883c3cfcd4790..47f8606559a9cb0918cb80572abcc9e3397940d8 100644 (file)
@@ -492,8 +492,7 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
        if (unlikely(vcpu->arch.apicv_active)) {
                /* need to update RVI */
                kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR);
-               static_call(kvm_x86_hwapic_irr_update)(vcpu,
-                               apic_find_highest_irr(apic));
+               static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, apic_find_highest_irr(apic));
        } else {
                apic->irr_pending = false;
                kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR);
@@ -523,7 +522,7 @@ static inline void apic_set_isr(int vec, struct kvm_lapic *apic)
         * just set SVI.
         */
        if (unlikely(vcpu->arch.apicv_active))
-               static_call(kvm_x86_hwapic_isr_update)(vcpu, vec);
+               static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, vec);
        else {
                ++apic->isr_count;
                BUG_ON(apic->isr_count > MAX_APIC_VECTOR);
@@ -571,8 +570,7 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
         * and must be left alone.
         */
        if (unlikely(vcpu->arch.apicv_active))
-               static_call(kvm_x86_hwapic_isr_update)(vcpu,
-                                               apic_find_highest_isr(apic));
+               static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, apic_find_highest_isr(apic));
        else {
                --apic->isr_count;
                BUG_ON(apic->isr_count < 0);
@@ -2288,7 +2286,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
                kvm_apic_set_x2apic_id(apic, vcpu->vcpu_id);
 
        if ((old_value ^ value) & (MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE))
-               static_call(kvm_x86_set_virtual_apic_mode)(vcpu);
+               static_call_cond(kvm_x86_set_virtual_apic_mode)(vcpu);
 
        apic->base_address = apic->vcpu->arch.apic_base &
                             MSR_IA32_APICBASE_BASE;
@@ -2374,9 +2372,9 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
        vcpu->arch.pv_eoi.msr_val = 0;
        apic_update_ppr(apic);
        if (vcpu->arch.apicv_active) {
-               static_call(kvm_x86_apicv_post_state_restore)(vcpu);
-               static_call(kvm_x86_hwapic_irr_update)(vcpu, -1);
-               static_call(kvm_x86_hwapic_isr_update)(vcpu, -1);
+               static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
+               static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, -1);
+               static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, -1);
        }
 
        vcpu->arch.apic_arb_prio = 0;
@@ -2639,11 +2637,9 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
        kvm_apic_update_apicv(vcpu);
        apic->highest_isr_cache = -1;
        if (vcpu->arch.apicv_active) {
-               static_call(kvm_x86_apicv_post_state_restore)(vcpu);
-               static_call(kvm_x86_hwapic_irr_update)(vcpu,
-                               apic_find_highest_irr(apic));
-               static_call(kvm_x86_hwapic_isr_update)(vcpu,
-                               apic_find_highest_isr(apic));
+               static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
+               static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, apic_find_highest_irr(apic));
+               static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, apic_find_highest_isr(apic));
        }
        kvm_make_request(KVM_REQ_EVENT, vcpu);
        if (ioapic_in_kernel(vcpu->kvm))
index abd0e664bf227b8ff32076e8d1306f75d7b49e04..4245cb99b497ff84a4ebde92e1d4068ef15762d2 100644 (file)
@@ -586,19 +586,6 @@ void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
        avic_handle_ldr_update(vcpu);
 }
 
-void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
-{
-       return;
-}
-
-void avic_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
-{
-}
-
-void avic_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
-{
-}
-
 static int avic_set_pi_irte_mode(struct kvm_vcpu *vcpu, bool activate)
 {
        int ret = 0;
@@ -663,11 +650,6 @@ void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
        avic_set_pi_irte_mode(vcpu, activated);
 }
 
-void avic_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
-{
-       return;
-}
-
 bool avic_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
 {
        return false;
index abced3fe2013ec7c72f2647b39ca1fafbd35326a..3daca34020fa0967c312e36fdfd278b61f201198 100644 (file)
@@ -4589,12 +4589,8 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
        .enable_nmi_window = svm_enable_nmi_window,
        .enable_irq_window = svm_enable_irq_window,
        .update_cr8_intercept = svm_update_cr8_intercept,
-       .set_virtual_apic_mode = avic_set_virtual_apic_mode,
        .refresh_apicv_exec_ctrl = avic_refresh_apicv_exec_ctrl,
        .check_apicv_inhibit_reasons = avic_check_apicv_inhibit_reasons,
-       .load_eoi_exitmap = avic_load_eoi_exitmap,
-       .hwapic_irr_update = avic_hwapic_irr_update,
-       .hwapic_isr_update = avic_hwapic_isr_update,
        .apicv_post_state_restore = avic_apicv_post_state_restore,
 
        .set_tss_addr = svm_set_tss_addr,
index dddcaa827c5f9ce3e39c01fa0416314661302c81..70850cbe5bcb5aa724511cd2bda69b325e7b3489 100644 (file)
@@ -582,7 +582,6 @@ void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu);
 void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
 void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu);
 bool avic_check_apicv_inhibit_reasons(ulong bit);
-void avic_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
 void avic_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr);
 void avic_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr);
 bool avic_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu);
index c3d44e6a34548f69984e59a1490df5a2e2cc2546..ab1c4778824abb2fcf7687639652ef3afa4ffa29 100644 (file)
@@ -9763,11 +9763,11 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
                bitmap_or((ulong *)eoi_exit_bitmap,
                          vcpu->arch.ioapic_handled_vectors,
                          to_hv_synic(vcpu)->vec_bitmap, 256);
-               static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
+               static_call_cond(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
                return;
        }
 
-       static_call(kvm_x86_load_eoi_exitmap)(
+       static_call_cond(kvm_x86_load_eoi_exitmap)(
                vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors);
 }