qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook
@ 2019-08-02 16:04 Peter Maydell
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override " Peter Maydell
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Peter Maydell @ 2019-08-02 16:04 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Hervé Poussineau, Aleksandar Markovic,
	Aurelien Jarno

This patchset converts the MIPS target away from the
old broken do_unassigned_access hook to the new (added in
2017...) do_transaction_failed hook.

The motivation here is:
 * do_unassigned_access is broken because:
    + it will be called for any kind of access to physical addresses
      where there is no assigned device, whether that access is by the
      CPU or by something else (like a DMA controller!), so it can
      result in spurious guest CPU exceptions.
    + It will also get called even when using KVM, when there's nothing
      useful it can do.
    + It isn't passed in the return-address within the TCG generated
      code, so it isn't able to correctly restore the CPU state
      before generating the exception, and so the exception will
      often be generated with the wrong faulting guest PC value
 * there are now only a few targets still using the old hook,
   so if we can convert them we can delete all the old code
   and complete this API transation. (Patches for SPARC are on
   the list; the other user is RISCV, which accidentally
   implemented the old hook rather than the new one recently.)

The general approach to the conversion is to check the target for
load/store-by-physical-address operations which were previously
implicitly causing exceptions, to see if they now need to explicitly
check for and handle memory access failures. (The 'git grep' regexes
in docs/devel/loads-stores.rst are useful here: the API families to
look for are ld*_phys/st*_phys, address_space_ld/st*, and
cpu_physical_memory*.)

For MIPS, there are none of these (the usual place where targets do
this is hardware page table walks where the page table entries are
loaded by physical address, and MIPS doesn't seem to have those).

Code audit out of the way, the actual hook changeover is pretty
simple.

The complication here is the MIPS Jazz board, which has some rather
dubious code that intercepts the do_unassigned_access hook to suppress
generation of exceptions for invalid accesses due to data accesses,
while leaving exceptions for invalid instruction fetches in place. I'm
a bit dubious about whether the behaviour we have implemented here is
really what the hardware does -- it seems pretty odd to me to not
generate exceptions for d-side accesses but to generate them for
i-side accesses, and looking back through git and mailing list history
this code is here mainly as "put back the behaviour we had before a
previous commit broke it", and that older behaviour in turn I think is
more historical-accident than because anybody deliberately checked the
hardware behaviour and made QEMU work that way. However, I don't have
any real hardware to do comparative tests on, so this series retains
the same behaviour we had before on this board, by making it intercept
the new hook in the same way it did the old one. I've beefed up the
comment somewhat to indicate what we're doing, why, and why it might
not be right.

The patch series is structured in three parts:
 * make the Jazz board code support CPUs regardless of which
   of the two hooks they implement
 * switch the MIPS CPUs over to implementing the new hook
 * remove the no-longer-needed Jazz board code for the old
   hook
(This seemed cleaner to me than squashing the whole thing into
a single patch that touched core mips code and the jazz board
at the same time.)

I have tested this with:
 * the ARC Multiboot BIOS linked to from the bug
   https://bugs.launchpad.net/qemu/+bug/1245924 (and which
   was the test case for needing the hook intercept)
 * a Linux kernel for the 'mips' mips r4k machine
 * 'make check'
Obviously more extensive testing would be useful, but I
don't have any other test images. I also don't have
a KVM MIPS host, which would be worth testing to confirm
that it also still works.

If anybody happens by some chance to still have a working
real-hardware Magnum or PICA61 board, we could perhaps test
how it handles accesses to invalid memory, but I suspect that
nobody does any more :-)

thanks
-- PMM


Peter Maydell (3):
  hw/mips/mips_jazz: Override do_transaction_failed hook
  target/mips: Switch to do_transaction_failed() hook
  hw/mips/mips_jazz: Remove no-longer-necessary override of
    do_unassigned_access

 target/mips/internal.h  |  8 ++++---
 hw/mips/mips_jazz.c     | 47 +++++++++++++++++++++++++++++------------
 target/mips/cpu.c       |  2 +-
 target/mips/op_helper.c | 24 +++++++--------------
 4 files changed, 47 insertions(+), 34 deletions(-)

-- 
2.20.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override do_transaction_failed hook
  2019-08-02 16:04 [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Peter Maydell
@ 2019-08-02 16:04 ` Peter Maydell
  2019-08-02 16:20   ` Philippe Mathieu-Daudé
  2019-09-09 21:41   ` Hervé Poussineau
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook Peter Maydell
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 14+ messages in thread
From: Peter Maydell @ 2019-08-02 16:04 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Hervé Poussineau, Aleksandar Markovic,
	Aurelien Jarno

The MIPS Jazz ('magnum' and 'pica61') boards have some code which
overrides the CPU's do_unassigned_access hook, so they can intercept
it and not raise exceptions on data accesses to invalid addresses,
only for instruction fetches.

We want to switch MIPS over to using the do_transaction_failed
hook instead, so add an intercept for that as well, and make
the board code install whichever hook the CPU is actually using.
Once we've changed the CPU implementation we can remove the
redundant code for the old hook.

Note: I am suspicious that the behaviour as implemented here may not
be what the hardware really does.  It was added in commit
54e755588cf1e90f0b14 to restore the behaviour that was broken by
commit c658b94f6e8c206c59d.  But prior to commit c658b94f6e8c206c59d
every MIPS board generated exceptions for instruction access to
invalid addresses but not for data accesses; and other boards,
notably Malta, were fixed by making all invalid accesses behave as
reads-as-zero (see the call to empty_slot_init() in
mips_malta_init()).  Hardware that raises exceptions for instruction
access and not data access seems to me to be an unlikely design, and
it's possible that the right way to emulate this is to make the Jazz
boards do what we did with Malta (or some variation of that).
Nonetheless, since I don't have access to real hardware to test
against I have taken the approach of "make QEMU continue to behave
the same way it did before this commit".  I have updated the comment
to correct the parts that are no longer accurate and note that
the hardware might behave differently.

The test case for the need for the hook-hijacking is in
https://bugs.launchpad.net/qemu/+bug/1245924 That BIOS will boot OK
either with this overriding of both hooks, or with a simple "global
memory region to ignore bad accesses of all types", so it doesn't
provide evidence either way, unfortunately.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/mips/mips_jazz.c | 54 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 8 deletions(-)

diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index fa8775d4284..c64b4c78809 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -123,6 +123,28 @@ static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr,
     (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size);
 }
 
+static void (*real_do_transaction_failed)(CPUState *cpu, hwaddr physaddr,
+                                          vaddr addr, unsigned size,
+                                          MMUAccessType access_type,
+                                          int mmu_idx, MemTxAttrs attrs,
+                                          MemTxResult response,
+                                          uintptr_t retaddr);
+
+static void mips_jazz_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 (access_type != MMU_INST_FETCH) {
+        /* ignore invalid access (ie do not raise exception) */
+        return;
+    }
+    (*real_do_transaction_failed)(cs, physaddr, addr, size, access_type,
+                                  mmu_idx, attrs, response, retaddr);
+}
+
 static void mips_jazz_init(MachineState *machine,
                            enum jazz_model_e jazz_model)
 {
@@ -157,16 +179,32 @@ static void mips_jazz_init(MachineState *machine,
     env = &cpu->env;
     qemu_register_reset(main_cpu_reset, cpu);
 
-    /* Chipset returns 0 in invalid reads and do not raise data exceptions.
+    /*
+     * Chipset returns 0 in invalid reads and do not raise data exceptions.
      * However, we can't simply add a global memory region to catch
-     * everything, as memory core directly call unassigned_mem_read/write
-     * on some invalid accesses, which call do_unassigned_access on the
-     * CPU, which raise an exception.
-     * Handle that case by hijacking the do_unassigned_access method on
-     * the CPU, and do not raise exceptions for data access. */
+     * everything, as this would make all accesses including instruction
+     * accesses be ignored and not raise exceptions.
+     * So instead we hijack either the do_unassigned_access method or
+     * the do_transaction_failed method on the CPU, and do not raise exceptions
+     * for data access.
+     *
+     * NOTE: this behaviour of raising exceptions for bad instruction
+     * fetches but not bad data accesses was added in commit 54e755588cf1e9
+     * to restore behaviour broken by c658b94f6e8c206, but it is not clear
+     * whether the real hardware behaves this way. It is possible that
+     * real hardware ignores bad instruction fetches as well -- if so then
+     * we could replace this hijacking of CPU methods with a simple global
+     * memory region that catches all memory accesses, as we do on Malta.
+     */
     cc = CPU_GET_CLASS(cpu);
-    real_do_unassigned_access = cc->do_unassigned_access;
-    cc->do_unassigned_access = mips_jazz_do_unassigned_access;
+    if (cc->do_unassigned_access) {
+        real_do_unassigned_access = cc->do_unassigned_access;
+        cc->do_unassigned_access = mips_jazz_do_unassigned_access;
+    }
+    if (cc->do_transaction_failed) {
+        real_do_transaction_failed = cc->do_transaction_failed;
+        cc->do_transaction_failed = mips_jazz_do_transaction_failed;
+    }
 
     /* allocate RAM */
     memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook
  2019-08-02 16:04 [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Peter Maydell
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override " Peter Maydell
@ 2019-08-02 16:04 ` Peter Maydell
  2019-08-02 16:29   ` Philippe Mathieu-Daudé
  2019-09-09 21:41   ` Hervé Poussineau
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access Peter Maydell
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 14+ messages in thread
From: Peter Maydell @ 2019-08-02 16:04 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Hervé Poussineau, Aleksandar Markovic,
	Aurelien Jarno

Switch the MIPS target from the old unassigned_access hook to the new
do_transaction_failed hook.

Unlike the old hook, do_transaction_failed is only ever called from
the TCG memory access paths, so there is no need for the "ignore this
if we're using KVM" hack that we were previously using to work around
the way unassigned_access was called for all kinds of memory accesses
to unassigned physical addresses.

The MIPS target does not ever do direct memory reads by physical
address (via either ldl_phys etc or address_space_ldl etc), so the
only memory accesses this affects are the 'normal' guest loads and
stores, which will be handled by the new hook; their behaviour is
unchanged.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/mips/internal.h  |  8 +++++---
 target/mips/cpu.c       |  2 +-
 target/mips/op_helper.c | 24 ++++++++----------------
 3 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/target/mips/internal.h b/target/mips/internal.h
index b2b41a51ab4..26533bb937d 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -138,9 +138,11 @@ void r4k_helper_tlbinv(CPUMIPSState *env);
 void r4k_helper_tlbinvf(CPUMIPSState *env);
 void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra);
 
-void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
-                                bool is_write, bool is_exec, int unused,
-                                unsigned size);
+void mips_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);
 hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
                                   int rw);
 #endif
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 39eafafc5cd..a79badcb1a6 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -197,7 +197,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->gdb_read_register = mips_cpu_gdb_read_register;
     cc->gdb_write_register = mips_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
-    cc->do_unassigned_access = mips_cpu_unassigned_access;
+    cc->do_transaction_failed = mips_cpu_do_transaction_failed;
     cc->do_unaligned_access = mips_cpu_do_unaligned_access;
     cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_mips_cpu;
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 9e2e02f8586..65ff9f5b935 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -2666,27 +2666,19 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
     do_raise_exception_err(env, excp, error_code, retaddr);
 }
 
-void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
-                                bool is_write, bool is_exec, int unused,
-                                unsigned size)
+void mips_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)
 {
     MIPSCPU *cpu = MIPS_CPU(cs);
     CPUMIPSState *env = &cpu->env;
 
-    /*
-     * Raising an exception with KVM enabled will crash because it won't be from
-     * the main execution loop so the longjmp won't have a matching setjmp.
-     * Until we can trigger a bus error exception through KVM lets just ignore
-     * the access.
-     */
-    if (kvm_enabled()) {
-        return;
-    }
-
-    if (is_exec) {
-        raise_exception(env, EXCP_IBE);
+    if (access_type == MMU_INST_FETCH) {
+        do_raise_exception(env, EXCP_IBE, retaddr);
     } else {
-        raise_exception(env, EXCP_DBE);
+        do_raise_exception(env, EXCP_DBE, retaddr);
     }
 }
 #endif /* !CONFIG_USER_ONLY */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access
  2019-08-02 16:04 [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Peter Maydell
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override " Peter Maydell
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook Peter Maydell
@ 2019-08-02 16:04 ` Peter Maydell
  2019-08-02 16:30   ` Philippe Mathieu-Daudé
  2019-09-09 21:42   ` Hervé Poussineau
  2019-08-02 16:29 ` [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Philippe Mathieu-Daudé
  2019-08-22 18:16 ` Aleksandar Markovic
  4 siblings, 2 replies; 14+ messages in thread
From: Peter Maydell @ 2019-08-02 16:04 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksandar Rikalo, Hervé Poussineau, Aleksandar Markovic,
	Aurelien Jarno

Now that the MIPS CPU implementation uses the new
do_transaction_failed hook, we can remove the old code that handled
the do_unassigned_access hook.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/mips/mips_jazz.c | 27 ++++-----------------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index c64b4c78809..540943932fd 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -111,18 +111,6 @@ static const MemoryRegionOps dma_dummy_ops = {
 #define MAGNUM_BIOS_SIZE_MAX 0x7e000
 #define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
 
-static CPUUnassignedAccess real_do_unassigned_access;
-static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr,
-                                           bool is_write, bool is_exec,
-                                           int opaque, unsigned size)
-{
-    if (!is_exec) {
-        /* ignore invalid access (ie do not raise exception) */
-        return;
-    }
-    (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size);
-}
-
 static void (*real_do_transaction_failed)(CPUState *cpu, hwaddr physaddr,
                                           vaddr addr, unsigned size,
                                           MMUAccessType access_type,
@@ -184,9 +172,8 @@ static void mips_jazz_init(MachineState *machine,
      * However, we can't simply add a global memory region to catch
      * everything, as this would make all accesses including instruction
      * accesses be ignored and not raise exceptions.
-     * So instead we hijack either the do_unassigned_access method or
-     * the do_transaction_failed method on the CPU, and do not raise exceptions
-     * for data access.
+     * So instead we hijack the do_transaction_failed method on the CPU, and
+     * do not raise exceptions for data access.
      *
      * NOTE: this behaviour of raising exceptions for bad instruction
      * fetches but not bad data accesses was added in commit 54e755588cf1e9
@@ -197,14 +184,8 @@ static void mips_jazz_init(MachineState *machine,
      * memory region that catches all memory accesses, as we do on Malta.
      */
     cc = CPU_GET_CLASS(cpu);
-    if (cc->do_unassigned_access) {
-        real_do_unassigned_access = cc->do_unassigned_access;
-        cc->do_unassigned_access = mips_jazz_do_unassigned_access;
-    }
-    if (cc->do_transaction_failed) {
-        real_do_transaction_failed = cc->do_transaction_failed;
-        cc->do_transaction_failed = mips_jazz_do_transaction_failed;
-    }
+    real_do_transaction_failed = cc->do_transaction_failed;
+    cc->do_transaction_failed = mips_jazz_do_transaction_failed;
 
     /* allocate RAM */
     memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override do_transaction_failed hook
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override " Peter Maydell
@ 2019-08-02 16:20   ` Philippe Mathieu-Daudé
  2019-09-09 21:41   ` Hervé Poussineau
  1 sibling, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-08-02 16:20 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel
  Cc: Aleksandar Rikalo, Hervé Poussineau, Aurelien Jarno,
	Aleksandar Markovic

On 8/2/19 6:04 PM, Peter Maydell wrote:
> The MIPS Jazz ('magnum' and 'pica61') boards have some code which
> overrides the CPU's do_unassigned_access hook, so they can intercept
> it and not raise exceptions on data accesses to invalid addresses,
> only for instruction fetches.
> 
> We want to switch MIPS over to using the do_transaction_failed
> hook instead, so add an intercept for that as well, and make
> the board code install whichever hook the CPU is actually using.
> Once we've changed the CPU implementation we can remove the
> redundant code for the old hook.
> 
> Note: I am suspicious that the behaviour as implemented here may not
> be what the hardware really does.  It was added in commit
> 54e755588cf1e90f0b14 to restore the behaviour that was broken by
> commit c658b94f6e8c206c59d.  But prior to commit c658b94f6e8c206c59d
> every MIPS board generated exceptions for instruction access to
> invalid addresses but not for data accesses; and other boards,
> notably Malta, were fixed by making all invalid accesses behave as
> reads-as-zero (see the call to empty_slot_init() in
> mips_malta_init()).  Hardware that raises exceptions for instruction
> access and not data access seems to me to be an unlikely design, and
> it's possible that the right way to emulate this is to make the Jazz
> boards do what we did with Malta (or some variation of that).
> Nonetheless, since I don't have access to real hardware to test
> against I have taken the approach of "make QEMU continue to behave
> the same way it did before this commit".  I have updated the comment
> to correct the parts that are no longer accurate and note that
> the hardware might behave differently.
> 
> The test case for the need for the hook-hijacking is in
> https://bugs.launchpad.net/qemu/+bug/1245924 That BIOS will boot OK
> either with this overriding of both hooks, or with a simple "global
> memory region to ignore bad accesses of all types", so it doesn't
> provide evidence either way, unfortunately.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/mips/mips_jazz.c | 54 ++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 46 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index fa8775d4284..c64b4c78809 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -123,6 +123,28 @@ static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr,
>      (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size);
>  }
>  
> +static void (*real_do_transaction_failed)(CPUState *cpu, hwaddr physaddr,
> +                                          vaddr addr, unsigned size,
> +                                          MMUAccessType access_type,
> +                                          int mmu_idx, MemTxAttrs attrs,
> +                                          MemTxResult response,
> +                                          uintptr_t retaddr);
> +
> +static void mips_jazz_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 (access_type != MMU_INST_FETCH) {
> +        /* ignore invalid access (ie do not raise exception) */
> +        return;
> +    }
> +    (*real_do_transaction_failed)(cs, physaddr, addr, size, access_type,
> +                                  mmu_idx, attrs, response, retaddr);
> +}
> +
>  static void mips_jazz_init(MachineState *machine,
>                             enum jazz_model_e jazz_model)
>  {
> @@ -157,16 +179,32 @@ static void mips_jazz_init(MachineState *machine,
>      env = &cpu->env;
>      qemu_register_reset(main_cpu_reset, cpu);
>  
> -    /* Chipset returns 0 in invalid reads and do not raise data exceptions.
> +    /*
> +     * Chipset returns 0 in invalid reads and do not raise data exceptions.
>       * However, we can't simply add a global memory region to catch
> -     * everything, as memory core directly call unassigned_mem_read/write
> -     * on some invalid accesses, which call do_unassigned_access on the
> -     * CPU, which raise an exception.
> -     * Handle that case by hijacking the do_unassigned_access method on
> -     * the CPU, and do not raise exceptions for data access. */
> +     * everything, as this would make all accesses including instruction
> +     * accesses be ignored and not raise exceptions.
> +     * So instead we hijack either the do_unassigned_access method or
> +     * the do_transaction_failed method on the CPU, and do not raise exceptions
> +     * for data access.
> +     *
> +     * NOTE: this behaviour of raising exceptions for bad instruction
> +     * fetches but not bad data accesses was added in commit 54e755588cf1e9
> +     * to restore behaviour broken by c658b94f6e8c206, but it is not clear
> +     * whether the real hardware behaves this way. It is possible that
> +     * real hardware ignores bad instruction fetches as well -- if so then
> +     * we could replace this hijacking of CPU methods with a simple global
> +     * memory region that catches all memory accesses, as we do on Malta.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> +     */
>      cc = CPU_GET_CLASS(cpu);
> -    real_do_unassigned_access = cc->do_unassigned_access;
> -    cc->do_unassigned_access = mips_jazz_do_unassigned_access;
> +    if (cc->do_unassigned_access) {
> +        real_do_unassigned_access = cc->do_unassigned_access;
> +        cc->do_unassigned_access = mips_jazz_do_unassigned_access;
> +    }
> +    if (cc->do_transaction_failed) {
> +        real_do_transaction_failed = cc->do_transaction_failed;
> +        cc->do_transaction_failed = mips_jazz_do_transaction_failed;
> +    }
>  
>      /* allocate RAM */
>      memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook
  2019-08-02 16:04 [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Peter Maydell
                   ` (2 preceding siblings ...)
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access Peter Maydell
@ 2019-08-02 16:29 ` Philippe Mathieu-Daudé
  2019-09-11  7:22   ` Aleksandar Markovic
  2019-08-22 18:16 ` Aleksandar Markovic
  4 siblings, 1 reply; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-08-02 16:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel
  Cc: Paul Burton, Maciej W. Rozycki, Aleksandar Rikalo, James Hogan,
	linux-mips, Hervé Poussineau, Aleksandar Markovic,
	Aurelien Jarno

Cc'ing broader MIPS audience.

On 8/2/19 6:04 PM, Peter Maydell wrote:
> This patchset converts the MIPS target away from the
> old broken do_unassigned_access hook to the new (added in
> 2017...) do_transaction_failed hook.
> 
> The motivation here is:
>  * do_unassigned_access is broken because:
>     + it will be called for any kind of access to physical addresses
>       where there is no assigned device, whether that access is by the
>       CPU or by something else (like a DMA controller!), so it can
>       result in spurious guest CPU exceptions.
>     + It will also get called even when using KVM, when there's nothing
>       useful it can do.
>     + It isn't passed in the return-address within the TCG generated
>       code, so it isn't able to correctly restore the CPU state
>       before generating the exception, and so the exception will
>       often be generated with the wrong faulting guest PC value
>  * there are now only a few targets still using the old hook,
>    so if we can convert them we can delete all the old code
>    and complete this API transation. (Patches for SPARC are on
>    the list; the other user is RISCV, which accidentally
>    implemented the old hook rather than the new one recently.)
> 
> The general approach to the conversion is to check the target for
> load/store-by-physical-address operations which were previously
> implicitly causing exceptions, to see if they now need to explicitly
> check for and handle memory access failures. (The 'git grep' regexes
> in docs/devel/loads-stores.rst are useful here: the API families to
> look for are ld*_phys/st*_phys, address_space_ld/st*, and
> cpu_physical_memory*.)
> 
> For MIPS, there are none of these (the usual place where targets do
> this is hardware page table walks where the page table entries are
> loaded by physical address, and MIPS doesn't seem to have those).
> 
> Code audit out of the way, the actual hook changeover is pretty
> simple.
> 
> The complication here is the MIPS Jazz board, which has some rather
> dubious code that intercepts the do_unassigned_access hook to suppress
> generation of exceptions for invalid accesses due to data accesses,
> while leaving exceptions for invalid instruction fetches in place. I'm
> a bit dubious about whether the behaviour we have implemented here is
> really what the hardware does -- it seems pretty odd to me to not
> generate exceptions for d-side accesses but to generate them for
> i-side accesses, and looking back through git and mailing list history
> this code is here mainly as "put back the behaviour we had before a
> previous commit broke it", and that older behaviour in turn I think is
> more historical-accident than because anybody deliberately checked the
> hardware behaviour and made QEMU work that way. However, I don't have
> any real hardware to do comparative tests on, so this series retains
> the same behaviour we had before on this board, by making it intercept
> the new hook in the same way it did the old one. I've beefed up the
> comment somewhat to indicate what we're doing, why, and why it might
> not be right.
> 
> The patch series is structured in three parts:
>  * make the Jazz board code support CPUs regardless of which
>    of the two hooks they implement
>  * switch the MIPS CPUs over to implementing the new hook
>  * remove the no-longer-needed Jazz board code for the old
>    hook
> (This seemed cleaner to me than squashing the whole thing into
> a single patch that touched core mips code and the jazz board
> at the same time.)
> 
> I have tested this with:
>  * the ARC Multiboot BIOS linked to from the bug
>    https://bugs.launchpad.net/qemu/+bug/1245924 (and which
>    was the test case for needing the hook intercept)
>  * a Linux kernel for the 'mips' mips r4k machine
>  * 'make check'
> Obviously more extensive testing would be useful, but I
> don't have any other test images. I also don't have
> a KVM MIPS host, which would be worth testing to confirm
> that it also still works.
> 
> If anybody happens by some chance to still have a working
> real-hardware Magnum or PICA61 board, we could perhaps test
> how it handles accesses to invalid memory, but I suspect that
> nobody does any more :-)
> 
> thanks
> -- PMM
> 
> 
> Peter Maydell (3):
>   hw/mips/mips_jazz: Override do_transaction_failed hook
>   target/mips: Switch to do_transaction_failed() hook
>   hw/mips/mips_jazz: Remove no-longer-necessary override of
>     do_unassigned_access
> 
>  target/mips/internal.h  |  8 ++++---
>  hw/mips/mips_jazz.c     | 47 +++++++++++++++++++++++++++++------------
>  target/mips/cpu.c       |  2 +-
>  target/mips/op_helper.c | 24 +++++++--------------
>  4 files changed, 47 insertions(+), 34 deletions(-)
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook Peter Maydell
@ 2019-08-02 16:29   ` Philippe Mathieu-Daudé
  2019-09-09 21:41   ` Hervé Poussineau
  1 sibling, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-08-02 16:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel
  Cc: Aleksandar Rikalo, James Hogan, Hervé Poussineau,
	Aurelien Jarno, Aleksandar Markovic

Cc'ing James Hogan.

On 8/2/19 6:04 PM, Peter Maydell wrote:
> Switch the MIPS target from the old unassigned_access hook to the new
> do_transaction_failed hook.
> 
> Unlike the old hook, do_transaction_failed is only ever called from
> the TCG memory access paths, so there is no need for the "ignore this
> if we're using KVM" hack that we were previously using to work around
> the way unassigned_access was called for all kinds of memory accesses
> to unassigned physical addresses.
> 
> The MIPS target does not ever do direct memory reads by physical
> address (via either ldl_phys etc or address_space_ldl etc), so the
> only memory accesses this affects are the 'normal' guest loads and
> stores, which will be handled by the new hook; their behaviour is
> unchanged.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/mips/internal.h  |  8 +++++---
>  target/mips/cpu.c       |  2 +-
>  target/mips/op_helper.c | 24 ++++++++----------------
>  3 files changed, 14 insertions(+), 20 deletions(-)
> 
> diff --git a/target/mips/internal.h b/target/mips/internal.h
> index b2b41a51ab4..26533bb937d 100644
> --- a/target/mips/internal.h
> +++ b/target/mips/internal.h
> @@ -138,9 +138,11 @@ void r4k_helper_tlbinv(CPUMIPSState *env);
>  void r4k_helper_tlbinvf(CPUMIPSState *env);
>  void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra);
>  
> -void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
> -                                bool is_write, bool is_exec, int unused,
> -                                unsigned size);
> +void mips_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);
>  hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
>                                    int rw);
>  #endif
> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
> index 39eafafc5cd..a79badcb1a6 100644
> --- a/target/mips/cpu.c
> +++ b/target/mips/cpu.c
> @@ -197,7 +197,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
>      cc->gdb_read_register = mips_cpu_gdb_read_register;
>      cc->gdb_write_register = mips_cpu_gdb_write_register;
>  #ifndef CONFIG_USER_ONLY
> -    cc->do_unassigned_access = mips_cpu_unassigned_access;
> +    cc->do_transaction_failed = mips_cpu_do_transaction_failed;
>      cc->do_unaligned_access = mips_cpu_do_unaligned_access;
>      cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_mips_cpu;
> diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
> index 9e2e02f8586..65ff9f5b935 100644
> --- a/target/mips/op_helper.c
> +++ b/target/mips/op_helper.c
> @@ -2666,27 +2666,19 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
>      do_raise_exception_err(env, excp, error_code, retaddr);
>  }
>  
> -void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
> -                                bool is_write, bool is_exec, int unused,
> -                                unsigned size)
> +void mips_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)
>  {
>      MIPSCPU *cpu = MIPS_CPU(cs);
>      CPUMIPSState *env = &cpu->env;
>  
> -    /*
> -     * Raising an exception with KVM enabled will crash because it won't be from
> -     * the main execution loop so the longjmp won't have a matching setjmp.
> -     * Until we can trigger a bus error exception through KVM lets just ignore
> -     * the access.
> -     */
> -    if (kvm_enabled()) {
> -        return;

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> -    }
> -
> -    if (is_exec) {
> -        raise_exception(env, EXCP_IBE);
> +    if (access_type == MMU_INST_FETCH) {
> +        do_raise_exception(env, EXCP_IBE, retaddr);
>      } else {
> -        raise_exception(env, EXCP_DBE);
> +        do_raise_exception(env, EXCP_DBE, retaddr);
>      }
>  }
>  #endif /* !CONFIG_USER_ONLY */
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access Peter Maydell
@ 2019-08-02 16:30   ` Philippe Mathieu-Daudé
  2019-09-09 21:42   ` Hervé Poussineau
  1 sibling, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-08-02 16:30 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel
  Cc: Aleksandar Rikalo, Hervé Poussineau, Aurelien Jarno,
	Aleksandar Markovic

On 8/2/19 6:04 PM, Peter Maydell wrote:
> Now that the MIPS CPU implementation uses the new
> do_transaction_failed hook, we can remove the old code that handled
> the do_unassigned_access hook.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/mips/mips_jazz.c | 27 ++++-----------------------
>  1 file changed, 4 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index c64b4c78809..540943932fd 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -111,18 +111,6 @@ static const MemoryRegionOps dma_dummy_ops = {
>  #define MAGNUM_BIOS_SIZE_MAX 0x7e000
>  #define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
>  
> -static CPUUnassignedAccess real_do_unassigned_access;
> -static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr,
> -                                           bool is_write, bool is_exec,
> -                                           int opaque, unsigned size)
> -{
> -    if (!is_exec) {
> -        /* ignore invalid access (ie do not raise exception) */
> -        return;
> -    }
> -    (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size);
> -}
> -
>  static void (*real_do_transaction_failed)(CPUState *cpu, hwaddr physaddr,
>                                            vaddr addr, unsigned size,
>                                            MMUAccessType access_type,
> @@ -184,9 +172,8 @@ static void mips_jazz_init(MachineState *machine,
>       * However, we can't simply add a global memory region to catch
>       * everything, as this would make all accesses including instruction
>       * accesses be ignored and not raise exceptions.
> -     * So instead we hijack either the do_unassigned_access method or
> -     * the do_transaction_failed method on the CPU, and do not raise exceptions
> -     * for data access.
> +     * So instead we hijack the do_transaction_failed method on the CPU, and
> +     * do not raise exceptions for data access.
>       *
>       * NOTE: this behaviour of raising exceptions for bad instruction
>       * fetches but not bad data accesses was added in commit 54e755588cf1e9
> @@ -197,14 +184,8 @@ static void mips_jazz_init(MachineState *machine,
>       * memory region that catches all memory accesses, as we do on Malta.
>       */
>      cc = CPU_GET_CLASS(cpu);
> -    if (cc->do_unassigned_access) {
> -        real_do_unassigned_access = cc->do_unassigned_access;
> -        cc->do_unassigned_access = mips_jazz_do_unassigned_access;
> -    }
> -    if (cc->do_transaction_failed) {
> -        real_do_transaction_failed = cc->do_transaction_failed;
> -        cc->do_transaction_failed = mips_jazz_do_transaction_failed;
> -    }
> +    real_do_transaction_failed = cc->do_transaction_failed;
> +    cc->do_transaction_failed = mips_jazz_do_transaction_failed;
>  
>      /* allocate RAM */
>      memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook
  2019-08-02 16:04 [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Peter Maydell
                   ` (3 preceding siblings ...)
  2019-08-02 16:29 ` [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Philippe Mathieu-Daudé
@ 2019-08-22 18:16 ` Aleksandar Markovic
  2019-09-09 10:30   ` Aleksandar Markovic
  4 siblings, 1 reply; 14+ messages in thread
From: Aleksandar Markovic @ 2019-08-22 18:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Aleksandar Rikalo, Aurelien Jarno, Hervé Poussineau,
	qemu-devel, Aleksandar Markovic

02.08.2019. 18.05, "Peter Maydell" <peter.maydell@linaro.org> је написао/ла:
>
> This patchset converts the MIPS target away from the
> old broken do_unassigned_access hook to the new (added in
> 2017...) do_transaction_failed hook.
>

Herve, bonjour.

As far as I can see these changes are fine. May I ask you for your opinion?
Can you run your Jazz tests without regressions with this change?

Mille mercis,
Aleksandar

> The motivation here is:
>  * do_unassigned_access is broken because:
>     + it will be called for any kind of access to physical addresses
>       where there is no assigned device, whether that access is by the
>       CPU or by something else (like a DMA controller!), so it can
>       result in spurious guest CPU exceptions.
>     + It will also get called even when using KVM, when there's nothing
>       useful it can do.
>     + It isn't passed in the return-address within the TCG generated
>       code, so it isn't able to correctly restore the CPU state
>       before generating the exception, and so the exception will
>       often be generated with the wrong faulting guest PC value
>  * there are now only a few targets still using the old hook,
>    so if we can convert them we can delete all the old code
>    and complete this API transation. (Patches for SPARC are on
>    the list; the other user is RISCV, which accidentally
>    implemented the old hook rather than the new one recently.)
>
> The general approach to the conversion is to check the target for
> load/store-by-physical-address operations which were previously
> implicitly causing exceptions, to see if they now need to explicitly
> check for and handle memory access failures. (The 'git grep' regexes
> in docs/devel/loads-stores.rst are useful here: the API families to
> look for are ld*_phys/st*_phys, address_space_ld/st*, and
> cpu_physical_memory*.)
>
> For MIPS, there are none of these (the usual place where targets do
> this is hardware page table walks where the page table entries are
> loaded by physical address, and MIPS doesn't seem to have those).
>
> Code audit out of the way, the actual hook changeover is pretty
> simple.
>
> The complication here is the MIPS Jazz board, which has some rather
> dubious code that intercepts the do_unassigned_access hook to suppress
> generation of exceptions for invalid accesses due to data accesses,
> while leaving exceptions for invalid instruction fetches in place. I'm
> a bit dubious about whether the behaviour we have implemented here is
> really what the hardware does -- it seems pretty odd to me to not
> generate exceptions for d-side accesses but to generate them for
> i-side accesses, and looking back through git and mailing list history
> this code is here mainly as "put back the behaviour we had before a
> previous commit broke it", and that older behaviour in turn I think is
> more historical-accident than because anybody deliberately checked the
> hardware behaviour and made QEMU work that way. However, I don't have
> any real hardware to do comparative tests on, so this series retains
> the same behaviour we had before on this board, by making it intercept
> the new hook in the same way it did the old one. I've beefed up the
> comment somewhat to indicate what we're doing, why, and why it might
> not be right.
>
> The patch series is structured in three parts:
>  * make the Jazz board code support CPUs regardless of which
>    of the two hooks they implement
>  * switch the MIPS CPUs over to implementing the new hook
>  * remove the no-longer-needed Jazz board code for the old
>    hook
> (This seemed cleaner to me than squashing the whole thing into
> a single patch that touched core mips code and the jazz board
> at the same time.)
>
> I have tested this with:
>  * the ARC Multiboot BIOS linked to from the bug
>    https://bugs.launchpad.net/qemu/+bug/1245924 (and which
>    was the test case for needing the hook intercept)
>  * a Linux kernel for the 'mips' mips r4k machine
>  * 'make check'
> Obviously more extensive testing would be useful, but I
> don't have any other test images. I also don't have
> a KVM MIPS host, which would be worth testing to confirm
> that it also still works.
>
> If anybody happens by some chance to still have a working
> real-hardware Magnum or PICA61 board, we could perhaps test
> how it handles accesses to invalid memory, but I suspect that
> nobody does any more :-)
>
> thanks
> -- PMM
>
>
> Peter Maydell (3):
>   hw/mips/mips_jazz: Override do_transaction_failed hook
>   target/mips: Switch to do_transaction_failed() hook
>   hw/mips/mips_jazz: Remove no-longer-necessary override of
>     do_unassigned_access
>
>  target/mips/internal.h  |  8 ++++---
>  hw/mips/mips_jazz.c     | 47 +++++++++++++++++++++++++++++------------
>  target/mips/cpu.c       |  2 +-
>  target/mips/op_helper.c | 24 +++++++--------------
>  4 files changed, 47 insertions(+), 34 deletions(-)
>
> --
> 2.20.1
>
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook
  2019-08-22 18:16 ` Aleksandar Markovic
@ 2019-09-09 10:30   ` Aleksandar Markovic
  0 siblings, 0 replies; 14+ messages in thread
From: Aleksandar Markovic @ 2019-09-09 10:30 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Aleksandar Rikalo, Aurelien Jarno, Hervé Poussineau,
	qemu-devel, Aleksandar Markovic

ping for Hervé.

22.08.2019. 20.16, "Aleksandar Markovic" <aleksandar.m.mail@gmail.com> је
написао/ла:
>
>
> 02.08.2019. 18.05, "Peter Maydell" <peter.maydell@linaro.org> је
написао/ла:
> >
> > This patchset converts the MIPS target away from the
> > old broken do_unassigned_access hook to the new (added in
> > 2017...) do_transaction_failed hook.
> >
>
> Herve, bonjour.
>
> As far as I can see these changes are fine. May I ask you for your
opinion? Can you run your Jazz tests without regressions with this change?
>
> Mille mercis,
> Aleksandar
>
> > The motivation here is:
> >  * do_unassigned_access is broken because:
> >     + it will be called for any kind of access to physical addresses
> >       where there is no assigned device, whether that access is by the
> >       CPU or by something else (like a DMA controller!), so it can
> >       result in spurious guest CPU exceptions.
> >     + It will also get called even when using KVM, when there's nothing
> >       useful it can do.
> >     + It isn't passed in the return-address within the TCG generated
> >       code, so it isn't able to correctly restore the CPU state
> >       before generating the exception, and so the exception will
> >       often be generated with the wrong faulting guest PC value
> >  * there are now only a few targets still using the old hook,
> >    so if we can convert them we can delete all the old code
> >    and complete this API transation. (Patches for SPARC are on
> >    the list; the other user is RISCV, which accidentally
> >    implemented the old hook rather than the new one recently.)
> >
> > The general approach to the conversion is to check the target for
> > load/store-by-physical-address operations which were previously
> > implicitly causing exceptions, to see if they now need to explicitly
> > check for and handle memory access failures. (The 'git grep' regexes
> > in docs/devel/loads-stores.rst are useful here: the API families to
> > look for are ld*_phys/st*_phys, address_space_ld/st*, and
> > cpu_physical_memory*.)
> >
> > For MIPS, there are none of these (the usual place where targets do
> > this is hardware page table walks where the page table entries are
> > loaded by physical address, and MIPS doesn't seem to have those).
> >
> > Code audit out of the way, the actual hook changeover is pretty
> > simple.
> >
> > The complication here is the MIPS Jazz board, which has some rather
> > dubious code that intercepts the do_unassigned_access hook to suppress
> > generation of exceptions for invalid accesses due to data accesses,
> > while leaving exceptions for invalid instruction fetches in place. I'm
> > a bit dubious about whether the behaviour we have implemented here is
> > really what the hardware does -- it seems pretty odd to me to not
> > generate exceptions for d-side accesses but to generate them for
> > i-side accesses, and looking back through git and mailing list history
> > this code is here mainly as "put back the behaviour we had before a
> > previous commit broke it", and that older behaviour in turn I think is
> > more historical-accident than because anybody deliberately checked the
> > hardware behaviour and made QEMU work that way. However, I don't have
> > any real hardware to do comparative tests on, so this series retains
> > the same behaviour we had before on this board, by making it intercept
> > the new hook in the same way it did the old one. I've beefed up the
> > comment somewhat to indicate what we're doing, why, and why it might
> > not be right.
> >
> > The patch series is structured in three parts:
> >  * make the Jazz board code support CPUs regardless of which
> >    of the two hooks they implement
> >  * switch the MIPS CPUs over to implementing the new hook
> >  * remove the no-longer-needed Jazz board code for the old
> >    hook
> > (This seemed cleaner to me than squashing the whole thing into
> > a single patch that touched core mips code and the jazz board
> > at the same time.)
> >
> > I have tested this with:
> >  * the ARC Multiboot BIOS linked to from the bug
> >    https://bugs.launchpad.net/qemu/+bug/1245924 (and which
> >    was the test case for needing the hook intercept)
> >  * a Linux kernel for the 'mips' mips r4k machine
> >  * 'make check'
> > Obviously more extensive testing would be useful, but I
> > don't have any other test images. I also don't have
> > a KVM MIPS host, which would be worth testing to confirm
> > that it also still works.
> >
> > If anybody happens by some chance to still have a working
> > real-hardware Magnum or PICA61 board, we could perhaps test
> > how it handles accesses to invalid memory, but I suspect that
> > nobody does any more :-)
> >
> > thanks
> > -- PMM
> >
> >
> > Peter Maydell (3):
> >   hw/mips/mips_jazz: Override do_transaction_failed hook
> >   target/mips: Switch to do_transaction_failed() hook
> >   hw/mips/mips_jazz: Remove no-longer-necessary override of
> >     do_unassigned_access
> >
> >  target/mips/internal.h  |  8 ++++---
> >  hw/mips/mips_jazz.c     | 47 +++++++++++++++++++++++++++++------------
> >  target/mips/cpu.c       |  2 +-
> >  target/mips/op_helper.c | 24 +++++++--------------
> >  4 files changed, 47 insertions(+), 34 deletions(-)
> >
> > --
> > 2.20.1
> >
> >

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override do_transaction_failed hook
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override " Peter Maydell
  2019-08-02 16:20   ` Philippe Mathieu-Daudé
@ 2019-09-09 21:41   ` Hervé Poussineau
  1 sibling, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2019-09-09 21:41 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel
  Cc: Aleksandar Rikalo, Aleksandar Markovic, Aurelien Jarno

Le 02/08/2019 à 18:04, Peter Maydell a écrit :
> The MIPS Jazz ('magnum' and 'pica61') boards have some code which
> overrides the CPU's do_unassigned_access hook, so they can intercept
> it and not raise exceptions on data accesses to invalid addresses,
> only for instruction fetches.
> 
> We want to switch MIPS over to using the do_transaction_failed
> hook instead, so add an intercept for that as well, and make
> the board code install whichever hook the CPU is actually using.
> Once we've changed the CPU implementation we can remove the
> redundant code for the old hook.
> 
> Note: I am suspicious that the behaviour as implemented here may not
> be what the hardware really does.  It was added in commit
> 54e755588cf1e90f0b14 to restore the behaviour that was broken by
> commit c658b94f6e8c206c59d.  But prior to commit c658b94f6e8c206c59d
> every MIPS board generated exceptions for instruction access to
> invalid addresses but not for data accesses; and other boards,
> notably Malta, were fixed by making all invalid accesses behave as
> reads-as-zero (see the call to empty_slot_init() in
> mips_malta_init()).  Hardware that raises exceptions for instruction
> access and not data access seems to me to be an unlikely design, and
> it's possible that the right way to emulate this is to make the Jazz
> boards do what we did with Malta (or some variation of that).
> Nonetheless, since I don't have access to real hardware to test
> against I have taken the approach of "make QEMU continue to behave
> the same way it did before this commit".  I have updated the comment
> to correct the parts that are no longer accurate and note that
> the hardware might behave differently.
> 
> The test case for the need for the hook-hijacking is in
> https://bugs.launchpad.net/qemu/+bug/1245924 That BIOS will boot OK
> either with this overriding of both hooks, or with a simple "global
> memory region to ignore bad accesses of all types", so it doesn't
> provide evidence either way, unfortunately.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Tested-by: Hervé Poussineau <hpoussin@reactos.org>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook Peter Maydell
  2019-08-02 16:29   ` Philippe Mathieu-Daudé
@ 2019-09-09 21:41   ` Hervé Poussineau
  1 sibling, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2019-09-09 21:41 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel
  Cc: Aleksandar Rikalo, Aleksandar Markovic, Aurelien Jarno

Le 02/08/2019 à 18:04, Peter Maydell a écrit :
> Switch the MIPS target from the old unassigned_access hook to the new
> do_transaction_failed hook.
> 
> Unlike the old hook, do_transaction_failed is only ever called from
> the TCG memory access paths, so there is no need for the "ignore this
> if we're using KVM" hack that we were previously using to work around
> the way unassigned_access was called for all kinds of memory accesses
> to unassigned physical addresses.
> 
> The MIPS target does not ever do direct memory reads by physical
> address (via either ldl_phys etc or address_space_ldl etc), so the
> only memory accesses this affects are the 'normal' guest loads and
> stores, which will be handled by the new hook; their behaviour is
> unchanged.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/mips/internal.h  |  8 +++++---
>   target/mips/cpu.c       |  2 +-
>   target/mips/op_helper.c | 24 ++++++++----------------
>   3 files changed, 14 insertions(+), 20 deletions(-)

Tested-by: Hervé Poussineau <hpoussin@reactos.org>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access
  2019-08-02 16:04 ` [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access Peter Maydell
  2019-08-02 16:30   ` Philippe Mathieu-Daudé
@ 2019-09-09 21:42   ` Hervé Poussineau
  1 sibling, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2019-09-09 21:42 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel
  Cc: Aleksandar Rikalo, Aleksandar Markovic, Aurelien Jarno

Le 02/08/2019 à 18:04, Peter Maydell a écrit :
> Now that the MIPS CPU implementation uses the new
> do_transaction_failed hook, we can remove the old code that handled
> the do_unassigned_access hook.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   hw/mips/mips_jazz.c | 27 ++++-----------------------
>   1 file changed, 4 insertions(+), 23 deletions(-)

Tested-by: Hervé Poussineau <hpoussin@reactos.org>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook
  2019-08-02 16:29 ` [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Philippe Mathieu-Daudé
@ 2019-09-11  7:22   ` Aleksandar Markovic
  0 siblings, 0 replies; 14+ messages in thread
From: Aleksandar Markovic @ 2019-09-11  7:22 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Peter Maydell, Aleksandar Markovic, Paul Burton,
	Aleksandar Rikalo, James Hogan, linux-mips, qemu-devel,
	Hervé Poussineau, Maciej W. Rozycki, Aurelien Jarno

02.08.2019. 18.29, "Philippe Mathieu-Daudé" <philmd@redhat.com> је
написао/ла:
>
> Cc'ing broader MIPS audience.
>
> On 8/2/19 6:04 PM, Peter Maydell wrote:
> > This patchset converts the MIPS target away from the
> > old broken do_unassigned_access hook to the new (added in
> > 2017...) do_transaction_failed hook.
> >

Since Herve now tested this series, unless somebody objects, I am going to
include it in the next Mips queue, scheduled in next few days.

Thanks to all involved!

Aleksandar

> > The motivation here is:
> >  * do_unassigned_access is broken because:
> >     + it will be called for any kind of access to physical addresses
> >       where there is no assigned device, whether that access is by the
> >       CPU or by something else (like a DMA controller!), so it can
> >       result in spurious guest CPU exceptions.
> >     + It will also get called even when using KVM, when there's nothing
> >       useful it can do.
> >     + It isn't passed in the return-address within the TCG generated
> >       code, so it isn't able to correctly restore the CPU state
> >       before generating the exception, and so the exception will
> >       often be generated with the wrong faulting guest PC value
> >  * there are now only a few targets still using the old hook,
> >    so if we can convert them we can delete all the old code
> >    and complete this API transation. (Patches for SPARC are on
> >    the list; the other user is RISCV, which accidentally
> >    implemented the old hook rather than the new one recently.)
> >
> > The general approach to the conversion is to check the target for
> > load/store-by-physical-address operations which were previously
> > implicitly causing exceptions, to see if they now need to explicitly
> > check for and handle memory access failures. (The 'git grep' regexes
> > in docs/devel/loads-stores.rst are useful here: the API families to
> > look for are ld*_phys/st*_phys, address_space_ld/st*, and
> > cpu_physical_memory*.)
> >
> > For MIPS, there are none of these (the usual place where targets do
> > this is hardware page table walks where the page table entries are
> > loaded by physical address, and MIPS doesn't seem to have those).
> >
> > Code audit out of the way, the actual hook changeover is pretty
> > simple.
> >
> > The complication here is the MIPS Jazz board, which has some rather
> > dubious code that intercepts the do_unassigned_access hook to suppress
> > generation of exceptions for invalid accesses due to data accesses,
> > while leaving exceptions for invalid instruction fetches in place. I'm
> > a bit dubious about whether the behaviour we have implemented here is
> > really what the hardware does -- it seems pretty odd to me to not
> > generate exceptions for d-side accesses but to generate them for
> > i-side accesses, and looking back through git and mailing list history
> > this code is here mainly as "put back the behaviour we had before a
> > previous commit broke it", and that older behaviour in turn I think is
> > more historical-accident than because anybody deliberately checked the
> > hardware behaviour and made QEMU work that way. However, I don't have
> > any real hardware to do comparative tests on, so this series retains
> > the same behaviour we had before on this board, by making it intercept
> > the new hook in the same way it did the old one. I've beefed up the
> > comment somewhat to indicate what we're doing, why, and why it might
> > not be right.
> >
> > The patch series is structured in three parts:
> >  * make the Jazz board code support CPUs regardless of which
> >    of the two hooks they implement
> >  * switch the MIPS CPUs over to implementing the new hook
> >  * remove the no-longer-needed Jazz board code for the old
> >    hook
> > (This seemed cleaner to me than squashing the whole thing into
> > a single patch that touched core mips code and the jazz board
> > at the same time.)
> >
> > I have tested this with:
> >  * the ARC Multiboot BIOS linked to from the bug
> >    https://bugs.launchpad.net/qemu/+bug/1245924 (and which
> >    was the test case for needing the hook intercept)
> >  * a Linux kernel for the 'mips' mips r4k machine
> >  * 'make check'
> > Obviously more extensive testing would be useful, but I
> > don't have any other test images. I also don't have
> > a KVM MIPS host, which would be worth testing to confirm
> > that it also still works.
> >
> > If anybody happens by some chance to still have a working
> > real-hardware Magnum or PICA61 board, we could perhaps test
> > how it handles accesses to invalid memory, but I suspect that
> > nobody does any more :-)
> >
> > thanks
> > -- PMM
> >
> >
> > Peter Maydell (3):
> >   hw/mips/mips_jazz: Override do_transaction_failed hook
> >   target/mips: Switch to do_transaction_failed() hook
> >   hw/mips/mips_jazz: Remove no-longer-necessary override of
> >     do_unassigned_access
> >
> >  target/mips/internal.h  |  8 ++++---
> >  hw/mips/mips_jazz.c     | 47 +++++++++++++++++++++++++++++------------
> >  target/mips/cpu.c       |  2 +-
> >  target/mips/op_helper.c | 24 +++++++--------------
> >  4 files changed, 47 insertions(+), 34 deletions(-)
> >
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2019-09-11  7:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-02 16:04 [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Peter Maydell
2019-08-02 16:04 ` [Qemu-devel] [PATCH 1/3] hw/mips/mips_jazz: Override " Peter Maydell
2019-08-02 16:20   ` Philippe Mathieu-Daudé
2019-09-09 21:41   ` Hervé Poussineau
2019-08-02 16:04 ` [Qemu-devel] [PATCH 2/3] target/mips: Switch to do_transaction_failed() hook Peter Maydell
2019-08-02 16:29   ` Philippe Mathieu-Daudé
2019-09-09 21:41   ` Hervé Poussineau
2019-08-02 16:04 ` [Qemu-devel] [PATCH 3/3] hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access Peter Maydell
2019-08-02 16:30   ` Philippe Mathieu-Daudé
2019-09-09 21:42   ` Hervé Poussineau
2019-08-02 16:29 ` [Qemu-devel] [PATCH 0/3] target/mips: Convert to do_transaction_failed hook Philippe Mathieu-Daudé
2019-09-11  7:22   ` Aleksandar Markovic
2019-08-22 18:16 ` Aleksandar Markovic
2019-09-09 10:30   ` Aleksandar Markovic

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).