From: Jing Zhang <jingzhangos@google.com>
To: KVM <kvm@vger.kernel.org>, KVMARM <kvmarm@lists.cs.columbia.edu>,
Paolo Bonzini <pbonzini@redhat.com>,
Marc Zyngier <maz@kernel.org>, Will Deacon <will@kernel.org>,
David Matlack <dmatlack@google.com>,
Peter Shier <pshier@google.com>,
Oliver Upton <oupton@google.com>,
Sean Christopherson <seanjc@google.com>
Subject: [PATCH v1 1/3] KVM: arm64: Add arch specific exit reasons
Date: Wed, 22 Sep 2021 01:08:49 +0000 [thread overview]
Message-ID: <20210922010851.2312845-1-jingzhangos@google.com> (raw)
Arch specific exit reasons have been available for other architectures.
Add arch specific exit reason support for ARM64, which would be used in
KVM stats for monitoring VCPU status.
Signed-off-by: Jing Zhang <jingzhangos@google.com>
---
arch/arm64/include/asm/kvm_emulate.h | 5 +++
arch/arm64/include/asm/kvm_host.h | 33 +++++++++++++++
arch/arm64/kvm/handle_exit.c | 62 +++++++++++++++++++++++++---
arch/arm64/kvm/mmu.c | 4 ++
arch/arm64/kvm/sys_regs.c | 6 +++
5 files changed, 105 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index fd418955e31e..eb5ec3a479d3 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -319,6 +319,11 @@ static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu)
return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW;
}
+static inline bool kvm_vcpu_trap_is_dabt(const struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_DABT_LOW;
+}
+
static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu)
{
return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f8be56d5342b..0f0cea26ce32 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -278,6 +278,36 @@ struct vcpu_reset_state {
bool reset;
};
+enum arm_exit_reason {
+ ARM_EXIT_UNKNOWN,
+ ARM_EXIT_IRQ,
+ ARM_EXIT_EL1_SERROR,
+ ARM_EXIT_HYP_GONE,
+ ARM_EXIT_IL,
+ ARM_EXIT_WFI,
+ ARM_EXIT_WFE,
+ ARM_EXIT_CP15_32,
+ ARM_EXIT_CP15_64,
+ ARM_EXIT_CP14_32,
+ ARM_EXIT_CP14_LS,
+ ARM_EXIT_CP14_64,
+ ARM_EXIT_HVC32,
+ ARM_EXIT_SMC32,
+ ARM_EXIT_HVC64,
+ ARM_EXIT_SMC64,
+ ARM_EXIT_SYS64,
+ ARM_EXIT_SVE,
+ ARM_EXIT_IABT_LOW,
+ ARM_EXIT_DABT_LOW,
+ ARM_EXIT_SOFTSTP_LOW,
+ ARM_EXIT_WATCHPT_LOW,
+ ARM_EXIT_BREAKPT_LOW,
+ ARM_EXIT_BKPT32,
+ ARM_EXIT_BRK64,
+ ARM_EXIT_FP_ASIMD,
+ ARM_EXIT_PAC,
+};
+
struct kvm_vcpu_arch {
struct kvm_cpu_context ctxt;
void *sve_state;
@@ -384,6 +414,9 @@ struct kvm_vcpu_arch {
u64 last_steal;
gpa_t base;
} steal;
+
+ /* Arch specific exit reason */
+ enum arm_exit_reason exit_reason;
};
/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 275a27368a04..90a47758b23d 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -49,6 +49,18 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
return ret;
}
+static int handle_hvc32(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.exit_reason = ARM_EXIT_HVC32;
+ return handle_hvc(vcpu);
+}
+
+static int handle_hvc64(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.exit_reason = ARM_EXIT_HVC64;
+ return handle_hvc(vcpu);
+}
+
static int handle_smc(struct kvm_vcpu *vcpu)
{
/*
@@ -64,12 +76,25 @@ static int handle_smc(struct kvm_vcpu *vcpu)
return 1;
}
+static int handle_smc32(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.exit_reason = ARM_EXIT_SMC32;
+ return handle_smc(vcpu);
+}
+
+static int handle_smc64(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.exit_reason = ARM_EXIT_SMC64;
+ return handle_smc(vcpu);
+}
+
/*
* Guest access to FP/ASIMD registers are routed to this handler only
* when the system doesn't support FP/ASIMD.
*/
static int handle_no_fpsimd(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_FP_ASIMD;
kvm_inject_undefined(vcpu);
return 1;
}
@@ -91,10 +116,12 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu)
if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_WFx_ISS_WFE) {
trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true);
vcpu->stat.wfe_exit_stat++;
+ vcpu->arch.exit_reason = ARM_EXIT_WFE;
kvm_vcpu_on_spin(vcpu, vcpu_mode_priv(vcpu));
} else {
trace_kvm_wfx_arm64(*vcpu_pc(vcpu), false);
vcpu->stat.wfi_exit_stat++;
+ vcpu->arch.exit_reason = ARM_EXIT_WFI;
kvm_vcpu_block(vcpu);
kvm_clear_request(KVM_REQ_UNHALT, vcpu);
}
@@ -119,12 +146,29 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
u32 esr = kvm_vcpu_get_esr(vcpu);
+ u8 esr_ec = ESR_ELx_EC(esr);
run->exit_reason = KVM_EXIT_DEBUG;
run->debug.arch.hsr = esr;
- if (ESR_ELx_EC(esr) == ESR_ELx_EC_WATCHPT_LOW)
+ switch (esr_ec) {
+ case ESR_ELx_EC_SOFTSTP_LOW:
+ vcpu->arch.exit_reason = ARM_EXIT_SOFTSTP_LOW;
+ break;
+ case ESR_ELx_EC_WATCHPT_LOW:
run->debug.arch.far = vcpu->arch.fault.far_el2;
+ vcpu->arch.exit_reason = ARM_EXIT_WATCHPT_LOW;
+ break;
+ case ESR_ELx_EC_BREAKPT_LOW:
+ vcpu->arch.exit_reason = ARM_EXIT_BREAKPT_LOW;
+ break;
+ case ESR_ELx_EC_BKPT32:
+ vcpu->arch.exit_reason = ARM_EXIT_BKPT32;
+ break;
+ case ESR_ELx_EC_BRK64:
+ vcpu->arch.exit_reason = ARM_EXIT_BRK64;
+ break;
+ }
return 0;
}
@@ -136,12 +180,14 @@ static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu)
kvm_pr_unimpl("Unknown exception class: esr: %#08x -- %s\n",
esr, esr_get_class_string(esr));
+ vcpu->arch.exit_reason = ARM_EXIT_UNKNOWN;
kvm_inject_undefined(vcpu);
return 1;
}
static int handle_sve(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_SVE;
/* Until SVE is supported for guests: */
kvm_inject_undefined(vcpu);
return 1;
@@ -154,6 +200,7 @@ static int handle_sve(struct kvm_vcpu *vcpu)
*/
static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_PAC;
kvm_inject_undefined(vcpu);
return 1;
}
@@ -166,10 +213,10 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_CP14_MR] = kvm_handle_cp14_32,
[ESR_ELx_EC_CP14_LS] = kvm_handle_cp14_load_store,
[ESR_ELx_EC_CP14_64] = kvm_handle_cp14_64,
- [ESR_ELx_EC_HVC32] = handle_hvc,
- [ESR_ELx_EC_SMC32] = handle_smc,
- [ESR_ELx_EC_HVC64] = handle_hvc,
- [ESR_ELx_EC_SMC64] = handle_smc,
+ [ESR_ELx_EC_HVC32] = handle_hvc32,
+ [ESR_ELx_EC_SMC32] = handle_smc32,
+ [ESR_ELx_EC_HVC64] = handle_hvc64,
+ [ESR_ELx_EC_SMC64] = handle_smc64,
[ESR_ELx_EC_SYS64] = kvm_handle_sys_reg,
[ESR_ELx_EC_SVE] = handle_sve,
[ESR_ELx_EC_IABT_LOW] = kvm_handle_guest_abort,
@@ -230,8 +277,10 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
switch (exception_index) {
case ARM_EXCEPTION_IRQ:
+ vcpu->arch.exit_reason = ARM_EXIT_IRQ;
return 1;
case ARM_EXCEPTION_EL1_SERROR:
+ vcpu->arch.exit_reason = ARM_EXIT_EL1_SERROR;
return 1;
case ARM_EXCEPTION_TRAP:
return handle_trap_exceptions(vcpu);
@@ -240,6 +289,7 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
* EL2 has been reset to the hyp-stub. This happens when a guest
* is pre-empted by kvm_reboot()'s shutdown call.
*/
+ vcpu->arch.exit_reason = ARM_EXIT_HYP_GONE;
run->exit_reason = KVM_EXIT_FAIL_ENTRY;
return 0;
case ARM_EXCEPTION_IL:
@@ -247,11 +297,13 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
* We attempted an illegal exception return. Guest state must
* have been corrupted somehow. Give up.
*/
+ vcpu->arch.exit_reason = ARM_EXIT_IL;
run->exit_reason = KVM_EXIT_FAIL_ENTRY;
return -EINVAL;
default:
kvm_pr_unimpl("Unsupported exception type: %d",
exception_index);
+ vcpu->arch.exit_reason = ARM_EXIT_UNKNOWN;
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
return 0;
}
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 1a94a7ca48f2..a6a18d113c98 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1197,6 +1197,10 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
+ if (is_iabt)
+ vcpu->arch.exit_reason = ARM_EXIT_IABT_LOW;
+ else if (kvm_vcpu_trap_is_dabt(vcpu))
+ vcpu->arch.exit_reason = ARM_EXIT_DABT_LOW;
/* Synchronous External Abort? */
if (kvm_vcpu_abt_issea(vcpu)) {
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1d46e185f31e..0915dfa589c7 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2158,6 +2158,7 @@ static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n,
int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_CP14_LS;
kvm_inject_undefined(vcpu);
return 1;
}
@@ -2325,21 +2326,25 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
int kvm_handle_cp15_64(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_CP15_64;
return kvm_handle_cp_64(vcpu, cp15_64_regs, ARRAY_SIZE(cp15_64_regs));
}
int kvm_handle_cp15_32(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_CP15_32;
return kvm_handle_cp_32(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs));
}
int kvm_handle_cp14_64(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_CP14_64;
return kvm_handle_cp_64(vcpu, cp14_64_regs, ARRAY_SIZE(cp14_64_regs));
}
int kvm_handle_cp14_32(struct kvm_vcpu *vcpu)
{
+ vcpu->arch.exit_reason = ARM_EXIT_CP14_32;
return kvm_handle_cp_32(vcpu, cp14_regs, ARRAY_SIZE(cp14_regs));
}
@@ -2397,6 +2402,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
int ret;
trace_kvm_handle_sys_reg(esr);
+ vcpu->arch.exit_reason = ARM_EXIT_SYS64;
params = esr_sys64_to_params(esr);
params.regval = vcpu_get_reg(vcpu, Rt);
--
2.33.0.464.g1972c5931b-goog
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
next reply other threads:[~2021-09-22 1:09 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-22 1:08 Jing Zhang [this message]
2021-09-22 1:08 ` [PATCH v1 2/3] KVM: arm64: Add counter stats for arch specific exit reasons Jing Zhang
2021-09-22 1:08 ` [PATCH v1 3/3] KVM: arm64: Add histogram stats for handling time of " Jing Zhang
2021-09-22 11:22 ` Marc Zyngier
2021-09-22 15:37 ` Paolo Bonzini
2021-09-22 16:09 ` Jing Zhang
2021-09-22 18:13 ` Sean Christopherson
2021-09-22 18:53 ` Marc Zyngier
2021-09-22 23:22 ` David Matlack
2021-09-30 14:04 ` Marc Zyngier
2021-09-30 18:05 ` Sean Christopherson
2021-09-23 6:36 ` Paolo Bonzini
2021-09-23 7:45 ` Marc Zyngier
2021-09-23 9:44 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210922010851.2312845-1-jingzhangos@google.com \
--to=jingzhangos@google.com \
--cc=dmatlack@google.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=maz@kernel.org \
--cc=oupton@google.com \
--cc=pbonzini@redhat.com \
--cc=pshier@google.com \
--cc=seanjc@google.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox