[PATCH v3 2/5] linux-user/riscv: Allow restore_sigcontext to return error

Nicholas Piggin posted 5 patches 1 day ago
[PATCH v3 2/5] linux-user/riscv: Allow restore_sigcontext to return error
Posted by Nicholas Piggin 1 day ago
Linux can return error from restore_sigcontext in some conditions, which
forces a SIGSEGV. Plumb through this error handling which will be used
by the next change.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 linux-user/riscv/signal.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
index 22b1b8149f..ece276f85f 100644
--- a/linux-user/riscv/signal.c
+++ b/linux-user/riscv/signal.c
@@ -145,7 +145,7 @@ badframe:
     force_sig(TARGET_SIGSEGV);
 }
 
-static void restore_sigcontext(CPURISCVState *env, struct target_sigcontext *sc)
+static bool restore_sigcontext(CPURISCVState *env, struct target_sigcontext *sc)
 {
     int i;
 
@@ -161,9 +161,11 @@ static void restore_sigcontext(CPURISCVState *env, struct target_sigcontext *sc)
     uint32_t fcsr;
     __get_user(fcsr, &sc->fcsr);
     riscv_csr_write(env, CSR_FCSR, fcsr);
+
+    return true;
 }
 
-static void restore_ucontext(CPURISCVState *env, struct target_ucontext *uc)
+static bool restore_ucontext(CPURISCVState *env, struct target_ucontext *uc)
 {
     sigset_t blocked;
     target_sigset_t target_set;
@@ -177,7 +179,7 @@ static void restore_ucontext(CPURISCVState *env, struct target_ucontext *uc)
     target_to_host_sigset_internal(&blocked, &target_set);
     set_sigmask(&blocked);
 
-    restore_sigcontext(env, &uc->uc_mcontext);
+    return restore_sigcontext(env, &uc->uc_mcontext);
 }
 
 long do_rt_sigreturn(CPURISCVState *env)
@@ -191,7 +193,10 @@ long do_rt_sigreturn(CPURISCVState *env)
         goto badframe;
     }
 
-    restore_ucontext(env, &frame->uc);
+    if (!restore_ucontext(env, &frame->uc)) {
+        goto badframe;
+    }
+
     target_restore_altstack(&frame->uc.uc_stack, env);
 
     unlock_user_struct(frame, frame_addr, 0);
-- 
2.51.0