From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
kvm@vger.kernel.org
Cc: James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Oliver Upton <oliver.upton@linux.dev>,
Zenghui Yu <yuzenghui@huawei.com>,
Joey Gouly <joey.gouly@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>
Subject: [PATCH 01/10] KVM: arm64: nv: Handle CNTHCTL_EL2 specially
Date: Tue, 13 Aug 2024 15:47:29 +0100 [thread overview]
Message-ID: <20240813144738.2048302-2-maz@kernel.org> (raw)
In-Reply-To: <20240813144738.2048302-1-maz@kernel.org>
Accessing CNTHCTL_EL2 is fraught with danger if running with
HCR_EL2.E2H=1: half of the bits are held in CNTKCTL_EL1, and
thus can be changed behind our back, while the rest lives
in the CNTHCTL_EL2 shadow copy that is memory-based.
Yes, this is a lot of fun!
Make sure that we merge the two on read access, while we can
write to CNTKCTL_EL1 in a more straightforward manner.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/sys_regs.c | 28 ++++++++++++++++++++++++++++
include/kvm/arm_arch_timer.h | 3 +++
2 files changed, 31 insertions(+)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index c90324060436..95832881fd66 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -140,6 +140,21 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
if (!is_hyp_ctxt(vcpu))
goto memory_read;
+ /*
+ * CNTHCTL_EL2 requires some special treatment to
+ * account for the bits that can be set via CNTKCTL_EL1.
+ */
+ switch (reg) {
+ case CNTHCTL_EL2:
+ if (vcpu_el2_e2h_is_set(vcpu)) {
+ val = read_sysreg_el1(SYS_CNTKCTL);
+ val &= CNTKCTL_VALID_BITS;
+ val |= __vcpu_sys_reg(vcpu, reg) & ~CNTKCTL_VALID_BITS;
+ return val;
+ }
+ break;
+ }
+
/*
* If this register does not have an EL1 counterpart,
* then read the stored EL2 version.
@@ -190,6 +205,19 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
*/
__vcpu_sys_reg(vcpu, reg) = val;
+ switch (reg) {
+ case CNTHCTL_EL2:
+ /*
+ * If E2H=0, CNHTCTL_EL2 is a pure shadow register.
+ * Otherwise, some of the bits are backed by
+ * CNTKCTL_EL1, while the rest is kept in memory.
+ * Yes, this is fun stuff.
+ */
+ if (vcpu_el2_e2h_is_set(vcpu))
+ write_sysreg_el1(val, SYS_CNTKCTL);
+ return;
+ }
+
/* No EL1 counterpart? We're done here.? */
if (reg == el1r)
return;
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index c819c5d16613..fd650a8789b9 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -147,6 +147,9 @@ u64 timer_get_cval(struct arch_timer_context *ctxt);
void kvm_timer_cpu_up(void);
void kvm_timer_cpu_down(void);
+/* CNTKCTL_EL1 valid bits as of DDI0487J.a */
+#define CNTKCTL_VALID_BITS (BIT(17) | GENMASK_ULL(9, 0))
+
static inline bool has_cntpoff(void)
{
return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
--
2.39.2
next prev parent reply other threads:[~2024-08-13 14:47 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
2024-08-13 14:47 ` Marc Zyngier [this message]
2024-08-13 14:47 ` [PATCH 02/10] KVM: arm64: nv: Save/Restore vEL2 sysregs Marc Zyngier
2024-08-13 14:47 ` [PATCH 03/10] KVM: arm64: Add TCR2_EL2 to the sysreg arrays Marc Zyngier
2024-08-13 15:03 ` Joey Gouly
2024-08-13 14:47 ` [PATCH 04/10] KVM: arm64: Add save/restore for TCR2_EL2 Marc Zyngier
2024-08-13 14:47 ` [PATCH 05/10] arm64: Add encoding for PIRE0_EL2 Marc Zyngier
2024-08-13 15:06 ` Joey Gouly
2024-08-13 14:47 ` [PATCH 06/10] arm64: Remove VNCR definition " Marc Zyngier
2024-08-13 15:10 ` Joey Gouly
2024-08-13 14:47 ` [PATCH 07/10] KVM: arm64: Add PIR{,E0}_EL2 to the sysreg arrays Marc Zyngier
2024-08-13 14:47 ` [PATCH 08/10] KVM: arm64: Add save/restore for PIR{,E0}_EL2 Marc Zyngier
2024-08-13 14:47 ` [PATCH 09/10] KVM: arm64: Handle PIR{,E0}_EL2 traps Marc Zyngier
2024-08-13 15:24 ` Joey Gouly
2024-08-13 15:45 ` Marc Zyngier
2024-08-13 16:19 ` Joey Gouly
2024-08-13 14:47 ` [PATCH 10/10] KVM: arm64: Sanitise ID_AA64MMFR3_EL1 Marc Zyngier
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=20240813144738.2048302-2-maz@kernel.org \
--to=maz@kernel.org \
--cc=alexandru.elisei@arm.com \
--cc=james.morse@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=oliver.upton@linux.dev \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@huawei.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.