linux-user/aarch64: Check syndrome for EXCP_UDEF
Note that we have been passing the incorrect code for most exception codes: uncategorized (do_el0_undef), systemregistertrap (do_el0_sys), smetrap (do_sme_acc), btitrap (do_el0_bti) and illegalstate (bad_el0_sync). Only pacfail uses ILL_ILLOPN (do_el0_fpac). Note that EC_MOP (do_el0_mops) ought not signal at all. For now, preserve existing behavior signalling ILL_ILLOPN. List all other exception codes and document why they do not apply to user-only. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250830054128.448363-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
71eba04575
commit
5fe3151c5e
1 changed files with 74 additions and 1 deletions
|
|
@ -65,6 +65,79 @@ static void signal_for_exception(CPUARMState *env, vaddr addr)
|
|||
si_code = TARGET_BUS_ADRALN;
|
||||
break;
|
||||
|
||||
case EC_UNCATEGORIZED: /* E.g. undefined instruction */
|
||||
case EC_SYSTEMREGISTERTRAP: /* E.g. inaccessible register */
|
||||
case EC_SMETRAP: /* E.g. invalid insn in streaming state */
|
||||
case EC_BTITRAP: /* E.g. invalid guarded branch target */
|
||||
case EC_ILLEGALSTATE:
|
||||
/*
|
||||
* Illegal state happens via an ERET from a privileged mode,
|
||||
* so is not normally possible from user-only. However, gdbstub
|
||||
* is not prevented from writing CPSR_IL, aka PSTATE.IL, which
|
||||
* would generate a trap from the next translated block.
|
||||
* In the kernel, default case -> el0_inv -> bad_el0_sync.
|
||||
*/
|
||||
si_signo = TARGET_SIGILL;
|
||||
si_code = TARGET_ILL_ILLOPC;
|
||||
break;
|
||||
|
||||
case EC_PACFAIL:
|
||||
si_signo = TARGET_SIGILL;
|
||||
si_code = TARGET_ILL_ILLOPN;
|
||||
break;
|
||||
|
||||
case EC_MOP:
|
||||
/*
|
||||
* FIXME: The kernel fixes up wrong-option exceptions.
|
||||
* For QEMU linux-user mode, you can only get these if
|
||||
* the process is doing something silly (not executing
|
||||
* the MOPS instructions in the required P/M/E sequence),
|
||||
* so it is not a problem in practice that we do not.
|
||||
*
|
||||
* We ought ideally to implement the same "rewind to the
|
||||
* start of the sequence" logic that the kernel does in
|
||||
* arm64_mops_reset_regs(). In the meantime, deliver
|
||||
* the guest a SIGILL, with the same ILLOPN si_code
|
||||
* we've always used for this.
|
||||
*/
|
||||
si_signo = TARGET_SIGILL;
|
||||
si_code = TARGET_ILL_ILLOPN;
|
||||
break;
|
||||
|
||||
case EC_WFX_TRAP: /* user-only WFI implemented as NOP */
|
||||
case EC_CP15RTTRAP: /* AArch32 */
|
||||
case EC_CP15RRTTRAP: /* AArch32 */
|
||||
case EC_CP14RTTRAP: /* AArch32 */
|
||||
case EC_CP14DTTRAP: /* AArch32 */
|
||||
case EC_ADVSIMDFPACCESSTRAP: /* user-only does not disable fpu */
|
||||
case EC_FPIDTRAP: /* AArch32 */
|
||||
case EC_PACTRAP: /* user-only does not disable pac regs */
|
||||
case EC_BXJTRAP: /* AArch32 */
|
||||
case EC_CP14RRTTRAP: /* AArch32 */
|
||||
case EC_AA32_SVC: /* AArch32 */
|
||||
case EC_AA32_HVC: /* AArch32 */
|
||||
case EC_AA32_SMC: /* AArch32 */
|
||||
case EC_AA64_SVC: /* generates EXCP_SWI */
|
||||
case EC_AA64_HVC: /* user-only generates EC_UNCATEGORIZED */
|
||||
case EC_AA64_SMC: /* user-only generates EC_UNCATEGORIZED */
|
||||
case EC_SVEACCESSTRAP: /* user-only does not disable sve */
|
||||
case EC_ERETTRAP: /* user-only generates EC_UNCATEGORIZED */
|
||||
case EC_GPC: /* user-only has no EL3 gpc tables */
|
||||
case EC_INSNABORT_SAME_EL: /* el0 cannot trap to el0 */
|
||||
case EC_DATAABORT_SAME_EL: /* el0 cannot trap to el0 */
|
||||
case EC_SPALIGNMENT: /* sp alignment checks not implemented */
|
||||
case EC_AA32_FPTRAP: /* fp exceptions not implemented */
|
||||
case EC_AA64_FPTRAP: /* fp exceptions not implemented */
|
||||
case EC_SERROR: /* user-only does not have hw faults */
|
||||
case EC_BREAKPOINT: /* user-only does not have hw debug */
|
||||
case EC_BREAKPOINT_SAME_EL: /* user-only does not have hw debug */
|
||||
case EC_SOFTWARESTEP: /* user-only does not have hw debug */
|
||||
case EC_SOFTWARESTEP_SAME_EL: /* user-only does not have hw debug */
|
||||
case EC_WATCHPOINT: /* user-only does not have hw debug */
|
||||
case EC_WATCHPOINT_SAME_EL: /* user-only does not have hw debug */
|
||||
case EC_AA32_BKPT: /* AArch32 */
|
||||
case EC_VECTORCATCH: /* AArch32 */
|
||||
case EC_AA64_BKPT: /* generates EXCP_BKPT */
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
|
@ -108,7 +181,7 @@ void cpu_loop(CPUARMState *env)
|
|||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_UDEF:
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->pc);
|
||||
signal_for_exception(env, env->pc);
|
||||
break;
|
||||
case EXCP_PREFETCH_ABORT:
|
||||
case EXCP_DATA_ABORT:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue