mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-17 13:53:39 +00:00
Some clarifications and updates for the comments, mostly retrieved
from Bruce Evans. Trim the trailing spaces. MFC after: 1 week
This commit is contained in:
parent
a0b9cbc8a2
commit
c788f92509
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=251988
|
@ -80,18 +80,22 @@ dtrace_invop_calltrap_addr:
|
||||||
* This is equivalent to the i386 port's use of SDT_SYS386TGT.
|
* This is equivalent to the i386 port's use of SDT_SYS386TGT.
|
||||||
*
|
*
|
||||||
* The cpu will push a certain amount of state onto the kernel stack for
|
* The cpu will push a certain amount of state onto the kernel stack for
|
||||||
* the current process. See amd64/include/frame.h.
|
* the current process. See amd64/include/frame.h.
|
||||||
* This includes the current RFLAGS (status register, which includes
|
* This includes the current RFLAGS (status register, which includes
|
||||||
* the interrupt disable state prior to the trap), the code segment register,
|
* the interrupt disable state prior to the trap), the code segment register,
|
||||||
* and the return instruction pointer are pushed by the cpu. The cpu
|
* and the return instruction pointer are pushed by the cpu. The cpu
|
||||||
* will also push an 'error' code for certain traps. We push a dummy
|
* will also push an 'error' code for certain traps. We push a dummy
|
||||||
* error code for those traps where the cpu doesn't in order to maintain
|
* error code for those traps where the cpu doesn't in order to maintain
|
||||||
* a consistent frame. We also push a contrived 'trap number'.
|
* a consistent frame. We also push a contrived 'trap number'.
|
||||||
*
|
*
|
||||||
* The cpu does not push the general registers, we must do that, and we
|
* The CPU does not push the general registers, so we must do that, and we
|
||||||
* must restore them prior to calling 'iret'. The cpu adjusts the %cs and
|
* must restore them prior to calling 'iret'. The CPU adjusts %cs and %ss
|
||||||
* %ss segment registers, but does not mess with %ds, %es, or %fs. Thus we
|
* but does not mess with %ds, %es, %gs or %fs. We swap the %gs base for
|
||||||
* must load them with appropriate values for supervisor mode operation.
|
* for the kernel mode operation shortly, without changes to the selector
|
||||||
|
* loaded. Since superuser long mode works with any selectors loaded into
|
||||||
|
* segment registers other then %cs, which makes them mostly unused in long
|
||||||
|
* mode, and kernel does not reference %fs, leave them alone. The segment
|
||||||
|
* registers are reloaded on return to the usermode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MCOUNT_LABEL(user)
|
MCOUNT_LABEL(user)
|
||||||
|
@ -503,7 +507,7 @@ nmi_calltrap:
|
||||||
#ifdef HWPMC_HOOKS
|
#ifdef HWPMC_HOOKS
|
||||||
/*
|
/*
|
||||||
* Capture a userspace callchain if needed.
|
* Capture a userspace callchain if needed.
|
||||||
*
|
*
|
||||||
* - Check if the current trap was from user mode.
|
* - Check if the current trap was from user mode.
|
||||||
* - Check if the current thread is valid.
|
* - Check if the current thread is valid.
|
||||||
* - Check if the thread requires a user call chain to be
|
* - Check if the thread requires a user call chain to be
|
||||||
|
@ -549,7 +553,7 @@ outofnmi:
|
||||||
* At this point the processor has exited NMI mode and is running
|
* At this point the processor has exited NMI mode and is running
|
||||||
* with interrupts turned off on the normal kernel stack.
|
* with interrupts turned off on the normal kernel stack.
|
||||||
*
|
*
|
||||||
* If a pending NMI gets recognized at or after this point, it
|
* If a pending NMI gets recognized at or after this point, it
|
||||||
* will cause a kernel callchain to be traced.
|
* will cause a kernel callchain to be traced.
|
||||||
*
|
*
|
||||||
* We turn interrupts back on, and call the user callchain capture hook.
|
* We turn interrupts back on, and call the user callchain capture hook.
|
||||||
|
@ -567,7 +571,7 @@ nocallchain:
|
||||||
#endif
|
#endif
|
||||||
testl %ebx,%ebx
|
testl %ebx,%ebx
|
||||||
jnz doreti_exit
|
jnz doreti_exit
|
||||||
nmi_kernelexit:
|
nmi_kernelexit:
|
||||||
/*
|
/*
|
||||||
* Put back the preserved MSR_GSBASE value.
|
* Put back the preserved MSR_GSBASE value.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -54,13 +54,13 @@
|
||||||
.globl dtrace_invop_jump_addr
|
.globl dtrace_invop_jump_addr
|
||||||
.align 4
|
.align 4
|
||||||
.type dtrace_invop_jump_addr, @object
|
.type dtrace_invop_jump_addr, @object
|
||||||
.size dtrace_invop_jump_addr, 4
|
.size dtrace_invop_jump_addr, 4
|
||||||
dtrace_invop_jump_addr:
|
dtrace_invop_jump_addr:
|
||||||
.zero 4
|
.zero 4
|
||||||
.globl dtrace_invop_calltrap_addr
|
.globl dtrace_invop_calltrap_addr
|
||||||
.align 4
|
.align 4
|
||||||
.type dtrace_invop_calltrap_addr, @object
|
.type dtrace_invop_calltrap_addr, @object
|
||||||
.size dtrace_invop_calltrap_addr, 4
|
.size dtrace_invop_calltrap_addr, 4
|
||||||
dtrace_invop_calltrap_addr:
|
dtrace_invop_calltrap_addr:
|
||||||
.zero 8
|
.zero 8
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,22 +75,22 @@ dtrace_invop_calltrap_addr:
|
||||||
* Trap and fault vector routines.
|
* Trap and fault vector routines.
|
||||||
*
|
*
|
||||||
* Most traps are 'trap gates', SDT_SYS386TGT. A trap gate pushes state on
|
* Most traps are 'trap gates', SDT_SYS386TGT. A trap gate pushes state on
|
||||||
* the stack that mostly looks like an interrupt, but does not disable
|
* the stack that mostly looks like an interrupt, but does not disable
|
||||||
* interrupts. A few of the traps we are use are interrupt gates,
|
* interrupts. A few of the traps we are use are interrupt gates,
|
||||||
* SDT_SYS386IGT, which are nearly the same thing except interrupts are
|
* SDT_SYS386IGT, which are nearly the same thing except interrupts are
|
||||||
* disabled on entry.
|
* disabled on entry.
|
||||||
*
|
*
|
||||||
* The cpu will push a certain amount of state onto the kernel stack for
|
* The cpu will push a certain amount of state onto the kernel stack for
|
||||||
* the current process. The amount of state depends on the type of trap
|
* the current process. The amount of state depends on the type of trap
|
||||||
* and whether the trap crossed rings or not. See i386/include/frame.h.
|
* and whether the trap crossed rings or not. See i386/include/frame.h.
|
||||||
* At the very least the current EFLAGS (status register, which includes
|
* At the very least the current EFLAGS (status register, which includes
|
||||||
* the interrupt disable state prior to the trap), the code segment register,
|
* the interrupt disable state prior to the trap), the code segment register,
|
||||||
* and the return instruction pointer are pushed by the cpu. The cpu
|
* and the return instruction pointer are pushed by the cpu. The cpu
|
||||||
* will also push an 'error' code for certain traps. We push a dummy
|
* will also push an 'error' code for certain traps. We push a dummy
|
||||||
* error code for those traps where the cpu doesn't in order to maintain
|
* error code for those traps where the cpu doesn't in order to maintain
|
||||||
* a consistent frame. We also push a contrived 'trap number'.
|
* a consistent frame. We also push a contrived 'trap number'.
|
||||||
*
|
*
|
||||||
* The cpu does not push the general registers, we must do that, and we
|
* The cpu does not push the general registers, we must do that, and we
|
||||||
* must restore them prior to calling 'iret'. The cpu adjusts the %cs and
|
* must restore them prior to calling 'iret'. The cpu adjusts the %cs and
|
||||||
* %ss segment registers, but does not mess with %ds, %es, or %fs. Thus we
|
* %ss segment registers, but does not mess with %ds, %es, or %fs. Thus we
|
||||||
* must load them with appropriate values for supervisor mode operation.
|
* must load them with appropriate values for supervisor mode operation.
|
||||||
|
@ -145,13 +145,14 @@ IDTVEC(xmm)
|
||||||
pushl $0; TRAP(T_XMMFLT)
|
pushl $0; TRAP(T_XMMFLT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* alltraps entry point. Interrupts are enabled if this was a trap
|
* All traps except ones for syscalls jump to alltraps. If
|
||||||
* gate (TGT), else disabled if this was an interrupt gate (IGT).
|
* interrupts were enabled when the trap occurred, then interrupts
|
||||||
* Note that int0x80_syscall is a trap gate. Interrupt gates are
|
* are enabled now if the trap was through a trap gate, else
|
||||||
* used by page faults, non-maskable interrupts, debug and breakpoint
|
* disabled if the trap was through an interrupt gate. Note that
|
||||||
|
* int0x80_syscall is a trap gate. Interrupt gates are used by
|
||||||
|
* page faults, non-maskable interrupts, debug and breakpoint
|
||||||
* exceptions.
|
* exceptions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SUPERALIGN_TEXT
|
SUPERALIGN_TEXT
|
||||||
.globl alltraps
|
.globl alltraps
|
||||||
.type alltraps,@function
|
.type alltraps,@function
|
||||||
|
@ -168,7 +169,7 @@ calltrap:
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call trap
|
call trap
|
||||||
add $4, %esp
|
add $4, %esp
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return via doreti to handle ASTs.
|
* Return via doreti to handle ASTs.
|
||||||
*/
|
*/
|
||||||
|
@ -187,10 +188,10 @@ IDTVEC(ill)
|
||||||
|
|
||||||
/* Check if this is a user fault. */
|
/* Check if this is a user fault. */
|
||||||
cmpl $GSEL_KPL, 4(%esp) /* Check the code segment. */
|
cmpl $GSEL_KPL, 4(%esp) /* Check the code segment. */
|
||||||
|
|
||||||
/* If so, just handle it as a normal trap. */
|
/* If so, just handle it as a normal trap. */
|
||||||
jne norm_ill
|
jne norm_ill
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a kernel instruction fault that might have been caused
|
* This is a kernel instruction fault that might have been caused
|
||||||
* by a DTrace provider.
|
* by a DTrace provider.
|
||||||
|
@ -215,10 +216,10 @@ norm_ill:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SYSCALL CALL GATE (old entry point for a.out binaries)
|
* Call gate entry for syscalls (lcall 7,0).
|
||||||
|
* This is used by FreeBSD 1.x a.out executables and "old" NetBSD executables.
|
||||||
*
|
*
|
||||||
* The intersegment call has been set up to specify one dummy parameter.
|
* The intersegment call has been set up to specify one dummy parameter.
|
||||||
*
|
|
||||||
* This leaves a place to put eflags so that the call frame can be
|
* This leaves a place to put eflags so that the call frame can be
|
||||||
* converted to a trap frame. Note that the eflags is (semi-)bogusly
|
* converted to a trap frame. Note that the eflags is (semi-)bogusly
|
||||||
* pushed into (what will be) tf_err and then copied later into the
|
* pushed into (what will be) tf_err and then copied later into the
|
||||||
|
@ -246,11 +247,13 @@ IDTVEC(lcall_syscall)
|
||||||
jmp doreti
|
jmp doreti
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80)
|
* Trap gate entry for syscalls (int 0x80).
|
||||||
|
* This is used by FreeBSD ELF executables, "new" NetBSD executables, and all
|
||||||
|
* Linux executables.
|
||||||
*
|
*
|
||||||
* Even though the name says 'int0x80', this is actually a TGT (trap gate)
|
* Even though the name says 'int0x80', this is actually a trap gate, not an
|
||||||
* rather then an IGT (interrupt gate). Thus interrupts are enabled on
|
* interrupt gate. Thus interrupts are enabled on entry just as they are for
|
||||||
* entry just as they are for a normal syscall.
|
* a normal syscall.
|
||||||
*/
|
*/
|
||||||
SUPERALIGN_TEXT
|
SUPERALIGN_TEXT
|
||||||
IDTVEC(int0x80_syscall)
|
IDTVEC(int0x80_syscall)
|
||||||
|
@ -348,13 +351,14 @@ doreti_next:
|
||||||
/*
|
/*
|
||||||
* PSL_VM must be checked first since segment registers only
|
* PSL_VM must be checked first since segment registers only
|
||||||
* have an RPL in non-VM86 mode.
|
* have an RPL in non-VM86 mode.
|
||||||
|
* ASTs can not be handled now if we are in a vm86 call.
|
||||||
*/
|
*/
|
||||||
testl $PSL_VM,TF_EFLAGS(%esp) /* are we in vm86 mode? */
|
testl $PSL_VM,TF_EFLAGS(%esp)
|
||||||
jz doreti_notvm86
|
jz doreti_notvm86
|
||||||
movl PCPU(CURPCB),%ecx
|
movl PCPU(CURPCB),%ecx
|
||||||
testl $PCB_VM86CALL,PCB_FLAGS(%ecx) /* are we in a vm86 call? */
|
testl $PCB_VM86CALL,PCB_FLAGS(%ecx)
|
||||||
jz doreti_ast /* can handle ASTS now if not */
|
jz doreti_ast
|
||||||
jmp doreti_exit
|
jmp doreti_exit
|
||||||
|
|
||||||
doreti_notvm86:
|
doreti_notvm86:
|
||||||
testb $SEL_RPL_MASK,TF_CS(%esp) /* are we returning to user mode? */
|
testb $SEL_RPL_MASK,TF_CS(%esp) /* are we returning to user mode? */
|
||||||
|
@ -401,7 +405,7 @@ doreti_popl_ds:
|
||||||
doreti_iret:
|
doreti_iret:
|
||||||
iret
|
iret
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* doreti_iret_fault and friends. Alternative return code for
|
* doreti_iret_fault and friends. Alternative return code for
|
||||||
* the case where we get a fault in the doreti_exit code
|
* the case where we get a fault in the doreti_exit code
|
||||||
* above. trap() (i386/i386/trap.c) catches this specific
|
* above. trap() (i386/i386/trap.c) catches this specific
|
||||||
|
|
Loading…
Reference in a new issue