linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE
@ 2024-08-13 14:47 Marc Zyngier
  2024-08-13 14:47 ` [PATCH 01/10] KVM: arm64: nv: Handle CNTHCTL_EL2 specially Marc Zyngier
                   ` (9 more replies)
  0 siblings, 10 replies; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

This series serves a few purposes:

- Complete the S1PIE support to include EL2
- Sneak in the EL2 system register world switch

As this is a parallel series to the one implementing Address
Translation, the S1PIE part of AT is not in any of the two. Depending
on which series goes in first, I'll add whatever is needed on top.

As mentioned in few of the patches, this implementation relies on a
very recent fix to the architecture (D22677 in [1]).

[1] https://developer.arm.com/documentation/102105/ka-04/

Marc Zyngier (10):
  KVM: arm64: nv: Handle CNTHCTL_EL2 specially
  KVM: arm64: nv: Save/Restore vEL2 sysregs
  KVM: arm64: Add TCR2_EL2 to the sysreg arrays
  KVM: arm64: Add save/restore for TCR2_EL2
  arm64: Add encoding for PIRE0_EL2
  arm64: Remove VNCR definition for PIRE0_EL2
  KVM: arm64: Add PIR{,E0}_EL2 to the sysreg arrays
  KVM: arm64: Add save/restore for PIR{,E0}_EL2
  KVM: arm64: Handle  PIR{,E0}_EL2 traps
  KVM: arm64: Sanitise ID_AA64MMFR3_EL1

 arch/arm64/include/asm/kvm_host.h          |   3 +
 arch/arm64/include/asm/vncr_mapping.h      |   1 -
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h |   5 +-
 arch/arm64/kvm/hyp/nvhe/sysreg-sr.c        |   2 +-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c         | 155 ++++++++++++++++++++-
 arch/arm64/kvm/sys_regs.c                  |  61 +++++++-
 arch/arm64/tools/sysreg                    |   4 +
 include/kvm/arm_arch_timer.h               |   3 +
 8 files changed, 227 insertions(+), 7 deletions(-)

-- 
2.39.2



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

* [PATCH 01/10] KVM: arm64: nv: Handle CNTHCTL_EL2 specially
  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
  2024-08-13 14:47 ` [PATCH 02/10] KVM: arm64: nv: Save/Restore vEL2 sysregs Marc Zyngier
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

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



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

* [PATCH 02/10] KVM: arm64: nv: Save/Restore vEL2 sysregs
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
  2024-08-13 14:47 ` [PATCH 01/10] KVM: arm64: nv: Handle CNTHCTL_EL2 specially Marc Zyngier
@ 2024-08-13 14:47 ` Marc Zyngier
  2024-08-13 14:47 ` [PATCH 03/10] KVM: arm64: Add TCR2_EL2 to the sysreg arrays Marc Zyngier
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

Whenever we need to restore the guest's system registers to the CPU, we
now need to take care of the EL2 system registers as well. Most of them
are accessed via traps only, but some have an immediate effect and also
a guest running in VHE mode would expect them to be accessible via their
EL1 encoding, which we do not trap.

For vEL2 we write the virtual EL2 registers with an identical format directly
into their EL1 counterpart, and translate the few registers that have a
different format for the same effect on the execution when running a
non-VHE guest guest hypervisor.

Based on an initial patch from Andre Przywara, rewritten many times
since.

Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h |   5 +-
 arch/arm64/kvm/hyp/nvhe/sysreg-sr.c        |   2 +-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c         | 137 ++++++++++++++++++++-
 3 files changed, 139 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index 4c0fdabaf8ae..dfbc0159bf0b 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -128,9 +128,10 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt)
 	write_sysreg(ctxt_sys_reg(ctxt, TPIDRRO_EL0),	tpidrro_el0);
 }
 
-static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
+static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,
+					      u64 mpidr)
 {
-	write_sysreg(ctxt_sys_reg(ctxt, MPIDR_EL1),	vmpidr_el2);
+	write_sysreg(mpidr,				vmpidr_el2);
 
 	if (has_vhe() ||
 	    !cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
diff --git a/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c b/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c
index 29305022bc04..dba101565de3 100644
--- a/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c
@@ -28,7 +28,7 @@ void __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt)
 
 void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt)
 {
-	__sysreg_restore_el1_state(ctxt);
+	__sysreg_restore_el1_state(ctxt, ctxt_sys_reg(ctxt, MPIDR_EL1));
 	__sysreg_restore_common_state(ctxt);
 	__sysreg_restore_user_state(ctxt);
 	__sysreg_restore_el2_return_state(ctxt);
diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index e12bd7d6d2dc..6db5b4d0f3a4 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -15,6 +15,108 @@
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_nested.h>
 
+static void __sysreg_save_vel2_state(struct kvm_cpu_context *ctxt)
+{
+	/* These registers are common with EL1 */
+	ctxt_sys_reg(ctxt, PAR_EL1)	= read_sysreg(par_el1);
+	ctxt_sys_reg(ctxt, TPIDR_EL1)	= read_sysreg(tpidr_el1);
+
+	ctxt_sys_reg(ctxt, ESR_EL2)	= read_sysreg_el1(SYS_ESR);
+	ctxt_sys_reg(ctxt, AFSR0_EL2)	= read_sysreg_el1(SYS_AFSR0);
+	ctxt_sys_reg(ctxt, AFSR1_EL2)	= read_sysreg_el1(SYS_AFSR1);
+	ctxt_sys_reg(ctxt, FAR_EL2)	= read_sysreg_el1(SYS_FAR);
+	ctxt_sys_reg(ctxt, MAIR_EL2)	= read_sysreg_el1(SYS_MAIR);
+	ctxt_sys_reg(ctxt, VBAR_EL2)	= read_sysreg_el1(SYS_VBAR);
+	ctxt_sys_reg(ctxt, CONTEXTIDR_EL2) = read_sysreg_el1(SYS_CONTEXTIDR);
+	ctxt_sys_reg(ctxt, AMAIR_EL2)	= read_sysreg_el1(SYS_AMAIR);
+
+	/*
+	 * In VHE mode those registers are compatible between EL1 and EL2,
+	 * and the guest uses the _EL1 versions on the CPU naturally.
+	 * So we save them into their _EL2 versions here.
+	 * For nVHE mode we trap accesses to those registers, so our
+	 * _EL2 copy in sys_regs[] is always up-to-date and we don't need
+	 * to save anything here.
+	 */
+	if (__vcpu_el2_e2h_is_set(ctxt)) {
+		u64 val;
+
+		/*
+		 * We don't save CPTR_EL2, as accesses to CPACR_EL1
+		 * are always trapped, ensuring that the in-memory
+		 * copy is always up-to-date. A small blessing...
+		 */
+		ctxt_sys_reg(ctxt, SCTLR_EL2)	= read_sysreg_el1(SYS_SCTLR);
+		ctxt_sys_reg(ctxt, TTBR0_EL2)	= read_sysreg_el1(SYS_TTBR0);
+		ctxt_sys_reg(ctxt, TTBR1_EL2)	= read_sysreg_el1(SYS_TTBR1);
+		ctxt_sys_reg(ctxt, TCR_EL2)	= read_sysreg_el1(SYS_TCR);
+
+		/*
+		 * The EL1 view of CNTKCTL_EL1 has a bunch of RES0 bits where
+		 * the interesting CNTHCTL_EL2 bits live. So preserve these
+		 * bits when reading back the guest-visible value.
+		 */
+		val = read_sysreg_el1(SYS_CNTKCTL);
+		val &= CNTKCTL_VALID_BITS;
+		ctxt_sys_reg(ctxt, CNTHCTL_EL2) &= ~CNTKCTL_VALID_BITS;
+		ctxt_sys_reg(ctxt, CNTHCTL_EL2) |= val;
+	}
+
+	ctxt_sys_reg(ctxt, SP_EL2)	= read_sysreg(sp_el1);
+	ctxt_sys_reg(ctxt, ELR_EL2)	= read_sysreg_el1(SYS_ELR);
+	ctxt_sys_reg(ctxt, SPSR_EL2)	= read_sysreg_el1(SYS_SPSR);
+}
+
+static void __sysreg_restore_vel2_state(struct kvm_cpu_context *ctxt)
+{
+	u64 val;
+
+	/* These registers are common with EL1 */
+	write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1),	par_el1);
+	write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1),	tpidr_el1);
+
+	write_sysreg(read_cpuid_id(),			vpidr_el2);
+	write_sysreg(ctxt_sys_reg(ctxt, MPIDR_EL1),	vmpidr_el2);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, MAIR_EL2),	SYS_MAIR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, VBAR_EL2),	SYS_VBAR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, CONTEXTIDR_EL2),SYS_CONTEXTIDR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, AMAIR_EL2),	SYS_AMAIR);
+
+	if (__vcpu_el2_e2h_is_set(ctxt)) {
+		/*
+		 * In VHE mode those registers are compatible between
+		 * EL1 and EL2.
+		 */
+		write_sysreg_el1(ctxt_sys_reg(ctxt, SCTLR_EL2),	SYS_SCTLR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, CPTR_EL2),	SYS_CPACR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL2),	SYS_TTBR0);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR1_EL2),	SYS_TTBR1);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TCR_EL2),	SYS_TCR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, CNTHCTL_EL2), SYS_CNTKCTL);
+	} else {
+		/*
+		 * CNTHCTL_EL2 only affects EL1 when running nVHE, so
+		 * no need to restore it.
+		 */
+		val = translate_sctlr_el2_to_sctlr_el1(ctxt_sys_reg(ctxt, SCTLR_EL2));
+		write_sysreg_el1(val, SYS_SCTLR);
+		val = translate_cptr_el2_to_cpacr_el1(ctxt_sys_reg(ctxt, CPTR_EL2));
+		write_sysreg_el1(val, SYS_CPACR);
+		val = translate_ttbr0_el2_to_ttbr0_el1(ctxt_sys_reg(ctxt, TTBR0_EL2));
+		write_sysreg_el1(val, SYS_TTBR0);
+		val = translate_tcr_el2_to_tcr_el1(ctxt_sys_reg(ctxt, TCR_EL2));
+		write_sysreg_el1(val, SYS_TCR);
+	}
+
+	write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL2),	SYS_ESR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL2),	SYS_AFSR0);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR1_EL2),	SYS_AFSR1);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, FAR_EL2),	SYS_FAR);
+	write_sysreg(ctxt_sys_reg(ctxt, SP_EL2),	sp_el1);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, ELR_EL2),	SYS_ELR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, SPSR_EL2),	SYS_SPSR);
+}
+
 /*
  * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and
  * pstate, which are handled as part of the el2 return state) on every
@@ -66,6 +168,7 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
 	struct kvm_cpu_context *host_ctxt;
+	u64 mpidr;
 
 	host_ctxt = host_data_ptr(host_ctxt);
 	__sysreg_save_user_state(host_ctxt);
@@ -89,7 +192,29 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
 	 */
 	__sysreg32_restore_state(vcpu);
 	__sysreg_restore_user_state(guest_ctxt);
-	__sysreg_restore_el1_state(guest_ctxt);
+
+	if (unlikely(__is_hyp_ctxt(guest_ctxt))) {
+		__sysreg_restore_vel2_state(guest_ctxt);
+	} else {
+		if (vcpu_has_nv(vcpu)) {
+			/*
+			 * Only set VPIDR_EL2 for nested VMs, as this is the
+			 * only time it changes. We'll restore the MIDR_EL1
+			 * view on put.
+			 */
+			write_sysreg(ctxt_sys_reg(guest_ctxt, VPIDR_EL2), vpidr_el2);
+
+			/*
+			 * As we're restoring a nested guest, set the value
+			 * provided by the guest hypervisor.
+			 */
+			mpidr = ctxt_sys_reg(guest_ctxt, VMPIDR_EL2);
+		} else {
+			mpidr = ctxt_sys_reg(guest_ctxt, MPIDR_EL1);
+		}
+
+		__sysreg_restore_el1_state(guest_ctxt, mpidr);
+	}
 
 	vcpu_set_flag(vcpu, SYSREGS_ON_CPU);
 }
@@ -112,12 +237,20 @@ void __vcpu_put_switch_sysregs(struct kvm_vcpu *vcpu)
 
 	host_ctxt = host_data_ptr(host_ctxt);
 
-	__sysreg_save_el1_state(guest_ctxt);
+	if (unlikely(__is_hyp_ctxt(guest_ctxt)))
+		__sysreg_save_vel2_state(guest_ctxt);
+	else
+		__sysreg_save_el1_state(guest_ctxt);
+
 	__sysreg_save_user_state(guest_ctxt);
 	__sysreg32_save_state(vcpu);
 
 	/* Restore host user state */
 	__sysreg_restore_user_state(host_ctxt);
 
+	/* If leaving a nesting guest, restore MPIDR_EL1 default view */
+	if (vcpu_has_nv(vcpu))
+		write_sysreg(read_cpuid_id(),	vpidr_el2);
+
 	vcpu_clear_flag(vcpu, SYSREGS_ON_CPU);
 }
-- 
2.39.2



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

* [PATCH 03/10] KVM: arm64: Add TCR2_EL2 to the sysreg arrays
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
  2024-08-13 14:47 ` [PATCH 01/10] KVM: arm64: nv: Handle CNTHCTL_EL2 specially Marc Zyngier
  2024-08-13 14:47 ` [PATCH 02/10] KVM: arm64: nv: Save/Restore vEL2 sysregs Marc Zyngier
@ 2024-08-13 14:47 ` 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
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

Add the TCR2_EL2 register to the per-vcpu sysreg register
array, as well as the sysreg descriptor array.

Access to this register is conditionned on ID_AA64MMFR3_EL1.TCRX
being advertised.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/sys_regs.c         | 13 +++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a33f5996ca9f..5a9e0ad35580 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -462,6 +462,7 @@ enum vcpu_sysreg {
 	TTBR0_EL2,	/* Translation Table Base Register 0 (EL2) */
 	TTBR1_EL2,	/* Translation Table Base Register 1 (EL2) */
 	TCR_EL2,	/* Translation Control Register (EL2) */
+	TCR2_EL2,	/* Extended Translation Control Register (EL2) */
 	SPSR_EL2,	/* EL2 saved program status register */
 	ELR_EL2,	/* EL2 exception link register */
 	AFSR0_EL2,	/* Auxiliary Fault Status Register 0 (EL2) */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 95832881fd66..52250db3c122 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -436,6 +436,18 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_tcr2_el2(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, TCRX, IMP)) {
+		kvm_inject_undefined(vcpu);
+		return false;
+	}
+
+	return access_rw(vcpu, p, r);
+}
+
 static bool access_actlr(struct kvm_vcpu *vcpu,
 			 struct sys_reg_params *p,
 			 const struct sys_reg_desc *r)
@@ -2783,6 +2795,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
 	EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
 	EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),
+	EL2_REG(TCR2_EL2, access_tcr2_el2, reset_val, TCR2_EL2_RES1),
 	EL2_REG_VNCR(VTTBR_EL2, reset_val, 0),
 	EL2_REG_VNCR(VTCR_EL2, reset_val, 0),
 
-- 
2.39.2



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

* [PATCH 04/10] KVM: arm64: Add save/restore for TCR2_EL2
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
                   ` (2 preceding siblings ...)
  2024-08-13 14:47 ` [PATCH 03/10] KVM: arm64: Add TCR2_EL2 to the sysreg arrays Marc Zyngier
@ 2024-08-13 14:47 ` Marc Zyngier
  2024-08-13 14:47 ` [PATCH 05/10] arm64: Add encoding for PIRE0_EL2 Marc Zyngier
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

Like its EL1 equivalent, TCR2_EL2 gets context-switched.
This is made conditional on FEAT_TCRX being adversised.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index 6db5b4d0f3a4..7099775cd505 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -51,6 +51,9 @@ static void __sysreg_save_vel2_state(struct kvm_cpu_context *ctxt)
 		ctxt_sys_reg(ctxt, TTBR1_EL2)	= read_sysreg_el1(SYS_TTBR1);
 		ctxt_sys_reg(ctxt, TCR_EL2)	= read_sysreg_el1(SYS_TCR);
 
+		if (ctxt_has_tcrx(ctxt))
+			ctxt_sys_reg(ctxt, TCR2_EL2) = read_sysreg_el1(SYS_TCR2);
+
 		/*
 		 * The EL1 view of CNTKCTL_EL1 has a bunch of RES0 bits where
 		 * the interesting CNTHCTL_EL2 bits live. So preserve these
@@ -108,6 +111,9 @@ static void __sysreg_restore_vel2_state(struct kvm_cpu_context *ctxt)
 		write_sysreg_el1(val, SYS_TCR);
 	}
 
+	if (ctxt_has_tcrx(ctxt))
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TCR2_EL2), SYS_TCR2);
+
 	write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL2),	SYS_ESR);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL2),	SYS_AFSR0);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR1_EL2),	SYS_AFSR1);
-- 
2.39.2



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

* [PATCH 05/10] arm64: Add encoding for PIRE0_EL2
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
                   ` (3 preceding siblings ...)
  2024-08-13 14:47 ` [PATCH 04/10] KVM: arm64: Add save/restore for TCR2_EL2 Marc Zyngier
@ 2024-08-13 14:47 ` Marc Zyngier
  2024-08-13 15:06   ` Joey Gouly
  2024-08-13 14:47 ` [PATCH 06/10] arm64: Remove VNCR definition " Marc Zyngier
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

PIRE0_EL2 is the equivalent of PIRE0_EL1 for the EL2&0 translation
regime, and it is sorely missing from the sysreg file.

Add the sucker.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/tools/sysreg | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 7ceaa1e0b4bc..8e1aed548e93 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2853,6 +2853,10 @@ Sysreg	PIRE0_EL12	3	5	10	2	2
 Fields	PIRx_ELx
 EndSysreg
 
+Sysreg	PIRE0_EL2	3	4	10	2	2
+Fields	PIRx_ELx
+EndSysreg
+
 Sysreg	PIR_EL1		3	0	10	2	3
 Fields	PIRx_ELx
 EndSysreg
-- 
2.39.2



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

* [PATCH 06/10] arm64: Remove VNCR definition for PIRE0_EL2
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
                   ` (4 preceding siblings ...)
  2024-08-13 14:47 ` [PATCH 05/10] arm64: Add encoding for PIRE0_EL2 Marc Zyngier
@ 2024-08-13 14:47 ` 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
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

As of the ARM ARM Known Issues document 102105_K.a_04_en, D22677
fixes a problem with the PIRE0_EL2 register, resulting in its
removal from the VNCR page (it had no purpose being there the
first place).

Follow the architecture update by removing this offset.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/vncr_mapping.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h
index df2c47c55972..9e593bb60975 100644
--- a/arch/arm64/include/asm/vncr_mapping.h
+++ b/arch/arm64/include/asm/vncr_mapping.h
@@ -50,7 +50,6 @@
 #define VNCR_VBAR_EL1           0x250
 #define VNCR_TCR2_EL1		0x270
 #define VNCR_PIRE0_EL1		0x290
-#define VNCR_PIRE0_EL2		0x298
 #define VNCR_PIR_EL1		0x2A0
 #define VNCR_ICH_LR0_EL2        0x400
 #define VNCR_ICH_LR1_EL2        0x408
-- 
2.39.2



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

* [PATCH 07/10] KVM: arm64: Add PIR{,E0}_EL2 to the sysreg arrays
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
                   ` (5 preceding siblings ...)
  2024-08-13 14:47 ` [PATCH 06/10] arm64: Remove VNCR definition " Marc Zyngier
@ 2024-08-13 14:47 ` Marc Zyngier
  2024-08-13 14:47 ` [PATCH 08/10] KVM: arm64: Add save/restore for PIR{,E0}_EL2 Marc Zyngier
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

Add the FEAT_S1PIE EL2 registers to the per-vcpu sysreg register
array.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5a9e0ad35580..ab4c675b491d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -463,6 +463,8 @@ enum vcpu_sysreg {
 	TTBR1_EL2,	/* Translation Table Base Register 1 (EL2) */
 	TCR_EL2,	/* Translation Control Register (EL2) */
 	TCR2_EL2,	/* Extended Translation Control Register (EL2) */
+	PIRE0_EL2,	/* Permission Indirection Register 0 (EL2) */
+	PIR_EL2,	/* Permission Indirection Register 1 (EL2) */
 	SPSR_EL2,	/* EL2 saved program status register */
 	ELR_EL2,	/* EL2 exception link register */
 	AFSR0_EL2,	/* Auxiliary Fault Status Register 0 (EL2) */
-- 
2.39.2



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

* [PATCH 08/10] KVM: arm64: Add save/restore for PIR{,E0}_EL2
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
                   ` (6 preceding siblings ...)
  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 ` Marc Zyngier
  2024-08-13 14:47 ` [PATCH 09/10] KVM: arm64: Handle PIR{,E0}_EL2 traps Marc Zyngier
  2024-08-13 14:47 ` [PATCH 10/10] KVM: arm64: Sanitise ID_AA64MMFR3_EL1 Marc Zyngier
  9 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

Like their EL1 equivalent, the EL2-specific FEAT_S1PIE registers
are context-switched. This is made conditional on both FEAT_TCRX
and FEAT_S1PIE being adversised.

Note that this change only makes sense if read together with the
issue D22677 contained in 102105_K.a_04_en.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index 7099775cd505..01551037df08 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -51,9 +51,15 @@ static void __sysreg_save_vel2_state(struct kvm_cpu_context *ctxt)
 		ctxt_sys_reg(ctxt, TTBR1_EL2)	= read_sysreg_el1(SYS_TTBR1);
 		ctxt_sys_reg(ctxt, TCR_EL2)	= read_sysreg_el1(SYS_TCR);
 
-		if (ctxt_has_tcrx(ctxt))
+		if (ctxt_has_tcrx(ctxt)) {
 			ctxt_sys_reg(ctxt, TCR2_EL2) = read_sysreg_el1(SYS_TCR2);
 
+			if (ctxt_has_s1pie(ctxt)) {
+				ctxt_sys_reg(ctxt, PIRE0_EL2) = read_sysreg_el1(SYS_PIRE0);
+				ctxt_sys_reg(ctxt, PIR_EL2) = read_sysreg_el1(SYS_PIR);
+			}
+		}
+
 		/*
 		 * The EL1 view of CNTKCTL_EL1 has a bunch of RES0 bits where
 		 * the interesting CNTHCTL_EL2 bits live. So preserve these
@@ -111,9 +117,15 @@ static void __sysreg_restore_vel2_state(struct kvm_cpu_context *ctxt)
 		write_sysreg_el1(val, SYS_TCR);
 	}
 
-	if (ctxt_has_tcrx(ctxt))
+	if (ctxt_has_tcrx(ctxt)) {
 		write_sysreg_el1(ctxt_sys_reg(ctxt, TCR2_EL2), SYS_TCR2);
 
+		if (ctxt_has_s1pie(ctxt)) {
+			write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL2),	SYS_PIR);
+			write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL2),	SYS_PIRE0);
+		}
+	}
+
 	write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL2),	SYS_ESR);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL2),	SYS_AFSR0);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR1_EL2),	SYS_AFSR1);
-- 
2.39.2



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

* [PATCH 09/10] KVM: arm64: Handle  PIR{,E0}_EL2 traps
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
                   ` (7 preceding siblings ...)
  2024-08-13 14:47 ` [PATCH 08/10] KVM: arm64: Add save/restore for PIR{,E0}_EL2 Marc Zyngier
@ 2024-08-13 14:47 ` Marc Zyngier
  2024-08-13 15:24   ` Joey Gouly
  2024-08-13 14:47 ` [PATCH 10/10] KVM: arm64: Sanitise ID_AA64MMFR3_EL1 Marc Zyngier
  9 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

Add the FEAT_S1PIE EL2 registers the sysreg descriptor array so that
they can be handled as a trap.

Access to these registers is conditionned on ID_AA64MMFR3_EL1.S1PIE
being advertised.

Similarly to other other changes, PIRE0_EL2 is guaranteed to trap
thanks to the D22677 update to the architecture..

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 52250db3c122..a5f604e24e05 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -346,6 +346,18 @@ static bool access_rw(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool check_s1pie_access_rw(struct kvm_vcpu *vcpu,
+				  struct sys_reg_params *p,
+				  const struct sys_reg_desc *r)
+{
+	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1PIE, IMP)) {
+		kvm_inject_undefined(vcpu);
+		return false;
+	}
+
+	return access_rw(vcpu, p, r);
+}
+
 /*
  * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
  */
@@ -2827,6 +2839,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
 
 	EL2_REG(MAIR_EL2, access_rw, reset_val, 0),
+	EL2_REG(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0),
+	EL2_REG(PIR_EL2, check_s1pie_access_rw, reset_val, 0),
 	EL2_REG(AMAIR_EL2, access_rw, reset_val, 0),
 
 	EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
-- 
2.39.2



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

* [PATCH 10/10] KVM: arm64: Sanitise ID_AA64MMFR3_EL1
  2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
                   ` (8 preceding siblings ...)
  2024-08-13 14:47 ` [PATCH 09/10] KVM: arm64: Handle PIR{,E0}_EL2 traps Marc Zyngier
@ 2024-08-13 14:47 ` Marc Zyngier
  9 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 14:47 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel, kvm
  Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
	Joey Gouly, Alexandru Elisei

Add the missing sanitisation of ID_AA64MMFR3_EL1, making sure we
solely expose S1PIE and TCRX (we currently don't support anything
else).

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index a5f604e24e05..d0b4509e59cb 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1608,6 +1608,9 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
 	case SYS_ID_AA64MMFR2_EL1:
 		val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK;
 		break;
+	case SYS_ID_AA64MMFR3_EL1:
+		val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1PIE;
+		break;
 	case SYS_ID_MMFR4_EL1:
 		val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX);
 		break;
@@ -2470,7 +2473,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 					ID_AA64MMFR2_EL1_IDS |
 					ID_AA64MMFR2_EL1_NV |
 					ID_AA64MMFR2_EL1_CCIDX)),
-	ID_SANITISED(ID_AA64MMFR3_EL1),
+	ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX	|
+				       ID_AA64MMFR3_EL1_S1PIE)),
 	ID_SANITISED(ID_AA64MMFR4_EL1),
 	ID_UNALLOCATED(7,5),
 	ID_UNALLOCATED(7,6),
-- 
2.39.2



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

* Re: [PATCH 03/10] KVM: arm64: Add TCR2_EL2 to the sysreg arrays
  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
  0 siblings, 0 replies; 17+ messages in thread
From: Joey Gouly @ 2024-08-13 15:03 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, kvm, James Morse, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Alexandru Elisei

On Tue, Aug 13, 2024 at 03:47:31PM +0100, Marc Zyngier wrote:
> Add the TCR2_EL2 register to the per-vcpu sysreg register
> array, as well as the sysreg descriptor array.
> 
> Access to this register is conditionned on ID_AA64MMFR3_EL1.TCRX
> being advertised.

s/conditionned/conditional based/

> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/include/asm/kvm_host.h |  1 +
>  arch/arm64/kvm/sys_regs.c         | 13 +++++++++++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index a33f5996ca9f..5a9e0ad35580 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -462,6 +462,7 @@ enum vcpu_sysreg {
>  	TTBR0_EL2,	/* Translation Table Base Register 0 (EL2) */
>  	TTBR1_EL2,	/* Translation Table Base Register 1 (EL2) */
>  	TCR_EL2,	/* Translation Control Register (EL2) */
> +	TCR2_EL2,	/* Extended Translation Control Register (EL2) */
>  	SPSR_EL2,	/* EL2 saved program status register */
>  	ELR_EL2,	/* EL2 exception link register */
>  	AFSR0_EL2,	/* Auxiliary Fault Status Register 0 (EL2) */
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 95832881fd66..52250db3c122 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -436,6 +436,18 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
>  	return true;
>  }
>  
> +static bool access_tcr2_el2(struct kvm_vcpu *vcpu,
> +			    struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r)
> +{
> +	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, TCRX, IMP)) {
> +		kvm_inject_undefined(vcpu);
> +		return false;
> +	}
> +
> +	return access_rw(vcpu, p, r);
> +}
> +
>  static bool access_actlr(struct kvm_vcpu *vcpu,
>  			 struct sys_reg_params *p,
>  			 const struct sys_reg_desc *r)
> @@ -2783,6 +2795,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
>  	EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
>  	EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),
> +	EL2_REG(TCR2_EL2, access_tcr2_el2, reset_val, TCR2_EL2_RES1),
>  	EL2_REG_VNCR(VTTBR_EL2, reset_val, 0),
>  	EL2_REG_VNCR(VTCR_EL2, reset_val, 0),
>  

Reviewed-by: Joey Gouly <joey.gouly@arm.com>


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

* Re: [PATCH 05/10] arm64: Add encoding for PIRE0_EL2
  2024-08-13 14:47 ` [PATCH 05/10] arm64: Add encoding for PIRE0_EL2 Marc Zyngier
@ 2024-08-13 15:06   ` Joey Gouly
  0 siblings, 0 replies; 17+ messages in thread
From: Joey Gouly @ 2024-08-13 15:06 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, kvm, James Morse, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Alexandru Elisei

On Tue, Aug 13, 2024 at 03:47:33PM +0100, Marc Zyngier wrote:
> PIRE0_EL2 is the equivalent of PIRE0_EL1 for the EL2&0 translation
> regime, and it is sorely missing from the sysreg file.
> 
> Add the sucker.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/tools/sysreg | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 7ceaa1e0b4bc..8e1aed548e93 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2853,6 +2853,10 @@ Sysreg	PIRE0_EL12	3	5	10	2	2
>  Fields	PIRx_ELx
>  EndSysreg
>  
> +Sysreg	PIRE0_EL2	3	4	10	2	2
> +Fields	PIRx_ELx
> +EndSysreg
> +
>  Sysreg	PIR_EL1		3	0	10	2	3
>  Fields	PIRx_ELx
>  EndSysreg

Reviewed-by: Joey Gouly <joey.gouly@arm.com>


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

* Re: [PATCH 06/10] arm64: Remove VNCR definition for PIRE0_EL2
  2024-08-13 14:47 ` [PATCH 06/10] arm64: Remove VNCR definition " Marc Zyngier
@ 2024-08-13 15:10   ` Joey Gouly
  0 siblings, 0 replies; 17+ messages in thread
From: Joey Gouly @ 2024-08-13 15:10 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, kvm, James Morse, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Alexandru Elisei

On Tue, Aug 13, 2024 at 03:47:34PM +0100, Marc Zyngier wrote:
> As of the ARM ARM Known Issues document 102105_K.a_04_en, D22677
> fixes a problem with the PIRE0_EL2 register, resulting in its
> removal from the VNCR page (it had no purpose being there the
> first place).
> 
> Follow the architecture update by removing this offset.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/include/asm/vncr_mapping.h | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h
> index df2c47c55972..9e593bb60975 100644
> --- a/arch/arm64/include/asm/vncr_mapping.h
> +++ b/arch/arm64/include/asm/vncr_mapping.h
> @@ -50,7 +50,6 @@
>  #define VNCR_VBAR_EL1           0x250
>  #define VNCR_TCR2_EL1		0x270
>  #define VNCR_PIRE0_EL1		0x290
> -#define VNCR_PIRE0_EL2		0x298
>  #define VNCR_PIR_EL1		0x2A0
>  #define VNCR_ICH_LR0_EL2        0x400
>  #define VNCR_ICH_LR1_EL2        0x408

Reviewed-by: Joey Gouly <joey.gouly@arm.com>


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

* Re: [PATCH 09/10] KVM: arm64: Handle  PIR{,E0}_EL2 traps
  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
  0 siblings, 1 reply; 17+ messages in thread
From: Joey Gouly @ 2024-08-13 15:24 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, kvm, James Morse, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Alexandru Elisei

On Tue, Aug 13, 2024 at 03:47:37PM +0100, Marc Zyngier wrote:
> Add the FEAT_S1PIE EL2 registers the sysreg descriptor array so that
> they can be handled as a trap.
> 
> Access to these registers is conditionned on ID_AA64MMFR3_EL1.S1PIE
> being advertised.
> 
> Similarly to other other changes, PIRE0_EL2 is guaranteed to trap
> thanks to the D22677 update to the architecture..
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm64/kvm/sys_regs.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 52250db3c122..a5f604e24e05 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -346,6 +346,18 @@ static bool access_rw(struct kvm_vcpu *vcpu,
>  	return true;
>  }
>  
> +static bool check_s1pie_access_rw(struct kvm_vcpu *vcpu,
> +				  struct sys_reg_params *p,
> +				  const struct sys_reg_desc *r)
> +{
> +	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1PIE, IMP)) {
> +		kvm_inject_undefined(vcpu);
> +		return false;
> +	}
> +
> +	return access_rw(vcpu, p, r);
> +}
> +
>  /*
>   * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
>   */
> @@ -2827,6 +2839,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
>  
>  	EL2_REG(MAIR_EL2, access_rw, reset_val, 0),
> +	EL2_REG(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0),
> +	EL2_REG(PIR_EL2, check_s1pie_access_rw, reset_val, 0),
>  	EL2_REG(AMAIR_EL2, access_rw, reset_val, 0),
>  
>  	EL2_REG(VBAR_EL2, access_rw, reset_val, 0),

I think we should also use this for PIR_EL1 / PIRE0_EL1? We have NULL for their access field.

	{ SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1 },


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

* Re: [PATCH 09/10] KVM: arm64: Handle  PIR{,E0}_EL2 traps
  2024-08-13 15:24   ` Joey Gouly
@ 2024-08-13 15:45     ` Marc Zyngier
  2024-08-13 16:19       ` Joey Gouly
  0 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2024-08-13 15:45 UTC (permalink / raw)
  To: Joey Gouly
  Cc: kvmarm, linux-arm-kernel, kvm, James Morse, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Alexandru Elisei

On Tue, 13 Aug 2024 16:24:52 +0100,
Joey Gouly <joey.gouly@arm.com> wrote:
> 
> On Tue, Aug 13, 2024 at 03:47:37PM +0100, Marc Zyngier wrote:
> > Add the FEAT_S1PIE EL2 registers the sysreg descriptor array so that
> > they can be handled as a trap.
> > 
> > Access to these registers is conditionned on ID_AA64MMFR3_EL1.S1PIE
> > being advertised.
> > 
> > Similarly to other other changes, PIRE0_EL2 is guaranteed to trap
> > thanks to the D22677 update to the architecture..
> > 
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm64/kvm/sys_regs.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 52250db3c122..a5f604e24e05 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -346,6 +346,18 @@ static bool access_rw(struct kvm_vcpu *vcpu,
> >  	return true;
> >  }
> >  
> > +static bool check_s1pie_access_rw(struct kvm_vcpu *vcpu,
> > +				  struct sys_reg_params *p,
> > +				  const struct sys_reg_desc *r)
> > +{
> > +	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1PIE, IMP)) {
> > +		kvm_inject_undefined(vcpu);
> > +		return false;
> > +	}
> > +
> > +	return access_rw(vcpu, p, r);
> > +}
> > +
> >  /*
> >   * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
> >   */
> > @@ -2827,6 +2839,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> >  	EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
> >  
> >  	EL2_REG(MAIR_EL2, access_rw, reset_val, 0),
> > +	EL2_REG(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0),
> > +	EL2_REG(PIR_EL2, check_s1pie_access_rw, reset_val, 0),
> >  	EL2_REG(AMAIR_EL2, access_rw, reset_val, 0),
> >  
> >  	EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
> 
> I think we should also use this for PIR_EL1 / PIRE0_EL1? We have NULL for their access field.
> 
> 	{ SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1 },

I don't think we need this. In general, the EL1 FEAT_S1PIE registers
are directly accessed by the VM, and do not trap.

However, if the VM has been configured to not expose S1PIE, then we
set the corresponding FGU bits in kvm_calculate_traps():

	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
		kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
						HFGxTR_EL2_nPIR_EL1);

The effect of this is that we don't even make to the sysreg array, and
inject an UNDEF directly from the point of decoding the trap (see the
beginning of triage_sysreg_trap()).

For EL2 registers, there is no concept of FGT since they always trap,
so no architectural trick we can play to shortcut the handling.
Therefore we make it to the handler and have to triage things there.

Does it make sense?

	M.

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


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

* Re: [PATCH 09/10] KVM: arm64: Handle  PIR{,E0}_EL2 traps
  2024-08-13 15:45     ` Marc Zyngier
@ 2024-08-13 16:19       ` Joey Gouly
  0 siblings, 0 replies; 17+ messages in thread
From: Joey Gouly @ 2024-08-13 16:19 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, linux-arm-kernel, kvm, James Morse, Suzuki K Poulose,
	Oliver Upton, Zenghui Yu, Alexandru Elisei

On Tue, Aug 13, 2024 at 04:45:46PM +0100, Marc Zyngier wrote:
> On Tue, 13 Aug 2024 16:24:52 +0100,
> Joey Gouly <joey.gouly@arm.com> wrote:
> > 
> > On Tue, Aug 13, 2024 at 03:47:37PM +0100, Marc Zyngier wrote:
> > > Add the FEAT_S1PIE EL2 registers the sysreg descriptor array so that
> > > they can be handled as a trap.
> > > 
> > > Access to these registers is conditionned on ID_AA64MMFR3_EL1.S1PIE
> > > being advertised.
> > > 
> > > Similarly to other other changes, PIRE0_EL2 is guaranteed to trap
> > > thanks to the D22677 update to the architecture..
> > > 
> > > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > > ---
> > >  arch/arm64/kvm/sys_regs.c | 14 ++++++++++++++
> > >  1 file changed, 14 insertions(+)
> > > 
> > > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > > index 52250db3c122..a5f604e24e05 100644
> > > --- a/arch/arm64/kvm/sys_regs.c
> > > +++ b/arch/arm64/kvm/sys_regs.c
> > > @@ -346,6 +346,18 @@ static bool access_rw(struct kvm_vcpu *vcpu,
> > >  	return true;
> > >  }
> > >  
> > > +static bool check_s1pie_access_rw(struct kvm_vcpu *vcpu,
> > > +				  struct sys_reg_params *p,
> > > +				  const struct sys_reg_desc *r)
> > > +{
> > > +	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1PIE, IMP)) {
> > > +		kvm_inject_undefined(vcpu);
> > > +		return false;
> > > +	}
> > > +
> > > +	return access_rw(vcpu, p, r);
> > > +}
> > > +
> > >  /*
> > >   * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
> > >   */
> > > @@ -2827,6 +2839,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> > >  	EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
> > >  
> > >  	EL2_REG(MAIR_EL2, access_rw, reset_val, 0),
> > > +	EL2_REG(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0),
> > > +	EL2_REG(PIR_EL2, check_s1pie_access_rw, reset_val, 0),
> > >  	EL2_REG(AMAIR_EL2, access_rw, reset_val, 0),
> > >  
> > >  	EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
> > 
> > I think we should also use this for PIR_EL1 / PIRE0_EL1? We have NULL for their access field.
> > 
> > 	{ SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1 },
> 
> I don't think we need this. In general, the EL1 FEAT_S1PIE registers
> are directly accessed by the VM, and do not trap.
> 
> However, if the VM has been configured to not expose S1PIE, then we
> set the corresponding FGU bits in kvm_calculate_traps():
> 
> 	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
> 		kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
> 						HFGxTR_EL2_nPIR_EL1);
> 
> The effect of this is that we don't even make to the sysreg array, and
> inject an UNDEF directly from the point of decoding the trap (see the
> beginning of triage_sysreg_trap()).
> 
> For EL2 registers, there is no concept of FGT since they always trap,
> so no architectural trick we can play to shortcut the handling.
> Therefore we make it to the handler and have to triage things there.
> 
> Does it make sense?

Ah yes, forgot how that worked, thanks for the reminder!

There's another 'conditionned' typo in the commit message, but otherwise:

Reviewed-by: Joey Gouly <joey.gouly@arm.com>

Thanks,
Joey


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

end of thread, other threads:[~2024-08-13 16:21 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-13 14:47 [PATCH 00/10] KVM: arm64: Add EL2 support to FEAT_S1PIE Marc Zyngier
2024-08-13 14:47 ` [PATCH 01/10] KVM: arm64: nv: Handle CNTHCTL_EL2 specially Marc Zyngier
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

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).