diff options
| -rw-r--r-- | usr/src/cmd/dtrace/test/tst/i386/error/tst.DTRACEFLT_DIVZERO.d | 38 | ||||
| -rw-r--r-- | usr/src/pkg/manifests/system-dtrace-tests.mf | 1 | ||||
| -rw-r--r-- | usr/src/uts/common/dtrace/dtrace.c | 8 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/ml/genassym.c | 1 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/ml/locore.s | 33 |
5 files changed, 71 insertions, 10 deletions
diff --git a/usr/src/cmd/dtrace/test/tst/i386/error/tst.DTRACEFLT_DIVZERO.d b/usr/src/cmd/dtrace/test/tst/i386/error/tst.DTRACEFLT_DIVZERO.d new file mode 100644 index 0000000000..a8fb302f3b --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/i386/error/tst.DTRACEFLT_DIVZERO.d @@ -0,0 +1,38 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2016, Joyent, Inc. All rights reserved. + */ + +BEGIN +{ + v = 0x8000000000000000LL; + print((long)v % -1); +} + +ERROR +/arg4 == DTRACEFLT_DIVZERO/ +{ + exit(0); +} + +ERROR +{ + printf("unexpected error code %d", arg4); + exit(1); +} + +BEGIN +{ + printf("did not get expected error"); + exit(1); +} diff --git a/usr/src/pkg/manifests/system-dtrace-tests.mf b/usr/src/pkg/manifests/system-dtrace-tests.mf index 3946445d99..bd2ac4f88a 100644 --- a/usr/src/pkg/manifests/system-dtrace-tests.mf +++ b/usr/src/pkg/manifests/system-dtrace-tests.mf @@ -140,6 +140,7 @@ file path=opt/SUNWdtrt/bin/exception.lst mode=0444 file path=opt/SUNWdtrt/bin/jdtrace mode=0555 file path=opt/SUNWdtrt/lib/java/jdtrace.jar file path=opt/SUNWdtrt/tst/$(ARCH)/arrays/tst.uregsarray.d mode=0444 +$(i386_ONLY)file path=opt/SUNWdtrt/tst/$(ARCH)/error/tst.DTRACEFLT_DIVZERO.d mode=0444 $(i386_ONLY)file path=opt/SUNWdtrt/tst/$(ARCH)/funcs/tst.badcopyin.d mode=0444 $(i386_ONLY)file path=opt/SUNWdtrt/tst/$(ARCH)/funcs/tst.badcopyinstr.d \ mode=0444 diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c index 9731c6f292..0d5bf02024 100644 --- a/usr/src/uts/common/dtrace/dtrace.c +++ b/usr/src/uts/common/dtrace/dtrace.c @@ -5759,8 +5759,10 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[rd] = 0; *flags |= CPU_DTRACE_DIVZERO; } else { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = (int64_t)regs[r1] / (int64_t)regs[r2]; + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); } break; @@ -5769,7 +5771,9 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[rd] = 0; *flags |= CPU_DTRACE_DIVZERO; } else { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = regs[r1] / regs[r2]; + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); } break; @@ -5778,8 +5782,10 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[rd] = 0; *flags |= CPU_DTRACE_DIVZERO; } else { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = (int64_t)regs[r1] % (int64_t)regs[r2]; + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); } break; @@ -5788,7 +5794,9 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[rd] = 0; *flags |= CPU_DTRACE_DIVZERO; } else { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = regs[r1] % regs[r2]; + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); } break; diff --git a/usr/src/uts/i86pc/ml/genassym.c b/usr/src/uts/i86pc/ml/genassym.c index 168a55cc84..088dd661a3 100644 --- a/usr/src/uts/i86pc/ml/genassym.c +++ b/usr/src/uts/i86pc/ml/genassym.c @@ -174,6 +174,7 @@ main(int argc, char *argv[]) printf("#define\tCPU_DTRACE_NOFAULT 0x%x\n", CPU_DTRACE_NOFAULT); printf("#define\tCPU_DTRACE_BADADDR 0x%x\n", CPU_DTRACE_BADADDR); + printf("#define\tCPU_DTRACE_DIVZERO 0x%x\n", CPU_DTRACE_DIVZERO); printf("#define\tCPU_DTRACE_ILLOP 0x%x\n", CPU_DTRACE_ILLOP); printf("#define\tMODS_NOUNLOAD 0x%x\n", MODS_NOUNLOAD); diff --git a/usr/src/uts/i86pc/ml/locore.s b/usr/src/uts/i86pc/ml/locore.s index 91e38307ca..042818844d 100644 --- a/usr/src/uts/i86pc/ml/locore.s +++ b/usr/src/uts/i86pc/ml/locore.s @@ -23,7 +23,7 @@ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright 2011 Joyent, Inc. All rights reserved. + * Copyright (c) 2016, Joyent, Inc. All rights reserved. */ /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ @@ -1158,7 +1158,12 @@ cmntrap() cmpl $T_ILLINST, REGOFF_TRAPNO(%rbp) je 0f - jne 4f /* if not PF, GP or UD, panic */ + cmpl $T_ZERODIV, REGOFF_TRAPNO(%rbp) + jne 4f /* if not PF/GP/UD/DE, panic */ + + orw $CPU_DTRACE_DIVZERO, %cx + movw %cx, CPUC_DTRACE_FLAGS(%rax) + jmp 2f /* * If we've taken a GPF, we don't (unfortunately) have the address that @@ -1249,14 +1254,22 @@ cmntrap() .dtrace_induced: cmpw $KCS_SEL, REGOFF_CS(%ebp) /* test CS for user-mode trap */ - jne 2f /* if from user, panic */ + jne 3f /* if from user, panic */ cmpl $T_PGFLT, REGOFF_TRAPNO(%ebp) - je 0f + je 1f cmpl $T_GPFLT, REGOFF_TRAPNO(%ebp) - jne 3f /* if not PF or GP, panic */ + je 0f + + cmpl $T_ZERODIV, REGOFF_TRAPNO(%ebp) + jne 4f /* if not PF/GP/UD/DE, panic */ + + orw $CPU_DTRACE_DIVZERO, %cx + movw %cx, CPUC_DTRACE_FLAGS(%eax) + jmp 2f +0: /* * If we've taken a GPF, we don't (unfortunately) have the address that * induced the fault. So instead of setting the fault to BADADDR, @@ -1264,13 +1277,13 @@ cmntrap() */ orw $CPU_DTRACE_ILLOP, %cx movw %cx, CPUC_DTRACE_FLAGS(%eax) - jmp 1f -0: + jmp 2f +1: orw $CPU_DTRACE_BADADDR, %cx movw %cx, CPUC_DTRACE_FLAGS(%eax) /* set fault to bad addr */ movl %esi, CPUC_DTRACE_ILLVAL(%eax) /* fault addr is illegal value */ -1: +2: pushl REGOFF_EIP(%ebp) call dtrace_instr_size addl $4, %esp @@ -1280,10 +1293,10 @@ cmntrap() INTR_POP_KERNEL IRET /*NOTREACHED*/ -2: +3: pushl $dtrace_badflags call panic -3: +4: pushl $dtrace_badtrap call panic SET_SIZE(cmntrap) |
