* [PATCH v3 1/4] KVM: x86: refactor req_immediate_exit logic
2023-09-28 10:36 [PATCH v3 0/4] KVM: x86: tracepoint updates Maxim Levitsky
@ 2023-09-28 10:36 ` Maxim Levitsky
2023-11-24 16:07 ` Paolo Bonzini
2023-09-28 10:36 ` [PATCH v3 2/4] KVM: x86: add more information to the kvm_entry tracepoint Maxim Levitsky
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Maxim Levitsky @ 2023-09-28 10:36 UTC (permalink / raw)
To: kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Paolo Bonzini, Borislav Petkov, linux-kernel, x86, Dave Hansen,
Maxim Levitsky
- move req_immediate_exit variable from arch specific to common code.
- remove arch specific callback .request_immediate_exit and move the code
down to the arch's vcpu_run's code.
No functional change is intended.
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
arch/x86/include/asm/kvm-x86-ops.h | 1 -
arch/x86/include/asm/kvm_host.h | 5 ++---
arch/x86/kvm/svm/svm.c | 5 +++--
arch/x86/kvm/vmx/vmx.c | 18 ++++++-----------
arch/x86/kvm/vmx/vmx.h | 2 --
arch/x86/kvm/x86.c | 31 +++++++++++++-----------------
6 files changed, 24 insertions(+), 38 deletions(-)
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index e3054e3e46d52d..f654a7f4cc8c0c 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -101,7 +101,6 @@ KVM_X86_OP(write_tsc_multiplier)
KVM_X86_OP(get_exit_info)
KVM_X86_OP(check_intercept)
KVM_X86_OP(handle_exit_irqoff)
-KVM_X86_OP(request_immediate_exit)
KVM_X86_OP(sched_in)
KVM_X86_OP_OPTIONAL(update_cpu_dirty_logging)
KVM_X86_OP_OPTIONAL(vcpu_blocking)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 17715cb8731d5d..383a1d0cc0743b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1011,6 +1011,8 @@ struct kvm_vcpu_arch {
*/
bool pdptrs_from_userspace;
+ bool req_immediate_exit;
+
#if IS_ENABLED(CONFIG_HYPERV)
hpa_t hv_root_tdp;
#endif
@@ -1690,8 +1692,6 @@ struct kvm_x86_ops {
struct x86_exception *exception);
void (*handle_exit_irqoff)(struct kvm_vcpu *vcpu);
- void (*request_immediate_exit)(struct kvm_vcpu *vcpu);
-
void (*sched_in)(struct kvm_vcpu *kvm, int cpu);
/*
@@ -2176,7 +2176,6 @@ extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn);
int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu);
int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
-void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu);
void __user *__x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
u32 size);
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 9507df93f410a6..60b130b7f9d510 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4176,6 +4176,9 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
clgi();
kvm_load_guest_xsave_state(vcpu);
+ if (vcpu->arch.req_immediate_exit)
+ smp_send_reschedule(vcpu->cpu);
+
kvm_wait_lapic_expire(vcpu);
/*
@@ -5004,8 +5007,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.check_intercept = svm_check_intercept,
.handle_exit_irqoff = svm_handle_exit_irqoff,
- .request_immediate_exit = __kvm_request_immediate_exit,
-
.sched_in = svm_sched_in,
.nested_ops = &svm_nested_ops,
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 72e3943f36935c..eb7e42235e8811 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -67,6 +67,8 @@
#include "x86.h"
#include "smm.h"
+#include <trace/events/ipi.h>
+
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
@@ -1288,8 +1290,6 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
u16 fs_sel, gs_sel;
int i;
- vmx->req_immediate_exit = false;
-
/*
* Note that guest MSRs to be saved/restored can also be changed
* when guest state is loaded. This happens when guest transitions
@@ -5996,7 +5996,7 @@ static fastpath_t handle_fastpath_preemption_timer(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- if (!vmx->req_immediate_exit &&
+ if (!vcpu->arch.req_immediate_exit &&
!unlikely(vmx->loaded_vmcs->hv_timer_soft_disabled)) {
kvm_lapic_expired_hv_timer(vcpu);
return EXIT_FASTPATH_REENTER_GUEST;
@@ -7154,7 +7154,7 @@ static void vmx_update_hv_timer(struct kvm_vcpu *vcpu)
u64 tscl;
u32 delta_tsc;
- if (vmx->req_immediate_exit) {
+ if (vcpu->arch.req_immediate_exit) {
vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, 0);
vmx->loaded_vmcs->hv_timer_soft_disabled = false;
} else if (vmx->hv_deadline_tsc != -1) {
@@ -7357,6 +7357,8 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
if (enable_preemption_timer)
vmx_update_hv_timer(vcpu);
+ else if (vcpu->arch.req_immediate_exit)
+ smp_send_reschedule(vcpu->cpu);
kvm_wait_lapic_expire(vcpu);
@@ -7902,11 +7904,6 @@ static __init void vmx_set_cpu_caps(void)
kvm_cpu_cap_check_and_set(X86_FEATURE_WAITPKG);
}
-static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu)
-{
- to_vmx(vcpu)->req_immediate_exit = true;
-}
-
static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info)
{
@@ -8315,8 +8312,6 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.check_intercept = vmx_check_intercept,
.handle_exit_irqoff = vmx_handle_exit_irqoff,
- .request_immediate_exit = vmx_request_immediate_exit,
-
.sched_in = vmx_sched_in,
.cpu_dirty_log_size = PML_ENTITY_NUM,
@@ -8574,7 +8569,6 @@ static __init int hardware_setup(void)
if (!enable_preemption_timer) {
vmx_x86_ops.set_hv_timer = NULL;
vmx_x86_ops.cancel_hv_timer = NULL;
- vmx_x86_ops.request_immediate_exit = __kvm_request_immediate_exit;
}
kvm_caps.supported_mce_cap |= MCG_LMCE_P;
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index c2130d2c8e24bb..4dabd16a3d7180 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -330,8 +330,6 @@ struct vcpu_vmx {
unsigned int ple_window;
bool ple_window_dirty;
- bool req_immediate_exit;
-
/* Support for PML */
#define PML_ENTITY_NUM 512
struct page *pml_pg;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9f18b06bbda66b..dfb7d25ed94f26 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10049,8 +10049,7 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu)
* ordering between that side effect, the instruction completing, _and_ the
* delivery of the asynchronous event.
*/
-static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
- bool *req_immediate_exit)
+static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu)
{
bool can_inject;
int r;
@@ -10227,8 +10226,9 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
if (is_guest_mode(vcpu) &&
kvm_x86_ops.nested_ops->has_events &&
- kvm_x86_ops.nested_ops->has_events(vcpu))
- *req_immediate_exit = true;
+ kvm_x86_ops.nested_ops->has_events(vcpu)) {
+ vcpu->arch.req_immediate_exit = true;
+ }
/*
* KVM must never queue a new exception while injecting an event; KVM
@@ -10245,10 +10245,9 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu,
WARN_ON_ONCE(vcpu->arch.exception.pending ||
vcpu->arch.exception_vmexit.pending);
return 0;
-
out:
if (r == -EBUSY) {
- *req_immediate_exit = true;
+ vcpu->arch.req_immediate_exit = true;
r = 0;
}
return r;
@@ -10475,12 +10474,6 @@ static void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
static_call_cond(kvm_x86_set_apic_access_page_addr)(vcpu);
}
-void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
-{
- smp_send_reschedule(vcpu->cpu);
-}
-EXPORT_SYMBOL_GPL(__kvm_request_immediate_exit);
-
/*
* Called within kvm->srcu read side.
* Returns 1 to let vcpu_run() continue the guest execution loop without
@@ -10495,7 +10488,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_cpu_accept_dm_intr(vcpu);
fastpath_t exit_fastpath;
- bool req_immediate_exit = false;
if (kvm_request_pending(vcpu)) {
if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu)) {
@@ -10657,7 +10649,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
goto out;
}
- r = kvm_check_and_inject_events(vcpu, &req_immediate_exit);
+ r = kvm_check_and_inject_events(vcpu);
if (r < 0) {
r = 0;
goto out;
@@ -10726,10 +10718,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
goto cancel_injection;
}
- if (req_immediate_exit) {
+
+ if (vcpu->arch.req_immediate_exit)
kvm_make_request(KVM_REQ_EVENT, vcpu);
- static_call(kvm_x86_request_immediate_exit)(vcpu);
- }
fpregs_assert_state_consistent();
if (test_thread_flag(TIF_NEED_FPU_LOAD))
@@ -10761,6 +10752,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
(kvm_get_apic_mode(vcpu) != LAPIC_MODE_DISABLED));
exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu);
+
if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST))
break;
@@ -10776,6 +10768,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
++vcpu->stat.exits;
}
+ vcpu->arch.req_immediate_exit = false;
/*
* Do this here before restoring debug registers on the host. And
* since we do this before handling the vmexit, a DR access vmexit
@@ -10863,8 +10856,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
return r;
cancel_injection:
- if (req_immediate_exit)
+ if (vcpu->arch.req_immediate_exit) {
+ vcpu->arch.req_immediate_exit = false;
kvm_make_request(KVM_REQ_EVENT, vcpu);
+ }
static_call(kvm_x86_cancel_injection)(vcpu);
if (unlikely(vcpu->arch.apic_attention))
kvm_lapic_sync_from_vapic(vcpu);
--
2.26.3
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v3 1/4] KVM: x86: refactor req_immediate_exit logic
2023-09-28 10:36 ` [PATCH v3 1/4] KVM: x86: refactor req_immediate_exit logic Maxim Levitsky
@ 2023-11-24 16:07 ` Paolo Bonzini
2023-11-28 6:41 ` Maxim Levitsky
0 siblings, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2023-11-24 16:07 UTC (permalink / raw)
To: Maxim Levitsky, kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Borislav Petkov, linux-kernel, x86, Dave Hansen
On 9/28/23 12:36, Maxim Levitsky wrote:
> @@ -4176,6 +4176,9 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
> clgi();
> kvm_load_guest_xsave_state(vcpu);
>
> + if (vcpu->arch.req_immediate_exit)
> + smp_send_reschedule(vcpu->cpu);
> +
This code is in a non-standard situation where IF=1 but interrupts are
effectively disabled. Better something like:
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index beea99c8e8e0..3b945de2d880 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4148,8 +4148,11 @@ static __no_kcsan fastpath_t svm_vcpu_run(
* is enough to force an immediate vmexit.
*/
disable_nmi_singlestep(svm);
+ vcpu->arch.req_immediate_exit = true;
+ }
+
+ if (vcpu->arch.req_immediate_exit)
smp_send_reschedule(vcpu->cpu);
- }
pre_svm_run(vcpu);
Paolo
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/4] KVM: x86: refactor req_immediate_exit logic
2023-11-24 16:07 ` Paolo Bonzini
@ 2023-11-28 6:41 ` Maxim Levitsky
0 siblings, 0 replies; 12+ messages in thread
From: Maxim Levitsky @ 2023-11-28 6:41 UTC (permalink / raw)
To: Paolo Bonzini, kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Borislav Petkov, linux-kernel, x86, Dave Hansen
On Fri, 2023-11-24 at 17:07 +0100, Paolo Bonzini wrote:
> On 9/28/23 12:36, Maxim Levitsky wrote:
> > @@ -4176,6 +4176,9 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
> > clgi();
> > kvm_load_guest_xsave_state(vcpu);
> >
> > + if (vcpu->arch.req_immediate_exit)
> > + smp_send_reschedule(vcpu->cpu);
> > +
>
> This code is in a non-standard situation where IF=1 but interrupts are
> effectively disabled. Better something like:
>
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index beea99c8e8e0..3b945de2d880 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -4148,8 +4148,11 @@ static __no_kcsan fastpath_t svm_vcpu_run(
> * is enough to force an immediate vmexit.
> */
> disable_nmi_singlestep(svm);
> + vcpu->arch.req_immediate_exit = true;
> + }
> +
> + if (vcpu->arch.req_immediate_exit)
> smp_send_reschedule(vcpu->cpu);
> - }
>
> pre_svm_run(vcpu);
>
>
> Paolo
>
Actually IF=0 at that point. We disable IF before we call svm_vcpu_run, at
vcpu_enter_guest().
Then we disable GIF, and we re-enable IF only right before VMRUN, in fact vmrun is
in the interrupt shadow although that doesn't really matter since GIF=0.
However I don't mind implementing the change you suggested, I don't think it will
affect anything.
Best regards,
Maxim Levitsky
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 2/4] KVM: x86: add more information to the kvm_entry tracepoint
2023-09-28 10:36 [PATCH v3 0/4] KVM: x86: tracepoint updates Maxim Levitsky
2023-09-28 10:36 ` [PATCH v3 1/4] KVM: x86: refactor req_immediate_exit logic Maxim Levitsky
@ 2023-09-28 10:36 ` Maxim Levitsky
2023-11-24 16:08 ` Paolo Bonzini
2023-09-28 10:36 ` [PATCH v3 3/4] KVM: x86: add information about pending requests to kvm_exit tracepoint Maxim Levitsky
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Maxim Levitsky @ 2023-09-28 10:36 UTC (permalink / raw)
To: kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Paolo Bonzini, Borislav Petkov, linux-kernel, x86, Dave Hansen,
Maxim Levitsky
Add VMX/SVM specific interrupt injection info to vm entry tracepoint.
Also add a flag showing that immediate vm exit is set to happen after
the entry.
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
arch/x86/include/asm/kvm-x86-ops.h | 1 +
arch/x86/include/asm/kvm_host.h | 5 ++++-
arch/x86/kvm/svm/svm.c | 17 +++++++++++++++++
arch/x86/kvm/trace.h | 15 +++++++++++++--
arch/x86/kvm/vmx/vmx.c | 12 ++++++++++++
5 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index f654a7f4cc8c0c..346fed6e3c33aa 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -99,6 +99,7 @@ KVM_X86_OP(get_l2_tsc_multiplier)
KVM_X86_OP(write_tsc_offset)
KVM_X86_OP(write_tsc_multiplier)
KVM_X86_OP(get_exit_info)
+KVM_X86_OP(get_entry_info)
KVM_X86_OP(check_intercept)
KVM_X86_OP(handle_exit_irqoff)
KVM_X86_OP(sched_in)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 383a1d0cc0743b..321721813474f7 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1679,13 +1679,16 @@ struct kvm_x86_ops {
void (*write_tsc_multiplier)(struct kvm_vcpu *vcpu);
/*
- * Retrieve somewhat arbitrary exit information. Intended to
+ * Retrieve somewhat arbitrary exit/entry information. Intended to
* be used only from within tracepoints or error paths.
*/
void (*get_exit_info)(struct kvm_vcpu *vcpu, u32 *reason,
u64 *info1, u64 *info2,
u32 *exit_int_info, u32 *exit_int_info_err_code);
+ void (*get_entry_info)(struct kvm_vcpu *vcpu,
+ u32 *inj_info, u32 *inj_info_error_code);
+
int (*check_intercept)(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info,
enum x86_intercept_stage stage,
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 60b130b7f9d510..cd65c04be3d0e2 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3504,6 +3504,22 @@ static void svm_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
*error_code = 0;
}
+static void svm_get_entry_info(struct kvm_vcpu *vcpu,
+ u32 *inj_info,
+ u32 *inj_info_error_code)
+{
+ struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control;
+
+ *inj_info = control->event_inj;
+
+ if ((*inj_info & SVM_EXITINTINFO_VALID) &&
+ (*inj_info & SVM_EXITINTINFO_VALID_ERR))
+ *inj_info_error_code = control->event_inj_err;
+ else
+ *inj_info_error_code = 0;
+
+}
+
static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -4992,6 +5008,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.required_apicv_inhibits = AVIC_REQUIRED_APICV_INHIBITS,
.get_exit_info = svm_get_exit_info,
+ .get_entry_info = svm_get_entry_info,
.vcpu_after_set_cpuid = svm_vcpu_after_set_cpuid,
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 83843379813ee3..28e8a63368cc02 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -21,14 +21,25 @@ TRACE_EVENT(kvm_entry,
TP_STRUCT__entry(
__field( unsigned int, vcpu_id )
__field( unsigned long, rip )
- ),
+ __field( u32, inj_info )
+ __field( u32, inj_info_err )
+ __field( bool, req_imm_exit )
+ ),
TP_fast_assign(
__entry->vcpu_id = vcpu->vcpu_id;
__entry->rip = kvm_rip_read(vcpu);
+ __entry->req_imm_exit = vcpu->arch.req_immediate_exit;
+
+ static_call(kvm_x86_get_entry_info)(vcpu,
+ &__entry->inj_info,
+ &__entry->inj_info_err);
),
- TP_printk("vcpu %u, rip 0x%lx", __entry->vcpu_id, __entry->rip)
+ TP_printk("vcpu %u, rip 0x%lx inj 0x%08x inj_error_code 0x%08x%s",
+ __entry->vcpu_id, __entry->rip,
+ __entry->inj_info, __entry->inj_info_err,
+ __entry->req_imm_exit ? " [req_imm_exit]" : "")
);
/*
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index eb7e42235e8811..9dd13f52d4999c 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6156,6 +6156,17 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
}
}
+static void vmx_get_entry_info(struct kvm_vcpu *vcpu,
+ u32 *inj_info,
+ u32 *inj_info_error_code)
+{
+ *inj_info = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
+ if (is_exception_with_error_code(*inj_info))
+ *inj_info_error_code = vmcs_read32(VM_ENTRY_EXCEPTION_ERROR_CODE);
+ else
+ *inj_info_error_code = 0;
+}
+
static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx)
{
if (vmx->pml_pg) {
@@ -8297,6 +8308,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.get_mt_mask = vmx_get_mt_mask,
.get_exit_info = vmx_get_exit_info,
+ .get_entry_info = vmx_get_entry_info,
.vcpu_after_set_cpuid = vmx_vcpu_after_set_cpuid,
--
2.26.3
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v3 2/4] KVM: x86: add more information to the kvm_entry tracepoint
2023-09-28 10:36 ` [PATCH v3 2/4] KVM: x86: add more information to the kvm_entry tracepoint Maxim Levitsky
@ 2023-11-24 16:08 ` Paolo Bonzini
0 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2023-11-24 16:08 UTC (permalink / raw)
To: Maxim Levitsky, kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Borislav Petkov, linux-kernel, x86, Dave Hansen
On 9/28/23 12:36, Maxim Levitsky wrote:
> Add VMX/SVM specific interrupt injection info to vm entry tracepoint.
> Also add a flag showing that immediate vm exit is set to happen after
> the entry.
>
> Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
> ---
> arch/x86/include/asm/kvm-x86-ops.h | 1 +
> arch/x86/include/asm/kvm_host.h | 5 ++++-
> arch/x86/kvm/svm/svm.c | 17 +++++++++++++++++
> arch/x86/kvm/trace.h | 15 +++++++++++++--
> arch/x86/kvm/vmx/vmx.c | 12 ++++++++++++
> 5 files changed, 47 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
> index f654a7f4cc8c0c..346fed6e3c33aa 100644
> --- a/arch/x86/include/asm/kvm-x86-ops.h
> +++ b/arch/x86/include/asm/kvm-x86-ops.h
> @@ -99,6 +99,7 @@ KVM_X86_OP(get_l2_tsc_multiplier)
> KVM_X86_OP(write_tsc_offset)
> KVM_X86_OP(write_tsc_multiplier)
> KVM_X86_OP(get_exit_info)
> +KVM_X86_OP(get_entry_info)
> KVM_X86_OP(check_intercept)
> KVM_X86_OP(handle_exit_irqoff)
> KVM_X86_OP(sched_in)
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 383a1d0cc0743b..321721813474f7 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1679,13 +1679,16 @@ struct kvm_x86_ops {
> void (*write_tsc_multiplier)(struct kvm_vcpu *vcpu);
>
> /*
> - * Retrieve somewhat arbitrary exit information. Intended to
> + * Retrieve somewhat arbitrary exit/entry information. Intended to
> * be used only from within tracepoints or error paths.
> */
> void (*get_exit_info)(struct kvm_vcpu *vcpu, u32 *reason,
> u64 *info1, u64 *info2,
> u32 *exit_int_info, u32 *exit_int_info_err_code);
>
> + void (*get_entry_info)(struct kvm_vcpu *vcpu,
> + u32 *inj_info, u32 *inj_info_error_code);
> +
> int (*check_intercept)(struct kvm_vcpu *vcpu,
> struct x86_instruction_info *info,
> enum x86_intercept_stage stage,
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 60b130b7f9d510..cd65c04be3d0e2 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -3504,6 +3504,22 @@ static void svm_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
> *error_code = 0;
> }
>
> +static void svm_get_entry_info(struct kvm_vcpu *vcpu,
> + u32 *inj_info,
> + u32 *inj_info_error_code)
> +{
> + struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control;
> +
> + *inj_info = control->event_inj;
> +
> + if ((*inj_info & SVM_EXITINTINFO_VALID) &&
> + (*inj_info & SVM_EXITINTINFO_VALID_ERR))
> + *inj_info_error_code = control->event_inj_err;
> + else
> + *inj_info_error_code = 0;
> +
> +}
> +
> static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
> {
> struct vcpu_svm *svm = to_svm(vcpu);
> @@ -4992,6 +5008,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
> .required_apicv_inhibits = AVIC_REQUIRED_APICV_INHIBITS,
>
> .get_exit_info = svm_get_exit_info,
> + .get_entry_info = svm_get_entry_info,
>
> .vcpu_after_set_cpuid = svm_vcpu_after_set_cpuid,
>
> diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
> index 83843379813ee3..28e8a63368cc02 100644
> --- a/arch/x86/kvm/trace.h
> +++ b/arch/x86/kvm/trace.h
> @@ -21,14 +21,25 @@ TRACE_EVENT(kvm_entry,
> TP_STRUCT__entry(
> __field( unsigned int, vcpu_id )
> __field( unsigned long, rip )
> - ),
> + __field( u32, inj_info )
> + __field( u32, inj_info_err )
> + __field( bool, req_imm_exit )
> + ),
>
> TP_fast_assign(
> __entry->vcpu_id = vcpu->vcpu_id;
> __entry->rip = kvm_rip_read(vcpu);
> + __entry->req_imm_exit = vcpu->arch.req_immediate_exit;
> +
> + static_call(kvm_x86_get_entry_info)(vcpu,
> + &__entry->inj_info,
> + &__entry->inj_info_err);
> ),
>
> - TP_printk("vcpu %u, rip 0x%lx", __entry->vcpu_id, __entry->rip)
> + TP_printk("vcpu %u, rip 0x%lx inj 0x%08x inj_error_code 0x%08x%s",
> + __entry->vcpu_id, __entry->rip,
> + __entry->inj_info, __entry->inj_info_err,
> + __entry->req_imm_exit ? " [req_imm_exit]" : "")
> );
>
> /*
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index eb7e42235e8811..9dd13f52d4999c 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -6156,6 +6156,17 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
> }
> }
>
> +static void vmx_get_entry_info(struct kvm_vcpu *vcpu,
> + u32 *inj_info,
> + u32 *inj_info_error_code)
> +{
> + *inj_info = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
> + if (is_exception_with_error_code(*inj_info))
> + *inj_info_error_code = vmcs_read32(VM_ENTRY_EXCEPTION_ERROR_CODE);
> + else
> + *inj_info_error_code = 0;
> +}
> +
> static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx)
> {
> if (vmx->pml_pg) {
> @@ -8297,6 +8308,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
> .get_mt_mask = vmx_get_mt_mask,
>
> .get_exit_info = vmx_get_exit_info,
> + .get_entry_info = vmx_get_entry_info,
>
> .vcpu_after_set_cpuid = vmx_vcpu_after_set_cpuid,
>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 3/4] KVM: x86: add information about pending requests to kvm_exit tracepoint
2023-09-28 10:36 [PATCH v3 0/4] KVM: x86: tracepoint updates Maxim Levitsky
2023-09-28 10:36 ` [PATCH v3 1/4] KVM: x86: refactor req_immediate_exit logic Maxim Levitsky
2023-09-28 10:36 ` [PATCH v3 2/4] KVM: x86: add more information to the kvm_entry tracepoint Maxim Levitsky
@ 2023-09-28 10:36 ` Maxim Levitsky
2023-11-24 16:08 ` Paolo Bonzini
2023-09-28 10:36 ` [PATCH v3 4/4] KVM: x86: add new nested vmexit tracepoints Maxim Levitsky
2023-10-17 12:12 ` [PATCH v3 0/4] KVM: x86: tracepoint updates Maxim Levitsky
4 siblings, 1 reply; 12+ messages in thread
From: Maxim Levitsky @ 2023-09-28 10:36 UTC (permalink / raw)
To: kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Paolo Bonzini, Borislav Petkov, linux-kernel, x86, Dave Hansen,
Maxim Levitsky
This allows to gather information on how often kvm interrupts vCPUs due
to specific requests.
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
arch/x86/kvm/trace.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 28e8a63368cc02..e275a02a21e523 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -316,12 +316,14 @@ TRACE_EVENT(name, \
__field( u32, intr_info ) \
__field( u32, error_code ) \
__field( unsigned int, vcpu_id ) \
+ __field( u64, requests ) \
), \
\
TP_fast_assign( \
__entry->guest_rip = kvm_rip_read(vcpu); \
__entry->isa = isa; \
__entry->vcpu_id = vcpu->vcpu_id; \
+ __entry->requests = READ_ONCE(vcpu->requests); \
static_call(kvm_x86_get_exit_info)(vcpu, \
&__entry->exit_reason, \
&__entry->info1, \
@@ -331,11 +333,13 @@ TRACE_EVENT(name, \
), \
\
TP_printk("vcpu %u reason %s%s%s rip 0x%lx info1 0x%016llx " \
- "info2 0x%016llx intr_info 0x%08x error_code 0x%08x", \
+ "info2 0x%016llx intr_info 0x%08x error_code 0x%08x " \
+ "requests 0x%016llx", \
__entry->vcpu_id, \
kvm_print_exit_reason(__entry->exit_reason, __entry->isa), \
__entry->guest_rip, __entry->info1, __entry->info2, \
- __entry->intr_info, __entry->error_code) \
+ __entry->intr_info, __entry->error_code, \
+ __entry->requests) \
)
/*
--
2.26.3
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v3 3/4] KVM: x86: add information about pending requests to kvm_exit tracepoint
2023-09-28 10:36 ` [PATCH v3 3/4] KVM: x86: add information about pending requests to kvm_exit tracepoint Maxim Levitsky
@ 2023-11-24 16:08 ` Paolo Bonzini
0 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2023-11-24 16:08 UTC (permalink / raw)
To: Maxim Levitsky, kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Borislav Petkov, linux-kernel, x86, Dave Hansen
On 9/28/23 12:36, Maxim Levitsky wrote:
> This allows to gather information on how often kvm interrupts vCPUs due
> to specific requests.
>
> Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
> ---
> arch/x86/kvm/trace.h | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
> index 28e8a63368cc02..e275a02a21e523 100644
> --- a/arch/x86/kvm/trace.h
> +++ b/arch/x86/kvm/trace.h
> @@ -316,12 +316,14 @@ TRACE_EVENT(name, \
> __field( u32, intr_info ) \
> __field( u32, error_code ) \
> __field( unsigned int, vcpu_id ) \
> + __field( u64, requests ) \
> ), \
> \
> TP_fast_assign( \
> __entry->guest_rip = kvm_rip_read(vcpu); \
> __entry->isa = isa; \
> __entry->vcpu_id = vcpu->vcpu_id; \
> + __entry->requests = READ_ONCE(vcpu->requests); \
> static_call(kvm_x86_get_exit_info)(vcpu, \
> &__entry->exit_reason, \
> &__entry->info1, \
> @@ -331,11 +333,13 @@ TRACE_EVENT(name, \
> ), \
> \
> TP_printk("vcpu %u reason %s%s%s rip 0x%lx info1 0x%016llx " \
> - "info2 0x%016llx intr_info 0x%08x error_code 0x%08x", \
> + "info2 0x%016llx intr_info 0x%08x error_code 0x%08x " \
> + "requests 0x%016llx", \
> __entry->vcpu_id, \
> kvm_print_exit_reason(__entry->exit_reason, __entry->isa), \
> __entry->guest_rip, __entry->info1, __entry->info2, \
> - __entry->intr_info, __entry->error_code) \
> + __entry->intr_info, __entry->error_code, \
> + __entry->requests) \
> )
>
> /*
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 4/4] KVM: x86: add new nested vmexit tracepoints
2023-09-28 10:36 [PATCH v3 0/4] KVM: x86: tracepoint updates Maxim Levitsky
` (2 preceding siblings ...)
2023-09-28 10:36 ` [PATCH v3 3/4] KVM: x86: add information about pending requests to kvm_exit tracepoint Maxim Levitsky
@ 2023-09-28 10:36 ` Maxim Levitsky
2023-11-24 16:11 ` Paolo Bonzini
2023-10-17 12:12 ` [PATCH v3 0/4] KVM: x86: tracepoint updates Maxim Levitsky
4 siblings, 1 reply; 12+ messages in thread
From: Maxim Levitsky @ 2023-09-28 10:36 UTC (permalink / raw)
To: kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Paolo Bonzini, Borislav Petkov, linux-kernel, x86, Dave Hansen,
Maxim Levitsky
Add 3 new tracepoints for nested VM exits which are intended
to capture extra information to gain insights about the nested guest
behavior.
The new tracepoints are:
- kvm_nested_msr
- kvm_nested_hypercall
These tracepoints capture extra register state to be able to know
which MSR or which hypercall was done.
- kvm_nested_page_fault
This tracepoint allows to capture extra info about which host pagefault
error code caused the nested page fault.
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
arch/x86/kvm/svm/nested.c | 22 +++++++++++
arch/x86/kvm/trace.h | 82 +++++++++++++++++++++++++++++++++++++--
arch/x86/kvm/vmx/nested.c | 27 +++++++++++++
arch/x86/kvm/x86.c | 3 ++
4 files changed, 131 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index dd496c9e5f91f2..1cd9c3ab60ab3a 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -38,6 +38,8 @@ static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
{
struct vcpu_svm *svm = to_svm(vcpu);
struct vmcb *vmcb = svm->vmcb;
+ u64 host_error_code = vmcb->control.exit_info_1;
+
if (vmcb->control.exit_code != SVM_EXIT_NPF) {
/*
@@ -48,11 +50,15 @@ static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
vmcb->control.exit_code_hi = 0;
vmcb->control.exit_info_1 = (1ULL << 32);
vmcb->control.exit_info_2 = fault->address;
+ host_error_code = 0;
}
vmcb->control.exit_info_1 &= ~0xffffffffULL;
vmcb->control.exit_info_1 |= fault->error_code;
+ trace_kvm_nested_page_fault(fault->address, host_error_code,
+ fault->error_code);
+
nested_svm_vmexit(svm);
}
@@ -1139,6 +1145,22 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
vmcb12->control.exit_int_info_err,
KVM_ISA_SVM);
+ /* Collect some info about nested VM exits */
+ switch (vmcb12->control.exit_code) {
+ case SVM_EXIT_MSR:
+ trace_kvm_nested_msr(vmcb12->control.exit_info_1 == 1,
+ kvm_rcx_read(vcpu),
+ (vmcb12->save.rax & -1u) |
+ (((u64)(kvm_rdx_read(vcpu) & -1u) << 32)));
+ break;
+ case SVM_EXIT_VMMCALL:
+ trace_kvm_nested_hypercall(vmcb12->save.rax,
+ kvm_rbx_read(vcpu),
+ kvm_rcx_read(vcpu),
+ kvm_rdx_read(vcpu));
+ break;
+ }
+
kvm_vcpu_unmap(vcpu, &map, true);
nested_svm_transition_tlb_flush(vcpu);
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index e275a02a21e523..782c435bddfd45 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -610,7 +610,7 @@ TRACE_EVENT(kvm_pv_eoi,
);
/*
- * Tracepoint for nested VMRUN
+ * Tracepoint for nested VMRUN/VMENTER
*/
TRACE_EVENT(kvm_nested_vmenter,
TP_PROTO(__u64 rip, __u64 vmcb, __u64 nested_rip, __u32 int_ctl,
@@ -743,8 +743,84 @@ TRACE_EVENT(kvm_nested_intr_vmexit,
TP_printk("rip: 0x%016llx", __entry->rip)
);
+
/*
- * Tracepoint for nested #vmexit because of interrupt pending
+ * Tracepoint for nested guest MSR access.
+ */
+TRACE_EVENT(kvm_nested_msr,
+ TP_PROTO(bool write, u32 ecx, u64 data),
+ TP_ARGS(write, ecx, data),
+
+ TP_STRUCT__entry(
+ __field( bool, write )
+ __field( u32, ecx )
+ __field( u64, data )
+ ),
+
+ TP_fast_assign(
+ __entry->write = write;
+ __entry->ecx = ecx;
+ __entry->data = data;
+ ),
+
+ TP_printk("msr_%s %x = 0x%llx",
+ __entry->write ? "write" : "read",
+ __entry->ecx, __entry->data)
+);
+
+/*
+ * Tracepoint for nested hypercalls, capturing generic info about the
+ * hypercall
+ */
+
+TRACE_EVENT(kvm_nested_hypercall,
+ TP_PROTO(u64 rax, u64 rbx, u64 rcx, u64 rdx),
+ TP_ARGS(rax, rbx, rcx, rdx),
+
+ TP_STRUCT__entry(
+ __field( u64, rax )
+ __field( u64, rbx )
+ __field( u64, rcx )
+ __field( u64, rdx )
+ ),
+
+ TP_fast_assign(
+ __entry->rax = rax;
+ __entry->rbx = rbx;
+ __entry->rcx = rcx;
+ __entry->rdx = rdx;
+ ),
+
+ TP_printk("rax 0x%llx rbx 0x%llx rcx 0x%llx rdx 0x%llx",
+ __entry->rax, __entry->rbx, __entry->rcx, __entry->rdx)
+);
+
+
+TRACE_EVENT(kvm_nested_page_fault,
+ TP_PROTO(u64 gpa, u64 host_error_code, u64 guest_error_code),
+ TP_ARGS(gpa, host_error_code, guest_error_code),
+
+ TP_STRUCT__entry(
+ __field( u64, gpa )
+ __field( u64, host_error_code )
+ __field( u64, guest_errror_code )
+ ),
+
+ TP_fast_assign(
+ __entry->gpa = gpa;
+ __entry->host_error_code = host_error_code;
+ __entry->guest_errror_code = guest_error_code;
+ ),
+
+ TP_printk("gpa 0x%llx host err 0x%llx guest err 0x%llx",
+ __entry->gpa,
+ __entry->host_error_code,
+ __entry->guest_errror_code)
+);
+
+
+/*
+ * Tracepoint for invlpga
*/
TRACE_EVENT(kvm_invlpga,
TP_PROTO(__u64 rip, int asid, u64 address),
@@ -767,7 +843,7 @@ TRACE_EVENT(kvm_invlpga,
);
/*
- * Tracepoint for nested #vmexit because of interrupt pending
+ * Tracepoint for skinit
*/
TRACE_EVENT(kvm_skinit,
TP_PROTO(__u64 rip, __u32 slb),
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index c5ec0ef51ff78f..7065ccd42ca229 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -402,6 +402,16 @@ static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu,
*/
nested_ept_invalidate_addr(vcpu, vmcs12->ept_pointer,
fault->address);
+
+ /*
+ * vmx_get_exit_qual() returns the original exit qualification,
+ * before it was overridden with exit qualification that
+ * is about to be injected to the guest.
+ */
+
+ trace_kvm_nested_page_fault(fault->address,
+ vmx_get_exit_qual(vcpu),
+ exit_qualification);
}
nested_vmx_vmexit(vcpu, vm_exit_reason, 0, exit_qualification);
@@ -4877,6 +4887,23 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,
vmcs12->vm_exit_intr_error_code,
KVM_ISA_VMX);
+ switch ((u16)vmcs12->vm_exit_reason) {
+ case EXIT_REASON_MSR_READ:
+ case EXIT_REASON_MSR_WRITE:
+ trace_kvm_nested_msr(vmcs12->vm_exit_reason == EXIT_REASON_MSR_WRITE,
+ kvm_rcx_read(vcpu),
+ (kvm_rax_read(vcpu) & -1u) |
+ (((u64)(kvm_rdx_read(vcpu) & -1u) << 32)));
+ break;
+ case EXIT_REASON_VMCALL:
+ trace_kvm_nested_hypercall(kvm_rax_read(vcpu),
+ kvm_rbx_read(vcpu),
+ kvm_rcx_read(vcpu),
+ kvm_rdx_read(vcpu));
+ break;
+
+ }
+
load_vmcs12_host_state(vcpu, vmcs12);
return;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index dfb7d25ed94f26..766d0dc333eac3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -13637,6 +13637,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmenter);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmexit);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmexit_inject);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intr_vmexit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_hypercall);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_page_fault);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_msr);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmenter_failed);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit);
--
2.26.3
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH v3 4/4] KVM: x86: add new nested vmexit tracepoints
2023-09-28 10:36 ` [PATCH v3 4/4] KVM: x86: add new nested vmexit tracepoints Maxim Levitsky
@ 2023-11-24 16:11 ` Paolo Bonzini
2023-11-28 6:42 ` Maxim Levitsky
0 siblings, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2023-11-24 16:11 UTC (permalink / raw)
To: Maxim Levitsky, kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Borislav Petkov, linux-kernel, x86, Dave Hansen
On 9/28/23 12:36, Maxim Levitsky wrote:
> Add 3 new tracepoints for nested VM exits which are intended
> to capture extra information to gain insights about the nested guest
> behavior.
>
> The new tracepoints are:
>
> - kvm_nested_msr
> - kvm_nested_hypercall
>
> These tracepoints capture extra register state to be able to know
> which MSR or which hypercall was done.
>
> - kvm_nested_page_fault
>
> This tracepoint allows to capture extra info about which host pagefault
> error code caused the nested page fault.
>
> Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
with just one question below that can be fixed when applying:
> @@ -1139,6 +1145,22 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
> vmcb12->control.exit_int_info_err,
> KVM_ISA_SVM);
>
> + /* Collect some info about nested VM exits */
> + switch (vmcb12->control.exit_code) {
> + case SVM_EXIT_MSR:
> + trace_kvm_nested_msr(vmcb12->control.exit_info_1 == 1,
> + kvm_rcx_read(vcpu),
> + (vmcb12->save.rax & -1u) |
> + (((u64)(kvm_rdx_read(vcpu) & -1u) << 32)));
Why the second "& -1u"? (And I also prefer 0xFFFFFFFFull
Paolo
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH v3 4/4] KVM: x86: add new nested vmexit tracepoints
2023-11-24 16:11 ` Paolo Bonzini
@ 2023-11-28 6:42 ` Maxim Levitsky
0 siblings, 0 replies; 12+ messages in thread
From: Maxim Levitsky @ 2023-11-28 6:42 UTC (permalink / raw)
To: Paolo Bonzini, kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Borislav Petkov, linux-kernel, x86, Dave Hansen
On Fri, 2023-11-24 at 17:11 +0100, Paolo Bonzini wrote:
> On 9/28/23 12:36, Maxim Levitsky wrote:
> > Add 3 new tracepoints for nested VM exits which are intended
> > to capture extra information to gain insights about the nested guest
> > behavior.
> >
> > The new tracepoints are:
> >
> > - kvm_nested_msr
> > - kvm_nested_hypercall
> >
> > These tracepoints capture extra register state to be able to know
> > which MSR or which hypercall was done.
> >
> > - kvm_nested_page_fault
> >
> > This tracepoint allows to capture extra info about which host pagefault
> > error code caused the nested page fault.
> >
> > Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
>
> with just one question below that can be fixed when applying:
>
> > @@ -1139,6 +1145,22 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
> > vmcb12->control.exit_int_info_err,
> > KVM_ISA_SVM);
> >
> > + /* Collect some info about nested VM exits */
> > + switch (vmcb12->control.exit_code) {
> > + case SVM_EXIT_MSR:
> > + trace_kvm_nested_msr(vmcb12->control.exit_info_1 == 1,
> > + kvm_rcx_read(vcpu),
> > + (vmcb12->save.rax & -1u) |
> > + (((u64)(kvm_rdx_read(vcpu) & -1u) << 32)));
>
> Why the second "& -1u"? (And I also prefer 0xFFFFFFFFull
I think I copied it from somewhere but I can't seem to find where.
I agree with both remarks, will fix.
Thanks,
Best regards,
Maxim Levitsky
>
> Paolo
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 0/4] KVM: x86: tracepoint updates
2023-09-28 10:36 [PATCH v3 0/4] KVM: x86: tracepoint updates Maxim Levitsky
` (3 preceding siblings ...)
2023-09-28 10:36 ` [PATCH v3 4/4] KVM: x86: add new nested vmexit tracepoints Maxim Levitsky
@ 2023-10-17 12:12 ` Maxim Levitsky
4 siblings, 0 replies; 12+ messages in thread
From: Maxim Levitsky @ 2023-10-17 12:12 UTC (permalink / raw)
To: kvm
Cc: Thomas Gleixner, H. Peter Anvin, Sean Christopherson, Ingo Molnar,
Paolo Bonzini, Borislav Petkov, linux-kernel, x86, Dave Hansen
У чт, 2023-09-28 у 13:36 +0300, Maxim Levitsky пише:
> This patch series is intended to add some selected information
> to the kvm tracepoints to make it easier to gather insights about
> running nested guests.
>
> This patch series was developed together with a new x86 performance analysis tool
> that I developed recently (https://gitlab.com/maximlevitsky/kvmon)
> which aims to be a better kvm_stat, and allows you at glance
> to see what is happening in a VM, including nesting.
>
> Best regards,
> Maxim Levitsky
>
> Maxim Levitsky (4):
> KVM: x86: refactor req_immediate_exit logic
> KVM: x86: add more information to the kvm_entry tracepoint
> KVM: x86: add information about pending requests to kvm_exit
> tracepoint
> KVM: x86: add new nested vmexit tracepoints
>
> arch/x86/include/asm/kvm-x86-ops.h | 2 +-
> arch/x86/include/asm/kvm_host.h | 10 +--
> arch/x86/kvm/svm/nested.c | 22 ++++++
> arch/x86/kvm/svm/svm.c | 22 +++++-
> arch/x86/kvm/trace.h | 105 +++++++++++++++++++++++++++--
> arch/x86/kvm/vmx/nested.c | 27 ++++++++
> arch/x86/kvm/vmx/vmx.c | 30 +++++----
> arch/x86/kvm/vmx/vmx.h | 2 -
> arch/x86/kvm/x86.c | 34 +++++-----
> 9 files changed, 208 insertions(+), 46 deletions(-)
>
> --
> 2.26.3
Ping on this patch series.
Best regards,
Maxim Levitsky
^ permalink raw reply [flat|nested] 12+ messages in thread