x86/asm/entry/64: Fix comments
- Misleading and slightly incorrect comments in "struct pt_regs" are fixed (four instances). - Fix incorrect comment atop EMPTY_FRAME macro. - Explain in more detail what we do with stack layout during hw interrupt. - Correct comments about "partial stack frame" which are no longer true. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Andy Lutomirski <luto@amacapital.net> Cc: Alexei Starovoitov <ast@plumgrid.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Kees Cook <keescook@chromium.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Will Drewry <wad@chromium.org> Link: http://lkml.kernel.org/r/1423778052-21038-3-git-send-email-dvlasenk@redhat.com Link: http://lkml.kernel.org/r/e1f4429c491fe6ceeddb879dea2786e0f8920f9c.1424989793.git.luto@amacapital.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Родитель
76f5df43ca
Коммит
e90e147cbc
|
@ -31,13 +31,17 @@ struct pt_regs {
|
|||
#else /* __i386__ */
|
||||
|
||||
struct pt_regs {
|
||||
/*
|
||||
* C ABI says these regs are callee-preserved. They aren't saved on kernel entry
|
||||
* unless syscall needs a complete, fully filled "struct pt_regs".
|
||||
*/
|
||||
unsigned long r15;
|
||||
unsigned long r14;
|
||||
unsigned long r13;
|
||||
unsigned long r12;
|
||||
unsigned long bp;
|
||||
unsigned long bx;
|
||||
/* arguments: non interrupts/non tracing syscalls only save up to here*/
|
||||
/* These regs are callee-clobbered. Always saved on kernel entry. */
|
||||
unsigned long r11;
|
||||
unsigned long r10;
|
||||
unsigned long r9;
|
||||
|
@ -47,9 +51,12 @@ struct pt_regs {
|
|||
unsigned long dx;
|
||||
unsigned long si;
|
||||
unsigned long di;
|
||||
/*
|
||||
* On syscall entry, this is syscall#. On CPU exception, this is error code.
|
||||
* On hw interrupt, it's IRQ number:
|
||||
*/
|
||||
unsigned long orig_ax;
|
||||
/* end of arguments */
|
||||
/* cpu exception frame or undefined */
|
||||
/* Return frame for iretq */
|
||||
unsigned long ip;
|
||||
unsigned long cs;
|
||||
unsigned long flags;
|
||||
|
|
|
@ -25,13 +25,17 @@
|
|||
#else /* __i386__ */
|
||||
|
||||
#if defined(__ASSEMBLY__) || defined(__FRAME_OFFSETS)
|
||||
/*
|
||||
* C ABI says these regs are callee-preserved. They aren't saved on kernel entry
|
||||
* unless syscall needs a complete, fully filled "struct pt_regs".
|
||||
*/
|
||||
#define R15 0
|
||||
#define R14 8
|
||||
#define R13 16
|
||||
#define R12 24
|
||||
#define RBP 32
|
||||
#define RBX 40
|
||||
/* arguments: interrupts/non tracing syscalls only save up to here*/
|
||||
/* These regs are callee-clobbered. Always saved on kernel entry. */
|
||||
#define R11 48
|
||||
#define R10 56
|
||||
#define R9 64
|
||||
|
@ -41,9 +45,12 @@
|
|||
#define RDX 96
|
||||
#define RSI 104
|
||||
#define RDI 112
|
||||
#define ORIG_RAX 120 /* = ERROR */
|
||||
/* end of arguments */
|
||||
/* cpu exception frame or undefined in case of fast syscall. */
|
||||
/*
|
||||
* On syscall entry, this is syscall#. On CPU exception, this is error code.
|
||||
* On hw interrupt, it's IRQ number:
|
||||
*/
|
||||
#define ORIG_RAX 120
|
||||
/* Return frame for iretq */
|
||||
#define RIP 128
|
||||
#define CS 136
|
||||
#define EFLAGS 144
|
||||
|
|
|
@ -41,13 +41,17 @@ struct pt_regs {
|
|||
#ifndef __KERNEL__
|
||||
|
||||
struct pt_regs {
|
||||
/*
|
||||
* C ABI says these regs are callee-preserved. They aren't saved on kernel entry
|
||||
* unless syscall needs a complete, fully filled "struct pt_regs".
|
||||
*/
|
||||
unsigned long r15;
|
||||
unsigned long r14;
|
||||
unsigned long r13;
|
||||
unsigned long r12;
|
||||
unsigned long rbp;
|
||||
unsigned long rbx;
|
||||
/* arguments: non interrupts/non tracing syscalls only save up to here*/
|
||||
/* These regs are callee-clobbered. Always saved on kernel entry. */
|
||||
unsigned long r11;
|
||||
unsigned long r10;
|
||||
unsigned long r9;
|
||||
|
@ -57,9 +61,12 @@ struct pt_regs {
|
|||
unsigned long rdx;
|
||||
unsigned long rsi;
|
||||
unsigned long rdi;
|
||||
/*
|
||||
* On syscall entry, this is syscall#. On CPU exception, this is error code.
|
||||
* On hw interrupt, it's IRQ number:
|
||||
*/
|
||||
unsigned long orig_rax;
|
||||
/* end of arguments */
|
||||
/* cpu exception frame or undefined */
|
||||
/* Return frame for iretq */
|
||||
unsigned long rip;
|
||||
unsigned long cs;
|
||||
unsigned long eflags;
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
* NOTE: This code handles signal-recognition, which happens every time
|
||||
* after an interrupt and after each system call.
|
||||
*
|
||||
* Normal syscalls and interrupts don't save a full stack frame, this is
|
||||
* only done for syscall tracing, signals or fork/exec et.al.
|
||||
*
|
||||
* A note on terminology:
|
||||
* - top of stack: Architecture defined interrupt frame from SS to RIP
|
||||
* at the top of the kernel process stack.
|
||||
|
@ -151,7 +148,7 @@ ENDPROC(native_usergs_sysret64)
|
|||
.endm
|
||||
|
||||
/*
|
||||
* initial frame state for interrupts (and exceptions without error code)
|
||||
* empty frame
|
||||
*/
|
||||
.macro EMPTY_FRAME start=1 offset=0
|
||||
.if \start
|
||||
|
@ -379,7 +376,7 @@ tracesys_phase2:
|
|||
call syscall_trace_enter_phase2
|
||||
|
||||
/*
|
||||
* Reload arg registers from stack in case ptrace changed them.
|
||||
* Reload registers from stack in case ptrace changed them.
|
||||
* We don't reload %rax because syscall_trace_entry_phase2() returned
|
||||
* the value it wants us to use in the table lookup.
|
||||
*/
|
||||
|
@ -629,6 +626,13 @@ END(interrupt)
|
|||
/* 0(%rsp): ~(interrupt number) */
|
||||
.macro interrupt func
|
||||
cld
|
||||
/*
|
||||
* Since nothing in interrupt handling code touches r12...r15 members
|
||||
* of "struct pt_regs", and since interrupts can nest, we can save
|
||||
* four stack slots and simultaneously provide
|
||||
* an unwind-friendly stack layout by saving "truncated" pt_regs
|
||||
* exactly up to rbp slot, without these members.
|
||||
*/
|
||||
ALLOC_PT_GPREGS_ON_STACK -RBP
|
||||
SAVE_C_REGS -RBP
|
||||
/* this goes to 0(%rsp) for unwinder, not for saving the value: */
|
||||
|
@ -641,6 +645,7 @@ END(interrupt)
|
|||
SWAPGS
|
||||
1:
|
||||
/*
|
||||
* Save previous stack pointer, optionally switch to interrupt stack.
|
||||
* irq_count is used to check if a CPU is already on an interrupt stack
|
||||
* or not. While this is essentially redundant with preempt_count it is
|
||||
* a little cheaper to use a separate counter in the PDA (short of
|
||||
|
@ -681,6 +686,7 @@ ret_from_intr:
|
|||
/* Restore saved previous stack */
|
||||
popq %rsi
|
||||
CFI_DEF_CFA rsi,SS+8-RBP /* reg/off reset after def_cfa_expr */
|
||||
/* return code expects complete pt_regs - adjust rsp accordingly: */
|
||||
leaq ARGOFFSET-RBP(%rsi), %rsp
|
||||
CFI_DEF_CFA_REGISTER rsp
|
||||
CFI_ADJUST_CFA_OFFSET RBP-ARGOFFSET
|
||||
|
@ -692,7 +698,7 @@ exit_intr:
|
|||
|
||||
/* Interrupt came from user space */
|
||||
/*
|
||||
* Has a correct top of stack, but a partial stack frame
|
||||
* Has a correct top of stack.
|
||||
* %rcx: thread info. Interrupts off.
|
||||
*/
|
||||
retint_with_reschedule:
|
||||
|
|
Загрузка…
Ссылка в новой задаче