All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] linux-user/riscv: Propagate fault address
@ 2019-10-01 16:39 LemonBoy
  2019-10-14 23:55 ` Palmer Dabbelt
  0 siblings, 1 reply; 2+ messages in thread
From: LemonBoy @ 2019-10-01 16:39 UTC (permalink / raw)
  To: qemu-devel, Riku Voipio, Laurent Vivier

The CPU loop tagged all the queued signals as QEMU_SI_KILL while it was
filling the `_sigfault` part of `siginfo`: this caused QEMU to copy the
wrong fields over to the userspace program.

Make sure the fault address recorded by the MMU is is stored in the CPU
environment structure.

In case of memory faults store the exception address into `siginfo`.

Signed-off-by: Giuseppe Musacchio <thatlemon@gmail.com>
---
 linux-user/riscv/cpu_loop.c | 3 ++-
 target/riscv/cpu_helper.c   | 5 ++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 12aa3c0f16..aa9e437875 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -89,6 +89,7 @@ void cpu_loop(CPURISCVState *env)
         case RISCV_EXCP_STORE_PAGE_FAULT:
             signum = TARGET_SIGSEGV;
             sigcode = TARGET_SEGV_MAPERR;
+            sigaddr = env->badaddr;
             break;
         case EXCP_DEBUG:
         gdbstep:
@@ -108,7 +109,7 @@ void cpu_loop(CPURISCVState *env)
                 .si_code = sigcode,
                 ._sifields._sigfault._addr = sigaddr
             };
-            queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
         }
 
         process_pending_signals(env);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 87dd6a6ece..58e40e9824 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -446,9 +446,9 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                         MMUAccessType access_type, int mmu_idx,
                         bool probe, uintptr_t retaddr)
 {
-#ifndef CONFIG_USER_ONLY
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
+#ifndef CONFIG_USER_ONLY
     hwaddr pa = 0;
     int prot;
     bool pmp_violation = false;
@@ -499,7 +499,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     case MMU_DATA_STORE:
         cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
         break;
+    default:
+        g_assert_not_reached();
     }
+    env->badaddr = address;
     cpu_loop_exit_restore(cs, retaddr);
 #endif
 }
-- 
2.20.1



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

* Re: [PATCH] linux-user/riscv: Propagate fault address
  2019-10-01 16:39 [PATCH] linux-user/riscv: Propagate fault address LemonBoy
@ 2019-10-14 23:55 ` Palmer Dabbelt
  0 siblings, 0 replies; 2+ messages in thread
From: Palmer Dabbelt @ 2019-10-14 23:55 UTC (permalink / raw)
  To: thatlemon; +Cc: riku.voipio, qemu-devel, laurent

On Tue, 01 Oct 2019 09:39:52 PDT (-0700), thatlemon@gmail.com wrote:
> The CPU loop tagged all the queued signals as QEMU_SI_KILL while it was
> filling the `_sigfault` part of `siginfo`: this caused QEMU to copy the
> wrong fields over to the userspace program.
>
> Make sure the fault address recorded by the MMU is is stored in the CPU
> environment structure.
>
> In case of memory faults store the exception address into `siginfo`.
>
> Signed-off-by: Giuseppe Musacchio <thatlemon@gmail.com>
> ---
>  linux-user/riscv/cpu_loop.c | 3 ++-
>  target/riscv/cpu_helper.c   | 5 ++++-
>  2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
> index 12aa3c0f16..aa9e437875 100644
> --- a/linux-user/riscv/cpu_loop.c
> +++ b/linux-user/riscv/cpu_loop.c
> @@ -89,6 +89,7 @@ void cpu_loop(CPURISCVState *env)
>          case RISCV_EXCP_STORE_PAGE_FAULT:
>              signum = TARGET_SIGSEGV;
>              sigcode = TARGET_SEGV_MAPERR;
> +            sigaddr = env->badaddr;
>              break;
>          case EXCP_DEBUG:
>          gdbstep:
> @@ -108,7 +109,7 @@ void cpu_loop(CPURISCVState *env)
>                  .si_code = sigcode,
>                  ._sifields._sigfault._addr = sigaddr
>              };
> -            queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
> +            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
>          }
>
>          process_pending_signals(env);
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 87dd6a6ece..58e40e9824 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -446,9 +446,9 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>                          MMUAccessType access_type, int mmu_idx,
>                          bool probe, uintptr_t retaddr)
>  {
> -#ifndef CONFIG_USER_ONLY
>      RISCVCPU *cpu = RISCV_CPU(cs);
>      CPURISCVState *env = &cpu->env;
> +#ifndef CONFIG_USER_ONLY
>      hwaddr pa = 0;
>      int prot;
>      bool pmp_violation = false;
> @@ -499,7 +499,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>      case MMU_DATA_STORE:
>          cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
>          break;
> +    default:
> +        g_assert_not_reached();
>      }
> +    env->badaddr = address;
>      cpu_loop_exit_restore(cs, retaddr);
>  #endif
>  }

Reviewed-by: Palmer Dabbelt <palmer@sifive.com>

I fixed up your Author tag and added this to for-master.  Thanks!


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

end of thread, other threads:[~2019-10-14 23:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-01 16:39 [PATCH] linux-user/riscv: Propagate fault address LemonBoy
2019-10-14 23:55 ` Palmer Dabbelt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.