From: Fuad Tabba <tabba@google.com>
To: kvmarm@lists.linux.dev
Cc: maz@kernel.org, will@kernel.org, qperret@google.com,
tabba@google.com, seanjc@google.com, alexandru.elisei@arm.com,
catalin.marinas@arm.com, philmd@linaro.org, james.morse@arm.com,
suzuki.poulose@arm.com, oliver.upton@linux.dev,
mark.rutland@arm.com, broonie@kernel.org, joey.gouly@arm.com,
rananta@google.com
Subject: [PATCH v1 20/44] KVM: arm64: Refactor enter_exception64()
Date: Wed, 27 Mar 2024 17:35:07 +0000 [thread overview]
Message-ID: <20240327173531.1379685-21-tabba@google.com> (raw)
In-Reply-To: <20240327173531.1379685-1-tabba@google.com>
From: Quentin Perret <qperret@google.com>
In order to simplify the injection of exceptions in the host in pkvm
context, let's factor out of enter_exception64() the code calculating
the exception offset from VBAR_EL1 and the cpsr.
No functional change intended.
Signed-off-by: Quentin Perret <qperret@google.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_emulate.h | 5 ++
arch/arm64/kvm/hyp/exception.c | 100 ++++++++++++++++-----------
2 files changed, 63 insertions(+), 42 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index dcb2aaf10d8c..4f0bc2df46f6 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -49,6 +49,11 @@ void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
void kvm_inject_size_fault(struct kvm_vcpu *vcpu);
+unsigned long get_except64_offset(unsigned long psr, unsigned long target_mode,
+ enum exception_type type);
+unsigned long get_except64_cpsr(unsigned long old, bool has_mte,
+ unsigned long sctlr, unsigned long mode);
+
void kvm_vcpu_wfi(struct kvm_vcpu *vcpu);
void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
index 424a5107cddb..da69a5685c47 100644
--- a/arch/arm64/kvm/hyp/exception.c
+++ b/arch/arm64/kvm/hyp/exception.c
@@ -71,31 +71,12 @@ static void __vcpu_write_spsr_und(struct kvm_vcpu *vcpu, u64 val)
vcpu->arch.ctxt.spsr_und = val;
}
-/*
- * This performs the exception entry at a given EL (@target_mode), stashing PC
- * and PSTATE into ELR and SPSR respectively, and compute the new PC/PSTATE.
- * The EL passed to this function *must* be a non-secure, privileged mode with
- * bit 0 being set (PSTATE.SP == 1).
- *
- * When an exception is taken, most PSTATE fields are left unchanged in the
- * handler. However, some are explicitly overridden (e.g. M[4:0]). Luckily all
- * of the inherited bits have the same position in the AArch64/AArch32 SPSR_ELx
- * layouts, so we don't need to shuffle these for exceptions from AArch32 EL0.
- *
- * For the SPSR_ELx layout for AArch64, see ARM DDI 0487E.a page C5-429.
- * For the SPSR_ELx layout for AArch32, see ARM DDI 0487E.a page C5-426.
- *
- * Here we manipulate the fields in order of the AArch64 SPSR_ELx layout, from
- * MSB to LSB.
- */
-static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
- enum exception_type type)
+unsigned long get_except64_offset(unsigned long psr, unsigned long target_mode,
+ enum exception_type type)
{
- unsigned long sctlr, vbar, old, new, mode;
+ u64 mode = psr & (PSR_MODE_MASK | PSR_MODE32_BIT);
u64 exc_offset;
- mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
-
if (mode == target_mode)
exc_offset = CURRENT_EL_SP_ELx_VECTOR;
else if ((mode | PSR_MODE_THREAD_BIT) == target_mode)
@@ -105,33 +86,32 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
else
exc_offset = LOWER_EL_AArch32_VECTOR;
- switch (target_mode) {
- case PSR_MODE_EL1h:
- vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL1);
- sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
- __vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1);
- break;
- case PSR_MODE_EL2h:
- vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL2);
- sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL2);
- __vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL2);
- break;
- default:
- /* Don't do that */
- BUG();
- }
-
- *vcpu_pc(vcpu) = vbar + exc_offset + type;
+ return exc_offset + type;
+}
- old = *vcpu_cpsr(vcpu);
- new = 0;
+/*
+ * When an exception is taken, most PSTATE fields are left unchanged in the
+ * handler. However, some are explicitly overridden (e.g. M[4:0]). Luckily all
+ * of the inherited bits have the same position in the AArch64/AArch32 SPSR_ELx
+ * layouts, so we don't need to shuffle these for exceptions from AArch32 EL0.
+ *
+ * For the SPSR_ELx layout for AArch64, see ARM DDI 0487E.a page C5-429.
+ * For the SPSR_ELx layout for AArch32, see ARM DDI 0487E.a page C5-426.
+ *
+ * Here we manipulate the fields in order of the AArch64 SPSR_ELx layout, from
+ * MSB to LSB.
+ */
+unsigned long get_except64_cpsr(unsigned long old, bool has_mte,
+ unsigned long sctlr, unsigned long target_mode)
+{
+ u64 new = 0;
new |= (old & PSR_N_BIT);
new |= (old & PSR_Z_BIT);
new |= (old & PSR_C_BIT);
new |= (old & PSR_V_BIT);
- if (kvm_has_mte(kern_hyp_va(vcpu->kvm)))
+ if (has_mte)
new |= PSR_TCO_BIT;
new |= (old & PSR_DIT_BIT);
@@ -167,6 +147,42 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
new |= target_mode;
+ return new;
+}
+
+/*
+ * This performs the exception entry at a given EL (@target_mode), stashing PC
+ * and PSTATE into ELR and SPSR respectively, and compute the new PC/PSTATE.
+ * The EL passed to this function *must* be a non-secure, privileged mode with
+ * bit 0 being set (PSTATE.SP == 1).
+ */
+static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
+ enum exception_type type)
+{
+ u64 offset = get_except64_offset(*vcpu_cpsr(vcpu), target_mode, type);
+ unsigned long sctlr, vbar, old, new;
+
+ switch (target_mode) {
+ case PSR_MODE_EL1h:
+ vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL1);
+ sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
+ __vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1);
+ break;
+ case PSR_MODE_EL2h:
+ vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL2);
+ sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL2);
+ __vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL2);
+ break;
+ default:
+ /* Don't do that */
+ BUG();
+ }
+
+ *vcpu_pc(vcpu) = vbar + offset;
+
+ old = *vcpu_cpsr(vcpu);
+ new = get_except64_cpsr(old, kvm_has_mte(kern_hyp_va(vcpu->kvm)), sctlr,
+ target_mode);
*vcpu_cpsr(vcpu) = new;
__vcpu_write_spsr(vcpu, target_mode, old);
}
--
2.44.0.478.gd926399ef9-goog
next prev parent reply other threads:[~2024-03-27 17:36 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-27 17:34 [PATCH v1 00/44] KVM: arm64: Preamble for pKVM Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 01/44] KVM: arm64: Change kvm_handle_mmio_return() return polarity Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 02/44] KVM: arm64: Use enum instead of helper for checking FP-state Fuad Tabba
2024-03-28 16:19 ` Mark Brown
2024-04-08 7:39 ` Marc Zyngier
2024-04-08 13:39 ` Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 03/44] KVM: arm64: Move setting the page as dirty out of the critical section Fuad Tabba
2024-04-08 7:41 ` Marc Zyngier
2024-04-08 15:41 ` Fuad Tabba
2024-04-08 15:53 ` Marc Zyngier
2024-04-08 15:57 ` Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 04/44] KVM: arm64: Avoid BUG-ing from the host abort path Fuad Tabba
2024-04-08 7:44 ` Marc Zyngier
2024-04-08 13:48 ` Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 05/44] KVM: arm64: Check for PTE validity when checking for executable/cacheable Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 06/44] KVM: arm64: Avoid BBM when changing only s/w bits in Stage-2 PTE Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 07/44] KVM: arm64: Support TLB invalidation in guest context Fuad Tabba
2024-04-15 11:36 ` Marc Zyngier
2024-04-15 15:02 ` Fuad Tabba
2024-04-15 15:59 ` Marc Zyngier
2024-03-27 17:34 ` [PATCH v1 08/44] KVM: arm64: Simplify vgic-v3 hypercalls Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 09/44] KVM: arm64: Add is_pkvm_initialized() helper Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 10/44] KVM: arm64: Introduce predicates to check for protected state Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 11/44] KVM: arm64: Split up nvhe/fixed_config.h Fuad Tabba
2024-03-27 17:34 ` [PATCH v1 12/44] KVM: arm64: Move pstate reset value definitions to kvm_arm.h Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 13/44] KVM: arm64: Clarify rationale for ZCR_EL1 value restored on guest exit Fuad Tabba
2024-03-28 18:53 ` Mark Brown
2024-04-08 13:34 ` Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 14/44] KVM: arm64: Refactor calculating SVE state size to use helpers Fuad Tabba
2024-03-28 18:57 ` Mark Brown
2024-04-08 13:35 ` Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 15/44] KVM: arm64: Use active guest SVE vector length on guest restore Fuad Tabba
2024-03-28 19:17 ` Mark Brown
2024-04-09 9:34 ` Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 16/44] KVM: arm64: Do not map the host fpsimd state to hyp in pKVM Fuad Tabba
2024-03-28 19:20 ` Mark Brown
2024-03-27 17:35 ` [PATCH v1 17/44] KVM: arm64: Move some kvm_psci functions to a shared header Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 18/44] KVM: arm64: Refactor reset_mpidr() to extract its computation Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 19/44] KVM: arm64: Refactor kvm_vcpu_enable_ptrauth() for hyp use Fuad Tabba
2024-03-27 17:35 ` Fuad Tabba [this message]
2024-03-27 17:35 ` [PATCH v1 21/44] KVM: arm64: Add PC_UPDATE_REQ flags covering all PC updates Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 22/44] KVM: arm64: Add vcpu flag copy primitive Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 23/44] KVM: arm64: Introduce gfn_to_memslot_prot() Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 24/44] KVM: arm64: Do not use the hva in kvm_handle_guest_abort() Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 25/44] KVM: arm64: Introduce hyp_rwlock_t Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 26/44] KVM: arm64: Add atomics-based checking refcount implementation at EL2 Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 27/44] KVM: arm64: Use atomic refcount helpers for 'struct hyp_page::refcount' Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 28/44] KVM: arm64: Remove locking from EL2 allocation fast-paths Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 29/44] KVM: arm64: Reformat/beautify PTP hypercall documentation Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 30/44] KVM: arm64: Rename firmware pseudo-register documentation file Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 31/44] KVM: arm64: Document the KVM/arm64-specific calls in hypercalls.rst Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 32/44] KVM: arm64: Prevent kmemleak from accessing .hyp.data Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 33/44] KVM: arm64: Issue CMOs when tearing down guest s2 pages Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 34/44] KVM: arm64: Do not set the virtual timer offset for protected vCPUs Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 35/44] KVM: arm64: Fix comment for __pkvm_vcpu_init_traps() Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 36/44] KVM: arm64: Do not re-initialize the KVM lock Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 37/44] KVM: arm64: Check directly whether a vcpu is protected Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 38/44] KVM: arm64: Trap debug break and watch from guest Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 39/44] KVM: arm64: Restrict protected VM capabilities Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 40/44] KVM: arm64: Do not support MTE for protected VMs Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 41/44] KVM: arm64: Move pkvm_vcpu_init_traps() to hyp vcpu init Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 42/44] KVM: arm64: Fix initializing traps in protected mode Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 43/44] KVM: arm64: Advertise GICv3 sysreg interface to protected guests Fuad Tabba
2024-03-27 17:35 ` [PATCH v1 44/44] KVM: arm64: Force injection of a data abort on NISV MMIO exit Fuad Tabba
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=20240327173531.1379685-21-tabba@google.com \
--to=tabba@google.com \
--cc=alexandru.elisei@arm.com \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=james.morse@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=philmd@linaro.org \
--cc=qperret@google.com \
--cc=rananta@google.com \
--cc=seanjc@google.com \
--cc=suzuki.poulose@arm.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