Skip to content

Commit 380e005

Browse files
Sean Christophersonbonzini
authored andcommitted
KVM: nVMX: trace nested VM-Enter failures detected by H/W
Use the recently added tracepoint for logging nested VM-Enter failures instead of spamming the kernel log when hardware detects a consistency check failure. Take the opportunity to print the name of the error code instead of dumping the raw hex number, but limit the symbol table to error codes that can reasonably be encountered by KVM. Add an equivalent tracepoint in nested_vmx_check_vmentry_hw(), e.g. so that tracing of "invalid control field" errors isn't suppressed when nested early checks are enabled. Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 5497b95 commit 380e005

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

arch/x86/include/asm/vmx.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,20 @@ enum vm_instruction_error_number {
562562
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID = 28,
563563
};
564564

565+
/*
566+
* VM-instruction errors that can be encountered on VM-Enter, used to trace
567+
* nested VM-Enter failures reported by hardware. Errors unique to VM-Enter
568+
* from a SMI Transfer Monitor are not included as things have gone seriously
569+
* sideways if we get one of those...
570+
*/
571+
#define VMX_VMENTER_INSTRUCTION_ERRORS \
572+
{ VMXERR_VMLAUNCH_NONCLEAR_VMCS, "VMLAUNCH_NONCLEAR_VMCS" }, \
573+
{ VMXERR_VMRESUME_NONLAUNCHED_VMCS, "VMRESUME_NONLAUNCHED_VMCS" }, \
574+
{ VMXERR_VMRESUME_AFTER_VMXOFF, "VMRESUME_AFTER_VMXOFF" }, \
575+
{ VMXERR_ENTRY_INVALID_CONTROL_FIELD, "VMENTRY_INVALID_CONTROL_FIELD" }, \
576+
{ VMXERR_ENTRY_INVALID_HOST_STATE_FIELD, "VMENTRY_INVALID_HOST_STATE_FIELD" }, \
577+
{ VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS, "VMENTRY_EVENTS_BLOCKED_BY_MOV_SS" }
578+
565579
enum vmx_l1d_flush_state {
566580
VMENTER_L1D_FLUSH_AUTO,
567581
VMENTER_L1D_FLUSH_NEVER,

arch/x86/kvm/trace.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,18 +1479,21 @@ TRACE_EVENT(kvm_pv_tlb_flush,
14791479
* Tracepoint for failed nested VMX VM-Enter.
14801480
*/
14811481
TRACE_EVENT(kvm_nested_vmenter_failed,
1482-
TP_PROTO(const char *msg),
1483-
TP_ARGS(msg),
1482+
TP_PROTO(const char *msg, u32 err),
1483+
TP_ARGS(msg, err),
14841484

14851485
TP_STRUCT__entry(
14861486
__field(const char *, msg)
1487+
__field(u32, err)
14871488
),
14881489

14891490
TP_fast_assign(
14901491
__entry->msg = msg;
1492+
__entry->err = err;
14911493
),
14921494

1493-
TP_printk("%s", __entry->msg)
1495+
TP_printk("%s%s", __entry->msg, !__entry->err ? "" :
1496+
__print_symbolic(__entry->err, VMX_VMENTER_INSTRUCTION_ERRORS))
14941497
);
14951498

14961499
#endif /* _TRACE_KVM_H */

arch/x86/kvm/vmx/nested.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module_param(nested_early_check, bool, S_IRUGO);
2323
({ \
2424
bool failed = (consistency_check); \
2525
if (failed) \
26-
trace_kvm_nested_vmenter_failed(#consistency_check); \
26+
trace_kvm_nested_vmenter_failed(#consistency_check, 0); \
2727
failed; \
2828
})
2929

@@ -2845,9 +2845,13 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
28452845
vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, vmx->msr_autoload.guest.nr);
28462846

28472847
if (vm_fail) {
2848+
u32 error = vmcs_read32(VM_INSTRUCTION_ERROR);
2849+
28482850
preempt_enable();
2849-
WARN_ON_ONCE(vmcs_read32(VM_INSTRUCTION_ERROR) !=
2850-
VMXERR_ENTRY_INVALID_CONTROL_FIELD);
2851+
2852+
trace_kvm_nested_vmenter_failed(
2853+
"early hardware check VM-instruction error: ", error);
2854+
WARN_ON_ONCE(error != VMXERR_ENTRY_INVALID_CONTROL_FIELD);
28512855
return 1;
28522856
}
28532857

@@ -5259,8 +5263,9 @@ bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason)
52595263
return false;
52605264

52615265
if (unlikely(vmx->fail)) {
5262-
pr_info_ratelimited("%s failed vm entry %x\n", __func__,
5263-
vmcs_read32(VM_INSTRUCTION_ERROR));
5266+
trace_kvm_nested_vmenter_failed(
5267+
"hardware VM-instruction error: ",
5268+
vmcs_read32(VM_INSTRUCTION_ERROR));
52645269
return true;
52655270
}
52665271

0 commit comments

Comments
 (0)