]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: x86: Differentiate Soft vs. Hard IRQs vs. reinjected in tracepoint
authorSean Christopherson <seanjc@google.com>
Sun, 1 May 2022 22:07:33 +0000 (00:07 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 8 Jun 2022 08:47:01 +0000 (04:47 -0400)
In the IRQ injection tracepoint, differentiate between Hard IRQs and Soft
"IRQs", i.e. interrupts that are reinjected after incomplete delivery of
a software interrupt from an INTn instruction.  Tag reinjected interrupts
as such, even though the information is usually redundant since soft
interrupts are only ever reinjected by KVM.  Though rare in practice, a
hard IRQ can be reinjected.

Signed-off-by: Sean Christopherson <seanjc@google.com>
[MSS: change "kvm_inj_virq" event "reinjected" field type to bool]
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
Message-Id: <9664d49b3bd21e227caa501cff77b0569bebffe2.1651440202.git.maciej.szmigiero@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/svm/svm.c
arch/x86/kvm/trace.h
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c

index 959d66b9be94d0230445faa642fc41e380bf5552..8109805b5429c0785ea77b6796d82d017dc03aae 100644 (file)
@@ -1405,7 +1405,7 @@ struct kvm_x86_ops {
        u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu);
        void (*patch_hypercall)(struct kvm_vcpu *vcpu,
                                unsigned char *hypercall_addr);
-       void (*inject_irq)(struct kvm_vcpu *vcpu);
+       void (*inject_irq)(struct kvm_vcpu *vcpu, bool reinjected);
        void (*inject_nmi)(struct kvm_vcpu *vcpu);
        void (*queue_exception)(struct kvm_vcpu *vcpu);
        void (*cancel_injection)(struct kvm_vcpu *vcpu);
index 6248967d4a77cec2ccaf4cc90cc281382800e19e..0f4d38e5ceab94946646f9e5c035d43a43a1b707 100644 (file)
@@ -3435,7 +3435,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu)
        ++vcpu->stat.nmi_injections;
 }
 
-static void svm_inject_irq(struct kvm_vcpu *vcpu)
+static void svm_inject_irq(struct kvm_vcpu *vcpu, bool reinjected)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
        u32 type;
@@ -3449,7 +3449,8 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu)
                type = SVM_EVTINJ_TYPE_INTR;
        }
 
-       trace_kvm_inj_virq(vcpu->arch.interrupt.nr);
+       trace_kvm_inj_virq(vcpu->arch.interrupt.nr,
+                          vcpu->arch.interrupt.soft, reinjected);
        ++vcpu->stat.irq_injections;
 
        svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr |
index 385436d120246fdf3b65d5653db551601e38b2ec..fd28dd40b81320300e122f2aa61ca60b6f55f58b 100644 (file)
@@ -333,18 +333,24 @@ TRACE_EVENT_KVM_EXIT(kvm_exit);
  * Tracepoint for kvm interrupt injection:
  */
 TRACE_EVENT(kvm_inj_virq,
-       TP_PROTO(unsigned int irq),
-       TP_ARGS(irq),
+       TP_PROTO(unsigned int vector, bool soft, bool reinjected),
+       TP_ARGS(vector, soft, reinjected),
 
        TP_STRUCT__entry(
-               __field(        unsigned int,   irq             )
+               __field(        unsigned int,   vector          )
+               __field(        bool,           soft            )
+               __field(        bool,           reinjected      )
        ),
 
        TP_fast_assign(
-               __entry->irq            = irq;
+               __entry->vector         = vector;
+               __entry->soft           = soft;
+               __entry->reinjected     = reinjected;
        ),
 
-       TP_printk("irq %u", __entry->irq)
+       TP_printk("%s 0x%x%s",
+                 __entry->soft ? "Soft/INTn" : "IRQ", __entry->vector,
+                 __entry->reinjected ? " [reinjected]" : "")
 );
 
 #define EXS(x) { x##_VECTOR, "#" #x }
index e1aa14743cdb6b08f2cc46d942608cb56b15bb12..9714ae95589f59114b489a45d745998a7d5a4ad6 100644 (file)
@@ -4573,13 +4573,13 @@ static void vmx_enable_nmi_window(struct kvm_vcpu *vcpu)
        exec_controls_setbit(to_vmx(vcpu), CPU_BASED_NMI_WINDOW_EXITING);
 }
 
-static void vmx_inject_irq(struct kvm_vcpu *vcpu)
+static void vmx_inject_irq(struct kvm_vcpu *vcpu, bool reinjected)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
        uint32_t intr;
        int irq = vcpu->arch.interrupt.nr;
 
-       trace_kvm_inj_virq(irq);
+       trace_kvm_inj_virq(irq, vcpu->arch.interrupt.soft, reinjected);
 
        ++vcpu->stat.irq_injections;
        if (vmx->rmode.vm86_active) {
index c9f3ad89bf4c901c2c36e64a7c9b21176e16aa57..501606e026888a00e3c48a503c5e9a1ea9483097 100644 (file)
@@ -9448,7 +9448,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
                        static_call(kvm_x86_inject_nmi)(vcpu);
                        can_inject = false;
                } else if (vcpu->arch.interrupt.injected) {
-                       static_call(kvm_x86_inject_irq)(vcpu);
+                       static_call(kvm_x86_inject_irq)(vcpu, true);
                        can_inject = false;
                }
        }
@@ -9539,7 +9539,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
                        goto out;
                if (r) {
                        kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false);
-                       static_call(kvm_x86_inject_irq)(vcpu);
+                       static_call(kvm_x86_inject_irq)(vcpu, false);
                        WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0);
                }
                if (kvm_cpu_has_injectable_intr(vcpu))