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 5e3296c..c0ec066 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 dd4e288..47f8606 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 abd0e66..4245cb9 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 abced3f..3daca34 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 dddcaa8..70850cb 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 c3d44e6..ab1c477 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);
 }