diff options
-rw-r--r-- | arch/arm64/include/asm/sysreg.h | 30 | ||||
-rw-r--r-- | arch/arm64/kernel/cpufeature.c | 6 |
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 | ||
1057 | static struct undef_hook ssbs_emulation_hook = { | 1057 | static 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 | ||