diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2025-09-17 11:10:55 -0700 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2025-09-17 11:10:55 -0700 |
| commit | f0007b7f03e2d7fc33e71c3a582f2364c51a226b (patch) | |
| tree | 44b34bb98c293bbfe5c839eb73762141633eec70 /linux-user/aarch64/cpu_loop.c | |
| parent | 6be998b9863b470ab3f399f4e37cf3a9c59c8fd9 (diff) | |
| parent | aaf042299acf83919862c7d7dd5fc36acf4e0671 (diff) | |
| download | focaccia-qemu-f0007b7f03e2d7fc33e71c3a582f2364c51a226b.tar.gz focaccia-qemu-f0007b7f03e2d7fc33e71c3a582f2364c51a226b.zip | |
Merge tag 'pull-target-arm-20250916' of https://gitlab.com/pm215/qemu into staging
target-arm queue: * tests, scripts: Don't import print_function from __future__ * Implement FEAT_ATS1A * Remove deprecated pxa CPU family * arm/kvm: report registers we failed to set * Expose SME registers to GDB via gdbstub * linux-user/aarch64: Generate ESR signal records * hw/arm/raspi4b: remove redundant check in raspi_add_memory_node * hw/arm/virt: Allow user-creatable SMMUv3 dev instantiation * system: drop the -old-param option # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmjJpt8ZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vRGEACO3VrePiMIA9N7egqlUiGn # aRQVqIKeuPVj6TRVG7BSNWlAX8qvnOWOKg1yGVHDZv/nLvRje9UyfUAw7pf6jXod # bzxWBCPJ0J0eOB64Tz87WRCLltKB5pEN+uIG00PtpBcXT1ixYCDgBZXyD3mwuJ4Q # 5Yc5hEwQzpmh+EycLtfCHbmjKDw3x1ncpVlGceOG4h5fvzIvIhcNcZJXfAHhbhyO # Y4c5PELrCkCLZaTtSSxd6VJ+vXQ9bNWyKaSZu2KRRnLcMeAqw2Ic7dLPlkzCVyxM # PTOHy4TuDu+kqCbkxdnhpI6fvq5kcHyfTL6qX6tth8ZZS+qKGtvMEIXnYoy6q1kh # 4jV5vizK8avx31fSiuTKVpttRv4dC+Aq5QrcgYtIVMeOwtkWHv610D8gcFPmXoG+ # uHX9WdzOjrYOzXVKzJaCZF6b7L31ptSEfOrx7asBC9k2wPRwonFXg4JGNq16Yann # aAO5TM7NAUvM2IPgqS+Tf1Bk0iQqORxGfqzCyL76OO/QMMgfBy9elKH0UR0G+ePJ # yjpub1oWIELSXsQGMrdFo1W4/NIpFMTu3DP9W+6XRPu1AvrAx/AsrTuvSvXoeFY9 # d/U3yWAXm5XxRzbCIUg7ke8I8zLwRz924M5PA8vophvSnfDLS3V8CJHLwbz/PqYc # 0P2KCeI6d2NIhVik4mgEoQ== # =5tK3 # -----END PGP SIGNATURE----- # gpg: Signature made Tue 16 Sep 2025 11:05:19 AM PDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [unknown] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [unknown] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [unknown] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20250916' of https://gitlab.com/pm215/qemu: (36 commits) hw/usb/network: Remove hardcoded 0x40 prefix in STRING_ETHADDR response qtest/bios-tables-test: Update tables for smmuv3 tests qtest/bios-tables-test: Add tests for legacy smmuv3 and smmuv3 device bios-tables-test: Allow for smmuv3 test data. qemu-options.hx: Document the arm-smmuv3 device hw/arm/virt: Allow user-creatable SMMUv3 dev instantiation hw/pci: Introduce pci_setup_iommu_per_bus() for per-bus IOMMU ops retrieval hw/arm/virt: Add an SMMU_IO_LEN macro hw/arm/virt: Factor out common SMMUV3 dt bindings code hw/arm/virt-acpi-build: Update IORT for multiple smmuv3 devices hw/arm/virt-acpi-build: Re-arrange SMMUv3 IORT build hw/arm/smmu-common: Check SMMU has PCIe Root Complex association target/arm: Added test case for SME register exposure to GDB target/arm: Added support for SME register exposure to GDB target/arm: Increase MAX_PACKET_LENGTH for SME ZA remote gdb debugging arm/kvm: report registers we failed to set system: drop the -old-param option target/arm: Drop ARM_FEATURE_IWMMXT handling target/arm: Drop ARM_FEATURE_XSCALE handling target/arm: Remove iwmmxt helper functions ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/aarch64/cpu_loop.c')
| -rw-r--r-- | linux-user/aarch64/cpu_loop.c | 162 |
1 files changed, 124 insertions, 38 deletions
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c index 4c4921152e..6060572eed 100644 --- a/linux-user/aarch64/cpu_loop.c +++ b/linux-user/aarch64/cpu_loop.c @@ -27,11 +27,132 @@ #include "target/arm/syndrome.h" #include "target/arm/cpu-features.h" +/* Use the exception syndrome to map a cpu exception to a signal. */ +static void signal_for_exception(CPUARMState *env, vaddr addr) +{ + uint32_t syn = env->exception.syndrome; + int si_code, si_signo; + + /* Let signal delivery see that ESR is live. */ + env->cp15.esr_el[1] = syn; + + switch (syn_get_ec(syn)) { + case EC_DATAABORT: + case EC_INSNABORT: + /* Both EC have the same format for FSC, or close enough. */ + switch (extract32(syn, 0, 6)) { + case 0x04 ... 0x07: /* Translation fault, level {0-3} */ + si_signo = TARGET_SIGSEGV; + si_code = TARGET_SEGV_MAPERR; + break; + case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */ + case 0x0d ... 0x0f: /* Permission fault, level {1-3} */ + si_signo = TARGET_SIGSEGV; + si_code = TARGET_SEGV_ACCERR; + break; + case 0x11: /* Synchronous Tag Check Fault */ + si_signo = TARGET_SIGSEGV; + si_code = TARGET_SEGV_MTESERR; + break; + case 0x21: /* Alignment fault */ + si_signo = TARGET_SIGBUS; + si_code = TARGET_BUS_ADRALN; + break; + default: + g_assert_not_reached(); + } + break; + + case EC_PCALIGNMENT: + si_signo = TARGET_SIGBUS; + 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(); + } + + force_sig_fault(si_signo, si_code, addr); +} + /* AArch64 main loop */ void cpu_loop(CPUARMState *env) { CPUState *cs = env_cpu(env); - int trapnr, ec, fsc, si_code, si_signo; + int trapnr; abi_long ret; for (;;) { @@ -63,46 +184,11 @@ 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: - ec = syn_get_ec(env->exception.syndrome); - switch (ec) { - case EC_DATAABORT: - case EC_INSNABORT: - /* Both EC have the same format for FSC, or close enough. */ - fsc = extract32(env->exception.syndrome, 0, 6); - switch (fsc) { - case 0x04 ... 0x07: /* Translation fault, level {0-3} */ - si_signo = TARGET_SIGSEGV; - si_code = TARGET_SEGV_MAPERR; - break; - case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */ - case 0x0d ... 0x0f: /* Permission fault, level {1-3} */ - si_signo = TARGET_SIGSEGV; - si_code = TARGET_SEGV_ACCERR; - break; - case 0x11: /* Synchronous Tag Check Fault */ - si_signo = TARGET_SIGSEGV; - si_code = TARGET_SEGV_MTESERR; - break; - case 0x21: /* Alignment fault */ - si_signo = TARGET_SIGBUS; - si_code = TARGET_BUS_ADRALN; - break; - default: - g_assert_not_reached(); - } - break; - case EC_PCALIGNMENT: - si_signo = TARGET_SIGBUS; - si_code = TARGET_BUS_ADRALN; - break; - default: - g_assert_not_reached(); - } - force_sig_fault(si_signo, si_code, env->exception.vaddress); + signal_for_exception(env, env->exception.vaddress); break; case EXCP_DEBUG: case EXCP_BKPT: |