linux-user: Fixed cpu restore with pc 0 on SIGBUS
Commitf4e1168198
(linux-user: Split out host_sig{segv,bus}_handler) introduced a bug, when returning from host_sigbus_handler the PC is never set. Thus cpu_loop_exit_restore is called with a zero PC and we immediate get a SIGSEGV. Signed-off-by: Robbin Ehn <rehn@rivosinc.com> Fixes:f4e1168198
("linux-user: Split out host_sig{segv,bus}_handler") Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com> Message-Id: <33f27425878fb529b9e39ef22c303f6e0d90525f.camel@rivosinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
8f8419d325
commit
6d913158b5
@ -925,7 +925,7 @@ static void host_sigsegv_handler(CPUState *cpu, siginfo_t *info,
|
|||||||
cpu_loop_exit_sigsegv(cpu, guest_addr, access_type, maperr, pc);
|
cpu_loop_exit_sigsegv(cpu, guest_addr, access_type, maperr, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void host_sigbus_handler(CPUState *cpu, siginfo_t *info,
|
static uintptr_t host_sigbus_handler(CPUState *cpu, siginfo_t *info,
|
||||||
host_sigcontext *uc)
|
host_sigcontext *uc)
|
||||||
{
|
{
|
||||||
uintptr_t pc = host_signal_pc(uc);
|
uintptr_t pc = host_signal_pc(uc);
|
||||||
@ -947,6 +947,7 @@ static void host_sigbus_handler(CPUState *cpu, siginfo_t *info,
|
|||||||
sigprocmask(SIG_SETMASK, host_signal_mask(uc), NULL);
|
sigprocmask(SIG_SETMASK, host_signal_mask(uc), NULL);
|
||||||
cpu_loop_exit_sigbus(cpu, guest_addr, access_type, pc);
|
cpu_loop_exit_sigbus(cpu, guest_addr, access_type, pc);
|
||||||
}
|
}
|
||||||
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
||||||
@ -974,7 +975,7 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
|||||||
host_sigsegv_handler(cpu, info, uc);
|
host_sigsegv_handler(cpu, info, uc);
|
||||||
return;
|
return;
|
||||||
case SIGBUS:
|
case SIGBUS:
|
||||||
host_sigbus_handler(cpu, info, uc);
|
pc = host_sigbus_handler(cpu, info, uc);
|
||||||
sync_sig = true;
|
sync_sig = true;
|
||||||
break;
|
break;
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
|
Loading…
Reference in New Issue
Block a user