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

Reply via email to