Message ID | 20210729004647.282017-13-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | Unaligned accesses for user-only | expand |
On Thu, 29 Jul 2021 at 02:01, Richard Henderson <richard.henderson@linaro.org> wrote: > > Cc: Yoshinori Sato <ysato@users.sourceforge.jp> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > linux-user/sh4/cpu_loop.c | 8 ++++++++ > target/sh4/cpu.c | 2 +- > target/sh4/op_helper.c | 3 --- > 3 files changed, 9 insertions(+), 4 deletions(-) > > diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c > index 222ed1c670..21d97250a8 100644 > --- a/linux-user/sh4/cpu_loop.c > +++ b/linux-user/sh4/cpu_loop.c > @@ -71,6 +71,14 @@ void cpu_loop(CPUSH4State *env) > info._sifields._sigfault._addr = env->tea; > queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); > break; > + case 0xe0: > + case 0x100: > + info.si_signo = TARGET_SIGBUS; > + info.si_errno = 0; > + info.si_code = TARGET_BUS_ADRALN; > + info._sifields._sigfault._addr = env->tea; > + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); > + break; sh4 kernel default for unaligned accesses seems to be "warn and fixup", not SIGBUS, unless the user changes that by writing to /proc/cpu/alignment or the process changes it via prctl(). -- PMM
On 7/29/21 3:52 AM, Peter Maydell wrote: > sh4 kernel default for unaligned accesses seems to be "warn and fixup", > not SIGBUS, unless the user changes that by writing to /proc/cpu/alignment > or the process changes it via prctl(). We will still need this for load-locked/store-conditional (MOVLI/MOVCO). It appears that the sh4 kernel fails to decode these properly, and will do something ugly, like interpreting MOVLI as a multiple-store instead of a load. There are also other instructions that the kernel does not attempt to handle, such as MAC. I suppose we could begin with turning off TARGET_ALIGNED_ONLY for sh4-linux-user, then re-enabling MO_ALIGN for the atomics (at least). r~
On 7/29/21 8:52 AM, Peter Maydell wrote: > On Thu, 29 Jul 2021 at 02:01, Richard Henderson > <richard.henderson@linaro.org> wrote: >> >> Cc: Yoshinori Sato <ysato@users.sourceforge.jp> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> --- >> linux-user/sh4/cpu_loop.c | 8 ++++++++ >> target/sh4/cpu.c | 2 +- >> target/sh4/op_helper.c | 3 --- >> 3 files changed, 9 insertions(+), 4 deletions(-) >> >> diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c >> index 222ed1c670..21d97250a8 100644 >> --- a/linux-user/sh4/cpu_loop.c >> +++ b/linux-user/sh4/cpu_loop.c >> @@ -71,6 +71,14 @@ void cpu_loop(CPUSH4State *env) >> info._sifields._sigfault._addr = env->tea; >> queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); >> break; >> + case 0xe0: >> + case 0x100: >> + info.si_signo = TARGET_SIGBUS; >> + info.si_errno = 0; >> + info.si_code = TARGET_BUS_ADRALN; >> + info._sifields._sigfault._addr = env->tea; >> + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); >> + break; > > sh4 kernel default for unaligned accesses seems to be "warn and fixup", > not SIGBUS, unless the user changes that by writing to /proc/cpu/alignment > or the process changes it via prctl(). It's still good to know, qemu-sh4 runs j-core binaries but that target doesn't have unaligned interrupts yet. (I think it just masks off the bottom 2 bits to do the next lowest aligned access? It's an sh2 variant and the plumbing to let interrupts restart multi-clock instructions is only in the j32 branch so far, so the j2 and ice40 targets don't generate interrupts for it. Todo item, in the meantime we need to clean unaligned access out of application code so faulting on it is good.) > -- PMM Thanks, Rob
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c index 222ed1c670..21d97250a8 100644 --- a/linux-user/sh4/cpu_loop.c +++ b/linux-user/sh4/cpu_loop.c @@ -71,6 +71,14 @@ void cpu_loop(CPUSH4State *env) info._sifields._sigfault._addr = env->tea; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; + case 0xe0: + case 0x100: + info.si_signo = TARGET_SIGBUS; + info.si_errno = 0; + info.si_code = TARGET_BUS_ADRALN; + info._sifields._sigfault._addr = env->tea; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; case EXCP_ATOMIC: cpu_exec_step_atomic(cs); arch_interrupt = false; diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index 8326922942..b60234cd31 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -238,10 +238,10 @@ static const struct TCGCPUOps superh_tcg_ops = { .synchronize_from_tb = superh_cpu_synchronize_from_tb, .cpu_exec_interrupt = superh_cpu_exec_interrupt, .tlb_fill = superh_cpu_tlb_fill, + .do_unaligned_access = superh_cpu_do_unaligned_access, #ifndef CONFIG_USER_ONLY .do_interrupt = superh_cpu_do_interrupt, - .do_unaligned_access = superh_cpu_do_unaligned_access, .io_recompile_replay_branch = superh_io_recompile_replay_branch, #endif /* !CONFIG_USER_ONLY */ }; diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c index d6d70c339f..b46fc1bf11 100644 --- a/target/sh4/op_helper.c +++ b/target/sh4/op_helper.c @@ -23,7 +23,6 @@ #include "exec/cpu_ldst.h" #include "fpu/softfloat.h" -#ifndef CONFIG_USER_ONLY void superh_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, @@ -46,8 +45,6 @@ void superh_cpu_do_unaligned_access(CPUState *cs, vaddr addr, cpu_loop_exit_restore(cs, retaddr); } -#endif - void helper_ldtlb(CPUSH4State *env) { #ifdef CONFIG_USER_ONLY
Cc: Yoshinori Sato <ysato@users.sourceforge.jp> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/sh4/cpu_loop.c | 8 ++++++++ target/sh4/cpu.c | 2 +- target/sh4/op_helper.c | 3 --- 3 files changed, 9 insertions(+), 4 deletions(-) -- 2.25.1