public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [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

* [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: [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

* 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