target/arm: Update MSR access for PAN

For aarch64, there's a dedicated msr (imm, reg) insn.
For aarch32, this is done via msr to cpsr. Writes from el0
are ignored, which is already handled by the CPSR_USER mask.

Backports commit 220f508f49c5f49fb771d5105f991c19ffede3f7 from qemu
This commit is contained in:
Richard Henderson 2020-03-21 17:32:03 -04:00 committed by Lioncash
parent 50bb867a6f
commit 35fab80c57
4 changed files with 40 additions and 0 deletions

View file

@ -1071,6 +1071,7 @@ void pmu_init(ARMCPU *cpu);
#define CPSR_IT_2_7 (0xfc00U)
#define CPSR_GE (0xfU << 16)
#define CPSR_IL (1U << 20)
#define CPSR_PAN (1U << 22)
#define CPSR_J (1U << 24)
#define CPSR_IT_0_1 (3U << 25)
#define CPSR_Q (1U << 27)
@ -1135,6 +1136,7 @@ void pmu_init(ARMCPU *cpu);
#define PSTATE_BTYPE (3U << 10)
#define PSTATE_IL (1U << 20)
#define PSTATE_SS (1U << 21)
#define PSTATE_PAN (1U << 22)
#define PSTATE_V (1U << 28)
#define PSTATE_C (1U << 29)
#define PSTATE_Z (1U << 30)

View file

@ -3938,6 +3938,24 @@ static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->daif = value & PSTATE_DAIF;
}
static uint64_t aa64_pan_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
return env->pstate & PSTATE_PAN;
}
static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN);
}
static const ARMCPRegInfo pan_reginfo = {
.name = "PAN", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 3,
.type = ARM_CP_NO_RAW, .access = PL1_RW,
.readfn = aa64_pan_read, .writefn = aa64_pan_write
};
static CPAccessResult aa64_cacheop_access(CPUARMState *env,
const ARMCPRegInfo *ri,
bool isread)
@ -7370,6 +7388,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
if (cpu_isar_feature(aa64_lor, cpu)) {
define_arm_cp_regs(cpu, lor_reginfo);
}
if (cpu_isar_feature(aa64_pan, cpu)) {
define_one_arm_cp_reg(cpu, &pan_reginfo);
}
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
define_arm_cp_regs(cpu, vhe_reginfo);

View file

@ -1083,6 +1083,9 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
if (isar_feature_jazelle(id)) {
valid |= CPSR_J;
}
if (isar_feature_aa32_pan(id)) {
valid |= CPSR_PAN;
}
return valid;
}
@ -1095,6 +1098,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
if (isar_feature_aa64_bti(id)) {
valid |= PSTATE_BTYPE;
}
if (isar_feature_aa64_pan(id)) {
valid |= PSTATE_PAN;
}
return valid;
}

View file

@ -1798,6 +1798,17 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
s->base.is_jmp = DISAS_NEXT;
break;
case 0x04: /* PAN */
if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) {
goto do_unallocated;
}
if (crm & 1) {
set_pstate_bits(s, PSTATE_PAN);
} else {
clear_pstate_bits(s, PSTATE_PAN);
}
break;
case 0x05: /* SPSel */
if (s->current_el == 0) {
goto do_unallocated;