target/arm: Add in_prot_check to S1Translate
Separate the access_type from the protection check. Save the trouble of modifying all helper functions by passing the new data in the control structure. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250830054128.448363-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
76fea60908
commit
015cefc0ed
1 changed files with 14 additions and 5 deletions
|
|
@ -64,6 +64,12 @@ typedef struct S1Translate {
|
|||
* Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}.
|
||||
*/
|
||||
bool in_s1_is_el0;
|
||||
/*
|
||||
* The set of PAGE_* bits to be use in the permission check.
|
||||
* This is normally directly related to the access_type, but
|
||||
* may be suppressed for debug or AT insns.
|
||||
*/
|
||||
uint8_t in_prot_check;
|
||||
bool out_rw;
|
||||
bool out_be;
|
||||
ARMSecuritySpace out_space;
|
||||
|
|
@ -581,6 +587,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
|
|||
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
|
||||
.in_space = s2_space,
|
||||
.in_debug = true,
|
||||
.in_prot_check = PAGE_READ,
|
||||
};
|
||||
GetPhysAddrResult s2 = { };
|
||||
|
||||
|
|
@ -1089,7 +1096,7 @@ static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw,
|
|||
}
|
||||
result->f.prot = ap_to_rw_prot(env, ptw->in_mmu_idx, ap, domain_prot);
|
||||
result->f.prot |= result->f.prot ? PAGE_EXEC : 0;
|
||||
if (!(result->f.prot & (1 << access_type))) {
|
||||
if (ptw->in_prot_check & ~result->f.prot) {
|
||||
/* Access permission fault. */
|
||||
fi->type = ARMFault_Permission;
|
||||
goto do_fault;
|
||||
|
|
@ -1243,7 +1250,7 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
|
|||
|
||||
result->f.prot = get_S1prot(env, mmu_idx, false, user_rw, prot_rw,
|
||||
xn, pxn, result->f.attrs.space, out_space);
|
||||
if (!(result->f.prot & (1 << access_type))) {
|
||||
if (ptw->in_prot_check & ~result->f.prot) {
|
||||
/* Access permission fault. */
|
||||
fi->type = ARMFault_Permission;
|
||||
goto do_fault;
|
||||
|
|
@ -2123,7 +2130,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
|||
result->f.tlb_fill_flags = 0;
|
||||
}
|
||||
|
||||
if (!(result->f.prot & (1 << access_type))) {
|
||||
if (ptw->in_prot_check & ~result->f.prot) {
|
||||
fi->type = ARMFault_Permission;
|
||||
goto do_fault;
|
||||
}
|
||||
|
|
@ -2537,7 +2544,7 @@ static bool get_phys_addr_pmsav7(CPUARMState *env,
|
|||
|
||||
fi->type = ARMFault_Permission;
|
||||
fi->level = 1;
|
||||
return !(result->f.prot & (1 << access_type));
|
||||
return (ptw->in_prot_check & ~result->f.prot) != 0;
|
||||
}
|
||||
|
||||
static uint32_t *regime_rbar(CPUARMState *env, ARMMMUIdx mmu_idx,
|
||||
|
|
@ -2953,7 +2960,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env,
|
|||
}
|
||||
}
|
||||
|
||||
ret = pmsav8_mpu_lookup(env, address, access_type, 1 << access_type,
|
||||
ret = pmsav8_mpu_lookup(env, address, access_type, ptw->in_prot_check,
|
||||
mmu_idx, secure, result, fi, NULL);
|
||||
if (sattrs.subpage) {
|
||||
result->f.lg_page_size = 0;
|
||||
|
|
@ -3625,6 +3632,7 @@ bool get_phys_addr(CPUARMState *env, vaddr address,
|
|||
S1Translate ptw = {
|
||||
.in_mmu_idx = mmu_idx,
|
||||
.in_space = arm_mmu_idx_to_security_space(env, mmu_idx),
|
||||
.in_prot_check = 1 << access_type,
|
||||
};
|
||||
|
||||
return get_phys_addr_gpc(env, &ptw, address, access_type,
|
||||
|
|
@ -3638,6 +3646,7 @@ static hwaddr arm_cpu_get_phys_page(CPUARMState *env, vaddr addr,
|
|||
.in_mmu_idx = mmu_idx,
|
||||
.in_space = arm_mmu_idx_to_security_space(env, mmu_idx),
|
||||
.in_debug = true,
|
||||
.in_prot_check = PAGE_READ,
|
||||
};
|
||||
GetPhysAddrResult res = {};
|
||||
ARMMMUFaultInfo fi = {};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue