summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/include/asm/sysreg.h30
-rw-r--r--arch/arm64/kernel/cpufeature.c6
2 files changed, 23 insertions, 13 deletions
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 3091ae5975a3..7e9ab1fa090c 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -84,16 +84,26 @@
84 84
85#endif /* CONFIG_BROKEN_GAS_INST */ 85#endif /* CONFIG_BROKEN_GAS_INST */
86 86
87#define REG_PSTATE_PAN_IMM sys_reg(0, 0, 4, 0, 4) 87/*
88#define REG_PSTATE_UAO_IMM sys_reg(0, 0, 4, 0, 3) 88 * Instructions for modifying PSTATE fields.
89#define REG_PSTATE_SSBS_IMM sys_reg(0, 3, 4, 0, 1) 89 * As per Arm ARM for v8-A, Section "C.5.1.3 op0 == 0b00, architectural hints,
90 90 * barriers and CLREX, and PSTATE access", ARM DDI 0487 C.a, system instructions
91#define SET_PSTATE_PAN(x) __emit_inst(0xd5000000 | REG_PSTATE_PAN_IMM | \ 91 * for accessing PSTATE fields have the following encoding:
92 (!!x)<<8 | 0x1f) 92 * Op0 = 0, CRn = 4
93#define SET_PSTATE_UAO(x) __emit_inst(0xd5000000 | REG_PSTATE_UAO_IMM | \ 93 * Op1, Op2 encodes the PSTATE field modified and defines the constraints.
94 (!!x)<<8 | 0x1f) 94 * CRm = Imm4 for the instruction.
95#define SET_PSTATE_SSBS(x) __emit_inst(0xd5000000 | REG_PSTATE_SSBS_IMM | \ 95 * Rt = 0x1f
96 (!!x)<<8 | 0x1f) 96 */
97#define pstate_field(op1, op2) ((op1) << Op1_shift | (op2) << Op2_shift)
98#define PSTATE_Imm_shift CRm_shift
99
100#define PSTATE_PAN pstate_field(0, 4)
101#define PSTATE_UAO pstate_field(0, 3)
102#define PSTATE_SSBS pstate_field(3, 1)
103
104#define SET_PSTATE_PAN(x) __emit_inst(0xd500401f | PSTATE_PAN | ((!!x) << PSTATE_Imm_shift))
105#define SET_PSTATE_UAO(x) __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift))
106#define SET_PSTATE_SSBS(x) __emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift))
97 107
98#define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2) 108#define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2)
99#define SYS_DC_CSW sys_insn(1, 0, 7, 10, 2) 109#define SYS_DC_CSW sys_insn(1, 0, 7, 10, 2)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 35796ca1db50..f15e2fb97011 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1045,7 +1045,7 @@ static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr)
1045 if (user_mode(regs)) 1045 if (user_mode(regs))
1046 return 1; 1046 return 1;
1047 1047
1048 if (instr & BIT(CRm_shift)) 1048 if (instr & BIT(PSTATE_Imm_shift))
1049 regs->pstate |= PSR_SSBS_BIT; 1049 regs->pstate |= PSR_SSBS_BIT;
1050 else 1050 else
1051 regs->pstate &= ~PSR_SSBS_BIT; 1051 regs->pstate &= ~PSR_SSBS_BIT;
@@ -1055,8 +1055,8 @@ static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr)
1055} 1055}
1056 1056
1057static struct undef_hook ssbs_emulation_hook = { 1057static struct undef_hook ssbs_emulation_hook = {
1058 .instr_mask = ~(1U << CRm_shift), 1058 .instr_mask = ~(1U << PSTATE_Imm_shift),
1059 .instr_val = 0xd500001f | REG_PSTATE_SSBS_IMM, 1059 .instr_val = 0xd500401f | PSTATE_SSBS,
1060 .fn = ssbs_emulation_handler, 1060 .fn = ssbs_emulation_handler,
1061}; 1061};
1062 1062