From 77d90985cc7129fd84cdb3456603cf3a3ce89d25 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Wed, 20 Nov 2019 13:49:15 -0500 Subject: [PATCH] target/sparc: Switch to do_transaction_failed() hook Switch the SPARC target from the old unassigned_access hook to the new do_transaction_failed hook. This will cause the "if transaction failed" code paths added in the previous commits to become active if the access is to an unassigned address. In particular we'll now handle bus errors during page table walks correctly (generating a translation error with the right kind of fault status). Backports commit f8c3db33a5e863291182f8862ddf81618a7c6194 from qemu --- qemu/header_gen.py | 2 +- qemu/sparc.h | 2 +- qemu/sparc64.h | 2 +- qemu/target/sparc/cpu.c | 2 +- qemu/target/sparc/cpu.h | 8 +++++--- qemu/target/sparc/ldst_helper.c | 15 +++++++++++---- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/qemu/header_gen.py b/qemu/header_gen.py index b3f1319f..59db1ddb 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -5627,11 +5627,11 @@ sparc_symbols = ( 'helper_udiv_cc', 'helper_wrgl', 'sparc_cpu_do_interrupt', + 'sparc_cpu_do_transaction_failed', 'sparc_cpu_do_unaligned_access', 'sparc_cpu_get_phys_page_debug', 'sparc_cpu_register_types', 'sparc_cpu_tlb_fill', - 'sparc_cpu_unassigned_access', 'sparc_reg_read', 'sparc_reg_reset', 'sparc_reg_write', diff --git a/qemu/sparc.h b/qemu/sparc.h index af0c1488..8914cf9f 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -3442,11 +3442,11 @@ #define helper_udiv_cc helper_udiv_cc_sparc #define helper_wrgl helper_wrgl_sparc #define sparc_cpu_do_interrupt sparc_cpu_do_interrupt_sparc +#define sparc_cpu_do_transaction_failed sparc_cpu_do_transaction_failed_sparc #define sparc_cpu_do_unaligned_access sparc_cpu_do_unaligned_access_sparc #define sparc_cpu_get_phys_page_debug sparc_cpu_get_phys_page_debug_sparc #define sparc_cpu_register_types sparc_cpu_register_types_sparc #define sparc_cpu_tlb_fill sparc_cpu_tlb_fill_sparc -#define sparc_cpu_unassigned_access sparc_cpu_unassigned_access_sparc #define sparc_reg_read sparc_reg_read_sparc #define sparc_reg_reset sparc_reg_reset_sparc #define sparc_reg_write sparc_reg_write_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index e9edcb8e..aadb5706 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -3442,11 +3442,11 @@ #define helper_udiv_cc helper_udiv_cc_sparc64 #define helper_wrgl helper_wrgl_sparc64 #define sparc_cpu_do_interrupt sparc_cpu_do_interrupt_sparc64 +#define sparc_cpu_do_transaction_failed sparc_cpu_do_transaction_failed_sparc64 #define sparc_cpu_do_unaligned_access sparc_cpu_do_unaligned_access_sparc64 #define sparc_cpu_get_phys_page_debug sparc_cpu_get_phys_page_debug_sparc64 #define sparc_cpu_register_types sparc_cpu_register_types_sparc64 #define sparc_cpu_tlb_fill sparc_cpu_tlb_fill_sparc64 -#define sparc_cpu_unassigned_access sparc_cpu_unassigned_access_sparc64 #define sparc_reg_read sparc_reg_read_sparc64 #define sparc_reg_reset sparc_reg_reset_sparc64 #define sparc_reg_write sparc_reg_write_sparc64 diff --git a/qemu/target/sparc/cpu.c b/qemu/target/sparc/cpu.c index f1b6d5b8..00426d7c 100644 --- a/qemu/target/sparc/cpu.c +++ b/qemu/target/sparc/cpu.c @@ -850,7 +850,7 @@ static void sparc_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *da cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; cc->tlb_fill = sparc_cpu_tlb_fill; #ifndef CONFIG_USER_ONLY - cc->do_unassigned_access = sparc_cpu_unassigned_access; + cc->do_transaction_failed = sparc_cpu_do_transaction_failed; cc->do_unaligned_access = sparc_cpu_do_unaligned_access; cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; // Unicorn: commented out diff --git a/qemu/target/sparc/cpu.h b/qemu/target/sparc/cpu.h index 5d48d6e4..9db27da1 100644 --- a/qemu/target/sparc/cpu.h +++ b/qemu/target/sparc/cpu.h @@ -603,9 +603,11 @@ static inline int tlb_compare_context(const SparcTLBEntry *tlb, /* cpu-exec.c */ #if !defined(CONFIG_USER_ONLY) -void sparc_cpu_unassigned_access(CPUState *cpu, hwaddr addr, - bool is_write, bool is_exec, int is_asi, - unsigned size); +void sparc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, + vaddr addr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr); #if defined(TARGET_SPARC64) hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr, int mmu_idx); diff --git a/qemu/target/sparc/ldst_helper.c b/qemu/target/sparc/ldst_helper.c index a3a9559a..1eead4ae 100644 --- a/qemu/target/sparc/ldst_helper.c +++ b/qemu/target/sparc/ldst_helper.c @@ -1948,11 +1948,18 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, #endif /* TARGET_SPARC64 */ #if !defined(CONFIG_USER_ONLY) -void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr, - bool is_write, bool is_exec, int is_asi, - unsigned size) +void sparc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, + vaddr addr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr) { - sparc_raise_mmu_fault(cs, addr, is_write, is_exec, is_asi, size, GETPC()); + bool is_write = access_type == MMU_DATA_STORE; + bool is_exec = access_type == MMU_INST_FETCH; + bool is_asi = false; + + sparc_raise_mmu_fault(cs, physaddr, is_write, is_exec, + is_asi, size, retaddr); } #endif