diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 0a1eb98c..ce4806c1 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_aarch64 #define arm_cp_write_ignore arm_cp_write_ignore_aarch64 #define arm_cpu_do_interrupt arm_cpu_do_interrupt_aarch64 +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_aarch64 #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_aarch64 #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_aarch64 #define arm_cpu_finalizefn arm_cpu_finalizefn_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 03bce8e1..ea3a27fc 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_aarch64eb #define arm_cp_write_ignore arm_cp_write_ignore_aarch64eb #define arm_cpu_do_interrupt arm_cpu_do_interrupt_aarch64eb +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_aarch64eb #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_aarch64eb #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_aarch64eb #define arm_cpu_finalizefn arm_cpu_finalizefn_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index a27463bb..3db03210 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_arm #define arm_cp_write_ignore arm_cp_write_ignore_arm #define arm_cpu_do_interrupt arm_cpu_do_interrupt_arm +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_arm #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_arm #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_arm #define arm_cpu_finalizefn arm_cpu_finalizefn_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 3b890443..68d484a0 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_armeb #define arm_cp_write_ignore arm_cp_write_ignore_armeb #define arm_cpu_do_interrupt arm_cpu_do_interrupt_armeb +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_armeb #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_armeb #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_armeb #define arm_cpu_finalizefn arm_cpu_finalizefn_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 37fb0581..971e2de6 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -146,6 +146,7 @@ symbols = ( 'arm_cp_reset_ignore', 'arm_cp_write_ignore', 'arm_cpu_do_interrupt', + 'arm_cpu_do_transaction_failed', 'arm_cpu_do_unaligned_access', 'arm_cpu_exec_interrupt', 'arm_cpu_finalizefn', diff --git a/qemu/include/hw/boards.h b/qemu/include/hw/boards.h index e592b034..6794c305 100644 --- a/qemu/include/hw/boards.h +++ b/qemu/include/hw/boards.h @@ -81,6 +81,16 @@ MachineClass *find_default_machine(struct uc_struct *uc, int arch); * size than the target architecture's minimum. (Attempting to create * such a CPU will fail.) Note that changing this is a migration * compatibility break for the machine. + * @ignore_memory_transaction_failures: + * If this is flag is true then the CPU will ignore memory transaction + * failures which should cause the CPU to take an exception due to an + * access to an unassigned physical address; the transaction will instead + * return zero (for a read) or be ignored (for a write). This should be + * set only by legacy board models which rely on the old RAZ/WI behaviour + * for handling devices that QEMU does not yet model. New board models + * should instead use "unimplemented-device" for all memory ranges where + * the guest will attempt to probe for a device that QEMU doesn't + * implement and a stub device is required. */ struct MachineClass { /*< private >*/ @@ -97,6 +107,8 @@ struct MachineClass { int is_default; int arch; int minimum_page_bits; + bool has_hotpluggable_cpus; + bool ignore_memory_transaction_failures; }; /** diff --git a/qemu/include/qom/cpu.h b/qemu/include/qom/cpu.h index d2077418..f00aaa0c 100644 --- a/qemu/include/qom/cpu.h +++ b/qemu/include/qom/cpu.h @@ -331,6 +331,8 @@ struct CPUState { */ bool throttle_thread_scheduled; + bool ignore_memory_transaction_failures; + /* Note that this is accessed at the start of every TB via a negative offset from AREG0. Leave this field at the end so as to make the (absolute value) offset as small as possible. This reduces code @@ -677,7 +679,7 @@ static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr, { CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu); - if (cc->do_transaction_failed) { + if (!cpu->ignore_memory_transaction_failures && cc->do_transaction_failed) { cc->do_transaction_failed(cpu, physaddr, addr, size, access_type, mmu_idx, attrs, response, retaddr); } diff --git a/qemu/m68k.h b/qemu/m68k.h index c32faa00..9cd9bed4 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_m68k #define arm_cp_write_ignore arm_cp_write_ignore_m68k #define arm_cpu_do_interrupt arm_cpu_do_interrupt_m68k +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_m68k #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_m68k #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_m68k #define arm_cpu_finalizefn arm_cpu_finalizefn_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 4503b6dc..b61e94aa 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_mips #define arm_cp_write_ignore arm_cp_write_ignore_mips #define arm_cpu_do_interrupt arm_cpu_do_interrupt_mips +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_mips #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_mips #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mips #define arm_cpu_finalizefn arm_cpu_finalizefn_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 8a62ed1b..01815173 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_mips64 #define arm_cp_write_ignore arm_cp_write_ignore_mips64 #define arm_cpu_do_interrupt arm_cpu_do_interrupt_mips64 +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_mips64 #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_mips64 #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mips64 #define arm_cpu_finalizefn arm_cpu_finalizefn_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index e32024c8..bd2c9cf0 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_mips64el #define arm_cp_write_ignore arm_cp_write_ignore_mips64el #define arm_cpu_do_interrupt arm_cpu_do_interrupt_mips64el +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_mips64el #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_mips64el #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mips64el #define arm_cpu_finalizefn arm_cpu_finalizefn_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 4f421147..61699635 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_mipsel #define arm_cp_write_ignore arm_cp_write_ignore_mipsel #define arm_cpu_do_interrupt arm_cpu_do_interrupt_mipsel +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_mipsel #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_mipsel #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_mipsel #define arm_cpu_finalizefn arm_cpu_finalizefn_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index feb093a0..738f0bbf 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_powerpc #define arm_cp_write_ignore arm_cp_write_ignore_powerpc #define arm_cpu_do_interrupt arm_cpu_do_interrupt_powerpc +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_powerpc #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_powerpc #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_powerpc #define arm_cpu_finalizefn arm_cpu_finalizefn_powerpc diff --git a/qemu/qom/cpu.c b/qemu/qom/cpu.c index 585df6cb..bb2c68b8 100644 --- a/qemu/qom/cpu.c +++ b/qemu/qom/cpu.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu-common.h" +#include "hw/boards.h" #include "qemu/log.h" #include "uc_priv.h" @@ -243,6 +244,21 @@ static void cpu_common_parse_features(CPUState *cpu, char *features, static int cpu_common_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) { CPUState *cpu = CPU(dev); + Object *machine = qdev_get_machine(uc); + + /* qdev_get_machine() can return something that's not TYPE_MACHINE + * if this is one of the user-only emulators; in that case there's + * no need to check the ignore_memory_transaction_failures board flag. + */ + if (object_dynamic_cast(uc, machine, TYPE_MACHINE)) { + ObjectClass *oc = object_get_class(machine); + MachineClass *mc = MACHINE_CLASS(uc, oc); + + if (mc) { + cpu->ignore_memory_transaction_failures = + mc->ignore_memory_transaction_failures; + } + } if (dev->hotplugged) { cpu_resume(cpu); diff --git a/qemu/sparc.h b/qemu/sparc.h index 570a5f64..849f4d92 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_sparc #define arm_cp_write_ignore arm_cp_write_ignore_sparc #define arm_cpu_do_interrupt arm_cpu_do_interrupt_sparc +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_sparc #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_sparc #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_sparc #define arm_cpu_finalizefn arm_cpu_finalizefn_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 56a45f12..15b24f0a 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_sparc64 #define arm_cp_write_ignore arm_cp_write_ignore_sparc64 #define arm_cpu_do_interrupt arm_cpu_do_interrupt_sparc64 +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_sparc64 #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_sparc64 #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_sparc64 #define arm_cpu_finalizefn arm_cpu_finalizefn_sparc64 diff --git a/qemu/target/arm/internals.h b/qemu/target/arm/internals.h index e1743a02..b3a5d012 100644 --- a/qemu/target/arm/internals.h +++ b/qemu/target/arm/internals.h @@ -474,6 +474,16 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); +/* arm_cpu_do_transaction_failed: handle a memory system error response + * (eg "no device/memory present at address") by raising an external abort + * exception + */ +void arm_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); + /* Call the EL change hook if one has been registered */ static inline void arm_call_el_change_hook(ARMCPU *cpu) { diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 7b404742..1a16fc60 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -140,6 +140,7 @@ #define arm_cp_reset_ignore arm_cp_reset_ignore_x86_64 #define arm_cp_write_ignore arm_cp_write_ignore_x86_64 #define arm_cpu_do_interrupt arm_cpu_do_interrupt_x86_64 +#define arm_cpu_do_transaction_failed arm_cpu_do_transaction_failed_x86_64 #define arm_cpu_do_unaligned_access arm_cpu_do_unaligned_access_x86_64 #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_x86_64 #define arm_cpu_finalizefn arm_cpu_finalizefn_x86_64