From: Marc Zyngier <maz@kernel.org>
To: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Cc: Alexandru Elisei <alexandru.elisei@arm.com>,
Andre Przywara <andre.przywara@arm.com>,
Chase Conklin <chase.conklin@arm.com>,
Christoffer Dall <christoffer.dall@arm.com>,
Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>,
Jintack Lim <jintack@cs.columbia.edu>,
Russell King <rmk+kernel@armlinux.org.uk>,
James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Oliver Upton <oliver.upton@linux.dev>,
Zenghui Yu <yuzenghui@huawei.com>
Subject: [PATCH v7 67/68] KVM: arm64: nv: Use FEAT_ECV to trap access to EL0 timers
Date: Thu, 12 Jan 2023 19:19:26 +0000 [thread overview]
Message-ID: <20230112191927.1814989-68-maz@kernel.org> (raw)
In-Reply-To: <20230112191927.1814989-1-maz@kernel.org>
Although FEAT_NV2 makes most things fast, it also makes it impossible
to correctly emulate the timers, as the sysreg accesses are redirected
to memory.
FEAT_ECV addresses this by giving a hypervisor the ability to trap
the EL02 sysregs as well as the virtual timer.
Add the required trap setting to make use of the feature, allowing
us to elide the ugly resync in the middle of the run loop.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/arch_timer.c | 54 +++++++++++++++++++++++++++-
include/clocksource/arm_arch_timer.h | 4 +++
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 71d2f1902de9..6295883f4223 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -740,6 +740,44 @@ static void kvm_timer_vcpu_load_nested_switch(struct kvm_vcpu *vcpu,
WARN_ON_ONCE(ret);
}
+ /*
+ * NV2 badly breaks the timer semantics by redirecting accesses to
+ * the EL0 timer state to memory, so let's call ECV to the rescue if
+ * available: we trap all CNT{P,V}_{CTL,CVAL,TVAL}_EL0 accesses.
+ *
+ * The treatment slightly varies depending whether we run a nVHE or
+ * VHE guest: nVHE will use the _EL0 registers directly, while VHE
+ * will use the _EL02 accessors. This translates in different trap
+ * bits.
+ *
+ * None of the trapping is engaged when running in non-HYP context,
+ * unless required by the L1 hypervisor settings once we advertise
+ * ECV+NV in the guest.
+ */
+ if (vcpu_has_nv2(vcpu) && cpus_have_const_cap(ARM64_HAS_ECV)) {
+ u64 clr = 0, set = 0;
+
+ if (vcpu_el2_e2h_is_set(vcpu)) {
+ set |= CNTHCTL_EL1NVVCT | CNTHCTL_EL1NVPCT;
+ } else {
+ /*
+ * Only trap the timers, not the counters, as they
+ * are in the "direct" state for nVHE.
+ */
+ clr |= CNTHCTL_EL1PCEN << 10;
+ set |= CNTHCTL_EL1TVT;
+ }
+
+ /*
+ * Apply these values for HYP context, and reverse them
+ * otherwise
+ */
+ if (is_hyp_ctxt(vcpu))
+ sysreg_clear_set(cntkctl_el1, clr, set);
+ else
+ sysreg_clear_set(cntkctl_el1, set, clr);
+ }
+
/*
* Apply the trapping bits that the guest hypervisor has
* requested for its own guest.
@@ -838,6 +876,16 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
if (kvm_vcpu_is_blocking(vcpu))
kvm_timer_blocking(vcpu);
+
+ /*
+ * Restore the standard, non-nested configuration so that we're
+ * ready to run a non-NV vcpu.
+ */
+ if (vcpu_has_nv2(vcpu))
+ sysreg_clear_set(cntkctl_el1,
+ (CNTHCTL_EL1NVPCT | CNTHCTL_EL1NVVCT |
+ CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT),
+ (CNTHCTL_EL1PCEN | CNTHCTL_EL1PCTEN) << 10);
}
void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
@@ -847,8 +895,12 @@ void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
* accesses redirected to the VNCR page. Any guest action taken on
* the timer is postponed until the next exit, leading to a very
* poor quality of emulation.
+ *
+ * This is an unmitigated disaster, only papered over by FEAT_ECV,
+ * which allows trapping of the timer registers even with NV2.
+ * Still, this is still worse than FEAT_NV on its own. Meh.
*/
- if (!is_hyp_ctxt(vcpu))
+ if (cpus_have_const_cap(ARM64_HAS_ECV) || !is_hyp_ctxt(vcpu))
return;
if (!vcpu_el2_e2h_is_set(vcpu)) {
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 057c8964aefb..e3c3816d19ba 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -21,6 +21,10 @@
#define CNTHCTL_EVNTEN (1 << 2)
#define CNTHCTL_EVNTDIR (1 << 3)
#define CNTHCTL_EVNTI (0xF << 4)
+#define CNTHCTL_EL1TVT (1 << 13)
+#define CNTHCTL_EL1TVCT (1 << 14)
+#define CNTHCTL_EL1NVPCT (1 << 15)
+#define CNTHCTL_EL1NVVCT (1 << 16)
enum arch_timer_reg {
ARCH_TIMER_REG_CTRL,
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-01-12 19:32 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-12 19:18 [PATCH v7 00/68] KVM: arm64: ARMv8.3/8.4 Nested Virtualization support Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 01/68] arm64: Add ARM64_HAS_NESTED_VIRT cpufeature Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 02/68] KVM: arm64: nv: Introduce nested virtualization VCPU feature Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 03/68] KVM: arm64: nv: Reset VCPU to EL2 registers if VCPU nested virt is set Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 04/68] KVM: arm64: nv: Allow userspace to set PSR_MODE_EL2x Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 05/68] KVM: arm64: nv: Add EL2 system registers to vcpu context Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 06/68] KVM: arm64: nv: Add nested virt VCPU primitives for vEL2 VCPU state Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 07/68] KVM: arm64: nv: Handle HCR_EL2.NV system register traps Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 08/68] KVM: arm64: nv: Reset VMPIDR_EL2 and VPIDR_EL2 to sane values Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 09/68] KVM: arm64: nv: Support virtual EL2 exceptions Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 10/68] KVM: arm64: nv: Inject HVC exceptions to the virtual EL2 Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 11/68] KVM: arm64: nv: Handle trapped ERET from " Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 12/68] KVM: arm64: nv: Add non-VHE-EL2->EL1 translation helpers Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 13/68] KVM: arm64: nv: Handle virtual EL2 registers in vcpu_read/write_sys_reg() Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 14/68] KVM: arm64: nv: Handle SPSR_EL2 specially Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 15/68] KVM: arm64: nv: Handle HCR_EL2.E2H specially Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 16/68] KVM: arm64: nv: Save/Restore vEL2 sysregs Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 17/68] KVM: arm64: nv: Emulate PSTATE.M for a guest hypervisor Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 18/68] KVM: arm64: nv: Trap EL1 VM register accesses in virtual EL2 Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 19/68] KVM: arm64: nv: Add accessors for SPSR_EL1, ELR_EL1 and VBAR_EL1 from " Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 20/68] KVM: arm64: nv: Trap CPACR_EL1 access in " Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 21/68] KVM: arm64: nv: Handle PSCI call via smc from the guest Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 22/68] KVM: arm64: nv: Respect virtual HCR_EL2.TWX setting Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 23/68] KVM: arm64: nv: Respect virtual CPTR_EL2.{TFP,FPEN} settings Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 24/68] KVM: arm64: nv: Respect the virtual HCR_EL2.NV bit setting Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 25/68] KVM: arm64: nv: Respect virtual HCR_EL2.TVM and TRVM settings Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 26/68] KVM: arm64: nv: Respect the virtual HCR_EL2.NV1 bit setting Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 27/68] KVM: arm64: nv: Allow a sysreg to be hidden from userspace only Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 28/68] KVM: arm64: nv: Emulate EL12 register accesses from the virtual EL2 Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 29/68] KVM: arm64: nv: Forward debug traps to the nested guest Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 30/68] KVM: arm64: nv: Configure HCR_EL2 for nested virtualization Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 31/68] KVM: arm64: nv: Only toggle cache for virtual EL2 when SCTLR_EL2 changes Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 32/68] KVM: arm64: nv: Filter out unsupported features from ID regs Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 33/68] KVM: arm64: nv: Hide RAS from nested guests Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 34/68] KVM: arm64: nv: Support multiple nested Stage-2 mmu structures Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 35/68] KVM: arm64: nv: Implement nested Stage-2 page table walk logic Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 36/68] KVM: arm64: nv: Handle shadow stage 2 page faults Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 37/68] KVM: arm64: nv: Restrict S2 RD/WR permissions to match the guest's Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 38/68] KVM: arm64: nv: Unmap/flush shadow stage 2 page tables Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 39/68] KVM: arm64: nv: Set a handler for the system instruction traps Marc Zyngier
2023-01-12 19:18 ` [PATCH v7 40/68] KVM: arm64: nv: Trap and emulate AT instructions from virtual EL2 Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 41/68] KVM: arm64: nv: Trap and emulate TLBI " Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 42/68] KVM: arm64: nv: Fold guest's HCR_EL2 configuration into the host's Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 43/68] KVM: arm64: nv: arch_timer: Support hyp timer emulation Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 44/68] KVM: arm64: nv: Add handling of EL2-specific timer registers Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 45/68] KVM: arm64: nv: Load timer before the GIC Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 46/68] KVM: arm64: nv: Nested GICv3 Support Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 47/68] KVM: arm64: nv: Don't load the GICv4 context on entering a nested guest Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 48/68] KVM: arm64: nv: vgic: Emulate the HW bit in software Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 49/68] KVM: arm64: nv: vgic: Allow userland to set VGIC maintenance IRQ Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 50/68] KVM: arm64: nv: Implement maintenance interrupt forwarding Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 51/68] KVM: arm64: nv: Deal with broken VGIC on maintenance interrupt delivery Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 52/68] KVM: arm64: nv: Add nested GICv3 tracepoints Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 53/68] KVM: arm64: nv: Allow userspace to request KVM_ARM_VCPU_NESTED_VIRT Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 54/68] KVM: arm64: nv: Add handling of FEAT_TTL TLB invalidation Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 55/68] KVM: arm64: nv: Invalidate TLBs based on shadow S2 TTL-like information Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 56/68] KVM: arm64: nv: Tag shadow S2 entries with nested level Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 57/68] KVM: arm64: nv: Add include containing the VNCR_EL2 offsets Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 58/68] KVM: arm64: nv: Map VNCR-capable registers to a separate page Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 59/68] KVM: arm64: nv: Move nested vgic state into the sysreg file Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 60/68] KVM: arm64: Add FEAT_NV2 cpu feature Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 61/68] KVM: arm64: nv: Sync nested timer state with FEAT_NV2 Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 62/68] KVM: arm64: nv: Publish emulated timer interrupt state in the in-memory state Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 63/68] KVM: arm64: nv: Allocate VNCR page when required Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 64/68] KVM: arm64: nv: Enable ARMv8.4-NV support Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 65/68] KVM: arm64: nv: Fast-track 'InHost' exception returns Marc Zyngier
2023-01-12 19:19 ` [PATCH v7 66/68] KVM: arm64: nv: Fast-track EL1 TLBIs for VHE guests Marc Zyngier
2023-01-12 19:19 ` Marc Zyngier [this message]
2023-01-12 19:19 ` [PATCH v7 68/68] KVM: arm64: nv: Accelerate EL0 timer read accesses when FEAT_ECV is on 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=20230112191927.1814989-68-maz@kernel.org \
--to=maz@kernel.org \
--cc=alexandru.elisei@arm.com \
--cc=andre.przywara@arm.com \
--cc=chase.conklin@arm.com \
--cc=christoffer.dall@arm.com \
--cc=gankulkarni@os.amperecomputing.com \
--cc=james.morse@arm.com \
--cc=jintack@cs.columbia.edu \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=oliver.upton@linux.dev \
--cc=rmk+kernel@armlinux.org.uk \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).