[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [Qemu-arm] [PATCH 2/6] armv7m: Replace armv7m.hack with
From: |
Alex Bennée |
Subject: |
Re: [Qemu-devel] [Qemu-arm] [PATCH 2/6] armv7m: Replace armv7m.hack with unassigned_access handler |
Date: |
Tue, 24 Jan 2017 16:31:26 +0000 |
User-agent: |
mu4e 0.9.19; emacs 25.1.91.4 |
Peter Maydell <address@hidden> writes:
> From: Michael Davidsaver <address@hidden>
>
> For v7m we need to catch attempts to execute from special
> addresses at 0xfffffff0 and above. Previously we did this
> with the aid of a hacky special purpose lump of memory
> in the address space and a check in translate.c for whether
> we were translating code at those addresses.
>
> We can implement this more cleanly using a CPU
> unassigned access handler which throws the exception
> if the unassigned access is for one of the special addresses.
>
> Signed-off-by: Michael Davidsaver <address@hidden>
> [PMM:
> * drop the deletion of the "don't interrupt if PC is magic"
> code in arm_v7m_cpu_exec_interrupt() -- this is still
> required
> * don't generate an exception for unassigned accesses
> which aren't to the magic address -- although doing
> this is in theory correct in practice it will break
> currently working guests which rely on the RAZ/WI
> behaviour when they touch devices which we haven't
> modelled.
> * trigger EXCP_EXCEPTION_EXIT on is_exec, not !is_write
> ]
> Signed-off-by: Peter Maydell <address@hidden>
> ---
> hw/arm/armv7m.c | 8 --------
> target/arm/cpu.c | 28 ++++++++++++++++++++++++++++
> target/arm/translate.c | 12 ++++++------
> 3 files changed, 34 insertions(+), 14 deletions(-)
>
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 49d3078..0c9ca7b 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -180,7 +180,6 @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int
> mem_size, int num_irq,
> uint64_t entry;
> uint64_t lowaddr;
> int big_endian;
> - MemoryRegion *hack = g_new(MemoryRegion, 1);
>
> if (cpu_model == NULL) {
> cpu_model = "cortex-m3";
> @@ -225,13 +224,6 @@ DeviceState *armv7m_init(MemoryRegion *system_memory,
> int mem_size, int num_irq,
> }
> }
>
> - /* Hack to map an additional page of ram at the top of the address
> - space. This stops qemu complaining about executing code outside RAM
> - when returning from an exception. */
> - memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000, &error_fatal);
> - vmstate_register_ram_global(hack);
> - memory_region_add_subregion(system_memory, 0xfffff000, hack);
> -
What stops a model inadvertently registering a block of memory on-top?
Should we check the memory region really is unassigned?
> qemu_register_reset(armv7m_reset, cpu);
> return nvic;
> }
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 3f2cdb6..47759c9 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -292,6 +292,33 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int
> interrupt_request)
> }
>
> #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
> +static void arm_v7m_unassigned_access(CPUState *cpu, hwaddr addr,
> + bool is_write, bool is_exec, int
> opaque,
> + unsigned size)
> +{
> + ARMCPU *arm = ARM_CPU(cpu);
> + CPUARMState *env = &arm->env;
> +
> + /* ARMv7-M interrupt return works by loading a magic value into the PC.
> + * On real hardware the load causes the return to occur. The qemu
> + * implementation performs the jump normally, then does the exception
> + * return by throwing a special exception when when the CPU tries to
> + * execute code at the magic address.
> + */
> + if (env->v7m.exception != 0 && addr >= 0xfffffff0 && is_exec) {
> + cpu->exception_index = EXCP_EXCEPTION_EXIT;
> + cpu_loop_exit(cpu);
> + }
> +
> + /* In real hardware an attempt to access parts of the address space
> + * with nothing there will usually cause an external abort.
> + * However our QEMU board models are often missing device models where
> + * the guest can boot anyway with the default read-as-zero/writes-ignored
> + * behaviour that you get without a QEMU unassigned_access hook.
> + * So just return here to retain that default behaviour.
> + */
> +}
> +
> static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> {
> CPUClass *cc = CPU_GET_CLASS(cs);
> @@ -1016,6 +1043,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void
> *data)
> cc->do_interrupt = arm_v7m_cpu_do_interrupt;
> #endif
>
> + cc->do_unassigned_access = arm_v7m_unassigned_access;
> cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
> }
>
> diff --git a/target/arm/translate.c b/target/arm/translate.c
> index c9186b6..a7c2abe 100644
> --- a/target/arm/translate.c
> +++ b/target/arm/translate.c
> @@ -11719,12 +11719,12 @@ void gen_intermediate_code(CPUARMState *env,
> TranslationBlock *tb)
> break;
> }
> #else
> - if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
> - /* We always get here via a jump, so know we are not in a
> - conditional execution block. */
> - gen_exception_internal(EXCP_EXCEPTION_EXIT);
> - dc->is_jmp = DISAS_EXC;
> - break;
> + if (arm_dc_feature(dc, ARM_FEATURE_M)) {
> + /* Branches to the magic exception-return addresses should
> + * already have been caught via the arm_v7m_unassigned_access
> hook,
> + * and never get here.
> + */
> + assert(dc->pc < 0xfffffff0);
> }
> #endif
Otherwise:
Reviewed-by: Alex Bennée <address@hidden>
--
Alex Bennée
- [Qemu-devel] [PATCH 0/6] ARMv7M: some simple bugfixes and cleanups, Peter Maydell, 2017/01/20
- [Qemu-devel] [PATCH 6/6] armv7m: Clear FAULTMASK on return from non-NMI exceptions, Peter Maydell, 2017/01/20
- [Qemu-devel] [PATCH 1/6] armv7m: MRS/MSR: handle unprivileged access, Peter Maydell, 2017/01/20
- [Qemu-devel] [PATCH 3/6] armv7m: Explicit error for bad vector table, Peter Maydell, 2017/01/20
- [Qemu-devel] [PATCH 2/6] armv7m: Replace armv7m.hack with unassigned_access handler, Peter Maydell, 2017/01/20
- Re: [Qemu-devel] [Qemu-arm] [PATCH 2/6] armv7m: Replace armv7m.hack with unassigned_access handler,
Alex Bennée <=
- [Qemu-devel] [PATCH 5/6] armv7m: Fix reads of CONTROL register bit 1, Peter Maydell, 2017/01/20
- [Qemu-devel] [PATCH 4/6] hw/registerfields.h: Pull FIELD etc macros out of hw/register.h, Peter Maydell, 2017/01/20
- Re: [Qemu-devel] [PATCH 0/6] ARMv7M: some simple bugfixes and cleanups, no-reply, 2017/01/20
- Re: [Qemu-devel] [Qemu-arm] [PATCH 0/6] ARMv7M: some simple bugfixes and cleanups, Alex Bennée, 2017/01/24