On Thu, Jan 13, 2022 at 10:40 AM Peter Maydell <peter.maydell@linaro.org> wrote:
On Sun, 9 Jan 2022 at 16:29, Warner Losh <imp@bsdimp.com> wrote:
>
> Update for the richer set of data faults that are now possible. Copied
> largely from linux-user/arm/cpu_loop.c
>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
>  bsd-user/arm/target_arch_cpu.h | 44 ++++++++++++++++++++++++++--------
>  1 file changed, 34 insertions(+), 10 deletions(-)
>
> diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
> index 996a361e3fe..51e592bcfe7 100644
> --- a/bsd-user/arm/target_arch_cpu.h
> +++ b/bsd-user/arm/target_arch_cpu.h
> @@ -39,8 +39,7 @@ static inline void target_cpu_init(CPUARMState *env,
>
>  static inline void target_cpu_loop(CPUARMState *env)
>  {
> -    int trapnr;
> -    target_siginfo_t info;
> +    int trapnr, si_signo, si_code;
>      unsigned int n;
>      CPUState *cs = env_cpu(env);
>
> @@ -143,15 +142,40 @@ static inline void target_cpu_loop(CPUARMState *env)
>              /* just indicate that signals should be handled asap */
>              break;
>          case EXCP_PREFETCH_ABORT:
> -            /* See arm/arm/trap.c prefetch_abort_handler() */
>          case EXCP_DATA_ABORT:
> -            /* See arm/arm/trap.c data_abort_handler() */
> -            info.si_signo = TARGET_SIGSEGV;
> -            info.si_errno = 0;
> -            /* XXX: check env->error_code */
> -            info.si_code = 0;
> -            info.si_addr = env->exception.vaddress;
> -            queue_signal(env, info.si_signo, &info);
> +            /*
> +             * See arm/arm/trap-v6.c prefetch_abort_handler() and data_abort_handler()
> +             *
> +             * However, FreeBSD maps these to a generic value and then uses that
> +             * to maybe fault in pages in vm/vm_fault.c:vm_fault_trap(). I
> +             * believe that the indirection maps the same as Linux, but haven't
> +             * chased down every single possible indirection.
> +             */
> +
> +            /* For user-only we don't set TTBCR_EAE, so look at the FSR. */
> +            switch (env->exception.fsr & 0x1f) {
> +            case 0x1: /* Alignment */
> +                si_signo = TARGET_SIGBUS;
> +                si_code = TARGET_BUS_ADRALN;
> +                break;
> +            case 0x3: /* Access flag fault, level 1 */
> +            case 0x6: /* Access flag fault, level 2 */
> +            case 0x9: /* Domain fault, level 1 */
> +            case 0xb: /* Domain fault, level 2 */
> +            case 0xd: /* Permision fault, level 1 */
> +            case 0xf: /* Permision fault, level 2 */

"Permission" (I see we have this typo in linux-user).

Fixed. Also, if you can, please cc me if you'd like on 'back ported' fixes into linux-user when you post them
for review that arise from this. It helps me keep track and not miss them in this rather high volume mailing
list.
 
> +                si_signo = TARGET_SIGSEGV;
> +                si_code = TARGET_SEGV_ACCERR;
> +                break;
> +            case 0x5: /* Translation fault, level 1 */
> +            case 0x7: /* Translation fault, level 2 */
> +                si_signo = TARGET_SIGSEGV;
> +                si_code = TARGET_SEGV_MAPERR;
> +                break;
> +            default:
> +                g_assert_not_reached();
> +            }

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

Thanks!

Warner