mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 11:46:58 +00:00
target/arm: Add assertion about FSC format for syndrome registers
In tlb_fill() we construct a syndrome register value from a fault status register value which is filled in by arm_tlb_fill(). arm_tlb_fill() returns FSR values which might be in the format used with short-format page descriptors, or the format used with long-format (LPAE) descriptors. The syndrome register always uses LPAE-format FSR status codes. It isn't actually possible to end up delivering a syndrome register value to the guest for a fault which is reported with a short-format FSR (that kind of stage 1 fault will only happen for an AArch32 translation regime which doesn't have a syndrome register, and can never be redirected to an AArch64 or Hyp exception level). Add an assertion which checks this, and adjust the code so that we construct a syndrome with an invalid status code, rather than allowing set bits in the FSR input to randomly corrupt other fields in the syndrome. Backports commit 65ed2ed90d9d81fd4b639029be850ea5651f919f from qemu
This commit is contained in:
parent
1cf80d7536
commit
e9d507a193
|
@ -129,7 +129,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
|
|||
if (unlikely(ret)) {
|
||||
ARMCPU *cpu = ARM_CPU(cs->uc, cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
uint32_t syn, exc;
|
||||
uint32_t syn, exc, fsc;
|
||||
unsigned int target_el;
|
||||
bool same_el;
|
||||
|
||||
|
@ -144,19 +144,32 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
|
|||
env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
|
||||
}
|
||||
same_el = arm_current_el(env) == target_el;
|
||||
/* AArch64 syndrome does not have an LPAE bit */
|
||||
syn = fsr & ~(1 << 9);
|
||||
|
||||
if (fsr & (1 << 9)) {
|
||||
/* LPAE format fault status register : bottom 6 bits are
|
||||
* status code in the same form as needed for syndrome
|
||||
*/
|
||||
fsc = extract32(fsr, 0, 6);
|
||||
} else {
|
||||
/* Short format FSR : this fault will never actually be reported
|
||||
* to an EL that uses a syndrome register. Check that here,
|
||||
* and use a (currently) reserved FSR code in case the constructed
|
||||
* syndrome does leak into the guest somehow.
|
||||
*/
|
||||
assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
|
||||
fsc = 0x3f;
|
||||
}
|
||||
|
||||
/* For insn and data aborts we assume there is no instruction syndrome
|
||||
* information; this is always true for exceptions reported to EL1.
|
||||
*/
|
||||
if (access_type == MMU_INST_FETCH) {
|
||||
syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn);
|
||||
syn = syn_insn_abort(same_el, 0, fi.s1ptw, fsc);
|
||||
exc = EXCP_PREFETCH_ABORT;
|
||||
} else {
|
||||
syn = merge_syn_data_abort(env->exception.syndrome, target_el,
|
||||
same_el, fi.s1ptw,
|
||||
access_type == MMU_DATA_STORE, syn);
|
||||
access_type == MMU_DATA_STORE, fsc);
|
||||
if (access_type == MMU_DATA_STORE
|
||||
&& arm_feature(env, ARM_FEATURE_V6)) {
|
||||
fsr |= (1 << 11);
|
||||
|
|
Loading…
Reference in a new issue