arm64: sysreg: Clean up instructions for modifying PSTATE fields
authorSuzuki K Poulose <suzuki.poulose@arm.com>
Sun, 16 Sep 2018 22:17:23 +0000 (23:17 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 17 Sep 2018 13:56:01 +0000 (14:56 +0100)
Instructions for modifying the PSTATE fields which were not supported
in the older toolchains (e.g, PAN, UAO) are generated using macros.
We have so far used the normal sys_reg() helper for defining the PSTATE
fields. While this works fine, it is really difficult to correlate the
code with the Arm ARM definition.

As per Arm ARM, the PSTATE fields are defined only using Op1, Op2 fields,
with fixed values for Op0, CRn. Also the CRm field has been reserved
for the Immediate value for the instruction. So using the sys_reg()
looks quite confusing.

This patch cleans up the instruction helpers by bringing them
in line with the Arm ARM definitions to make it easier to correlate
code with the document. No functional changes.

Cc: Will Deacon <will.deacon@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/sysreg.h
arch/arm64/kernel/cpufeature.c

index 3091ae5..7e9ab1f 100644 (file)
 
 #endif /* CONFIG_BROKEN_GAS_INST */
 
-#define REG_PSTATE_PAN_IMM             sys_reg(0, 0, 4, 0, 4)
-#define REG_PSTATE_UAO_IMM             sys_reg(0, 0, 4, 0, 3)
-#define REG_PSTATE_SSBS_IMM            sys_reg(0, 3, 4, 0, 1)
-
-#define SET_PSTATE_PAN(x) __emit_inst(0xd5000000 | REG_PSTATE_PAN_IMM |        \
-                                     (!!x)<<8 | 0x1f)
-#define SET_PSTATE_UAO(x) __emit_inst(0xd5000000 | REG_PSTATE_UAO_IMM |        \
-                                     (!!x)<<8 | 0x1f)
-#define SET_PSTATE_SSBS(x) __emit_inst(0xd5000000 | REG_PSTATE_SSBS_IMM | \
-                                      (!!x)<<8 | 0x1f)
+/*
+ * Instructions for modifying PSTATE fields.
+ * As per Arm ARM for v8-A, Section "C.5.1.3 op0 == 0b00, architectural hints,
+ * barriers and CLREX, and PSTATE access", ARM DDI 0487 C.a, system instructions
+ * for accessing PSTATE fields have the following encoding:
+ *     Op0 = 0, CRn = 4
+ *     Op1, Op2 encodes the PSTATE field modified and defines the constraints.
+ *     CRm = Imm4 for the instruction.
+ *     Rt = 0x1f
+ */
+#define pstate_field(op1, op2)         ((op1) << Op1_shift | (op2) << Op2_shift)
+#define PSTATE_Imm_shift               CRm_shift
+
+#define PSTATE_PAN                     pstate_field(0, 4)
+#define PSTATE_UAO                     pstate_field(0, 3)
+#define PSTATE_SSBS                    pstate_field(3, 1)
+
+#define SET_PSTATE_PAN(x)              __emit_inst(0xd500401f | PSTATE_PAN | ((!!x) << PSTATE_Imm_shift))
+#define SET_PSTATE_UAO(x)              __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift))
+#define SET_PSTATE_SSBS(x)             __emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift))
 
 #define SYS_DC_ISW                     sys_insn(1, 0, 7, 6, 2)
 #define SYS_DC_CSW                     sys_insn(1, 0, 7, 10, 2)
index 35796ca..f15e2fb 100644 (file)
@@ -1045,7 +1045,7 @@ static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr)
        if (user_mode(regs))
                return 1;
 
-       if (instr & BIT(CRm_shift))
+       if (instr & BIT(PSTATE_Imm_shift))
                regs->pstate |= PSR_SSBS_BIT;
        else
                regs->pstate &= ~PSR_SSBS_BIT;
@@ -1055,8 +1055,8 @@ static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr)
 }
 
 static struct undef_hook ssbs_emulation_hook = {
-       .instr_mask     = ~(1U << CRm_shift),
-       .instr_val      = 0xd500001f | REG_PSTATE_SSBS_IMM,
+       .instr_mask     = ~(1U << PSTATE_Imm_shift),
+       .instr_val      = 0xd500401f | PSTATE_SSBS,
        .fn             = ssbs_emulation_handler,
 };