Message ID | 20230309201604.3885359-3-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | target/m68k: Reject immediate as destination | expand |
Le 09/03/2023 à 21:16, Richard Henderson a écrit : > This exception can be raised by illegal instructions. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > linux-user/m68k/cpu_loop.c | 5 ++++- > tests/tcg/m68k/excp-address.c | 32 ++++++++++++++++++++++++++++++++ > tests/tcg/m68k/Makefile.target | 1 + > 3 files changed, 37 insertions(+), 1 deletion(-) > create mode 100644 tests/tcg/m68k/excp-address.c > > diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c > index caead1cb74..84b5d290c0 100644 > --- a/linux-user/m68k/cpu_loop.c > +++ b/linux-user/m68k/cpu_loop.c > @@ -35,7 +35,10 @@ void cpu_loop(CPUM68KState *env) > cpu_exec_end(cs); > process_queued_cpu_work(cs); > > - switch(trapnr) { > + switch (trapnr) { > + case EXCP_ADDRESS: > + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->pc); > + break; > case EXCP_ILLEGAL: > case EXCP_LINEA: > case EXCP_LINEF: > diff --git a/tests/tcg/m68k/excp-address.c b/tests/tcg/m68k/excp-address.c > new file mode 100644 > index 0000000000..1dbdddef58 > --- /dev/null > +++ b/tests/tcg/m68k/excp-address.c > @@ -0,0 +1,32 @@ > +/* > + * Test m68k address exception > + */ > + > +#define _GNU_SOURCE 1 > +#include <signal.h> > +#include <stdlib.h> > + > +static void sig_handler(int sig, siginfo_t *si, void *puc) > +{ > + exit(0); > +} > + > +int main(int argc, char **argv) > +{ > + struct sigaction act = { > + .sa_sigaction = sig_handler, > + .sa_flags = SA_SIGINFO > + }; > + > + sigaction(SIGBUS, &act, NULL); > + > + /* > + * addl %d0,#0 -- with immediate as destination is illegal. > + * Buggy qemu interpreted the insn as 5 words: 2 for immediate source > + * and another 2 for immediate destination. Provide all that padding > + * so that abort gets called. > + */ > + asm volatile(".word 0xd1bc,0,0,0,0"); > + > + abort(); > +} > diff --git a/tests/tcg/m68k/Makefile.target b/tests/tcg/m68k/Makefile.target > index 1163c7ef03..d3b0bc48a3 100644 > --- a/tests/tcg/m68k/Makefile.target > +++ b/tests/tcg/m68k/Makefile.target > @@ -4,6 +4,7 @@ > # > > VPATH += $(SRC_PATH)/tests/tcg/m68k > +TESTS += excp-address > TESTS += trap > > # On m68k Linux supports 4k and 8k pages (but 8k is currently broken) Reviewed-by: Laurent Vivier <laurent@vivier.eu> I've tested tests/tcg/m68k/excp-address.c on a real hardware (Q800), and the result differs from the one from QEMU: On Q800 (etch m68k, kernel 5.14.0): $ ./excp-address Illegal instruction $ strace ./excp-address ... rt_sigaction(SIGBUS, {0x80000478, [], SA_SIGINFO}, NULL, 8) = 0 --- SIGILL (Illegal instruction) @ 0 (0) --- +++ killed by SIGILL +++ With QEMU, we have: # QEMU_STRACE= ./excp-address ... 677354 rt_sigaction(SIGBUS,0x40800454,NULL) = 0 --- SIGBUS {si_signo=SIGBUS, si_code=1, si_addr=0x800004ce} --- 677354 exit_group(0) Thanks, Laurent
On 3/15/23 11:16, Laurent Vivier wrote: > I've tested tests/tcg/m68k/excp-address.c on a real hardware (Q800), and the result > differs from the one from QEMU: > > On Q800 (etch m68k, kernel 5.14.0): > > $ ./excp-address > Illegal instruction > $ strace ./excp-address > ... > rt_sigaction(SIGBUS, {0x80000478, [], SA_SIGINFO}, NULL, 8) = 0 > --- SIGILL (Illegal instruction) @ 0 (0) --- > +++ killed by SIGILL +++ Ok, that suggests that we need to do something different in the translator in patch 1. I'll give it some thought. r~
diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c index caead1cb74..84b5d290c0 100644 --- a/linux-user/m68k/cpu_loop.c +++ b/linux-user/m68k/cpu_loop.c @@ -35,7 +35,10 @@ void cpu_loop(CPUM68KState *env) cpu_exec_end(cs); process_queued_cpu_work(cs); - switch(trapnr) { + switch (trapnr) { + case EXCP_ADDRESS: + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->pc); + break; case EXCP_ILLEGAL: case EXCP_LINEA: case EXCP_LINEF: diff --git a/tests/tcg/m68k/excp-address.c b/tests/tcg/m68k/excp-address.c new file mode 100644 index 0000000000..1dbdddef58 --- /dev/null +++ b/tests/tcg/m68k/excp-address.c @@ -0,0 +1,32 @@ +/* + * Test m68k address exception + */ + +#define _GNU_SOURCE 1 +#include <signal.h> +#include <stdlib.h> + +static void sig_handler(int sig, siginfo_t *si, void *puc) +{ + exit(0); +} + +int main(int argc, char **argv) +{ + struct sigaction act = { + .sa_sigaction = sig_handler, + .sa_flags = SA_SIGINFO + }; + + sigaction(SIGBUS, &act, NULL); + + /* + * addl %d0,#0 -- with immediate as destination is illegal. + * Buggy qemu interpreted the insn as 5 words: 2 for immediate source + * and another 2 for immediate destination. Provide all that padding + * so that abort gets called. + */ + asm volatile(".word 0xd1bc,0,0,0,0"); + + abort(); +} diff --git a/tests/tcg/m68k/Makefile.target b/tests/tcg/m68k/Makefile.target index 1163c7ef03..d3b0bc48a3 100644 --- a/tests/tcg/m68k/Makefile.target +++ b/tests/tcg/m68k/Makefile.target @@ -4,6 +4,7 @@ # VPATH += $(SRC_PATH)/tests/tcg/m68k +TESTS += excp-address TESTS += trap # On m68k Linux supports 4k and 8k pages (but 8k is currently broken)
This exception can be raised by illegal instructions. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/m68k/cpu_loop.c | 5 ++++- tests/tcg/m68k/excp-address.c | 32 ++++++++++++++++++++++++++++++++ tests/tcg/m68k/Makefile.target | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/m68k/excp-address.c