Commit 2d613912 authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini

KVM: x86: Differentiate Soft vs. Hard IRQs vs. reinjected in tracepoint

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: default avatarSean Christopherson <seanjc@google.com>
[MSS: change "kvm_inj_virq" event "reinjected" field type to bool]
Signed-off-by: default avatarMaciej S. Szmigiero <maciej.szmigiero@oracle.com>
Message-Id: <9664d49b3bd21e227caa501cff77b0569bebffe2.1651440202.git.maciej.szmigiero@oracle.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 21d4c575
...@@ -1405,7 +1405,7 @@ struct kvm_x86_ops { ...@@ -1405,7 +1405,7 @@ struct kvm_x86_ops {
u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu); u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu);
void (*patch_hypercall)(struct kvm_vcpu *vcpu, void (*patch_hypercall)(struct kvm_vcpu *vcpu,
unsigned char *hypercall_addr); 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 (*inject_nmi)(struct kvm_vcpu *vcpu);
void (*queue_exception)(struct kvm_vcpu *vcpu); void (*queue_exception)(struct kvm_vcpu *vcpu);
void (*cancel_injection)(struct kvm_vcpu *vcpu); void (*cancel_injection)(struct kvm_vcpu *vcpu);
......
...@@ -3435,7 +3435,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) ...@@ -3435,7 +3435,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu)
++vcpu->stat.nmi_injections; ++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); struct vcpu_svm *svm = to_svm(vcpu);
u32 type; u32 type;
...@@ -3449,7 +3449,8 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu) ...@@ -3449,7 +3449,8 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu)
type = SVM_EVTINJ_TYPE_INTR; 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; ++vcpu->stat.irq_injections;
svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr | svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr |
......
...@@ -333,18 +333,24 @@ TRACE_EVENT_KVM_EXIT(kvm_exit); ...@@ -333,18 +333,24 @@ TRACE_EVENT_KVM_EXIT(kvm_exit);
* Tracepoint for kvm interrupt injection: * Tracepoint for kvm interrupt injection:
*/ */
TRACE_EVENT(kvm_inj_virq, TRACE_EVENT(kvm_inj_virq,
TP_PROTO(unsigned int irq), TP_PROTO(unsigned int vector, bool soft, bool reinjected),
TP_ARGS(irq), TP_ARGS(vector, soft, reinjected),
TP_STRUCT__entry( TP_STRUCT__entry(
__field( unsigned int, irq ) __field( unsigned int, vector )
__field( bool, soft )
__field( bool, reinjected )
), ),
TP_fast_assign( 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 } #define EXS(x) { x##_VECTOR, "#" #x }
......
...@@ -4573,13 +4573,13 @@ static void vmx_enable_nmi_window(struct kvm_vcpu *vcpu) ...@@ -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); 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); struct vcpu_vmx *vmx = to_vmx(vcpu);
uint32_t intr; uint32_t intr;
int irq = vcpu->arch.interrupt.nr; 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; ++vcpu->stat.irq_injections;
if (vmx->rmode.vm86_active) { if (vmx->rmode.vm86_active) {
......
...@@ -9448,7 +9448,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit) ...@@ -9448,7 +9448,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
static_call(kvm_x86_inject_nmi)(vcpu); static_call(kvm_x86_inject_nmi)(vcpu);
can_inject = false; can_inject = false;
} else if (vcpu->arch.interrupt.injected) { } else if (vcpu->arch.interrupt.injected) {
static_call(kvm_x86_inject_irq)(vcpu); static_call(kvm_x86_inject_irq)(vcpu, true);
can_inject = false; can_inject = false;
} }
} }
...@@ -9539,7 +9539,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit) ...@@ -9539,7 +9539,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
goto out; goto out;
if (r) { if (r) {
kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false); 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); WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0);
} }
if (kvm_cpu_has_injectable_intr(vcpu)) if (kvm_cpu_has_injectable_intr(vcpu))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment