* [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO
@ 2005-11-08 13:02 Jan Beulich
2005-11-08 14:21 ` [PATCH] x86-64: fix bound check IDT gate Jan Beulich
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Jan Beulich @ 2005-11-08 13:02 UTC (permalink / raw)
To: Andreas Kleen; +Cc: linux-kernel, discuss
[-- Attachment #1: Type: text/plain, Size: 231 bytes --]
As a follow-up to the introduction of CONFIG_UNWIND_INFO, this
separates the generation of frame unwind information for x86-64 from
that of full debug information.
From: Jan Beulich <jbeulich@novell.com>
(actual patch attached)
[-- Attachment #2: linux-2.6.14-unwind-info-x86_64.patch --]
[-- Type: application/octet-stream, Size: 1521 bytes --]
As a follow-up to the introduction of CONFIG_UNWIND_INFO, this
separates the generation of frame unwind information for x86-64 from
that of full debug information.
From: Jan Beulich <jbeulich@novell.com>
--- 2.6.14/arch/x86_64/Makefile 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-unwind-info-x86_64/arch/x86_64/Makefile 2005-11-04 16:19:33.000000000 +0100
@@ -38,8 +38,10 @@ CFLAGS += -pipe
# actually it makes the kernel smaller too.
CFLAGS += -fno-reorder-blocks
CFLAGS += -Wno-sign-compare
-ifneq ($(CONFIG_DEBUG_INFO),y)
+ifneq ($(CONFIG_UNWIND_INFO),y)
CFLAGS += -fno-asynchronous-unwind-tables
+endif
+ifneq ($(CONFIG_DEBUG_INFO),y)
# -fweb shrinks the kernel a bit, but the difference is very small
# it also messes up debugging, so don't use it for now.
#CFLAGS += $(call cc-option,-fweb)
--- 2.6.14/arch/x86_64/kernel/vmlinux.lds.S 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-unwind-info-x86_64/arch/x86_64/kernel/vmlinux.lds.S 2005-11-04 16:19:33.000000000 +0100
@@ -189,7 +189,7 @@ SECTIONS
/* Sections to be discarded */
/DISCARD/ : {
*(.exitcall.exit)
-#ifndef CONFIG_DEBUG_INFO
+#ifndef CONFIG_UNWIND_INFO
*(.eh_frame)
#endif
}
--- 2.6.14/include/asm-x86_64/dwarf2.h 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-unwind-info-x86_64/include/asm-x86_64/dwarf2.h 2005-11-04 16:19:34.000000000 +0100
@@ -14,7 +14,7 @@
away for older version.
*/
-#ifdef CONFIG_DEBUG_INFO
+#ifdef CONFIG_UNWIND_INFO
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH] x86-64: fix bound check IDT gate 2005-11-08 13:02 [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO Jan Beulich @ 2005-11-08 14:21 ` Jan Beulich 2005-11-08 14:22 ` [PATCH] x86-64: remove dead die_if_kernel() Jan Beulich ` (4 subsequent siblings) 5 siblings, 0 replies; 12+ messages in thread From: Jan Beulich @ 2005-11-08 14:21 UTC (permalink / raw) To: Andreas Kleen; +Cc: linux-kernel, discuss [-- Attachment #1: Type: text/plain, Size: 189 bytes --] Other than apparently commonly assumed, the bound instruction does not require the corresponding IDT entry to have DPL 3. From: Jan Beulich <jbeulich@novell.com> (actual patch attached) [-- Attachment #2: linux-2.6.14-x86_64-bound.patch --] [-- Type: application/octet-stream, Size: 806 bytes --] Other than apparently commonly assumed, the bound instruction does not require the corresponding IDT entry to have DPL 3. From: Jan Beulich <jbeulich@novell.com> --- 2.6.14/arch/x86_64/kernel/traps.c 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-bound/arch/x86_64/kernel/traps.c 2005-11-07 09:33:53.000000000 +0100 @@ -917,8 +917,8 @@ void __init trap_init(void) set_intr_gate_ist(1,&debug,DEBUG_STACK); set_intr_gate_ist(2,&nmi,NMI_STACK); set_system_gate(3,&int3); - set_system_gate(4,&overflow); /* int4-5 can be called from all */ - set_system_gate(5,&bounds); + set_system_gate(4,&overflow); /* int4 can be called from all */ + set_intr_gate(5,&bounds); set_intr_gate(6,&invalid_op); set_intr_gate(7,&device_not_available); set_intr_gate_ist(8,&double_fault, DOUBLEFAULT_STACK); ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] x86-64: remove dead die_if_kernel() 2005-11-08 13:02 [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO Jan Beulich 2005-11-08 14:21 ` [PATCH] x86-64: fix bound check IDT gate Jan Beulich @ 2005-11-08 14:22 ` Jan Beulich 2005-11-08 14:23 ` [PATCH] x86-64: make trap information available to die notification handlers Jan Beulich ` (3 subsequent siblings) 5 siblings, 0 replies; 12+ messages in thread From: Jan Beulich @ 2005-11-08 14:22 UTC (permalink / raw) To: Andreas Kleen; +Cc: linux-kernel, discuss [-- Attachment #1: Type: text/plain, Size: 109 bytes --] Removing unused function die_if_kernel(). From: Jan Beulich <jbeulich@novell.com> (actual patch attached) [-- Attachment #2: linux-2.6.14-x86_64-die-if-kernel.patch --] [-- Type: application/octet-stream, Size: 587 bytes --] Removing unused function die_if_kernel(). From: Jan Beulich <jbeulich@novell.com> --- 2.6.14/arch/x86_64/kernel/traps.c 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-die-if-kernel/arch/x86_64/kernel/traps.c 2005-11-07 09:33:53.000000000 +0100 @@ -399,11 +399,6 @@ void die(const char * str, struct pt_reg oops_end(flags); do_exit(SIGSEGV); } -static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) -{ - if (!(regs->eflags & VM_MASK) && (regs->cs == __KERNEL_CS)) - die(str, regs, err); -} void die_nmi(char *str, struct pt_regs *regs) { ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] x86-64: make trap information available to die notification handlers 2005-11-08 13:02 [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO Jan Beulich 2005-11-08 14:21 ` [PATCH] x86-64: fix bound check IDT gate Jan Beulich 2005-11-08 14:22 ` [PATCH] x86-64: remove dead die_if_kernel() Jan Beulich @ 2005-11-08 14:23 ` Jan Beulich 2005-11-08 14:23 ` [PATCH] x86-64: adjust double fault handling Jan Beulich ` (2 subsequent siblings) 5 siblings, 0 replies; 12+ messages in thread From: Jan Beulich @ 2005-11-08 14:23 UTC (permalink / raw) To: Andreas Kleen; +Cc: linux-kernel, discuss [-- Attachment #1: Type: text/plain, Size: 273 bytes --] This adjusts things so that handlers of the die() notifier will have sufficient information about the trap currently being handled. It also adjusts the notify_die() prototype to (again) match that of i386. From: Jan Beulich <jbeulich@novell.com> (actual patch attached) [-- Attachment #2: linux-2.6.14-x86_64-die-trap-info.patch --] [-- Type: application/octet-stream, Size: 4393 bytes --] This adjusts things so that handlers of the die() notifier will have sufficient information about the trap currently being handled. It also adjusts the notify_die() prototype to (again) match that of i386. From: Jan Beulich <jbeulich@novell.com> --- 2.6.14/arch/x86_64/kernel/traps.c 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-die-trap-info/arch/x86_64/kernel/traps.c 2005-11-07 09:33:53.000000000 +0100 @@ -382,7 +382,7 @@ void __die(const char * str, struct pt_r printk("DEBUG_PAGEALLOC"); #endif printk("\n"); - notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); + notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); show_registers(regs); /* Executive summary in case the oops scrolled away */ printk(KERN_ALERT "RIP "); @@ -426,6 +426,8 @@ static void __kprobes do_trap(int trapnr struct pt_regs * regs, long error_code, siginfo_t *info) { + struct task_struct *tsk = current; + conditional_sti(regs); #ifdef CONFIG_CHECKING @@ -441,17 +443,16 @@ static void __kprobes do_trap(int trapnr } #endif - if (user_mode(regs)) { - struct task_struct *tsk = current; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + if (user_mode(regs)) { if (exception_trace && unhandled_signal(tsk, signr)) printk(KERN_INFO "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", tsk->comm, tsk->pid, str, regs->rip,regs->rsp,error_code); - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; if (info) force_sig_info(signr, info, tsk); else @@ -511,6 +512,8 @@ DO_ERROR( 8, SIGSEGV, "double fault", do asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, long error_code) { + struct task_struct *tsk = current; + conditional_sti(regs); #ifdef CONFIG_CHECKING @@ -527,17 +530,16 @@ asmlinkage void __kprobes do_general_pro } #endif - if (user_mode(regs)) { - struct task_struct *tsk = current; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + if (user_mode(regs)) { if (exception_trace && unhandled_signal(tsk, SIGSEGV)) printk(KERN_INFO "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", tsk->comm, tsk->pid, regs->rip,regs->rsp,error_code); - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 13; force_sig(SIGSEGV, tsk); return; } @@ -748,6 +750,7 @@ static int kernel_math_error(struct pt_r } notify_die(DIE_GPF, str, regs, 0, 16, SIGFPE); /* Illegal floating point operation in the kernel */ + current->thread.trap_no = 16; die(str, regs, 0); return 0; } --- 2.6.14/arch/x86_64/mm/fault.c 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-die-trap-info/arch/x86_64/mm/fault.c 2005-11-07 14:27:42.000000000 +0100 @@ -222,10 +222,15 @@ static noinline void pgtable_bad(unsigne unsigned long error_code) { unsigned long flags = oops_begin(); + struct task_struct *tsk; printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", current->comm, address); dump_pagetable(address); + tsk = current; + tsk->thread.cr2 = address; + tsk->thread.trap_no = 14; + tsk->thread.error_code = error_code; __die("Bad pagetable", regs, error_code); oops_end(flags); do_exit(SIGKILL); @@ -533,6 +538,9 @@ no_context: printk_address(regs->rip); printk("\n"); dump_pagetable(address); + tsk->thread.cr2 = address; + tsk->thread.trap_no = 14; + tsk->thread.error_code = error_code; __die("Oops", regs, error_code); /* Executive summary in case the body of the oops scrolled away */ printk(KERN_EMERG "CR2: %016lx\n", address); --- 2.6.14/include/asm-x86_64/kdebug.h 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-die-trap-info/include/asm-x86_64/kdebug.h 2005-11-07 10:31:52.000000000 +0100 @@ -35,9 +35,16 @@ enum die_val { DIE_PAGE_FAULT, }; -static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) -{ - struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; +static inline int notify_die(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; return notifier_call_chain(&die_chain, val, &args); } ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] x86-64: adjust double fault handling 2005-11-08 13:02 [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO Jan Beulich ` (2 preceding siblings ...) 2005-11-08 14:23 ` [PATCH] x86-64: make trap information available to die notification handlers Jan Beulich @ 2005-11-08 14:23 ` Jan Beulich 2005-11-08 14:24 ` [PATCH] x86-64: remove unprotected iret Jan Beulich 2005-11-08 14:25 ` [PATCH] x86-64: adjust page fault handling Jan Beulich 5 siblings, 0 replies; 12+ messages in thread From: Jan Beulich @ 2005-11-08 14:23 UTC (permalink / raw) To: Andreas Kleen; +Cc: linux-kernel, discuss [-- Attachment #1: Type: text/plain, Size: 490 bytes --] Since a double fault always implies that kernel data structures are corrupt, this fault should neither be handed to user mode handling, nor should the handler allow resuming the faulting code stream (since architecturally this isn't a fault, but an abort). Note that this slightly depends on the previously submitted patch adjusting the prototype of notify_die() (a compiler warning will result without that other patch). From: Jan Beulich <jbeulich@novell.com> (actual patch attached) [-- Attachment #2: linux-2.6.14-x86_64-doublefault.patch --] [-- Type: application/octet-stream, Size: 1767 bytes --] Since a double fault always implies that kernel data structures are corrupt, this fault should neither be handed to user mode handling, nor should the handler allow resuming the faulting code stream (since architecturally this isn't a fault, but an abort). Note that this slightly depends on the previously submitted patch adjusting the prototype of notify_die() (a compiler warning will result without that other patch). From: Jan Beulich <jbeulich@novell.com> --- 2.6.14/arch/x86_64/kernel/traps.c 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-doublefault/arch/x86_64/kernel/traps.c 2005-11-07 09:33:53.000000000 +0100 @@ -506,7 +506,35 @@ DO_ERROR(11, SIGBUS, "segment not prese DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) DO_ERROR(18, SIGSEGV, "reserved", reserved) DO_ERROR(12, SIGBUS, "stack segment", stack_segment) -DO_ERROR( 8, SIGSEGV, "double fault", double_fault) + +asmlinkage void do_double_fault(struct pt_regs * regs, long error_code) +{ + static const char str[] = "double fault"; + struct task_struct *tsk = current; + + notify_die(DIE_TRAP, str, regs, error_code, 8, SIGSEGV); + +#ifdef CONFIG_CHECKING + { + unsigned long gs; + struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); + rdmsrl(MSR_GS_BASE, gs); + if (gs != (unsigned long)pda) { + wrmsrl(MSR_GS_BASE, pda); + printk("%s: wrong gs %lx expected %p rip %lx\n", + str, gs, pda, regs->rip); + } + } +#endif + + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 8; + + /* This is always a kernel trap and never fixable (and thus must + never return). */ + for (;;) + die(str, regs, error_code); +} asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, long error_code) ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] x86-64: remove unprotected iret 2005-11-08 13:02 [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO Jan Beulich ` (3 preceding siblings ...) 2005-11-08 14:23 ` [PATCH] x86-64: adjust double fault handling Jan Beulich @ 2005-11-08 14:24 ` Jan Beulich 2005-11-10 3:38 ` [discuss] " Andi Kleen 2005-11-08 14:25 ` [PATCH] x86-64: adjust page fault handling Jan Beulich 5 siblings, 1 reply; 12+ messages in thread From: Jan Beulich @ 2005-11-08 14:24 UTC (permalink / raw) To: Andreas Kleen; +Cc: linux-kernel, discuss [-- Attachment #1: Type: text/plain, Size: 127 bytes --] Make sure no iret can fault without attached recovery code. From: Jan Beulich <jbeulich@novell.com> (actual patch attached) [-- Attachment #2: linux-2.6.14-x86_64-iret.patch --] [-- Type: application/octet-stream, Size: 416 bytes --] Make sure no iret can fault without attached recovery code. From: Jan Beulich <jbeulich@novell.com> --- 2.6.14/arch/x86_64/kernel/entry.S 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-iret/arch/x86_64/kernel/entry.S 2005-11-07 14:56:02.000000000 +0100 @@ -751,7 +751,7 @@ error_exit: jnz retint_careful swapgs RESTORE_ARGS 0,8,0 - iretq + jmp iret_label CFI_ENDPROC error_kernelspace: ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [discuss] [PATCH] x86-64: remove unprotected iret 2005-11-08 14:24 ` [PATCH] x86-64: remove unprotected iret Jan Beulich @ 2005-11-10 3:38 ` Andi Kleen 0 siblings, 0 replies; 12+ messages in thread From: Andi Kleen @ 2005-11-10 3:38 UTC (permalink / raw) To: discuss; +Cc: Jan Beulich, linux-kernel On Tuesday 08 November 2005 15:24, Jan Beulich wrote: > Make sure no iret can fault without attached recovery code. The reason it was done this way was that normally iret can only go bad after ptrace and ptrace is handled in the careful path. But I agree it's safer. Your patch series looks good. I will try to merge it later -Andi ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] x86-64: adjust page fault handling 2005-11-08 13:02 [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO Jan Beulich ` (4 preceding siblings ...) 2005-11-08 14:24 ` [PATCH] x86-64: remove unprotected iret Jan Beulich @ 2005-11-08 14:25 ` Jan Beulich 2005-11-09 16:10 ` [PATCH] x86-64: adjust ia32entry.S Jan Beulich 5 siblings, 1 reply; 12+ messages in thread From: Jan Beulich @ 2005-11-08 14:25 UTC (permalink / raw) To: Andreas Kleen; +Cc: linux-kernel, discuss [-- Attachment #1: Type: text/plain, Size: 173 bytes --] Adjust page fault protection error check before considering it to be a vmalloc synchronization candidate. From: Jan Beulich <jbeulich@novell.com> (actual patch attached) [-- Attachment #2: linux-2.6.14-x86_64-pagefault.patch --] [-- Type: application/octet-stream, Size: 1304 bytes --] Adjust page fault protection error check before considering it to be a vmalloc synchronization candidate. From: Jan Beulich <jbeulich@novell.com> --- 2.6.14/arch/x86_64/mm/fault.c 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-pagefault/arch/x86_64/mm/fault.c 2005-11-07 14:27:42.000000000 +0100 @@ -294,7 +294,8 @@ int exception_trace = 1; * bit 0 == 0 means no page found, 1 means protection fault * bit 1 == 0 means read, 1 means write * bit 2 == 0 means kernel, 1 means user-mode - * bit 3 == 1 means fault was an instruction fetch + * bit 3 == 1 means use of reserved bit detected + * bit 4 == 1 means fault was an instruction fetch */ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) @@ -349,10 +350,10 @@ asmlinkage void __kprobes do_page_fault( * * This verifies that the fault happens in kernel space * (error_code & 4) == 0, and that the fault was not a - * protection error (error_code & 1) == 0. + * protection error (error_code & 9) == 0. */ if (unlikely(address >= TASK_SIZE64)) { - if (!(error_code & 5) && + if (!(error_code & 0xd) && ((address >= VMALLOC_START && address < VMALLOC_END) || (address >= MODULES_VADDR && address < MODULES_END))) { if (vmalloc_fault(address) < 0) ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] x86-64: adjust ia32entry.S 2005-11-08 14:25 ` [PATCH] x86-64: adjust page fault handling Jan Beulich @ 2005-11-09 16:10 ` Jan Beulich 2005-11-11 15:34 ` Andi Kleen 0 siblings, 1 reply; 12+ messages in thread From: Jan Beulich @ 2005-11-09 16:10 UTC (permalink / raw) To: Andreas Kleen; +Cc: linux-kernel, discuss [-- Attachment #1: Type: text/plain, Size: 243 bytes --] IA32 compatibility entry points needlessly played with extended registers. Additionally, frame unwind information was still incorrect for ia32_ptregs_common (sorry, my fault). From: Jan Beulich <jbeulich@novell.com> (actual patch attached) [-- Attachment #2: linux-2.6.14-x86_64-ia32entry.patch --] [-- Type: application/octet-stream, Size: 8388 bytes --] IA32 compatibility entry points needlessly played with extended registers. Additionally, frame unwind information was still incorrect for ia32_ptregs_common (sorry, my fault). From: Jan Beulich <jbeulich@novell.com> --- 2.6.14/arch/x86_64/ia32/ia32entry.S 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-ia32entry/arch/x86_64/ia32/ia32entry.S 2005-11-09 14:02:12.000000000 +0100 @@ -26,13 +26,29 @@ movl %edx,%edx /* zero extension */ .endm - /* clobbers %eax */ - .macro CLEAR_RREGS - xorl %eax,%eax - movq %rax,R11(%rsp) - movq %rax,R10(%rsp) - movq %rax,R9(%rsp) - movq %rax,R8(%rsp) + /* clobbers specified register (or %eax) */ + .macro CLEAR_RREGS r=ax + xorl %e\r,%e\r + movq %r\r,R15(%rsp) + movq %r\r,R14(%rsp) + movq %r\r,R13(%rsp) + movq %r\r,R12(%rsp) + movq %r\r,R11(%rsp) + movq %r\r,R10(%rsp) + movq %r\r,R9(%rsp) + movq %r\r,R8(%rsp) + .endm + + .macro CFI_STARTPROC32 simple + CFI_STARTPROC \simple + CFI_UNDEFINED r8 + CFI_UNDEFINED r9 + CFI_UNDEFINED r10 + CFI_UNDEFINED r11 + CFI_UNDEFINED r12 + CFI_UNDEFINED r13 + CFI_UNDEFINED r14 + CFI_UNDEFINED r15 .endm /* @@ -55,7 +71,7 @@ * with the int 0x80 path. */ ENTRY(ia32_sysenter_target) - CFI_STARTPROC simple + CFI_STARTPROC32 simple CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp swapgs @@ -107,7 +123,7 @@ sysenter_do_call: jnz int_ret_from_sys_call /* clear IF, that popfq doesn't enable interrupts early */ andl $~0x200,EFLAGS-R11(%rsp) - RESTORE_ARGS 1,24,1,1,1,1 + RESTORE_ARGS 1,24,1,1,1 popfq CFI_ADJUST_CFA_OFFSET -8 /*CFI_RESTORE rflags*/ @@ -123,14 +139,13 @@ sysenter_do_call: sysenter_tracesys: CFI_RESTORE_STATE - SAVE_REST + SAVE_REST 1 CLEAR_RREGS movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ - RESTORE_REST - movl %ebp, %ebp + LOAD_ARGS ARGOFFSET,0,1 /* reload args from stack in case ptrace changed it */ + RESTORE_REST 1 /* no need to do an access_ok check here because rbp has been 32bit zero extended */ 1: movl (%rbp),%r9d @@ -161,7 +176,7 @@ sysenter_tracesys: * with the int 0x80 path. */ ENTRY(ia32_cstar_target) - CFI_STARTPROC simple + CFI_STARTPROC32 simple CFI_DEF_CFA rsp,0 CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ @@ -204,7 +219,7 @@ cstar_do_call: cli testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) jnz int_ret_from_sys_call - RESTORE_ARGS 1,-ARG_SKIP,1,1,1 + RESTORE_ARGS 1,-ARG_SKIP,1,1 movl RIP-ARGOFFSET(%rsp),%ecx CFI_REGISTER rip,rcx movl EFLAGS-ARGOFFSET(%rsp),%r11d @@ -216,14 +231,14 @@ cstar_do_call: cstar_tracesys: CFI_RESTORE_STATE - SAVE_REST + SAVE_REST 1 CLEAR_RREGS movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ - RESTORE_REST - movl RSP-ARGOFFSET(%rsp), %r8d + LOAD_ARGS ARGOFFSET,0,1 /* reload args from stack in case ptrace changed it */ + movl RSP(%rsp), %r8d + RESTORE_REST 1 /* no need to do an access_ok check here because r8 has been 32bit zero extended */ 1: movl (%r8),%r9d @@ -259,7 +274,7 @@ ia32_badarg: */ ENTRY(ia32_syscall) - CFI_STARTPROC simple + CFI_STARTPROC32 simple CFI_DEF_CFA rsp,SS+8-RIP /*CFI_REL_OFFSET ss,SS-RIP*/ CFI_REL_OFFSET rsp,RSP-RIP @@ -288,12 +303,13 @@ ia32_sysret: jmp int_ret_from_sys_call ia32_tracesys: - SAVE_REST + SAVE_REST 1 + CLEAR_RREGS movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace_enter - LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ - RESTORE_REST + LOAD_ARGS ARGOFFSET,0,1 /* reload args from stack in case ptrace changed it */ + RESTORE_REST 1 jmp ia32_do_syscall ia32_badsys: @@ -318,7 +334,7 @@ quiet_ni_syscall: jmp ia32_ptregs_common .endm - CFI_STARTPROC + CFI_STARTPROC32 PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi @@ -333,11 +349,23 @@ quiet_ni_syscall: ENTRY(ia32_ptregs_common) popq %r11 - CFI_ADJUST_CFA_OFFSET -8 - CFI_REGISTER rip, r11 - SAVE_REST + CFI_ENDPROC + CFI_STARTPROC32 simple + CFI_DEF_CFA rsp,SS+8-ARGOFFSET + CFI_REL_OFFSET rax,RAX-ARGOFFSET + CFI_REL_OFFSET rcx,RCX-ARGOFFSET + CFI_REL_OFFSET rdx,RDX-ARGOFFSET + CFI_REL_OFFSET rsi,RSI-ARGOFFSET + CFI_REL_OFFSET rdi,RDI-ARGOFFSET + CFI_REL_OFFSET rip,RIP-ARGOFFSET +/* CFI_REL_OFFSET cs,CS-ARGOFFSET*/ +/* CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/ + CFI_REL_OFFSET rsp,RSP-ARGOFFSET +/* CFI_REL_OFFSET ss,SS-ARGOFFSET*/ + SAVE_REST 1 + CLEAR_RREGS bx call *%rax - RESTORE_REST + RESTORE_REST 1 jmp ia32_sysret /* misbalances the return cache */ CFI_ENDPROC --- 2.6.14/include/asm-x86_64/calling.h 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-ia32entry/include/asm-x86_64/calling.h 2005-11-09 13:33:26.000000000 +0100 @@ -31,7 +31,7 @@ #define ARGOFFSET R11 #define SWFRAME ORIG_RAX - .macro SAVE_ARGS addskip=0,norcx=0,nor891011=0 + .macro SAVE_ARGS addskip=0,norcx=0,compat=0 subq $9*8+\addskip,%rsp CFI_ADJUST_CFA_OFFSET 9*8+\addskip movq %rdi,8*8(%rsp) @@ -47,7 +47,7 @@ .endif movq %rax,4*8(%rsp) CFI_REL_OFFSET rax,4*8 - .if \nor891011 + .if \compat .else movq %r8,3*8(%rsp) CFI_REL_OFFSET r8,3*8 @@ -61,14 +61,11 @@ .endm #define ARG_SKIP 9*8 - .macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0 - .if \skipr11 + .macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,compat=0,skiprdx=0 + .if \compat .else movq (%rsp),%r11 CFI_RESTORE r11 - .endif - .if \skipr8910 - .else movq 1*8(%rsp),%r10 CFI_RESTORE r10 movq 2*8(%rsp),%r9 @@ -78,22 +75,42 @@ .endif .if \skiprax .else + .if \compat + movl 4*8(%rsp),%eax + .else movq 4*8(%rsp),%rax + .endif CFI_RESTORE rax .endif .if \skiprcx .else + .if \compat + movl 5*8(%rsp),%ecx + .else movq 5*8(%rsp),%rcx + .endif CFI_RESTORE rcx .endif .if \skiprdx .else + .if \compat + movl 6*8(%rsp),%edx + .else movq 6*8(%rsp),%rdx + .endif CFI_RESTORE rdx .endif + .if \compat + movl 7*8(%rsp),%esi + .else movq 7*8(%rsp),%rsi + .endif CFI_RESTORE rsi + .if \compat + movl 8*8(%rsp),%edi + .else movq 8*8(%rsp),%rdi + .endif CFI_RESTORE rdi .if ARG_SKIP+\addskip > 0 addq $ARG_SKIP+\addskip,%rsp @@ -101,26 +118,42 @@ .endif .endm - .macro LOAD_ARGS offset + .macro LOAD_ARGS offset,skiprcx=0,compat=0 + .if \compat + .if \skiprcx + .else + movl \offset+40(%rsp),%ecx + .endif + movl \offset+48(%rsp),%edx + movl \offset+56(%rsp),%esi + movl \offset+64(%rsp),%edi + movl \offset+72(%rsp),%eax + .else movq \offset(%rsp),%r11 movq \offset+8(%rsp),%r10 movq \offset+16(%rsp),%r9 movq \offset+24(%rsp),%r8 + .if \skiprcx + .else movq \offset+40(%rsp),%rcx + .endif movq \offset+48(%rsp),%rdx movq \offset+56(%rsp),%rsi movq \offset+64(%rsp),%rdi movq \offset+72(%rsp),%rax + .endif .endm #define REST_SKIP 6*8 - .macro SAVE_REST + .macro SAVE_REST compat=0 subq $REST_SKIP,%rsp CFI_ADJUST_CFA_OFFSET REST_SKIP movq %rbx,5*8(%rsp) CFI_REL_OFFSET rbx,5*8 movq %rbp,4*8(%rsp) CFI_REL_OFFSET rbp,4*8 + .if \compat + .else movq %r12,3*8(%rsp) CFI_REL_OFFSET r12,3*8 movq %r13,2*8(%rsp) @@ -129,9 +162,16 @@ CFI_REL_OFFSET r14,1*8 movq %r15,(%rsp) CFI_REL_OFFSET r15,0*8 + .endif .endm - .macro RESTORE_REST + .macro RESTORE_REST compat=0 + .if \compat + movl 4*8(%rsp),%ebp + CFI_RESTORE rbp + movl 5*8(%rsp),%ebx + CFI_RESTORE rbx + .else movq (%rsp),%r15 CFI_RESTORE r15 movq 1*8(%rsp),%r14 @@ -144,6 +184,7 @@ CFI_RESTORE rbp movq 5*8(%rsp),%rbx CFI_RESTORE rbx + .endif addq $REST_SKIP,%rsp CFI_ADJUST_CFA_OFFSET -(REST_SKIP) .endm --- 2.6.14/include/asm-x86_64/dwarf2.h 2005-10-28 02:02:08.000000000 +0200 +++ 2.6.14-x86_64-ia32entry/include/asm-x86_64/dwarf2.h 2005-11-09 12:49:51.000000000 +0100 @@ -28,6 +28,7 @@ #define CFI_RESTORE .cfi_restore #define CFI_REMEMBER_STATE .cfi_remember_state #define CFI_RESTORE_STATE .cfi_restore_state +#define CFI_UNDEFINED .cfi_undefined #else @@ -44,6 +45,7 @@ #define CFI_RESTORE # #define CFI_REMEMBER_STATE # #define CFI_RESTORE_STATE # +#define CFI_UNDEFINED # #endif ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] x86-64: adjust ia32entry.S 2005-11-09 16:10 ` [PATCH] x86-64: adjust ia32entry.S Jan Beulich @ 2005-11-11 15:34 ` Andi Kleen 2005-11-11 15:50 ` Jan Beulich 0 siblings, 1 reply; 12+ messages in thread From: Andi Kleen @ 2005-11-11 15:34 UTC (permalink / raw) To: Jan Beulich; +Cc: linux-kernel, discuss On Wednesday 09 November 2005 17:10, Jan Beulich wrote: > IA32 compatibility entry points needlessly played with extended > registers. Additionally, frame unwind information was still incorrect > for ia32_ptregs_common (sorry, my fault). What do you mean with needlessly played? That it didn't initialize all on the stack frame? That was more a feature than a bug. Did it cause you problems? In general I'm weary of making the asm macros more complex (adding more arguments etc.) Please keep it simple. -Andi ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] x86-64: adjust ia32entry.S 2005-11-11 15:34 ` Andi Kleen @ 2005-11-11 15:50 ` Jan Beulich 2005-11-11 15:53 ` [discuss] " Andi Kleen 0 siblings, 1 reply; 12+ messages in thread From: Jan Beulich @ 2005-11-11 15:50 UTC (permalink / raw) To: Andi Kleen; +Cc: linux-kernel, discuss >>> Andi Kleen <ak@suse.de> 11.11.05 16:34:44 >>> >On Wednesday 09 November 2005 17:10, Jan Beulich wrote: >> IA32 compatibility entry points needlessly played with extended >> registers. Additionally, frame unwind information was still incorrect >> for ia32_ptregs_common (sorry, my fault). > >What do you mean with needlessly played? That it didn't initialize >all on the stack frame? That was more a feature than a bug. >Did it cause you problems? It saved and restored R12-R15, even though these registers have no meaning (and are architecturally undefined) when coming from/going to 32-bit mode. Problems? No, except that without the extra loads (stores don't matter that much I believe) performance is better... >In general I'm weary of making the asm macros more complex >(adding more arguments etc.) Please keep it simple. Then ignore this, perhaps with the exception of the unwind info adjustment. Jan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [discuss] Re: [PATCH] x86-64: adjust ia32entry.S 2005-11-11 15:50 ` Jan Beulich @ 2005-11-11 15:53 ` Andi Kleen 0 siblings, 0 replies; 12+ messages in thread From: Andi Kleen @ 2005-11-11 15:53 UTC (permalink / raw) To: discuss; +Cc: Jan Beulich, linux-kernel On Friday 11 November 2005 16:50, Jan Beulich wrote: > >>> Andi Kleen <ak@suse.de> 11.11.05 16:34:44 >>> > > > >On Wednesday 09 November 2005 17:10, Jan Beulich wrote: > >> IA32 compatibility entry points needlessly played with extended > >> registers. Additionally, frame unwind information was still > > incorrect > > >> for ia32_ptregs_common (sorry, my fault). > > > >What do you mean with needlessly played? That it didn't initialize > >all on the stack frame? That was more a feature than a bug. > >Did it cause you problems? > > It saved and restored R12-R15, even though these registers have no > meaning (and are architecturally undefined) when coming from/going to > 32-bit mode. Problems? No, except that without the extra loads (stores > don't matter that much I believe) performance is better... int 0x80 can be called from long mode too. We especially kept this option to allow JITs like valgrind to run a 32bit process in a 64bit image. In this case we shouldn't leak kernel registers. You're right they normally shouldn't be leaked anyways because the C ABI will save/restore it. I will think about it. > > >In general I'm weary of making the asm macros more complex > >(adding more arguments etc.) Please keep it simple. > > Then ignore this, perhaps with the exception of the unwind info > adjustment. Can you please resubmit that as a separate patch? -Andi ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-11-11 15:54 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-11-08 13:02 [PATCH] x86-64: separate unwind info generation from CONFIG_DEBUG_INFO Jan Beulich 2005-11-08 14:21 ` [PATCH] x86-64: fix bound check IDT gate Jan Beulich 2005-11-08 14:22 ` [PATCH] x86-64: remove dead die_if_kernel() Jan Beulich 2005-11-08 14:23 ` [PATCH] x86-64: make trap information available to die notification handlers Jan Beulich 2005-11-08 14:23 ` [PATCH] x86-64: adjust double fault handling Jan Beulich 2005-11-08 14:24 ` [PATCH] x86-64: remove unprotected iret Jan Beulich 2005-11-10 3:38 ` [discuss] " Andi Kleen 2005-11-08 14:25 ` [PATCH] x86-64: adjust page fault handling Jan Beulich 2005-11-09 16:10 ` [PATCH] x86-64: adjust ia32entry.S Jan Beulich 2005-11-11 15:34 ` Andi Kleen 2005-11-11 15:50 ` Jan Beulich 2005-11-11 15:53 ` [discuss] " Andi Kleen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox