To aid in debugging failures in the field, when instruction emulation
fails, report the VM exit reason to userspace in order that it can be
recorded.
The changes are on top of Aaron's patches from
https://lore.kernel.org/r/[email protected]
which are in the KVM queue, but not yet upstream.
David Edmondson (2):
KVM: x86: Add kvm_x86_ops.get_exit_reason
KVM: x86: On emulation failure, convey the exit reason to userspace
arch/x86/include/asm/kvm-x86-ops.h | 1 +
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/svm/svm.c | 6 ++++++
arch/x86/kvm/vmx/vmx.c | 6 ++++++
arch/x86/kvm/x86.c | 23 +++++++++++++++++------
include/uapi/linux/kvm.h | 2 ++
6 files changed, 33 insertions(+), 6 deletions(-)
--
2.30.2
For later use.
Signed-off-by: David Edmondson <[email protected]>
---
arch/x86/include/asm/kvm-x86-ops.h | 1 +
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/svm/svm.c | 6 ++++++
arch/x86/kvm/vmx/vmx.c | 6 ++++++
4 files changed, 14 insertions(+)
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index a12a4987154e..afb0917497c1 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -85,6 +85,7 @@ KVM_X86_OP_NULL(sync_pir_to_irr)
KVM_X86_OP(set_tss_addr)
KVM_X86_OP(set_identity_map_addr)
KVM_X86_OP(get_mt_mask)
+KVM_X86_OP(get_exit_reason)
KVM_X86_OP(load_mmu_pgd)
KVM_X86_OP_NULL(has_wbinvd_exit)
KVM_X86_OP(get_l2_tsc_offset)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 974cbfb1eefe..0ee580c68839 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1365,6 +1365,7 @@ struct kvm_x86_ops {
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr);
u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
+ u64 (*get_exit_reason)(struct kvm_vcpu *vcpu);
void (*load_mmu_pgd)(struct kvm_vcpu *vcpu, hpa_t root_hpa,
int root_level);
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 616b9679ddcc..408c854b4ac9 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4009,6 +4009,11 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
return 0;
}
+static u64 svm_get_exit_reason(struct kvm_vcpu *vcpu)
+{
+ return to_svm(vcpu)->vmcb->control.exit_code;
+}
+
static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -4573,6 +4578,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.set_tss_addr = svm_set_tss_addr,
.set_identity_map_addr = svm_set_identity_map_addr,
.get_mt_mask = svm_get_mt_mask,
+ .get_exit_reason = svm_get_exit_reason,
.get_exit_info = svm_get_exit_info,
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 927a552393b9..a19b006c287a 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6997,6 +6997,11 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
return (cache << VMX_EPT_MT_EPTE_SHIFT) | ipat;
}
+static u64 vmx_get_exit_reason(struct kvm_vcpu *vcpu)
+{
+ return to_vmx(vcpu)->exit_reason.basic;
+}
+
static void vmcs_set_secondary_exec_control(struct vcpu_vmx *vmx)
{
/*
@@ -7613,6 +7618,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.set_tss_addr = vmx_set_tss_addr,
.set_identity_map_addr = vmx_set_identity_map_addr,
.get_mt_mask = vmx_get_mt_mask,
+ .get_exit_reason = vmx_get_exit_reason,
.get_exit_info = vmx_get_exit_info,
--
2.30.2
On Mon, Jun 28, 2021 at 06:31:50PM +0100, David Edmondson wrote:
> To aid in debugging failures in the field, when instruction emulation
What do you mean by a "debugging failure"?
> fails, report the VM exit reason to userspace in order that it can be
> recorded.
What is the benefit of seeing the VM-exit reason that led to an
emulation failure?
>
> The changes are on top of Aaron's patches from
> https://lore.kernel.org/r/[email protected]
> which are in the KVM queue, but not yet upstream.
>
> David Edmondson (2):
> KVM: x86: Add kvm_x86_ops.get_exit_reason
> KVM: x86: On emulation failure, convey the exit reason to userspace
>
> arch/x86/include/asm/kvm-x86-ops.h | 1 +
> arch/x86/include/asm/kvm_host.h | 1 +
> arch/x86/kvm/svm/svm.c | 6 ++++++
> arch/x86/kvm/vmx/vmx.c | 6 ++++++
> arch/x86/kvm/x86.c | 23 +++++++++++++++++------
> include/uapi/linux/kvm.h | 2 ++
> 6 files changed, 33 insertions(+), 6 deletions(-)
>
> --
> 2.30.2
>
On Mon, Jun 28, 2021 at 06:31:51PM +0100, David Edmondson wrote:
> For later use.
Please add more context to the commit message.
>
> Signed-off-by: David Edmondson <[email protected]>
> ---
> arch/x86/include/asm/kvm-x86-ops.h | 1 +
> arch/x86/include/asm/kvm_host.h | 1 +
> arch/x86/kvm/svm/svm.c | 6 ++++++
> arch/x86/kvm/vmx/vmx.c | 6 ++++++
> 4 files changed, 14 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
> index a12a4987154e..afb0917497c1 100644
> --- a/arch/x86/include/asm/kvm-x86-ops.h
> +++ b/arch/x86/include/asm/kvm-x86-ops.h
> @@ -85,6 +85,7 @@ KVM_X86_OP_NULL(sync_pir_to_irr)
> KVM_X86_OP(set_tss_addr)
> KVM_X86_OP(set_identity_map_addr)
> KVM_X86_OP(get_mt_mask)
> +KVM_X86_OP(get_exit_reason)
> KVM_X86_OP(load_mmu_pgd)
> KVM_X86_OP_NULL(has_wbinvd_exit)
> KVM_X86_OP(get_l2_tsc_offset)
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 974cbfb1eefe..0ee580c68839 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1365,6 +1365,7 @@ struct kvm_x86_ops {
> int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
> int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr);
> u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
> + u64 (*get_exit_reason)(struct kvm_vcpu *vcpu);
>
> void (*load_mmu_pgd)(struct kvm_vcpu *vcpu, hpa_t root_hpa,
> int root_level);
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 616b9679ddcc..408c854b4ac9 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -4009,6 +4009,11 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
> return 0;
> }
>
> +static u64 svm_get_exit_reason(struct kvm_vcpu *vcpu)
> +{
> + return to_svm(vcpu)->vmcb->control.exit_code;
> +}
> +
> static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
> {
> struct vcpu_svm *svm = to_svm(vcpu);
> @@ -4573,6 +4578,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
> .set_tss_addr = svm_set_tss_addr,
> .set_identity_map_addr = svm_set_identity_map_addr,
> .get_mt_mask = svm_get_mt_mask,
> + .get_exit_reason = svm_get_exit_reason,
>
> .get_exit_info = svm_get_exit_info,
>
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 927a552393b9..a19b006c287a 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -6997,6 +6997,11 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
> return (cache << VMX_EPT_MT_EPTE_SHIFT) | ipat;
> }
>
> +static u64 vmx_get_exit_reason(struct kvm_vcpu *vcpu)
> +{
> + return to_vmx(vcpu)->exit_reason.basic;
Why not the full exit reason?
> +}
> +
> static void vmcs_set_secondary_exec_control(struct vcpu_vmx *vmx)
> {
> /*
> @@ -7613,6 +7618,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
> .set_tss_addr = vmx_set_tss_addr,
> .set_identity_map_addr = vmx_set_identity_map_addr,
> .get_mt_mask = vmx_get_mt_mask,
> + .get_exit_reason = vmx_get_exit_reason,
>
> .get_exit_info = vmx_get_exit_info,
>
> --
> 2.30.2
>
On Wed, Jun 30, 2021 at 9:33 AM David Matlack <[email protected]> wrote:
>
> On Mon, Jun 28, 2021 at 06:31:50PM +0100, David Edmondson wrote:
> > To aid in debugging failures in the field, when instruction emulation
>
> What do you mean by a "debugging failure"?
Oh! Sorry I misread this as "*debugging failures*" rather than
"debugging *failures*". I know what you mean here :-).
>
> > fails, report the VM exit reason to userspace in order that it can be
> > recorded.
>
> What is the benefit of seeing the VM-exit reason that led to an
> emulation failure?
>
> >
> > The changes are on top of Aaron's patches from
> > https://lore.kernel.org/r/[email protected]
> > which are in the KVM queue, but not yet upstream.
> >
> > David Edmondson (2):
> > KVM: x86: Add kvm_x86_ops.get_exit_reason
> > KVM: x86: On emulation failure, convey the exit reason to userspace
> >
> > arch/x86/include/asm/kvm-x86-ops.h | 1 +
> > arch/x86/include/asm/kvm_host.h | 1 +
> > arch/x86/kvm/svm/svm.c | 6 ++++++
> > arch/x86/kvm/vmx/vmx.c | 6 ++++++
> > arch/x86/kvm/x86.c | 23 +++++++++++++++++------
> > include/uapi/linux/kvm.h | 2 ++
> > 6 files changed, 33 insertions(+), 6 deletions(-)
> >
> > --
> > 2.30.2
> >