Skip to contentSkip to conversation

arm64: PSR <-> SPSR_ELx mapping fixes

PATCH New Mark Rutland 5 participants 16 messages Jun 25, 2018 – Jul 5, 2018

Subsystems (4)
lore
Share & tools
lore

Mark Rutland

author reviewer
#0 lore raw

cover arm64: PSR <-> SPSR_ELx mapping fixes

The SPSR_ELx format has diverged from the AArch32-native SPSR format since the addition of DIT. Thus, we need to map between the two for certain compat operations.

Also, when we added support for DIT, we forgot to account for this in valid_user_regs(), causing PSTATE.DIT to be cleared upon sigreturn.

These patches (based on v4.18-rc2) fix those issues, cleaning up the COMPAT_PSR definitions to try to avoid confusiong in future.

The COMPAT_PSR_ definitions are now used for the AArch32-native SPR format (i.e. they are the compat userspace view), with PSR_AA32_ definitions used for the AArch64 view of the PSR for AArch32 tasks.

Thanks,
Mark.

Mark Rutland (7):
arm64: add PSR_AA32_* definitions
arm64: don't zero DIT on signal return
arm64: compat: map SPSR_ELx<->PSR for signals
arm64: ptrace: map SPSR_ELx<->PSR for compat tasks
arm64: use PSR_AA32 definitions
kvm/arm: use PSR_AA32 definitions
arm64: remove unused COMPAT_PSR definitions

 arch/arm/include/asm/kvm_emulate.h       | 14 +++---
 arch/arm64/include/asm/kvm_emulate.h     | 10 ++---
 arch/arm64/include/asm/processor.h       |  6 +--
 arch/arm64/include/asm/ptrace.h          | 77 +++++++++++++++++++++-----------
 arch/arm64/kernel/armv8_deprecated.c     | 24 +++++-----
 arch/arm64/kernel/cpufeature.c           |  2 +-
 arch/arm64/kernel/process.c              | 20 ++++-----
 arch/arm64/kernel/ptrace.c               | 34 ++++++++------
 arch/arm64/kernel/signal32.c             | 18 +++++---
 arch/arm64/kvm/guest.c                   | 14 +++---
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c |  2 +-
 arch/arm64/kvm/regmap.c                  | 22 ++++-----
 arch/arm64/kvm/reset.c                   |  4 +-
 virt/kvm/arm/aarch32.c                   | 20 ++++-----
 14 files changed, 152 insertions(+), 115 deletions(-)
Signature · 1 line
2.11.0
author reviewer
#1 lore raw

PATCH 1/7 arm64: add PSR_AA32_* definitions

The AArch32 CPSR/SPSR format is *almost* identical to the AArch64 SPSR_ELx format for exceptions taken from AArch32, but the two have diverged with the addition of DIT, and we need to treat the two as logically distinct.

This patch adds new definitions for the SPSR_ELx format for exceptions taken from AArch32, with a consistent PSR_AA32_ prefix. The existing COMPAT_PSR_ definitions will be used for the PSR format as seen from AArch32.

Definitions of DIT are provided for both, and inline functions are provided to map between the two formats. Note that for SPSR_ELx, the (RES0) J bit has been re-allocated as the DIT bit.

Once users of the COMPAT_PSR definitions have been migrated over to the PSR_AA32 definitions, the (majority of) the former will be removed, so no efforts is made to avoid duplication until then.

Cc Catalin Marinas <[email protected]>
Cc Christoffer Dall <[email protected]>
Cc Marc Zyngier <[email protected]>
Cc Suzuki Poulose <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/include/asm/ptrace.h | 57 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)
arch/arm64/include/asm/ptrace.h +56 -1
index 6069d66e0bc2..ee27468a1ba6 100644
@@ -35,7 +35,37 @@
 #define COMPAT_PTRACE_GETHBPREGS	29
 #define COMPAT_PTRACE_SETHBPREGS	30
 
-/* AArch32 CPSR bits */
+/* SPSR_ELx bits for exceptions taken from AArch32 */
+#define PSR_AA32_MODE_MASK	0x0000001f
+#define PSR_AA32_MODE_USR	0x00000010
+#define PSR_AA32_MODE_FIQ	0x00000011
+#define PSR_AA32_MODE_IRQ	0x00000012
+#define PSR_AA32_MODE_SVC	0x00000013
+#define PSR_AA32_MODE_ABT	0x00000017
+#define PSR_AA32_MODE_HYP	0x0000001a
+#define PSR_AA32_MODE_UND	0x0000001b
+#define PSR_AA32_MODE_SYS	0x0000001f
+#define PSR_AA32_T_BIT		0x00000020
+#define PSR_AA32_F_BIT		0x00000040
+#define PSR_AA32_I_BIT		0x00000080
+#define PSR_AA32_A_BIT		0x00000100
+#define PSR_AA32_E_BIT		0x00000200
+#define PSR_AA32_DIT_BIT	0x01000000
+#define PSR_AA32_Q_BIT		0x08000000
+#define PSR_AA32_V_BIT		0x10000000
+#define PSR_AA32_C_BIT		0x20000000
+#define PSR_AA32_Z_BIT		0x40000000
+#define PSR_AA32_N_BIT		0x80000000
+#define PSR_AA32_IT_MASK	0x0600fc00	/* If-Then execution state mask */
+#define PSR_AA32_GE_MASK	0x000f0000
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define PSR_AA32_ENDSTATE	PSR_AA32_E_BIT
+#else
+#define PSR_AA32_ENDSTATE	0
+#endif
+
+/* AArch32 CPSR bits, as seen in AArch32 */
 #define COMPAT_PSR_MODE_MASK	0x0000001f
 #define COMPAT_PSR_MODE_USR	0x00000010
 #define COMPAT_PSR_MODE_FIQ	0x00000011
@@ -50,6 +80,7 @@
 #define COMPAT_PSR_I_BIT	0x00000080
 #define COMPAT_PSR_A_BIT	0x00000100
 #define COMPAT_PSR_E_BIT	0x00000200
+#define COMPAT_PSR_DIT_BIT	0x00200000
 #define COMPAT_PSR_J_BIT	0x01000000
 #define COMPAT_PSR_Q_BIT	0x08000000
 #define COMPAT_PSR_V_BIT	0x10000000
@@ -65,6 +96,30 @@
 #define COMPAT_PSR_ENDSTATE	0
 #endif
 
+static inline unsigned long compat_psr_to_pstate(const unsigned long psr)
+{
+	unsigned long pstate;
+
+	pstate = psr & ~COMPAT_PSR_DIT_BIT;
+
+	if (psr & COMPAT_PSR_DIT_BIT)
+		pstate |= PSR_AA32_DIT_BIT;
+
+	return pstate;
+}
+
+static inline unsigned long pstate_to_compat_psr(const unsigned long pstate)
+{
+	unsigned long psr;
+
+	psr = pstate & ~PSR_AA32_DIT_BIT;
+
+	if (pstate & PSR_AA32_DIT_BIT)
+		psr |= COMPAT_PSR_DIT_BIT;
+
+	return psr;
+}
+
 /*
  * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
  * process is located in memory.
Signature · 1 line
2.11.0
author reviewer
#2 lore raw

PATCH 2/7 arm64: don't zero DIT on signal return

In reply to Mark Rutland

Currently valid_user_regs() treats SPSR_ELx.DIT as a RES0 bit, causing it to be zeroed upon exception return, rather than preserved. Thus, code relying on DIT will not function as expected, and may expose an unexpected timing sidechannel.

Let's remove DIT from the set of RES0 bits, such that it is preserved. At the same time, the related comment is updated to better describe the situation, and to take into account the most recent documentation of SPSR_ELx, in ARM DDI 0487C.a.

Fixes 7206dc93a58fb764 ("arm64: Expose Arm v8.4 features")
Cc Catalin Marinas <[email protected]>
Cc Suzuki K Poulose <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/ptrace.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
arch/arm64/kernel/ptrace.c +8 -4
index 5c338ce5a7fa..fff665988e21 100644
@@ -1659,15 +1659,19 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs)
 }
 
 /*
- * Bits which are always architecturally RES0 per ARM DDI 0487A.h
+ * SPSR_ELx bits which are always architecturally RES0 per ARM DDI 0487C.a 
+ * We also take into account DIT (bit 24), which is not yet documented, and
+ * treat PAN and UAO as RES0 bits, as they are meaningless at EL0, and may be
+ * allocated an EL0 meaning in future.
  * Userspace cannot use these until they have an architectural meaning.
+ * Note that this follows the SPSR_ELx format, not the AArch32 PSR format.
  * We also reserve IL for the kernel; SS is handled dynamically.
  */
 #define SPSR_EL1_AARCH64_RES0_BITS \
-	(GENMASK_ULL(63,32) | GENMASK_ULL(27, 22) | GENMASK_ULL(20, 10) | \
-	 GENMASK_ULL(5, 5))
+	(GENMASK_ULL(63,32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \
+	 GENMASK_ULL(20, 10) | GENMASK_ULL(5, 5))
 #define SPSR_EL1_AARCH32_RES0_BITS \
-	(GENMASK_ULL(63,32) | GENMASK_ULL(24, 22) | GENMASK_ULL(20,20))
+	(GENMASK_ULL(63,32) | GENMASK_ULL(23, 22) | GENMASK_ULL(20,20))
 
 static int valid_compat_regs(struct user_pt_regs *regs)
 {
Signature · 1 line
2.11.0
author reviewer
#3 lore raw

PATCH 3/7 arm64: compat: map SPSR_ELx<->PSR for signals

In reply to Mark Rutland

The SPSR_ELx format for exceptions taken from AArch32 differs from the AArch32 PSR format. Thus, we must translate between the two when setting up a compat sigframe, or restoring context from a compat sigframe.

Fixes 7206dc93a58fb764 ("arm64: Expose Arm v8.4 features")
Cc Catalin Marinas <[email protected]>
Cc Suzuki Poulose <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/signal32.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
arch/arm64/kernel/signal32.c +6 -2
index 77b91f478995..fa9fb782f077 100644
@@ -243,6 +243,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
 	int err;
 	sigset_t set;
 	struct compat_aux_sigframe __user *aux;
+	unsigned long psr;
 
 	err = get_sigset_t(&set, &sf->uc.uc_sigmask);
 	if (err == 0) {
@@ -266,7 +267,9 @@ static int compat_restore_sigframe(struct pt_regs *regs,
 	__get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
 	__get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
 	__get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
-	__get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
+	__get_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
+
+	regs->pstate = compat_psr_to_pstate(regs->pstate);
 
 	/*
 	 * Avoid compat_sys_sigreturn() restarting.
@@ -414,6 +417,7 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
 				 struct pt_regs *regs, sigset_t *set)
 {
 	struct compat_aux_sigframe __user *aux;
+	unsigned long psr = pstate_to_compat_psr(regs->pstate);
 	int err = 0;
 
 	__put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
@@ -432,7 +436,7 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
 	__put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
 	__put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
 	__put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
-	__put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
+	__put_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
 
 	__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
 	/* set the compat FSR WnR */
Signature · 1 line
2.11.0
#4 lore raw

PATCH 3/7 arm64: compat: map SPSR_ELx<->PSR for signals

Quoted 26 lines · Mark Rutland

The SPSR_ELx format for exceptions taken from AArch32 differs from the AArch32 PSR format. Thus, we must translate between the two when setting up a compat sigframe, or restoring context from a compat sigframe.

Fixes 7206dc93a58fb764 ("arm64: Expose Arm v8.4 features")
Cc Catalin Marinas <[email protected]>
Cc Suzuki Poulose <[email protected]>
Cc Will Deacon <[email protected]>
---
  arch/arm64/kernel/signal32.c | 8 ++++++--
  1 file changed, 6 insertions(+), 2 deletions(-)
arch/arm64/kernel/signal32.c +1 -0
index 77b91f478995..fa9fb782f077 100644
@@ -243,6 +243,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
  	int err;
  	sigset_t set;
  	struct compat_aux_sigframe __user *aux;
+	unsigned long psr;
 
  	err = get_sigset_t(&set, &sf->uc.uc_sigmask);
  	if (err == 0) {

arch/arm64/kernel/signal32.c static int compat_restore_sigframe(struct pt_regs *regs, · line 272

Quoted 7 lines
arch/arm64/kernel/signal32.c +3 -1
@@ -266,7 +267,9 @@ static int compat_restore_sigframe(struct pt_regs *regs,
  	__get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
  	__get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
  	__get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
-	__get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
+	__get_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
+
+	regs->pstate = compat_psr_to_pstate(regs->pstate);

Did you mean

	regs->pstate = compat_psr_to_pstate(psr)

above ?

Otherwise, looks good to me.

Suzuki

author reviewer
#5 lore raw

PATCH 3/7 arm64: compat: map SPSR_ELx<->PSR for signals

Quoted 35 lines · Suzuki K Poulose
Quoted 25 lines · Mark Rutland

The SPSR_ELx format for exceptions taken from AArch32 differs from the AArch32 PSR format. Thus, we must translate between the two when setting up a compat sigframe, or restoring context from a compat sigframe.

Fixes 7206dc93a58fb764 ("arm64: Expose Arm v8.4 features")
Cc Catalin Marinas <[email protected]>
Cc Suzuki Poulose <[email protected]>
Cc Will Deacon <[email protected]>
---
  arch/arm64/kernel/signal32.c | 8 ++++++--
  1 file changed, 6 insertions(+), 2 deletions(-)
arch/arm64/kernel/signal32.c +1 -0
index 77b91f478995..fa9fb782f077 100644
@@ -243,6 +243,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
  	int err;
  	sigset_t set;
  	struct compat_aux_sigframe __user *aux;
+	unsigned long psr;
  	err = get_sigset_t(&set, &sf->uc.uc_sigmask);
  	if (err == 0) {

arch/arm64/kernel/signal32.c static int compat_restore_sigframe(struct pt_regs *regs, · line 272

Quoted 7 lines
arch/arm64/kernel/signal32.c +3 -1
@@ -266,7 +267,9 @@ static int compat_restore_sigframe(struct pt_regs *regs,
  	__get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
  	__get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
  	__get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
-	__get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
+	__get_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
+
+	regs->pstate = compat_psr_to_pstate(regs->pstate);

Did you mean

Quoted 2 lines
	regs->pstate = compat_psr_to_pstate(psr)

above ?

Yes!

Thanks for spotting that; I've fixed that up locally.

Mark.

author reviewer
#6 lore raw

PATCH 4/7 arm64: ptrace: map SPSR_ELx<->PSR for compat tasks

In reply to Mark Rutland

The SPSR_ELx format for exceptions taken from AArch32 is slightly different to the AArch32 PSR format.

Map between the two in the compat ptrace code.

Fixes 7206dc93a58fb764 ("arm64: Expose Arm v8.4 features")
Cc Catalin Marinas <[email protected]>
Cc Suzuki Poulose <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/ptrace.c | 2 ++
 1 file changed, 2 insertions(+)
arch/arm64/kernel/ptrace.c +2 -0
index fff665988e21..bc07e8ec062b 100644
@@ -1076,6 +1076,7 @@ static int compat_gpr_get(struct task_struct *target,
 			break;
 		case 16:
 			reg = task_pt_regs(target)->pstate;
+			reg = pstate_to_compat_psr(reg);
 			break;
 		case 17:
 			reg = task_pt_regs(target)->orig_x0;
@@ -1143,6 +1144,7 @@ static int compat_gpr_set(struct task_struct *target,
 			newregs.pc = reg;
 			break;
 		case 16:
+			reg = compat_psr_to_pstate(reg);
 			newregs.pstate = reg;
 			break;
 		case 17:
Signature · 1 line
2.11.0
author reviewer
#7 lore raw

PATCH 5/7 arm64: use PSR_AA32 definitions

In reply to Mark Rutland

Some code cares about the SPSR_ELx format for exceptions taken from AArch32 to inspect or manipulate the SPSR_ELx value, which is already in the SPSR_ELx format, and not in the AArch32 PSR format.

To separate these from cases where we care about the AArch32 PSR format, migrate these cases to use the PSR_AA32_* definitions rather than COMPAT_PSR_*.

There should be no functional change as a result of this patch.

Cc Catalin Marinas <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/include/asm/processor.h   |  6 +++---
 arch/arm64/kernel/armv8_deprecated.c | 24 ++++++++++++------------
 arch/arm64/kernel/cpufeature.c       |  2 +-
 arch/arm64/kernel/process.c          | 20 ++++++++++----------
 arch/arm64/kernel/ptrace.c           | 20 ++++++++++----------
 arch/arm64/kernel/signal32.c         | 10 +++++-----
 6 files changed, 41 insertions(+), 41 deletions(-)
arch/arm64/include/asm/processor.h +3 -3
index a73ae1e49200..e02612105d78 100644
@@ -182,12 +182,12 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
 				       unsigned long sp)
 {
 	start_thread_common(regs, pc);
-	regs->pstate = COMPAT_PSR_MODE_USR;
+	regs->pstate = PSR_AA32_MODE_USR;
 	if (pc & 1)
-		regs->pstate |= COMPAT_PSR_T_BIT;
+		regs->pstate |= PSR_AA32_T_BIT;
 
 #ifdef __AARCH64EB__
-	regs->pstate |= COMPAT_PSR_E_BIT;
+	regs->pstate |= PSR_AA32_E_BIT;
 #endif
 
 	regs->compat_sp = sp;
arch/arm64/kernel/armv8_deprecated.c +12 -12
index d4707abb2f16..d2c0938ccaec 100644
@@ -441,8 +441,8 @@ static struct undef_hook swp_hooks[] = {
 	{
 		.instr_mask	= 0x0fb00ff0,
 		.instr_val	= 0x01000090,
-		.pstate_mask	= COMPAT_PSR_MODE_MASK,
-		.pstate_val	= COMPAT_PSR_MODE_USR,
+		.pstate_mask	= PSR_AA32_MODE_MASK,
+		.pstate_val	= PSR_AA32_MODE_USR,
 		.fn		= swp_handler
 	},
 	{ }
@@ -521,15 +521,15 @@ static struct undef_hook cp15_barrier_hooks[] = {
 	{
 		.instr_mask	= 0x0fff0fdf,
 		.instr_val	= 0x0e070f9a,
-		.pstate_mask	= COMPAT_PSR_MODE_MASK,
-		.pstate_val	= COMPAT_PSR_MODE_USR,
+		.pstate_mask	= PSR_AA32_MODE_MASK,
+		.pstate_val	= PSR_AA32_MODE_USR,
 		.fn		= cp15barrier_handler,
 	},
 	{
 		.instr_mask	= 0x0fff0fff,
 		.instr_val	= 0x0e070f95,
-		.pstate_mask	= COMPAT_PSR_MODE_MASK,
-		.pstate_val	= COMPAT_PSR_MODE_USR,
+		.pstate_mask	= PSR_AA32_MODE_MASK,
+		.pstate_val	= PSR_AA32_MODE_USR,
 		.fn		= cp15barrier_handler,
 	},
 	{ }
@@ -562,10 +562,10 @@ static int compat_setend_handler(struct pt_regs *regs, u32 big_endian)
 
 	if (big_endian) {
 		insn = "setend be";
-		regs->pstate |= COMPAT_PSR_E_BIT;
+		regs->pstate |= PSR_AA32_E_BIT;
 	} else {
 		insn = "setend le";
-		regs->pstate &= ~COMPAT_PSR_E_BIT;
+		regs->pstate &= ~PSR_AA32_E_BIT;
 	}
 
 	trace_instruction_emulation(insn, regs->pc);
@@ -593,16 +593,16 @@ static struct undef_hook setend_hooks[] = {
 	{
 		.instr_mask	= 0xfffffdff,
 		.instr_val	= 0xf1010000,
-		.pstate_mask	= COMPAT_PSR_MODE_MASK,
-		.pstate_val	= COMPAT_PSR_MODE_USR,
+		.pstate_mask	= PSR_AA32_MODE_MASK,
+		.pstate_val	= PSR_AA32_MODE_USR,
 		.fn		= a32_setend_handler,
 	},
 	{
 		/* Thumb mode */
 		.instr_mask	= 0x0000fff7,
 		.instr_val	= 0x0000b650,
-		.pstate_mask	= (COMPAT_PSR_T_BIT | COMPAT_PSR_MODE_MASK),
-		.pstate_val	= (COMPAT_PSR_T_BIT | COMPAT_PSR_MODE_USR),
+		.pstate_mask	= (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK),
+		.pstate_val	= (PSR_AA32_T_BIT | PSR_AA32_MODE_USR),
 		.fn		= t16_setend_handler,
 	},
 	{}
arch/arm64/kernel/cpufeature.c +1 -1
index f24892a40d2c..48d813defe5e 100644
@@ -1723,7 +1723,7 @@ static int emulate_mrs(struct pt_regs *regs, u32 insn)
 static struct undef_hook mrs_hook = {
 	.instr_mask = 0xfff00000,
 	.instr_val  = 0xd5300000,
-	.pstate_mask = COMPAT_PSR_MODE_MASK,
+	.pstate_mask = PSR_AA32_MODE_MASK,
 	.pstate_val = PSR_MODE_EL0t,
 	.fn = emulate_mrs,
 };
arch/arm64/kernel/process.c +10 -10
index e10bc363f533..740b31f77ade 100644
@@ -177,16 +177,16 @@ static void print_pstate(struct pt_regs *regs)
 	if (compat_user_mode(regs)) {
 		printk("pstate: %08llx (%c%c%c%c %c %s %s %c%c%c)\n",
 			pstate,
-			pstate & COMPAT_PSR_N_BIT ? 'N' : 'n',
-			pstate & COMPAT_PSR_Z_BIT ? 'Z' : 'z',
-			pstate & COMPAT_PSR_C_BIT ? 'C' : 'c',
-			pstate & COMPAT_PSR_V_BIT ? 'V' : 'v',
-			pstate & COMPAT_PSR_Q_BIT ? 'Q' : 'q',
-			pstate & COMPAT_PSR_T_BIT ? "T32" : "A32",
-			pstate & COMPAT_PSR_E_BIT ? "BE" : "LE",
-			pstate & COMPAT_PSR_A_BIT ? 'A' : 'a',
-			pstate & COMPAT_PSR_I_BIT ? 'I' : 'i',
-			pstate & COMPAT_PSR_F_BIT ? 'F' : 'f');
+			pstate & PSR_AA32_N_BIT ? 'N' : 'n',
+			pstate & PSR_AA32_Z_BIT ? 'Z' : 'z',
+			pstate & PSR_AA32_C_BIT ? 'C' : 'c',
+			pstate & PSR_AA32_V_BIT ? 'V' : 'v',
+			pstate & PSR_AA32_Q_BIT ? 'Q' : 'q',
+			pstate & PSR_AA32_T_BIT ? "T32" : "A32",
+			pstate & PSR_AA32_E_BIT ? "BE" : "LE",
+			pstate & PSR_AA32_A_BIT ? 'A' : 'a',
+			pstate & PSR_AA32_I_BIT ? 'I' : 'i',
+			pstate & PSR_AA32_F_BIT ? 'F' : 'f');
 	} else {
 		printk("pstate: %08llx (%c%c%c%c %c%c%c%c %cPAN %cUAO)\n",
 			pstate,
arch/arm64/kernel/ptrace.c +10 -10
index bc07e8ec062b..ee2677bdc41e 100644
@@ -1681,15 +1681,15 @@ static int valid_compat_regs(struct user_pt_regs *regs)
 
 	if (!system_supports_mixed_endian_el0()) {
 		if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
-			regs->pstate |= COMPAT_PSR_E_BIT;
+			regs->pstate |= PSR_AA32_E_BIT;
 		else
-			regs->pstate &= ~COMPAT_PSR_E_BIT;
+			regs->pstate &= ~PSR_AA32_E_BIT;
 	}
 
 	if (user_mode(regs) && (regs->pstate & PSR_MODE32_BIT) &&
-	    (regs->pstate & COMPAT_PSR_A_BIT) == 0 &&
-	    (regs->pstate & COMPAT_PSR_I_BIT) == 0 &&
-	    (regs->pstate & COMPAT_PSR_F_BIT) == 0) {
+	    (regs->pstate & PSR_AA32_A_BIT) == 0 &&
+	    (regs->pstate & PSR_AA32_I_BIT) == 0 &&
+	    (regs->pstate & PSR_AA32_F_BIT) == 0) {
 		return 1;
 	}
 
@@ -1697,11 +1697,11 @@ static int valid_compat_regs(struct user_pt_regs *regs)
 	 * Force PSR to a valid 32-bit EL0t, preserving the same bits as
 	 * arch/arm.
 	 */
-	regs->pstate &= COMPAT_PSR_N_BIT | COMPAT_PSR_Z_BIT |
-			COMPAT_PSR_C_BIT | COMPAT_PSR_V_BIT |
-			COMPAT_PSR_Q_BIT | COMPAT_PSR_IT_MASK |
-			COMPAT_PSR_GE_MASK | COMPAT_PSR_E_BIT |
-			COMPAT_PSR_T_BIT;
+	regs->pstate &= PSR_AA32_N_BIT | PSR_AA32_Z_BIT |
+			PSR_AA32_C_BIT | PSR_AA32_V_BIT |
+			PSR_AA32_Q_BIT | PSR_AA32_IT_MASK |
+			PSR_AA32_GE_MASK | PSR_AA32_E_BIT |
+			PSR_AA32_T_BIT;
 	regs->pstate |= PSR_MODE32_BIT;
 
 	return 0;
arch/arm64/kernel/signal32.c +5 -5
index fa9fb782f077..9ff4f958c679 100644
@@ -375,22 +375,22 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 {
 	compat_ulong_t handler = ptr_to_compat(ka->sa.sa_handler);
 	compat_ulong_t retcode;
-	compat_ulong_t spsr = regs->pstate & ~(PSR_f | COMPAT_PSR_E_BIT);
+	compat_ulong_t spsr = regs->pstate & ~(PSR_f | PSR_AA32_E_BIT);
 	int thumb;
 
 	/* Check if the handler is written for ARM or Thumb */
 	thumb = handler & 1;
 
 	if (thumb)
-		spsr |= COMPAT_PSR_T_BIT;
+		spsr |= PSR_AA32_T_BIT;
 	else
-		spsr &= ~COMPAT_PSR_T_BIT;
+		spsr &= ~PSR_AA32_T_BIT;
 
 	/* The IT state must be cleared for both ARM and Thumb-2 */
-	spsr &= ~COMPAT_PSR_IT_MASK;
+	spsr &= ~PSR_AA32_IT_MASK;
 
 	/* Restore the original endianness */
-	spsr |= COMPAT_PSR_ENDSTATE;
+	spsr |= PSR_AA32_ENDSTATE;
 
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		retcode = ptr_to_compat(ka->sa.sa_restorer);
Signature · 1 line
2.11.0
author reviewer
#8 lore raw

PATCH 6/7 kvm/arm: use PSR_AA32 definitions

In reply to Mark Rutland

Some code cares about the SPSR_ELx format for exceptions taken from AArch32 to inspect or manipulate the SPSR_ELx value, which is already in the SPSR_ELx format, and not in the AArch32 PSR format.

To separate these from cases where we care about the AArch32 PSR format, migrate these cases to use the PSR_AA32_* definitions rather than COMPAT_PSR_*.

There should be no functional change as a result of this patch.

Note that arm64 KVM does not support a compat KVM API, and always uses the SPSR_ELx format, even for AArch32 guests.

Cc Christoffer Dall <[email protected]>
Cc Marc Zyngier <[email protected]>
---
 arch/arm/include/asm/kvm_emulate.h       | 14 +++++++-------
 arch/arm64/include/asm/kvm_emulate.h     | 10 +++++-----
 arch/arm64/kvm/guest.c                   | 14 +++++++-------
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c |  2 +-
 arch/arm64/kvm/regmap.c                  | 22 +++++++++++-----------
 arch/arm64/kvm/reset.c                   |  4 ++--
 virt/kvm/arm/aarch32.c                   | 20 ++++++++++----------
 7 files changed, 43 insertions(+), 43 deletions(-)
arch/arm/include/asm/kvm_emulate.h +7 -7
index 6493bd479ddc..fe2fb1ddd771 100644
@@ -26,13 +26,13 @@
 #include <asm/cputype.h>
 
 /* arm64 compatibility macros */
-#define COMPAT_PSR_MODE_ABT	ABT_MODE
-#define COMPAT_PSR_MODE_UND	UND_MODE
-#define COMPAT_PSR_T_BIT	PSR_T_BIT
-#define COMPAT_PSR_I_BIT	PSR_I_BIT
-#define COMPAT_PSR_A_BIT	PSR_A_BIT
-#define COMPAT_PSR_E_BIT	PSR_E_BIT
-#define COMPAT_PSR_IT_MASK	PSR_IT_MASK
+#define PSR_AA32_MODE_ABT	ABT_MODE
+#define PSR_AA32_MODE_UND	UND_MODE
+#define PSR_AA32_T_BIT		PSR_T_BIT
+#define PSR_AA32_I_BIT		PSR_I_BIT
+#define PSR_AA32_A_BIT		PSR_A_BIT
+#define PSR_AA32_E_BIT		PSR_E_BIT
+#define PSR_AA32_IT_MASK	PSR_IT_MASK
 
 unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
 
arch/arm64/include/asm/kvm_emulate.h +5 -5
index 1dab3a984608..0c97e45d1dc3 100644
@@ -140,7 +140,7 @@ static inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr)
 
 static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
 {
-	*vcpu_cpsr(vcpu) |= COMPAT_PSR_T_BIT;
+	*vcpu_cpsr(vcpu) |= PSR_AA32_T_BIT;
 }
 
 /*
@@ -190,8 +190,8 @@ static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
 	u32 mode;
 
 	if (vcpu_mode_is_32bit(vcpu)) {
-		mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
-		return mode > COMPAT_PSR_MODE_USR;
+		mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK;
+		return mode > PSR_AA32_MODE_USR;
 	}
 
 	mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
@@ -329,7 +329,7 @@ static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
 static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
 {
 	if (vcpu_mode_is_32bit(vcpu)) {
-		*vcpu_cpsr(vcpu) |= COMPAT_PSR_E_BIT;
+		*vcpu_cpsr(vcpu) |= PSR_AA32_E_BIT;
 	} else {
 		u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1);
 		sctlr |= (1 << 25);
@@ -340,7 +340,7 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
 static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
 {
 	if (vcpu_mode_is_32bit(vcpu))
-		return !!(*vcpu_cpsr(vcpu) & COMPAT_PSR_E_BIT);
+		return !!(*vcpu_cpsr(vcpu) & PSR_AA32_E_BIT);
 
 	return !!(vcpu_read_sys_reg(vcpu, SCTLR_EL1) & (1 << 25));
 }
arch/arm64/kvm/guest.c +7 -7
index 56a0260ceb11..cdd4d9d6d575 100644
@@ -107,14 +107,14 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	}
 
 	if (off == KVM_REG_ARM_CORE_REG(regs.pstate)) {
-		u32 mode = (*(u32 *)valp) & COMPAT_PSR_MODE_MASK;
+		u32 mode = (*(u32 *)valp) & PSR_AA32_MODE_MASK;
 		switch (mode) {
-		case COMPAT_PSR_MODE_USR:
-		case COMPAT_PSR_MODE_FIQ:
-		case COMPAT_PSR_MODE_IRQ:
-		case COMPAT_PSR_MODE_SVC:
-		case COMPAT_PSR_MODE_ABT:
-		case COMPAT_PSR_MODE_UND:
+		case PSR_AA32_MODE_USR:
+		case PSR_AA32_MODE_FIQ:
+		case PSR_AA32_MODE_IRQ:
+		case PSR_AA32_MODE_SVC:
+		case PSR_AA32_MODE_ABT:
+		case PSR_AA32_MODE_UND:
 		case PSR_MODE_EL0t:
 		case PSR_MODE_EL1t:
 		case PSR_MODE_EL1h:
arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c +1 -1
index 39be799d0417..215c7c0eb3b0 100644
@@ -27,7 +27,7 @@
 static bool __hyp_text __is_be(struct kvm_vcpu *vcpu)
 {
 	if (vcpu_mode_is_32bit(vcpu))
-		return !!(read_sysreg_el2(spsr) & COMPAT_PSR_E_BIT);
+		return !!(read_sysreg_el2(spsr) & PSR_AA32_E_BIT);
 
 	return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE);
 }
arch/arm64/kvm/regmap.c +11 -11
index eefe403a2e63..7a5173ea2276 100644
@@ -112,22 +112,22 @@ static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][16] = {
 unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num)
 {
 	unsigned long *reg_array = (unsigned long *)&vcpu->arch.ctxt.gp_regs.regs;
-	unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
+	unsigned long mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK;
 
 	switch (mode) {
-	case COMPAT_PSR_MODE_USR ... COMPAT_PSR_MODE_SVC:
+	case PSR_AA32_MODE_USR ... PSR_AA32_MODE_SVC:
 		mode &= ~PSR_MODE32_BIT; /* 0 ... 3 */
 		break;
 
-	case COMPAT_PSR_MODE_ABT:
+	case PSR_AA32_MODE_ABT:
 		mode = 4;
 		break;
 
-	case COMPAT_PSR_MODE_UND:
+	case PSR_AA32_MODE_UND:
 		mode = 5;
 		break;
 
-	case COMPAT_PSR_MODE_SYS:
+	case PSR_AA32_MODE_SYS:
 		mode = 0;	/* SYS maps to USR */
 		break;
 
@@ -143,13 +143,13 @@ unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num)
  */
 static int vcpu_spsr32_mode(const struct kvm_vcpu *vcpu)
 {
-	unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
+	unsigned long mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK;
 	switch (mode) {
-	case COMPAT_PSR_MODE_SVC: return KVM_SPSR_SVC;
-	case COMPAT_PSR_MODE_ABT: return KVM_SPSR_ABT;
-	case COMPAT_PSR_MODE_UND: return KVM_SPSR_UND;
-	case COMPAT_PSR_MODE_IRQ: return KVM_SPSR_IRQ;
-	case COMPAT_PSR_MODE_FIQ: return KVM_SPSR_FIQ;
+	case PSR_AA32_MODE_SVC: return KVM_SPSR_SVC;
+	case PSR_AA32_MODE_ABT: return KVM_SPSR_ABT;
+	case PSR_AA32_MODE_UND: return KVM_SPSR_UND;
+	case PSR_AA32_MODE_IRQ: return KVM_SPSR_IRQ;
+	case PSR_AA32_MODE_FIQ: return KVM_SPSR_FIQ;
 	default: BUG();
 	}
 }
arch/arm64/kvm/reset.c +2 -2
index a74311beda35..4e4aedaf7ab7 100644
@@ -42,8 +42,8 @@ static const struct kvm_regs default_regs_reset = {
 };
 
 static const struct kvm_regs default_regs_reset32 = {
-	.regs.pstate = (COMPAT_PSR_MODE_SVC | COMPAT_PSR_A_BIT |
-			COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT),
+	.regs.pstate = (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT |
+			PSR_AA32_I_BIT | PSR_AA32_F_BIT),
 };
 
 static bool cpu_has_32bit_el1(void)
virt/kvm/arm/aarch32.c +10 -10
index efc84cbe8277..5abbe9b3c652 100644
@@ -108,9 +108,9 @@ static void __hyp_text kvm_adjust_itstate(struct kvm_vcpu *vcpu)
 {
 	unsigned long itbits, cond;
 	unsigned long cpsr = *vcpu_cpsr(vcpu);
-	bool is_arm = !(cpsr & COMPAT_PSR_T_BIT);
+	bool is_arm = !(cpsr & PSR_AA32_T_BIT);
 
-	if (is_arm || !(cpsr & COMPAT_PSR_IT_MASK))
+	if (is_arm || !(cpsr & PSR_AA32_IT_MASK))
 		return;
 
 	cond = (cpsr & 0xe000) >> 13;
@@ -123,7 +123,7 @@ static void __hyp_text kvm_adjust_itstate(struct kvm_vcpu *vcpu)
 	else
 		itbits = (itbits << 1) & 0x1f;
 
-	cpsr &= ~COMPAT_PSR_IT_MASK;
+	cpsr &= ~PSR_AA32_IT_MASK;
 	cpsr |= cond << 13;
 	cpsr |= (itbits & 0x1c) << (10 - 2);
 	cpsr |= (itbits & 0x3) << 25;
@@ -138,7 +138,7 @@ void __hyp_text kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr)
 {
 	bool is_thumb;
 
-	is_thumb = !!(*vcpu_cpsr(vcpu) & COMPAT_PSR_T_BIT);
+	is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_AA32_T_BIT);
 	if (is_thumb && !is_wide_instr)
 		*vcpu_pc(vcpu) += 2;
 	else
@@ -164,16 +164,16 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
 {
 	unsigned long cpsr;
 	unsigned long new_spsr_value = *vcpu_cpsr(vcpu);
-	bool is_thumb = (new_spsr_value & COMPAT_PSR_T_BIT);
+	bool is_thumb = (new_spsr_value & PSR_AA32_T_BIT);
 	u32 return_offset = return_offsets[vect_offset >> 2][is_thumb];
 	u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);
 
-	cpsr = mode | COMPAT_PSR_I_BIT;
+	cpsr = mode | PSR_AA32_I_BIT;
 
 	if (sctlr & (1 << 30))
-		cpsr |= COMPAT_PSR_T_BIT;
+		cpsr |= PSR_AA32_T_BIT;
 	if (sctlr & (1 << 25))
-		cpsr |= COMPAT_PSR_E_BIT;
+		cpsr |= PSR_AA32_E_BIT;
 
 	*vcpu_cpsr(vcpu) = cpsr;
 
@@ -192,7 +192,7 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
 
 void kvm_inject_undef32(struct kvm_vcpu *vcpu)
 {
-	prepare_fault32(vcpu, COMPAT_PSR_MODE_UND, 4);
+	prepare_fault32(vcpu, PSR_AA32_MODE_UND, 4);
 }
 
 /*
@@ -216,7 +216,7 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
 		fsr = &vcpu_cp15(vcpu, c5_DFSR);
 	}
 
-	prepare_fault32(vcpu, COMPAT_PSR_MODE_ABT | COMPAT_PSR_A_BIT, vect_offset);
+	prepare_fault32(vcpu, PSR_AA32_MODE_ABT | PSR_AA32_A_BIT, vect_offset);
 
 	*far = addr;
 
Signature · 1 line
2.11.0
#9 lore raw

PATCH 6/7 kvm/arm: use PSR_AA32 definitions

Quoted 16 lines · Mark Rutland

Some code cares about the SPSR_ELx format for exceptions taken from AArch32 to inspect or manipulate the SPSR_ELx value, which is already in the SPSR_ELx format, and not in the AArch32 PSR format.

To separate these from cases where we care about the AArch32 PSR format, migrate these cases to use the PSR_AA32_* definitions rather than COMPAT_PSR_*.

There should be no functional change as a result of this patch.

Note that arm64 KVM does not support a compat KVM API, and always uses the SPSR_ELx format, even for AArch32 guests.

Cc Christoffer Dall <[email protected]>
Cc Marc Zyngier <[email protected]>
Quoted 9 lines
---
 arch/arm/include/asm/kvm_emulate.h       | 14 +++++++-------
 arch/arm64/include/asm/kvm_emulate.h     | 10 +++++-----
 arch/arm64/kvm/guest.c                   | 14 +++++++-------
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c |  2 +-
 arch/arm64/kvm/regmap.c                  | 22 +++++++++++-----------
 arch/arm64/kvm/reset.c                   |  4 ++--
 virt/kvm/arm/aarch32.c                   | 20 ++++++++++----------
 7 files changed, 43 insertions(+), 43 deletions(-)

I need an ack from the KVM maintainers before I can take this. I can also put this series on a separate branch if necessary.

Will

#10 lore raw

PATCH 6/7 kvm/arm: use PSR_AA32 definitions

Quoted 27 lines · Will Deacon
Quoted 16 lines · Mark Rutland

Some code cares about the SPSR_ELx format for exceptions taken from AArch32 to inspect or manipulate the SPSR_ELx value, which is already in the SPSR_ELx format, and not in the AArch32 PSR format.

To separate these from cases where we care about the AArch32 PSR format, migrate these cases to use the PSR_AA32_* definitions rather than COMPAT_PSR_*.

There should be no functional change as a result of this patch.

Note that arm64 KVM does not support a compat KVM API, and always uses the SPSR_ELx format, even for AArch32 guests.

Cc Christoffer Dall <[email protected]>
Cc Marc Zyngier <[email protected]>
Quoted 9 lines
---
 arch/arm/include/asm/kvm_emulate.h       | 14 +++++++-------
 arch/arm64/include/asm/kvm_emulate.h     | 10 +++++-----
 arch/arm64/kvm/guest.c                   | 14 +++++++-------
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c |  2 +-
 arch/arm64/kvm/regmap.c                  | 22 +++++++++++-----------
 arch/arm64/kvm/reset.c                   |  4 ++--
 virt/kvm/arm/aarch32.c                   | 20 ++++++++++----------
 7 files changed, 43 insertions(+), 43 deletions(-)
Quoted 2 lines

I need an ack from the KVM maintainers before I can take this. I can also put this series on a separate branch if necessary.

Feel free to add my

I don't have much queued for KVM ATM, so there is no need for a separate branch. Pending stuff shouldn't conflict (famous last word...).

	M.
Signature · 1 line
Jazz is not dead. It just smells funny...
#11 lore raw

PATCH 6/7 kvm/arm: use PSR_AA32 definitions

Quoted 31 lines · Marc Zyngier
Quoted 27 lines · Will Deacon
Quoted 16 lines · Mark Rutland

Some code cares about the SPSR_ELx format for exceptions taken from AArch32 to inspect or manipulate the SPSR_ELx value, which is already in the SPSR_ELx format, and not in the AArch32 PSR format.

To separate these from cases where we care about the AArch32 PSR format, migrate these cases to use the PSR_AA32_* definitions rather than COMPAT_PSR_*.

There should be no functional change as a result of this patch.

Note that arm64 KVM does not support a compat KVM API, and always uses the SPSR_ELx format, even for AArch32 guests.

Cc Christoffer Dall <[email protected]>
Cc Marc Zyngier <[email protected]>
Quoted 9 lines
---
 arch/arm/include/asm/kvm_emulate.h       | 14 +++++++-------
 arch/arm64/include/asm/kvm_emulate.h     | 10 +++++-----
 arch/arm64/kvm/guest.c                   | 14 +++++++-------
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c |  2 +-
 arch/arm64/kvm/regmap.c                  | 22 +++++++++++-----------
 arch/arm64/kvm/reset.c                   |  4 ++--
 virt/kvm/arm/aarch32.c                   | 20 ++++++++++----------
 7 files changed, 43 insertions(+), 43 deletions(-)
Quoted 2 lines

I need an ack from the KVM maintainers before I can take this. I can also put this series on a separate branch if necessary.

Quoted 6 lines

Feel free to add my

I don't have much queued for KVM ATM, so there is no need for a separate branch. Pending stuff shouldn't conflict (famous last word...).

Brill; thanks for the quick reply, Marc.

Will

#12 lore raw

PATCH 6/7 kvm/arm: use PSR_AA32 definitions

In reply to Mark Rutland
Quoted 8 lines · Mark Rutland

Some code cares about the SPSR_ELx format for exceptions taken from AArch32 to inspect or manipulate the SPSR_ELx value, which is already in the SPSR_ELx format, and not in the AArch32 PSR format.

To separate these from cases where we care about the AArch32 PSR format, migrate these cases to use the PSR_AA32_* definitions rather than COMPAT_PSR_*.

Quoted 8 lines

There should be no functional change as a result of this patch.

Note that arm64 KVM does not support a compat KVM API, and always uses the SPSR_ELx format, even for AArch32 guests.

Cc Christoffer Dall <[email protected]>
Cc Marc Zyngier <[email protected]>
Quoted 257 lines
---
 arch/arm/include/asm/kvm_emulate.h       | 14 +++++++-------
 arch/arm64/include/asm/kvm_emulate.h     | 10 +++++-----
 arch/arm64/kvm/guest.c                   | 14 +++++++-------
 arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c |  2 +-
 arch/arm64/kvm/regmap.c                  | 22 +++++++++++-----------
 arch/arm64/kvm/reset.c                   |  4 ++--
 virt/kvm/arm/aarch32.c                   | 20 ++++++++++----------
 7 files changed, 43 insertions(+), 43 deletions(-)
arch/arm/include/asm/kvm_emulate.h +7 -7
index 6493bd479ddc..fe2fb1ddd771 100644
@@ -26,13 +26,13 @@
 #include <asm/cputype.h>
 
 /* arm64 compatibility macros */
-#define COMPAT_PSR_MODE_ABT  ABT_MODE
-#define COMPAT_PSR_MODE_UND  UND_MODE
-#define COMPAT_PSR_T_BIT     PSR_T_BIT
-#define COMPAT_PSR_I_BIT     PSR_I_BIT
-#define COMPAT_PSR_A_BIT     PSR_A_BIT
-#define COMPAT_PSR_E_BIT     PSR_E_BIT
-#define COMPAT_PSR_IT_MASK   PSR_IT_MASK
+#define PSR_AA32_MODE_ABT    ABT_MODE
+#define PSR_AA32_MODE_UND    UND_MODE
+#define PSR_AA32_T_BIT               PSR_T_BIT
+#define PSR_AA32_I_BIT               PSR_I_BIT
+#define PSR_AA32_A_BIT               PSR_A_BIT
+#define PSR_AA32_E_BIT               PSR_E_BIT
+#define PSR_AA32_IT_MASK     PSR_IT_MASK
 
 unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
 
arch/arm64/include/asm/kvm_emulate.h +5 -5
index 1dab3a984608..0c97e45d1dc3 100644
@@ -140,7 +140,7 @@ static inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr)
 
 static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
 {
-     *vcpu_cpsr(vcpu) |= COMPAT_PSR_T_BIT;
+     *vcpu_cpsr(vcpu) |= PSR_AA32_T_BIT;
 }
 
 /*
@@ -190,8 +190,8 @@ static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
      u32 mode;
 
      if (vcpu_mode_is_32bit(vcpu)) {
-             mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
-             return mode > COMPAT_PSR_MODE_USR;
+             mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK;
+             return mode > PSR_AA32_MODE_USR;
      }
 
      mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
@@ -329,7 +329,7 @@ static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
 static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
 {
      if (vcpu_mode_is_32bit(vcpu)) {
-             *vcpu_cpsr(vcpu) |= COMPAT_PSR_E_BIT;
+             *vcpu_cpsr(vcpu) |= PSR_AA32_E_BIT;
      } else {
              u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1);
              sctlr |= (1 << 25);
@@ -340,7 +340,7 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
 static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
 {
      if (vcpu_mode_is_32bit(vcpu))
-             return !!(*vcpu_cpsr(vcpu) & COMPAT_PSR_E_BIT);
+             return !!(*vcpu_cpsr(vcpu) & PSR_AA32_E_BIT);
 
      return !!(vcpu_read_sys_reg(vcpu, SCTLR_EL1) & (1 << 25));
 }
arch/arm64/kvm/guest.c +7 -7
index 56a0260ceb11..cdd4d9d6d575 100644
@@ -107,14 +107,14 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
      }
 
      if (off == KVM_REG_ARM_CORE_REG(regs.pstate)) {
-             u32 mode = (*(u32 *)valp) & COMPAT_PSR_MODE_MASK;
+             u32 mode = (*(u32 *)valp) & PSR_AA32_MODE_MASK;
              switch (mode) {
-             case COMPAT_PSR_MODE_USR:
-             case COMPAT_PSR_MODE_FIQ:
-             case COMPAT_PSR_MODE_IRQ:
-             case COMPAT_PSR_MODE_SVC:
-             case COMPAT_PSR_MODE_ABT:
-             case COMPAT_PSR_MODE_UND:
+             case PSR_AA32_MODE_USR:
+             case PSR_AA32_MODE_FIQ:
+             case PSR_AA32_MODE_IRQ:
+             case PSR_AA32_MODE_SVC:
+             case PSR_AA32_MODE_ABT:
+             case PSR_AA32_MODE_UND:
              case PSR_MODE_EL0t:
              case PSR_MODE_EL1t:
              case PSR_MODE_EL1h:
arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c +1 -1
index 39be799d0417..215c7c0eb3b0 100644
@@ -27,7 +27,7 @@
 static bool __hyp_text __is_be(struct kvm_vcpu *vcpu)
 {
      if (vcpu_mode_is_32bit(vcpu))
-             return !!(read_sysreg_el2(spsr) & COMPAT_PSR_E_BIT);
+             return !!(read_sysreg_el2(spsr) & PSR_AA32_E_BIT);
 
      return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE);
 }
arch/arm64/kvm/regmap.c +11 -11
index eefe403a2e63..7a5173ea2276 100644
@@ -112,22 +112,22 @@ static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][16] = {
 unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num)
 {
      unsigned long *reg_array = (unsigned long *)&vcpu->arch.ctxt.gp_regs.regs;
-     unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
+     unsigned long mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK;
 
      switch (mode) {
-     case COMPAT_PSR_MODE_USR ... COMPAT_PSR_MODE_SVC:
+     case PSR_AA32_MODE_USR ... PSR_AA32_MODE_SVC:
              mode &= ~PSR_MODE32_BIT; /* 0 ... 3 */
              break;
 
-     case COMPAT_PSR_MODE_ABT:
+     case PSR_AA32_MODE_ABT:
              mode = 4;
              break;
 
-     case COMPAT_PSR_MODE_UND:
+     case PSR_AA32_MODE_UND:
              mode = 5;
              break;
 
-     case COMPAT_PSR_MODE_SYS:
+     case PSR_AA32_MODE_SYS:
              mode = 0;       /* SYS maps to USR */
              break;
 
@@ -143,13 +143,13 @@ unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num)
  */
 static int vcpu_spsr32_mode(const struct kvm_vcpu *vcpu)
 {
-     unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
+     unsigned long mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK;
      switch (mode) {
-     case COMPAT_PSR_MODE_SVC: return KVM_SPSR_SVC;
-     case COMPAT_PSR_MODE_ABT: return KVM_SPSR_ABT;
-     case COMPAT_PSR_MODE_UND: return KVM_SPSR_UND;
-     case COMPAT_PSR_MODE_IRQ: return KVM_SPSR_IRQ;
-     case COMPAT_PSR_MODE_FIQ: return KVM_SPSR_FIQ;
+     case PSR_AA32_MODE_SVC: return KVM_SPSR_SVC;
+     case PSR_AA32_MODE_ABT: return KVM_SPSR_ABT;
+     case PSR_AA32_MODE_UND: return KVM_SPSR_UND;
+     case PSR_AA32_MODE_IRQ: return KVM_SPSR_IRQ;
+     case PSR_AA32_MODE_FIQ: return KVM_SPSR_FIQ;
      default: BUG();
      }
 }
arch/arm64/kvm/reset.c +2 -2
index a74311beda35..4e4aedaf7ab7 100644
@@ -42,8 +42,8 @@ static const struct kvm_regs default_regs_reset = {
 };
 
 static const struct kvm_regs default_regs_reset32 = {
-     .regs.pstate = (COMPAT_PSR_MODE_SVC | COMPAT_PSR_A_BIT |
-                     COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT),
+     .regs.pstate = (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT |
+                     PSR_AA32_I_BIT | PSR_AA32_F_BIT),
 };
 
 static bool cpu_has_32bit_el1(void)
virt/kvm/arm/aarch32.c +10 -11
index efc84cbe8277..5abbe9b3c652 100644
@@ -108,9 +108,9 @@ static void __hyp_text kvm_adjust_itstate(struct kvm_vcpu *vcpu)
 {
      unsigned long itbits, cond;
      unsigned long cpsr = *vcpu_cpsr(vcpu);
-     bool is_arm = !(cpsr & COMPAT_PSR_T_BIT);
+     bool is_arm = !(cpsr & PSR_AA32_T_BIT);
 
-     if (is_arm || !(cpsr & COMPAT_PSR_IT_MASK))
+     if (is_arm || !(cpsr & PSR_AA32_IT_MASK))
              return;
 
      cond = (cpsr & 0xe000) >> 13;
@@ -123,7 +123,7 @@ static void __hyp_text kvm_adjust_itstate(struct kvm_vcpu *vcpu)
      else
              itbits = (itbits << 1) & 0x1f;
 
-     cpsr &= ~COMPAT_PSR_IT_MASK;
+     cpsr &= ~PSR_AA32_IT_MASK;
      cpsr |= cond << 13;
      cpsr |= (itbits & 0x1c) << (10 - 2);
      cpsr |= (itbits & 0x3) << 25;
@@ -138,7 +138,7 @@ void __hyp_text kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr)
 {
      bool is_thumb;
 
-     is_thumb = !!(*vcpu_cpsr(vcpu) & COMPAT_PSR_T_BIT);
+     is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_AA32_T_BIT);
      if (is_thumb && !is_wide_instr)
              *vcpu_pc(vcpu) += 2;
      else
@@ -164,16 +164,16 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
 {
      unsigned long cpsr;
      unsigned long new_spsr_value = *vcpu_cpsr(vcpu);
-     bool is_thumb = (new_spsr_value & COMPAT_PSR_T_BIT);
+     bool is_thumb = (new_spsr_value & PSR_AA32_T_BIT);
      u32 return_offset = return_offsets[vect_offset >> 2][is_thumb];
      u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);
 
-     cpsr = mode | COMPAT_PSR_I_BIT;
+     cpsr = mode | PSR_AA32_I_BIT;
 
      if (sctlr & (1 << 30))
-             cpsr |= COMPAT_PSR_T_BIT;
+             cpsr |= PSR_AA32_T_BIT;
      if (sctlr & (1 << 25))
-             cpsr |= COMPAT_PSR_E_BIT;
+             cpsr |= PSR_AA32_E_BIT;
 
      *vcpu_cpsr(vcpu) = cpsr;
 
@@ -192,7 +192,7 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
 
 void kvm_inject_undef32(struct kvm_vcpu *vcpu)
 {
-     prepare_fault32(vcpu, COMPAT_PSR_MODE_UND, 4);
+     prepare_fault32(vcpu, PSR_AA32_MODE_UND, 4);
 }
 
 /*
@@ -216,7 +216,7 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
              fsr = &vcpu_cp15(vcpu, c5_DFSR);
      }
 
-     prepare_fault32(vcpu, COMPAT_PSR_MODE_ABT | COMPAT_PSR_A_BIT, vect_offset);
+     prepare_fault32(vcpu, PSR_AA32_MODE_ABT | PSR_AA32_A_BIT, vect_offset);
 
      *far = addr;
 
--
Quoted 2 lines

2.11.0

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

author reviewer
#13 lore raw

PATCH 7/7 arm64: remove unused COMPAT_PSR definitions

In reply to Mark Rutland

Now that users have been migrated to PSR_AA32, kill the unused COMPAT_PSR definitions.

The only difference we need a definition for is COMPAT_PSR_DIT_BIT, which differs from PSR_AA32_DIT_BIT.

Cc Catalin Marinas <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/include/asm/ptrace.h | 28 ----------------------------
 1 file changed, 28 deletions(-)
arch/arm64/include/asm/ptrace.h +0 -28
index ee27468a1ba6..550c64dd83cb 100644
@@ -66,35 +66,7 @@
 #endif
 
 /* AArch32 CPSR bits, as seen in AArch32 */
-#define COMPAT_PSR_MODE_MASK	0x0000001f
-#define COMPAT_PSR_MODE_USR	0x00000010
-#define COMPAT_PSR_MODE_FIQ	0x00000011
-#define COMPAT_PSR_MODE_IRQ	0x00000012
-#define COMPAT_PSR_MODE_SVC	0x00000013
-#define COMPAT_PSR_MODE_ABT	0x00000017
-#define COMPAT_PSR_MODE_HYP	0x0000001a
-#define COMPAT_PSR_MODE_UND	0x0000001b
-#define COMPAT_PSR_MODE_SYS	0x0000001f
-#define COMPAT_PSR_T_BIT	0x00000020
-#define COMPAT_PSR_F_BIT	0x00000040
-#define COMPAT_PSR_I_BIT	0x00000080
-#define COMPAT_PSR_A_BIT	0x00000100
-#define COMPAT_PSR_E_BIT	0x00000200
 #define COMPAT_PSR_DIT_BIT	0x00200000
-#define COMPAT_PSR_J_BIT	0x01000000
-#define COMPAT_PSR_Q_BIT	0x08000000
-#define COMPAT_PSR_V_BIT	0x10000000
-#define COMPAT_PSR_C_BIT	0x20000000
-#define COMPAT_PSR_Z_BIT	0x40000000
-#define COMPAT_PSR_N_BIT	0x80000000
-#define COMPAT_PSR_IT_MASK	0x0600fc00	/* If-Then execution state mask */
-#define COMPAT_PSR_GE_MASK	0x000f0000
-
-#ifdef CONFIG_CPU_BIG_ENDIAN
-#define COMPAT_PSR_ENDSTATE	COMPAT_PSR_E_BIT
-#else
-#define COMPAT_PSR_ENDSTATE	0
-#endif
 
 static inline unsigned long compat_psr_to_pstate(const unsigned long psr)
 {
Signature · 1 line
2.11.0
#14 lore raw

cover arm64: PSR <-> SPSR_ELx mapping fixes

In reply to Mark Rutland

Mark,

Quoted 7 lines · Mark Rutland

The SPSR_ELx format has diverged from the AArch32-native SPSR format since the addition of DIT. Thus, we need to map between the two for certain compat operations.

Also, when we added support for DIT, we forgot to account for this in valid_user_regs(), causing PSTATE.DIT to be cleared upon sigreturn.

Quoted 6 lines

These patches (based on v4.18-rc2) fix those issues, cleaning up the COMPAT_PSR definitions to try to avoid confusiong in future.

The COMPAT_PSR_ definitions are now used for the AArch32-native SPR format (i.e. they are the compat userspace view), with PSR_AA32_ definitions used for the AArch64 view of the PSR for AArch32 tasks.

I applied this, but it doesn't even build with defconfig :(

How much testing has this seen? I also get some other errors because code is trying to refer to COMPAT definitions that you've removed. So I've dropped all of this for now.

arch/arm64/include/asm/ptrace.h: Assembler messages:
arch/arm64/include/asm/ptrace.h:71: Error: unknown mnemonic static' -- static inline unsigned long compat_psr_to_pstate(const unsigned long psr)' arch/arm64/include/asm/ptrace.h:72: Error: junk at end of line, first unrecognised character is {' arch/arm64/include/asm/ptrace.h:73: Error: unknown mnemonic unsigned' -- unsigned long pstate' arch/arm64/include/asm/ptrace.h:77: Error: unknown mnemonic if' -- `if (psr&0x00200000)'
arch/arm64/include/asm/ptrace.h:78: Error: unknown mnemonic pstate' -- pstate |=0x01000000' arch/arm64/include/asm/ptrace.h:80: Error: unknown mnemonic return' -- return pstate'
arch/arm64/include/asm/ptrace.h:81: Error: junk at end of line, first unrecognised character is }' arch/arm64/include/asm/ptrace.h:83: Error: unknown mnemonic static' -- static inline unsigned long pstate_to_compat_psr(const unsigned long pstate)' arch/arm64/include/asm/ptrace.h:84: Error: junk at end of line, first unrecognised character is {' arch/arm64/include/asm/ptrace.h:85: Error: unknown mnemonic unsigned' -- unsigned long psr' arch/arm64/include/asm/ptrace.h:89: Error: unknown mnemonic if' -- if (pstate&0x01000000)' arch/arm64/include/asm/ptrace.h:90: Error: unknown mnemonic psr' -- psr |=0x00200000'
arch/arm64/include/asm/ptrace.h:92: Error: unknown mnemonic return' -- return psr'
arch/arm64/include/asm/ptrace.h:93: Error: junk at end of line, first unrecognised character is `}'
/tmp/ccvDpb9g.s: Error: symbol definition loop encountered at `pstate'
/tmp/ccvDpb9g.s: Error: invalid operands (*GAS expr' section* and *ABS* sections) for &' when setting `psr' /tmp/ccvDpb9g.s: Error: Invalid operation on symbol
/tmp/ccvDpb9g.s: Error: can't resolve value for symbol `pstate'
make[2]: *** [arch/arm64/crypto/sha1-ce-core.o] Error 1

Will

author reviewer
#15 lore raw

cover arm64: PSR <-> SPSR_ELx mapping fixes

Quoted 13 lines · Will Deacon

Mark,

Quoted 10 lines · Mark Rutland

The SPSR_ELx format has diverged from the AArch32-native SPSR format since the addition of DIT. Thus, we need to map between the two for certain compat operations.

Also, when we added support for DIT, we forgot to account for this in valid_user_regs(), causing PSTATE.DIT to be cleared upon sigreturn.

These patches (based on v4.18-rc2) fix those issues, cleaning up the COMPAT_PSR definitions to try to avoid confusiong in future.

Quoted 7 lines
Quoted 3 lines

The COMPAT_PSR_ definitions are now used for the AArch32-native SPR format (i.e. they are the compat userspace view), with PSR_AA32_ definitions used for the AArch64 view of the PSR for AArch32 tasks.

I applied this, but it doesn't even build with defconfig :(

How much testing has this seen?

Quite evidently, none.

Quoted 2 lines

I also get some other errors because code is trying to refer to COMPAT definitions that you've removed. So I've dropped all of this for now.

Understood.

I will fix these up, make sure that the resulting series builds cleanly at every step, and send that out as a v2 shortly.

Sorry for this mess.

Mark.