linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses
@ 2020-05-29 15:06 James Morse
  2020-05-29 15:06 ` [PATCH v2 1/3] KVM: arm64: Stop writing aarch32's CSSELR into ACTLR James Morse
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: James Morse @ 2020-05-29 15:06 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: Marc Zyngier, Julien Thierry, Suzuki K Poulose

Hello!

Changes since v1:
 * Patches 2 & 3 have been swapped.
 * Copy access_vm_reg() to swizzle 32bit offets back to 64bit
 * Peek at the encoding to tell ACTLR and ACTLR2 apart...

I didn't pick up the suggestion to remove the ACTLR_EL1 storage from
sys_regs[] as this turns out to break migration. Fixing it would require
a get_user() helper, which has a different prototype to access_actlr(),
would be noisier overall.

~

Patch 1 fixes an issue where the 32bit and 64bit indexes into copro[]
and sys_regs[] are muddled.

Patch 2 adds support for aarch32 accessing the top 32bits of ACTLR_EL1
via ACTLR2. Support for this register is advertised in ID_MMFR4.AC2, which
doesn't get removed by cpufeature. The register is mandatory from v8.2, but
imp-def before then.

Patch 3 stops the sys_regs[] value we use for emulation being save/restored.

I think Patch 1 is stable material, I'm not sure about 2&3.


Thanks,

James Morse (3):
  KVM: arm64: Stop writing aarch32's CSSELR into ACTLR
  KVM: arm64: Add emulation for 32bit guests accessing ACTLR2
  KVM: arm64: Stop save/restoring ACTLR_EL1

 arch/arm64/kvm/hyp/sysreg-sr.c       |  2 --
 arch/arm64/kvm/sys_regs.c            | 12 ++++++++----
 arch/arm64/kvm/sys_regs_generic_v8.c | 10 ++++++++++
 3 files changed, 18 insertions(+), 6 deletions(-)

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 1/3] KVM: arm64: Stop writing aarch32's CSSELR into ACTLR
  2020-05-29 15:06 [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses James Morse
@ 2020-05-29 15:06 ` James Morse
  2020-05-29 15:06 ` [PATCH v2 2/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2 James Morse
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: James Morse @ 2020-05-29 15:06 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: Marc Zyngier, Julien Thierry, Suzuki K Poulose

aarch32 has pairs of registers to access the high and low parts of 64bit
registers. KVM has a union of 64bit sys_regs[] and 32bit copro[]. The
32bit accessors read the high or low part of the 64bit sys_reg[] value
through the union.

Both sys_reg_descs[] and cp15_regs[] list access_csselr() as the accessor
for CSSELR{,_EL1}. access_csselr() is only aware of the 64bit sys_regs[],
and expects r->reg to be 'CSSELR_EL1' in the enum, index 2 of the 64bit
array.

cp15_regs[] uses the 32bit copro[] alias of sys_regs[]. Here CSSELR is
c0_CSSELR which is the same location in sys_reg[]. r->reg is 'c0_CSSELR',
index 4 in the 32bit array.

access_csselr() uses the 32bit r->reg value to access the 64bit array,
so reads and write the wrong value. sys_regs[4], is ACTLR_EL1, which
is subsequently save/restored when we enter the guest.

ACTLR_EL1 is supposed to be read-only for the guest. This register
only affects execution at EL1, and the host's value is restored before
we return to host EL1.

Convert the 32bit register index back to the 64bit version.

Cc: stable@vger.kernel.org
Suggested-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/kvm/sys_regs.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 51db934702b6..bfd68cd4fc54 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1305,10 +1305,16 @@ static bool access_clidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 static bool access_csselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 			  const struct sys_reg_desc *r)
 {
+	int reg = r->reg;
+
+	/* See the 32bit mapping in kvm_host.h */
+	if (p->is_aarch32)
+		reg = r->reg / 2;
+
 	if (p->is_write)
-		vcpu_write_sys_reg(vcpu, p->regval, r->reg);
+		vcpu_write_sys_reg(vcpu, p->regval, reg);
 	else
-		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
+		p->regval = vcpu_read_sys_reg(vcpu, reg);
 	return true;
 }
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 2/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2
  2020-05-29 15:06 [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses James Morse
  2020-05-29 15:06 ` [PATCH v2 1/3] KVM: arm64: Stop writing aarch32's CSSELR into ACTLR James Morse
@ 2020-05-29 15:06 ` James Morse
  2020-05-29 15:06 ` [PATCH v2 3/3] KVM: arm64: Stop save/restoring ACTLR_EL1 James Morse
  2020-06-10 13:17 ` [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses Marc Zyngier
  3 siblings, 0 replies; 5+ messages in thread
From: James Morse @ 2020-05-29 15:06 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: Marc Zyngier, Julien Thierry, Suzuki K Poulose

ACTLR_EL1 is a 64bit register while the 32bit ACTLR is obviously 32bit.
For 32bit software, the extra bits are accessible via ACTLR2... which
KVM doesn't emulate.

Suggested-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/kvm/sys_regs_generic_v8.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c b/arch/arm64/kvm/sys_regs_generic_v8.c
index 9cb6b4c8355a..aa9d356451eb 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -27,6 +27,14 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
 		return ignore_write(vcpu, p);
 
 	p->regval = vcpu_read_sys_reg(vcpu, ACTLR_EL1);
+
+	if (p->is_aarch32) {
+		if (r->Op2 & 2)
+			p->regval = upper_32_bits(p->regval);
+		else
+			p->regval = lower_32_bits(p->regval);
+	}
+
 	return true;
 }
 
@@ -47,6 +55,8 @@ static const struct sys_reg_desc genericv8_cp15_regs[] = {
 	/* ACTLR */
 	{ Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
 	  access_actlr },
+	{ Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b011),
+	  access_actlr },
 };
 
 static struct kvm_sys_reg_target_table genericv8_target_table = {
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 3/3] KVM: arm64: Stop save/restoring ACTLR_EL1
  2020-05-29 15:06 [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses James Morse
  2020-05-29 15:06 ` [PATCH v2 1/3] KVM: arm64: Stop writing aarch32's CSSELR into ACTLR James Morse
  2020-05-29 15:06 ` [PATCH v2 2/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2 James Morse
@ 2020-05-29 15:06 ` James Morse
  2020-06-10 13:17 ` [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses Marc Zyngier
  3 siblings, 0 replies; 5+ messages in thread
From: James Morse @ 2020-05-29 15:06 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: Marc Zyngier, Julien Thierry, Suzuki K Poulose

KVM sets HCR_EL2.TACR via HCR_GUEST_FLAGS. This means ACTLR* accesses
from the guest are always trapped, and always return the value in the
sys_regs array.

The guest can't change the value of these registers, so we are
save restoring the reset value, which came from the host.

Stop save/restoring this register. Keep the storage for this register
in sys_regs[] as this is how the value is exposed to user-space,
removing it would break migration.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/kvm/hyp/sysreg-sr.c | 2 --
 arch/arm64/kvm/sys_regs.c      | 2 --
 2 files changed, 4 deletions(-)

diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
index 75b1925763f1..57116cf3a1a5 100644
--- a/arch/arm64/kvm/hyp/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/sysreg-sr.c
@@ -44,7 +44,6 @@ static void __hyp_text __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 {
 	ctxt->sys_regs[CSSELR_EL1]	= read_sysreg(csselr_el1);
 	ctxt->sys_regs[SCTLR_EL1]	= read_sysreg_el1(SYS_SCTLR);
-	ctxt->sys_regs[ACTLR_EL1]	= read_sysreg(actlr_el1);
 	ctxt->sys_regs[CPACR_EL1]	= read_sysreg_el1(SYS_CPACR);
 	ctxt->sys_regs[TTBR0_EL1]	= read_sysreg_el1(SYS_TTBR0);
 	ctxt->sys_regs[TTBR1_EL1]	= read_sysreg_el1(SYS_TTBR1);
@@ -133,7 +132,6 @@ static void __hyp_text __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
 		isb();
 	}
 
-	write_sysreg(ctxt->sys_regs[ACTLR_EL1],		actlr_el1);
 	write_sysreg_el1(ctxt->sys_regs[CPACR_EL1],	SYS_CPACR);
 	write_sysreg_el1(ctxt->sys_regs[TTBR0_EL1],	SYS_TTBR0);
 	write_sysreg_el1(ctxt->sys_regs[TTBR1_EL1],	SYS_TTBR1);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index bfd68cd4fc54..545bc18b9c24 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -81,7 +81,6 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
 	switch (reg) {
 	case CSSELR_EL1:	return read_sysreg_s(SYS_CSSELR_EL1);
 	case SCTLR_EL1:		return read_sysreg_s(SYS_SCTLR_EL12);
-	case ACTLR_EL1:		return read_sysreg_s(SYS_ACTLR_EL1);
 	case CPACR_EL1:		return read_sysreg_s(SYS_CPACR_EL12);
 	case TTBR0_EL1:		return read_sysreg_s(SYS_TTBR0_EL12);
 	case TTBR1_EL1:		return read_sysreg_s(SYS_TTBR1_EL12);
@@ -124,7 +123,6 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
 	switch (reg) {
 	case CSSELR_EL1:	write_sysreg_s(val, SYS_CSSELR_EL1);	return;
 	case SCTLR_EL1:		write_sysreg_s(val, SYS_SCTLR_EL12);	return;
-	case ACTLR_EL1:		write_sysreg_s(val, SYS_ACTLR_EL1);	return;
 	case CPACR_EL1:		write_sysreg_s(val, SYS_CPACR_EL12);	return;
 	case TTBR0_EL1:		write_sysreg_s(val, SYS_TTBR0_EL12);	return;
 	case TTBR1_EL1:		write_sysreg_s(val, SYS_TTBR1_EL12);	return;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses
  2020-05-29 15:06 [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses James Morse
                   ` (2 preceding siblings ...)
  2020-05-29 15:06 ` [PATCH v2 3/3] KVM: arm64: Stop save/restoring ACTLR_EL1 James Morse
@ 2020-06-10 13:17 ` Marc Zyngier
  3 siblings, 0 replies; 5+ messages in thread
From: Marc Zyngier @ 2020-06-10 13:17 UTC (permalink / raw)
  To: James Morse, linux-arm-kernel, kvmarm

On Fri, 29 May 2020 15:06:53 +0000, James Morse wrote:
> Hello!
> 
> Changes since v1:
>  * Patches 2 & 3 have been swapped.
>  * Copy access_vm_reg() to swizzle 32bit offets back to 64bit
>  * Peek at the encoding to tell ACTLR and ACTLR2 apart...
> 
> [...]

Applied to kvm-arm64/32bit-fixes, thanks!

[1/3] KVM: arm64: Stop writing aarch32's CSSELR into ACTLR
      commit: 7c582bf4ed84f3eb58bdd1f63024a14c17551e7d
[2/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2
      commit: ef5a294be8d0e17b91d23be905f69368b0d3952e
[3/3] KVM: arm64: Stop save/restoring ACTLR_EL1
      commit: e8679fedd026eb3b4655af83829d9036e32c9b97

Cheers,

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



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2020-06-10 13:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-29 15:06 [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses James Morse
2020-05-29 15:06 ` [PATCH v2 1/3] KVM: arm64: Stop writing aarch32's CSSELR into ACTLR James Morse
2020-05-29 15:06 ` [PATCH v2 2/3] KVM: arm64: Add emulation for 32bit guests accessing ACTLR2 James Morse
2020-05-29 15:06 ` [PATCH v2 3/3] KVM: arm64: Stop save/restoring ACTLR_EL1 James Morse
2020-06-10 13:17 ` [PATCH v2 0/3] KVM: arm64: aarch32 ACTLR accesses 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).