mirror of https://github.com/xemu-project/xemu.git
target/arm: Implement arm_cpu_record_sigsegv
Because of the complexity of setting ESR, continue to use arm_deliver_fault. This means we cannot remove the code within cpu_loop that decodes EXCP_DATA_ABORT and EXCP_PREFETCH_ABORT. But using the new hook means that we don't have to do the page_get_flags check manually, and we'll be able to restrict the tlb_fill hook to sysemu later. Reviewed-by: Warner Losh <imp@bsdimp.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
5e98763c0e
commit
9b12b6b442
|
@ -2031,10 +2031,12 @@ static const struct SysemuCPUOps arm_sysemu_ops = {
|
|||
static const struct TCGCPUOps arm_tcg_ops = {
|
||||
.initialize = arm_translate_init,
|
||||
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
|
||||
.tlb_fill = arm_cpu_tlb_fill,
|
||||
.debug_excp_handler = arm_debug_excp_handler,
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
.record_sigsegv = arm_cpu_record_sigsegv,
|
||||
#else
|
||||
.tlb_fill = arm_cpu_tlb_fill,
|
||||
.cpu_exec_interrupt = arm_cpu_exec_interrupt,
|
||||
.do_interrupt = arm_cpu_do_interrupt,
|
||||
.do_transaction_failed = arm_cpu_do_transaction_failed,
|
||||
|
|
|
@ -898,10 +898,12 @@ static void pxa270c5_initfn(Object *obj)
|
|||
static const struct TCGCPUOps arm_v7m_tcg_ops = {
|
||||
.initialize = arm_translate_init,
|
||||
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
|
||||
.tlb_fill = arm_cpu_tlb_fill,
|
||||
.debug_excp_handler = arm_debug_excp_handler,
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
.record_sigsegv = arm_cpu_record_sigsegv,
|
||||
#else
|
||||
.tlb_fill = arm_cpu_tlb_fill,
|
||||
.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
|
||||
.do_interrupt = arm_v7m_cpu_do_interrupt,
|
||||
.do_transaction_failed = arm_cpu_do_transaction_failed,
|
||||
|
|
|
@ -544,9 +544,15 @@ static inline bool arm_extabort_type(MemTxResult result)
|
|||
return result != MEMTX_DECODE_ERROR;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
void arm_cpu_record_sigsegv(CPUState *cpu, vaddr addr,
|
||||
MMUAccessType access_type,
|
||||
bool maperr, uintptr_t ra);
|
||||
#else
|
||||
bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
MMUAccessType access_type, int mmu_idx,
|
||||
bool probe, uintptr_t retaddr);
|
||||
#endif
|
||||
|
||||
static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
|
||||
{
|
||||
|
|
|
@ -147,28 +147,12 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
|
|||
arm_deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
|
||||
}
|
||||
|
||||
#endif /* !defined(CONFIG_USER_ONLY) */
|
||||
|
||||
bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
MMUAccessType access_type, int mmu_idx,
|
||||
bool probe, uintptr_t retaddr)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
ARMMMUFaultInfo fi = {};
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
int flags = page_get_flags(useronly_clean_ptr(address));
|
||||
if (flags & PAGE_VALID) {
|
||||
fi.type = ARMFault_Permission;
|
||||
} else {
|
||||
fi.type = ARMFault_Translation;
|
||||
}
|
||||
fi.level = 3;
|
||||
|
||||
/* now we have a real cpu fault */
|
||||
cpu_restore_state(cs, retaddr, true);
|
||||
arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
|
||||
#else
|
||||
hwaddr phys_addr;
|
||||
target_ulong page_size;
|
||||
int prot, ret;
|
||||
|
@ -210,5 +194,23 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|||
cpu_restore_state(cs, retaddr, true);
|
||||
arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr,
|
||||
MMUAccessType access_type,
|
||||
bool maperr, uintptr_t ra)
|
||||
{
|
||||
ARMMMUFaultInfo fi = {
|
||||
.type = maperr ? ARMFault_Translation : ARMFault_Permission,
|
||||
.level = 3,
|
||||
};
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
|
||||
/*
|
||||
* We report both ESR and FAR to signal handlers.
|
||||
* For now, it's easiest to deliver the fault normally.
|
||||
*/
|
||||
cpu_restore_state(cs, ra, true);
|
||||
arm_deliver_fault(cpu, addr, access_type, MMU_USER_IDX, &fi);
|
||||
}
|
||||
#endif /* !defined(CONFIG_USER_ONLY) */
|
||||
|
|
Loading…
Reference in New Issue