mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	[PATCH] i386: Redo semaphore and rwlock assembly helpers
- Move them to a pure assembly file. Previously they were in a C file that only consisted of inline assembly. Doing it in pure assembler is much nicer. - Add a frame.i include with FRAME/ENDFRAME macros to easily add frame pointers to assembly functions - Add dwarf2 annotation to them so that the new dwarf2 unwinder doesn't get stuck on them - Random cleanups Includes feedback from Jan Beulich and a UML build fix from Andrew Morton. Cc: jbeulich@novell.com Cc: jdike@addtoit.com Signed-off-by: Andi Kleen <ak@suse.de>
This commit is contained in:
		
							parent
							
								
									07c9819b31
								
							
						
					
					
						commit
						ecaf45ee5c
					
				
					 8 changed files with 193 additions and 137 deletions
				
			
		|  | @ -4,7 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| extra-y := head.o init_task.o vmlinux.lds | extra-y := head.o init_task.o vmlinux.lds | ||||||
| 
 | 
 | ||||||
| obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
 | obj-y	:= process.o signal.o entry.o traps.o irq.o \
 | ||||||
| 		ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
 | 		ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
 | ||||||
| 		pci-dma.o i386_ksyms.o i387.o bootflag.o \
 | 		pci-dma.o i386_ksyms.o i387.o bootflag.o \
 | ||||||
| 		quirks.o i8237.o topology.o alternative.o i8253.o tsc.o | 		quirks.o i8237.o topology.o alternative.o i8253.o tsc.o | ||||||
|  |  | ||||||
|  | @ -1,134 +0,0 @@ | ||||||
| /*
 |  | ||||||
|  * i386 semaphore implementation. |  | ||||||
|  * |  | ||||||
|  * (C) Copyright 1999 Linus Torvalds |  | ||||||
|  * |  | ||||||
|  * Portions Copyright 1999 Red Hat, Inc. |  | ||||||
|  * |  | ||||||
|  *	This program is free software; you can redistribute it and/or |  | ||||||
|  *	modify it under the terms of the GNU General Public License |  | ||||||
|  *	as published by the Free Software Foundation; either version |  | ||||||
|  *	2 of the License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> |  | ||||||
|  */ |  | ||||||
| #include <asm/semaphore.h> |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * The semaphore operations have a special calling sequence that |  | ||||||
|  * allow us to do a simpler in-line version of them. These routines |  | ||||||
|  * need to convert that sequence back into the C sequence when |  | ||||||
|  * there is contention on the semaphore. |  | ||||||
|  * |  | ||||||
|  * %eax contains the semaphore pointer on entry. Save the C-clobbered |  | ||||||
|  * registers (%eax, %edx and %ecx) except %eax whish is either a return |  | ||||||
|  * value or just clobbered.. |  | ||||||
|  */ |  | ||||||
| asm( |  | ||||||
| ".section .sched.text\n" |  | ||||||
| ".align 4\n" |  | ||||||
| ".globl __down_failed\n" |  | ||||||
| "__down_failed:\n\t" |  | ||||||
| #if defined(CONFIG_FRAME_POINTER) |  | ||||||
| 	"pushl %ebp\n\t" |  | ||||||
| 	"movl  %esp,%ebp\n\t" |  | ||||||
| #endif |  | ||||||
| 	"pushl %edx\n\t" |  | ||||||
| 	"pushl %ecx\n\t" |  | ||||||
| 	"call __down\n\t" |  | ||||||
| 	"popl %ecx\n\t" |  | ||||||
| 	"popl %edx\n\t" |  | ||||||
| #if defined(CONFIG_FRAME_POINTER) |  | ||||||
| 	"movl %ebp,%esp\n\t" |  | ||||||
| 	"popl %ebp\n\t" |  | ||||||
| #endif |  | ||||||
| 	"ret" |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| asm( |  | ||||||
| ".section .sched.text\n" |  | ||||||
| ".align 4\n" |  | ||||||
| ".globl __down_failed_interruptible\n" |  | ||||||
| "__down_failed_interruptible:\n\t" |  | ||||||
| #if defined(CONFIG_FRAME_POINTER) |  | ||||||
| 	"pushl %ebp\n\t" |  | ||||||
| 	"movl  %esp,%ebp\n\t" |  | ||||||
| #endif |  | ||||||
| 	"pushl %edx\n\t" |  | ||||||
| 	"pushl %ecx\n\t" |  | ||||||
| 	"call __down_interruptible\n\t" |  | ||||||
| 	"popl %ecx\n\t" |  | ||||||
| 	"popl %edx\n\t" |  | ||||||
| #if defined(CONFIG_FRAME_POINTER) |  | ||||||
| 	"movl %ebp,%esp\n\t" |  | ||||||
| 	"popl %ebp\n\t" |  | ||||||
| #endif |  | ||||||
| 	"ret" |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| asm( |  | ||||||
| ".section .sched.text\n" |  | ||||||
| ".align 4\n" |  | ||||||
| ".globl __down_failed_trylock\n" |  | ||||||
| "__down_failed_trylock:\n\t" |  | ||||||
| #if defined(CONFIG_FRAME_POINTER) |  | ||||||
| 	"pushl %ebp\n\t" |  | ||||||
| 	"movl  %esp,%ebp\n\t" |  | ||||||
| #endif |  | ||||||
| 	"pushl %edx\n\t" |  | ||||||
| 	"pushl %ecx\n\t" |  | ||||||
| 	"call __down_trylock\n\t" |  | ||||||
| 	"popl %ecx\n\t" |  | ||||||
| 	"popl %edx\n\t" |  | ||||||
| #if defined(CONFIG_FRAME_POINTER) |  | ||||||
| 	"movl %ebp,%esp\n\t" |  | ||||||
| 	"popl %ebp\n\t" |  | ||||||
| #endif |  | ||||||
| 	"ret" |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| asm( |  | ||||||
| ".section .sched.text\n" |  | ||||||
| ".align 4\n" |  | ||||||
| ".globl __up_wakeup\n" |  | ||||||
| "__up_wakeup:\n\t" |  | ||||||
| 	"pushl %edx\n\t" |  | ||||||
| 	"pushl %ecx\n\t" |  | ||||||
| 	"call __up\n\t" |  | ||||||
| 	"popl %ecx\n\t" |  | ||||||
| 	"popl %edx\n\t" |  | ||||||
| 	"ret" |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * rw spinlock fallbacks |  | ||||||
|  */ |  | ||||||
| #if defined(CONFIG_SMP) |  | ||||||
| asm( |  | ||||||
| ".section .sched.text\n" |  | ||||||
| ".align	4\n" |  | ||||||
| ".globl	__write_lock_failed\n" |  | ||||||
| "__write_lock_failed:\n\t" |  | ||||||
| 	LOCK_PREFIX "addl	$" RW_LOCK_BIAS_STR ",(%eax)\n" |  | ||||||
| "1:	rep; nop\n\t" |  | ||||||
| 	"cmpl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t" |  | ||||||
| 	"jne	1b\n\t" |  | ||||||
| 	LOCK_PREFIX "subl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t" |  | ||||||
| 	"jnz	__write_lock_failed\n\t" |  | ||||||
| 	"ret" |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| asm( |  | ||||||
| ".section .sched.text\n" |  | ||||||
| ".align	4\n" |  | ||||||
| ".globl	__read_lock_failed\n" |  | ||||||
| "__read_lock_failed:\n\t" |  | ||||||
| 	LOCK_PREFIX "incl	(%eax)\n" |  | ||||||
| "1:	rep; nop\n\t" |  | ||||||
| 	"cmpl	$1,(%eax)\n\t" |  | ||||||
| 	"js	1b\n\t" |  | ||||||
| 	LOCK_PREFIX "decl	(%eax)\n\t" |  | ||||||
| 	"js	__read_lock_failed\n\t" |  | ||||||
| 	"ret" |  | ||||||
| ); |  | ||||||
| #endif |  | ||||||
|  | @ -4,6 +4,6 @@ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
 | lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
 | ||||||
| 	bitops.o | 	bitops.o semaphore.o | ||||||
| 
 | 
 | ||||||
| lib-$(CONFIG_X86_USE_3DNOW) += mmx.o | lib-$(CONFIG_X86_USE_3DNOW) += mmx.o | ||||||
|  |  | ||||||
							
								
								
									
										154
									
								
								arch/i386/lib/semaphore.S
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								arch/i386/lib/semaphore.S
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,154 @@ | ||||||
|  | /* | ||||||
|  |  * i386 semaphore implementation. | ||||||
|  |  * | ||||||
|  |  * (C) Copyright 1999 Linus Torvalds | ||||||
|  |  * | ||||||
|  |  * Portions Copyright 1999 Red Hat, Inc. | ||||||
|  |  * | ||||||
|  |  *	This program is free software; you can redistribute it and/or
 | ||||||
|  |  *	modify it under the terms of the GNU General Public License | ||||||
|  |  *	as published by the Free Software Foundation; either version
 | ||||||
|  |  *	2 of the License, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org>
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <linux/config.h> | ||||||
|  | #include <linux/linkage.h> | ||||||
|  | #include <asm/rwlock.h> | ||||||
|  | #include <asm/alternative-asm.i> | ||||||
|  | #include <asm/frame.i> | ||||||
|  | #include <asm/dwarf2.h> | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * The semaphore operations have a special calling sequence that | ||||||
|  |  * allow us to do a simpler in-line version of them. These routines | ||||||
|  |  * need to convert that sequence back into the C sequence when | ||||||
|  |  * there is contention on the semaphore. | ||||||
|  |  * | ||||||
|  |  * %eax contains the semaphore pointer on entry. Save the C-clobbered | ||||||
|  |  * registers (%eax, %edx and %ecx) except %eax whish is either a return | ||||||
|  |  * value or just clobbered.. | ||||||
|  |  */ | ||||||
|  | 	.section .sched.text | ||||||
|  | ENTRY(__down_failed) | ||||||
|  | 	CFI_STARTPROC | ||||||
|  | 	FRAME | ||||||
|  | 	pushl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET edx,0 | ||||||
|  | 	pushl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET ecx,0 | ||||||
|  | 	call __down | ||||||
|  | 	popl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE ecx | ||||||
|  | 	popl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE edx | ||||||
|  | 	ENDFRAME | ||||||
|  | 	ret | ||||||
|  | 	CFI_ENDPROC | ||||||
|  | 	END(__down_failed) | ||||||
|  | 
 | ||||||
|  | ENTRY(__down_failed_interruptible) | ||||||
|  | 	CFI_STARTPROC | ||||||
|  | 	FRAME | ||||||
|  | 	pushl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET edx,0 | ||||||
|  | 	pushl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET ecx,0 | ||||||
|  | 	call __down_interruptible | ||||||
|  | 	popl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE ecx | ||||||
|  | 	popl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE edx | ||||||
|  | 	ENDFRAME | ||||||
|  | 	ret | ||||||
|  | 	CFI_ENDPROC | ||||||
|  | 	END(__down_failed_interruptible) | ||||||
|  | 
 | ||||||
|  | ENTRY(__down_failed_trylock) | ||||||
|  | 	CFI_STARTPROC | ||||||
|  | 	FRAME | ||||||
|  | 	pushl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET edx,0 | ||||||
|  | 	pushl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET ecx,0 | ||||||
|  | 	call __down_trylock | ||||||
|  | 	popl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE ecx | ||||||
|  | 	popl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE edx | ||||||
|  | 	ENDFRAME | ||||||
|  | 	ret | ||||||
|  | 	CFI_ENDPROC | ||||||
|  | 	END(__down_failed_trylock) | ||||||
|  | 
 | ||||||
|  | ENTRY(__up_wakeup) | ||||||
|  | 	CFI_STARTPROC | ||||||
|  | 	FRAME | ||||||
|  | 	pushl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET edx,0 | ||||||
|  | 	pushl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET ecx,0 | ||||||
|  | 	call __up | ||||||
|  | 	popl %ecx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE ecx | ||||||
|  | 	popl %edx | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE edx | ||||||
|  | 	ENDFRAME | ||||||
|  | 	ret | ||||||
|  | 	CFI_ENDPROC | ||||||
|  | 	END(__up_wakeup) | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * rw spinlock fallbacks | ||||||
|  |  */ | ||||||
|  | #ifdef CONFIG_SMP | ||||||
|  | ENTRY(__write_lock_failed) | ||||||
|  | 	CFI_STARTPROC simple | ||||||
|  | 	FRAME | ||||||
|  | 2: 	LOCK_PREFIX | ||||||
|  | 	addl	$ RW_LOCK_BIAS,(%eax) | ||||||
|  | 1:	rep; nop
 | ||||||
|  | 	cmpl	$ RW_LOCK_BIAS,(%eax) | ||||||
|  | 	jne	1b | ||||||
|  | 	LOCK_PREFIX | ||||||
|  | 	subl	$ RW_LOCK_BIAS,(%eax) | ||||||
|  | 	jnz	2b | ||||||
|  | 	ENDFRAME | ||||||
|  | 	ret | ||||||
|  | 	CFI_ENDPROC | ||||||
|  | 	END(__write_lock_failed) | ||||||
|  | 
 | ||||||
|  | ENTRY(__read_lock_failed) | ||||||
|  | 	CFI_STARTPROC | ||||||
|  | 	FRAME | ||||||
|  | 2: 	LOCK_PREFIX | ||||||
|  | 	incl	(%eax) | ||||||
|  | 1:	rep; nop
 | ||||||
|  | 	cmpl	$1,(%eax) | ||||||
|  | 	js	1b | ||||||
|  | 	LOCK_PREFIX | ||||||
|  | 	decl	(%eax) | ||||||
|  | 	js	2b | ||||||
|  | 	ENDFRAME | ||||||
|  | 	ret | ||||||
|  | 	CFI_ENDPROC | ||||||
|  | 	END(__read_lock_failed) | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -4,7 +4,7 @@ obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | ||||||
| 
 | 
 | ||||||
| obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o | obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o | ||||||
| 
 | 
 | ||||||
| subarch-obj-y = lib/bitops.o kernel/semaphore.o | subarch-obj-y = lib/bitops.o lib/semaphore.o | ||||||
| subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o | ||||||
| subarch-obj-$(CONFIG_MODULES) += kernel/module.o | subarch-obj-$(CONFIG_MODULES) += kernel/module.o | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								include/asm-i386/frame.i
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/asm-i386/frame.i
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | #include <linux/config.h> | ||||||
|  | #include <asm/dwarf2.h> | ||||||
|  | 
 | ||||||
|  | /* The annotation hides the frame from the unwinder and makes it look | ||||||
|  |    like a ordinary ebp save/restore. This avoids some special cases for | ||||||
|  |    frame pointer later */ | ||||||
|  | #ifdef CONFIG_FRAME_POINTER | ||||||
|  | 	.macro FRAME | ||||||
|  | 	pushl %ebp | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET 4 | ||||||
|  | 	CFI_REL_OFFSET ebp,0 | ||||||
|  | 	movl %esp,%ebp | ||||||
|  | 	.endm | ||||||
|  | 	.macro ENDFRAME | ||||||
|  | 	popl %ebp | ||||||
|  | 	CFI_ADJUST_CFA_OFFSET -4 | ||||||
|  | 	CFI_RESTORE ebp | ||||||
|  | 	.endm | ||||||
|  | #else | ||||||
|  | 	.macro FRAME | ||||||
|  | 	.endm | ||||||
|  | 	.macro ENDFRAME | ||||||
|  | 	.endm | ||||||
|  | #endif | ||||||
							
								
								
									
										6
									
								
								include/asm-um/alternative-asm.i
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/asm-um/alternative-asm.i
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | #ifndef __UM_ALTERNATIVE_ASM_I | ||||||
|  | #define __UM_ALTERNATIVE_ASM_I | ||||||
|  | 
 | ||||||
|  | #include "asm/arch/alternative-asm.i" | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										6
									
								
								include/asm-um/frame.i
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/asm-um/frame.i
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | #ifndef __UM_FRAME_I | ||||||
|  | #define __UM_FRAME_I | ||||||
|  | 
 | ||||||
|  | #include "asm/arch/frame.i" | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Andi Kleen
						Andi Kleen