Hi Richard,
On 2022/6/10 上午2:42, Richard Henderson wrote:
void helper_asrtle_d(CPULoongArchState *env, target_ulong rj,
target_ulong rk)
{
if (rj > rk) {
+#ifdef CONFIG_USER_ONLY
+ cpu_loop_exit_sigsegv(env_cpu(env), GETPC(),
+ MMU_DATA_LOAD, true, GETPC());
+#else
do_raise_exception(env, EXCCODE_ADEM, GETPC());
+#endif
This change is wrong. First, the kernel's do_ade raises SIGBUS.
Second, GETPC() is a host address, not a guest address. Third, this
highlights the fact that the existing system code is wrong, and should
be setting badvaddr.
You need to
(1) set badvaddr here, and then
(2) handle EXCCODE_ADEM in linux-user/loongarch/cpu_loop.c to
force_fix_fault(TARGET_SIGBUS, TARGET_BUS_ADRERR, env->badvaddr).
badvaddr is env->pc or base->pc_next? and we just raise exception on
use-mode,
like this
void helper_asrtle_d(CPULoongArchState *env, target_ulong rj,
target_ulong rk)
{
if (rj > rk) {
env->badvaddr = env->pc;
#ifdef CONFIG_USER_ONLY
do_raise_exception(env, EXCCODE_ADEM, GETPC());
#endif
}
}
cpu_loop.c
case EXCCODE_ADEM:
force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRERR,
env->badvaddr);
break;
Thanks.
Song Gao