Linux KVM/arm64 development list
 help / color / mirror / Atom feed
* [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2
@ 2025-09-17 20:31 Oliver Upton
  2025-09-17 20:31 ` [PATCH 1/2] KVM: arm64: nv: Trap debug registers when in hyp context Oliver Upton
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Oliver Upton @ 2025-09-17 20:31 UTC (permalink / raw)
  To: kvmarm; +Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Oliver Upton

As I was working on EL2 support for KVM selftests I realized that use of
self-hosted debug inside of the VM is completely broken. Further
inspection reveals yet another case where FEAT_NV2 does something
insane -- MDSCR_EL1 is redirected to the VNCR page in spite of affecting
the EL2 context.

The situation can be remedied with traps. And after implementing that it
became clear we make no effort of honoring the guest's MDCR traps.
Whoops.

Small series to tidy both of these issues up. While FEAT_FGT provides a
precise trap for MDSCR_EL1, I don't have access to such a system and
would rather send something out that works for now. We can worry about
making this fast later.

Applies to 6.17-rc4.

Oliver Upton (2):
  KVM: arm64: nv: Trap debug registers when in hyp context
  KVM: arm64: nv: Apply guest's MDCR traps in nested context

 arch/arm64/include/asm/kvm_nested.h |  2 ++
 arch/arm64/kvm/debug.c              |  3 +++
 arch/arm64/kvm/nested.c             | 30 +++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)


base-commit: b320789d6883cc00ac78ce83bccbfe7ed58afcf0
-- 
2.47.3


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] KVM: arm64: nv: Trap debug registers when in hyp context
  2025-09-17 20:31 [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2 Oliver Upton
@ 2025-09-17 20:31 ` Oliver Upton
  2025-09-17 20:31 ` [PATCH 2/2] KVM: arm64: nv: Apply guest's MDCR traps in nested context Oliver Upton
  2025-09-18 15:49 ` [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2 Marc Zyngier
  2 siblings, 0 replies; 4+ messages in thread
From: Oliver Upton @ 2025-09-17 20:31 UTC (permalink / raw)
  To: kvmarm; +Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Oliver Upton

In case you haven't realized it yet, the architecture is _slightly_
broken in the context of nested virt. Here we have another example of
FEAT_NV2 redirecting a sysreg (MDSCR_EL1) to memory that actually
affects execution at vEL2.

Fortunately, MDCR_EL2.TDA provides the necessary traps to hide this
mess at the expense of unnecessarily trapping the breakpoint/watchpoint
registers. Yes, FEAT_FGT gives us a precise trap but let's just opt for
obvious correctness to start.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
 arch/arm64/include/asm/kvm_nested.h |  2 ++
 arch/arm64/kvm/debug.c              |  3 +++
 arch/arm64/kvm/nested.c             | 11 +++++++++++
 3 files changed, 16 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 7fd76f41c296..cd3ab06abdca 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -83,6 +83,8 @@ extern void check_nested_vcpu_requests(struct kvm_vcpu *vcpu);
 extern void kvm_nested_flush_hwstate(struct kvm_vcpu *vcpu);
 extern void kvm_nested_sync_hwstate(struct kvm_vcpu *vcpu);
 
+extern void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu);
+
 struct kvm_s2_trans {
 	phys_addr_t output;
 	unsigned long block_size;
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 381382c19fe4..fc275335c0ee 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -56,6 +56,9 @@ static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
 	if (!kvm_guest_owns_debug_regs(vcpu))
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
+	if (vcpu_has_nv(vcpu))
+		kvm_nested_setup_mdcr_el2(vcpu);
+
 	/* Write MDCR_EL2 directly if we're already at EL2 */
 	if (has_vhe())
 		write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 77db81bae86f..9559c64e7e0c 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1796,3 +1796,14 @@ void kvm_nested_sync_hwstate(struct kvm_vcpu *vcpu)
 	if (unlikely(vcpu_test_and_clear_flag(vcpu, NESTED_SERROR_PENDING)))
 		kvm_inject_serror_esr(vcpu, vcpu_get_vsesr(vcpu));
 }
+
+void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * In yet another example where FEAT_NV2 is fscking broken, accesses
+	 * to MDSCR_EL1 are redirected to the VNCR despite having an effect
+	 * at EL2. Use a big hammer to apply sanity.
+	 */
+	if (is_hyp_ctxt(vcpu))
+		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+}
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] KVM: arm64: nv: Apply guest's MDCR traps in nested context
  2025-09-17 20:31 [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2 Oliver Upton
  2025-09-17 20:31 ` [PATCH 1/2] KVM: arm64: nv: Trap debug registers when in hyp context Oliver Upton
@ 2025-09-17 20:31 ` Oliver Upton
  2025-09-18 15:49 ` [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2 Marc Zyngier
  2 siblings, 0 replies; 4+ messages in thread
From: Oliver Upton @ 2025-09-17 20:31 UTC (permalink / raw)
  To: kvmarm; +Cc: Marc Zyngier, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Oliver Upton

KVM needs to ensure the guest hypervisor's traps take effect when the
vCPU is in a nested context. While supporting infrastructure is in place
for most of the EL2 trap registers, MDCR_EL2 is not.

Fold the guest's trap configuration into the effective MDCR_EL2. Apply
it directly to the in-memory representation as it gets recomputed on
every vcpu_load() anyway.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
 arch/arm64/kvm/nested.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 9559c64e7e0c..61542d6fd8f5 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1797,8 +1797,25 @@ void kvm_nested_sync_hwstate(struct kvm_vcpu *vcpu)
 		kvm_inject_serror_esr(vcpu, vcpu_get_vsesr(vcpu));
 }
 
+/*
+ * KVM unconditionally sets most of these traps anyway but use an allowlist
+ * to document the guest hypervisor traps that may take precedence and guard
+ * against future changes to the non-nested trap configuration.
+ */
+#define NV_MDCR_GUEST_INCLUDE	(MDCR_EL2_TDE	|	\
+				 MDCR_EL2_TDA	|	\
+				 MDCR_EL2_TDRA	|	\
+				 MDCR_EL2_TTRF	|	\
+				 MDCR_EL2_TPMS	|	\
+				 MDCR_EL2_TPM	|	\
+				 MDCR_EL2_TPMCR	|	\
+				 MDCR_EL2_TDCC	|	\
+				 MDCR_EL2_TDOSA)
+
 void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu)
 {
+	u64 guest_mdcr = __vcpu_sys_reg(vcpu, MDCR_EL2);
+
 	/*
 	 * In yet another example where FEAT_NV2 is fscking broken, accesses
 	 * to MDSCR_EL1 are redirected to the VNCR despite having an effect
@@ -1806,4 +1823,6 @@ void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu)
 	 */
 	if (is_hyp_ctxt(vcpu))
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+	else
+		vcpu->arch.mdcr_el2 |= (guest_mdcr & NV_MDCR_GUEST_INCLUDE);
 }
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2
  2025-09-17 20:31 [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2 Oliver Upton
  2025-09-17 20:31 ` [PATCH 1/2] KVM: arm64: nv: Trap debug registers when in hyp context Oliver Upton
  2025-09-17 20:31 ` [PATCH 2/2] KVM: arm64: nv: Apply guest's MDCR traps in nested context Oliver Upton
@ 2025-09-18 15:49 ` Marc Zyngier
  2 siblings, 0 replies; 4+ messages in thread
From: Marc Zyngier @ 2025-09-18 15:49 UTC (permalink / raw)
  To: kvmarm, Oliver Upton; +Cc: Joey Gouly, Suzuki K Poulose, Zenghui Yu

On Wed, 17 Sep 2025 13:31:23 -0700, Oliver Upton wrote:
> As I was working on EL2 support for KVM selftests I realized that use of
> self-hosted debug inside of the VM is completely broken. Further
> inspection reveals yet another case where FEAT_NV2 does something
> insane -- MDSCR_EL1 is redirected to the VNCR page in spite of affecting
> the EL2 context.
> 
> The situation can be remedied with traps. And after implementing that it
> became clear we make no effort of honoring the guest's MDCR traps.
> Whoops.
> 
> [...]

Applied to next, thanks!

[1/2] KVM: arm64: nv: Trap debug registers when in hyp context
      commit: 4a684088421d5a1ffb3b13243c58a9078c99e4b9
[2/2] KVM: arm64: nv: Apply guest's MDCR traps in nested context
      commit: 3af1105c4fa362d17d577b55d2b8a7c4609f16fc

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-09-18 15:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-17 20:31 [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2 Oliver Upton
2025-09-17 20:31 ` [PATCH 1/2] KVM: arm64: nv: Trap debug registers when in hyp context Oliver Upton
2025-09-17 20:31 ` [PATCH 2/2] KVM: arm64: nv: Apply guest's MDCR traps in nested context Oliver Upton
2025-09-18 15:49 ` [PATCH 0/2] KVM: arm64: nv: Fixes for handling debug, MDCR_EL2 Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox