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