diff options
| author | Andi Kleen <ak@suse.de> | 2006-09-26 04:52:29 -0400 |
|---|---|---|
| committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:29 -0400 |
| commit | ecaf45ee5ce60afe7cc46e91d82c1b0cbda09387 (patch) | |
| tree | 09ff150151dc6724f250da068c2653dc13b4e3c0 | |
| parent | 07c9819b31eda7954feddc83f2fae035f31c11e1 (diff) | |
[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>
| -rw-r--r-- | arch/i386/kernel/Makefile | 2 | ||||
| -rw-r--r-- | arch/i386/kernel/semaphore.c | 134 | ||||
| -rw-r--r-- | arch/i386/lib/Makefile | 2 | ||||
| -rw-r--r-- | arch/i386/lib/semaphore.S | 154 | ||||
| -rw-r--r-- | arch/um/sys-i386/Makefile | 2 | ||||
| -rw-r--r-- | include/asm-i386/frame.i | 24 | ||||
| -rw-r--r-- | include/asm-um/alternative-asm.i | 6 | ||||
| -rw-r--r-- | include/asm-um/frame.i | 6 |
8 files changed, 193 insertions, 137 deletions
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 5427a842e841..dab497472deb 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | extra-y := head.o init_task.o vmlinux.lds | 5 | extra-y := head.o init_task.o vmlinux.lds |
| 6 | 6 | ||
| 7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ | 7 | obj-y := process.o signal.o entry.o traps.o irq.o \ |
| 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ |
| 9 | pci-dma.o i386_ksyms.o i387.o bootflag.o \ | 9 | pci-dma.o i386_ksyms.o i387.o bootflag.o \ |
| 10 | quirks.o i8237.o topology.o alternative.o i8253.o tsc.o | 10 | quirks.o i8237.o topology.o alternative.o i8253.o tsc.o |
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c deleted file mode 100644 index 98352c374c76..000000000000 --- a/arch/i386/kernel/semaphore.c +++ /dev/null | |||
| @@ -1,134 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * i386 semaphore implementation. | ||
| 3 | * | ||
| 4 | * (C) Copyright 1999 Linus Torvalds | ||
| 5 | * | ||
| 6 | * Portions Copyright 1999 Red Hat, Inc. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License | ||
| 10 | * as published by the Free Software Foundation; either version | ||
| 11 | * 2 of the License, or (at your option) any later version. | ||
| 12 | * | ||
| 13 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> | ||
| 14 | */ | ||
| 15 | #include <asm/semaphore.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * The semaphore operations have a special calling sequence that | ||
| 19 | * allow us to do a simpler in-line version of them. These routines | ||
| 20 | * need to convert that sequence back into the C sequence when | ||
| 21 | * there is contention on the semaphore. | ||
| 22 | * | ||
| 23 | * %eax contains the semaphore pointer on entry. Save the C-clobbered | ||
| 24 | * registers (%eax, %edx and %ecx) except %eax whish is either a return | ||
| 25 | * value or just clobbered.. | ||
| 26 | */ | ||
| 27 | asm( | ||
| 28 | ".section .sched.text\n" | ||
| 29 | ".align 4\n" | ||
| 30 | ".globl __down_failed\n" | ||
| 31 | "__down_failed:\n\t" | ||
| 32 | #if defined(CONFIG_FRAME_POINTER) | ||
| 33 | "pushl %ebp\n\t" | ||
| 34 | "movl %esp,%ebp\n\t" | ||
| 35 | #endif | ||
| 36 | "pushl %edx\n\t" | ||
| 37 | "pushl %ecx\n\t" | ||
| 38 | "call __down\n\t" | ||
| 39 | "popl %ecx\n\t" | ||
| 40 | "popl %edx\n\t" | ||
| 41 | #if defined(CONFIG_FRAME_POINTER) | ||
| 42 | "movl %ebp,%esp\n\t" | ||
| 43 | "popl %ebp\n\t" | ||
| 44 | #endif | ||
| 45 | "ret" | ||
| 46 | ); | ||
| 47 | |||
| 48 | asm( | ||
| 49 | ".section .sched.text\n" | ||
| 50 | ".align 4\n" | ||
| 51 | ".globl __down_failed_interruptible\n" | ||
| 52 | "__down_failed_interruptible:\n\t" | ||
| 53 | #if defined(CONFIG_FRAME_POINTER) | ||
| 54 | "pushl %ebp\n\t" | ||
| 55 | "movl %esp,%ebp\n\t" | ||
| 56 | #endif | ||
| 57 | "pushl %edx\n\t" | ||
| 58 | "pushl %ecx\n\t" | ||
| 59 | "call __down_interruptible\n\t" | ||
| 60 | "popl %ecx\n\t" | ||
| 61 | "popl %edx\n\t" | ||
| 62 | #if defined(CONFIG_FRAME_POINTER) | ||
| 63 | "movl %ebp,%esp\n\t" | ||
| 64 | "popl %ebp\n\t" | ||
| 65 | #endif | ||
| 66 | "ret" | ||
| 67 | ); | ||
| 68 | |||
| 69 | asm( | ||
| 70 | ".section .sched.text\n" | ||
| 71 | ".align 4\n" | ||
| 72 | ".globl __down_failed_trylock\n" | ||
| 73 | "__down_failed_trylock:\n\t" | ||
| 74 | #if defined(CONFIG_FRAME_POINTER) | ||
| 75 | "pushl %ebp\n\t" | ||
| 76 | "movl %esp,%ebp\n\t" | ||
| 77 | #endif | ||
| 78 | "pushl %edx\n\t" | ||
| 79 | "pushl %ecx\n\t" | ||
| 80 | "call __down_trylock\n\t" | ||
| 81 | "popl %ecx\n\t" | ||
| 82 | "popl %edx\n\t" | ||
| 83 | #if defined(CONFIG_FRAME_POINTER) | ||
| 84 | "movl %ebp,%esp\n\t" | ||
| 85 | "popl %ebp\n\t" | ||
| 86 | #endif | ||
| 87 | "ret" | ||
| 88 | ); | ||
| 89 | |||
| 90 | asm( | ||
| 91 | ".section .sched.text\n" | ||
| 92 | ".align 4\n" | ||
| 93 | ".globl __up_wakeup\n" | ||
| 94 | "__up_wakeup:\n\t" | ||
| 95 | "pushl %edx\n\t" | ||
| 96 | "pushl %ecx\n\t" | ||
| 97 | "call __up\n\t" | ||
| 98 | "popl %ecx\n\t" | ||
| 99 | "popl %edx\n\t" | ||
| 100 | "ret" | ||
| 101 | ); | ||
| 102 | |||
| 103 | /* | ||
| 104 | * rw spinlock fallbacks | ||
| 105 | */ | ||
| 106 | #if defined(CONFIG_SMP) | ||
| 107 | asm( | ||
| 108 | ".section .sched.text\n" | ||
| 109 | ".align 4\n" | ||
| 110 | ".globl __write_lock_failed\n" | ||
| 111 | "__write_lock_failed:\n\t" | ||
| 112 | LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" | ||
| 113 | "1: rep; nop\n\t" | ||
| 114 | "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" | ||
| 115 | "jne 1b\n\t" | ||
| 116 | LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" | ||
| 117 | "jnz __write_lock_failed\n\t" | ||
| 118 | "ret" | ||
| 119 | ); | ||
| 120 | |||
| 121 | asm( | ||
| 122 | ".section .sched.text\n" | ||
| 123 | ".align 4\n" | ||
| 124 | ".globl __read_lock_failed\n" | ||
| 125 | "__read_lock_failed:\n\t" | ||
| 126 | LOCK_PREFIX "incl (%eax)\n" | ||
| 127 | "1: rep; nop\n\t" | ||
| 128 | "cmpl $1,(%eax)\n\t" | ||
| 129 | "js 1b\n\t" | ||
| 130 | LOCK_PREFIX "decl (%eax)\n\t" | ||
| 131 | "js __read_lock_failed\n\t" | ||
| 132 | "ret" | ||
| 133 | ); | ||
| 134 | #endif | ||
diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index 914933e9ec3d..d86a548b8d54 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile | |||
| @@ -4,6 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \ | 6 | lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \ |
| 7 | bitops.o | 7 | bitops.o semaphore.o |
| 8 | 8 | ||
| 9 | lib-$(CONFIG_X86_USE_3DNOW) += mmx.o | 9 | lib-$(CONFIG_X86_USE_3DNOW) += mmx.o |
diff --git a/arch/i386/lib/semaphore.S b/arch/i386/lib/semaphore.S new file mode 100644 index 000000000000..e16ff1696390 --- /dev/null +++ b/arch/i386/lib/semaphore.S | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | /* | ||
| 2 | * i386 semaphore implementation. | ||
| 3 | * | ||
| 4 | * (C) Copyright 1999 Linus Torvalds | ||
| 5 | * | ||
| 6 | * Portions Copyright 1999 Red Hat, Inc. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License | ||
| 10 | * as published by the Free Software Foundation; either version | ||
| 11 | * 2 of the License, or (at your option) any later version. | ||
| 12 | * | ||
| 13 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/config.h> | ||
| 17 | #include <linux/linkage.h> | ||
| 18 | #include <asm/rwlock.h> | ||
| 19 | #include <asm/alternative-asm.i> | ||
| 20 | #include <asm/frame.i> | ||
| 21 | #include <asm/dwarf2.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * The semaphore operations have a special calling sequence that | ||
| 25 | * allow us to do a simpler in-line version of them. These routines | ||
| 26 | * need to convert that sequence back into the C sequence when | ||
| 27 | * there is contention on the semaphore. | ||
| 28 | * | ||
| 29 | * %eax contains the semaphore pointer on entry. Save the C-clobbered | ||
| 30 | * registers (%eax, %edx and %ecx) except %eax whish is either a return | ||
| 31 | * value or just clobbered.. | ||
| 32 | */ | ||
| 33 | .section .sched.text | ||
| 34 | ENTRY(__down_failed) | ||
| 35 | CFI_STARTPROC | ||
| 36 | FRAME | ||
| 37 | pushl %edx | ||
| 38 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 39 | CFI_REL_OFFSET edx,0 | ||
| 40 | pushl %ecx | ||
| 41 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 42 | CFI_REL_OFFSET ecx,0 | ||
| 43 | call __down | ||
| 44 | popl %ecx | ||
| 45 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 46 | CFI_RESTORE ecx | ||
| 47 | popl %edx | ||
| 48 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 49 | CFI_RESTORE edx | ||
| 50 | ENDFRAME | ||
| 51 | ret | ||
| 52 | CFI_ENDPROC | ||
| 53 | END(__down_failed) | ||
| 54 | |||
| 55 | ENTRY(__down_failed_interruptible) | ||
| 56 | CFI_STARTPROC | ||
| 57 | FRAME | ||
| 58 | pushl %edx | ||
| 59 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 60 | CFI_REL_OFFSET edx,0 | ||
| 61 | pushl %ecx | ||
| 62 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 63 | CFI_REL_OFFSET ecx,0 | ||
| 64 | call __down_interruptible | ||
| 65 | popl %ecx | ||
| 66 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 67 | CFI_RESTORE ecx | ||
| 68 | popl %edx | ||
| 69 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 70 | CFI_RESTORE edx | ||
| 71 | ENDFRAME | ||
| 72 | ret | ||
| 73 | CFI_ENDPROC | ||
| 74 | END(__down_failed_interruptible) | ||
| 75 | |||
| 76 | ENTRY(__down_failed_trylock) | ||
| 77 | CFI_STARTPROC | ||
| 78 | FRAME | ||
| 79 | pushl %edx | ||
| 80 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 81 | CFI_REL_OFFSET edx,0 | ||
| 82 | pushl %ecx | ||
| 83 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 84 | CFI_REL_OFFSET ecx,0 | ||
| 85 | call __down_trylock | ||
| 86 | popl %ecx | ||
| 87 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 88 | CFI_RESTORE ecx | ||
| 89 | popl %edx | ||
| 90 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 91 | CFI_RESTORE edx | ||
| 92 | ENDFRAME | ||
| 93 | ret | ||
| 94 | CFI_ENDPROC | ||
| 95 | END(__down_failed_trylock) | ||
| 96 | |||
| 97 | ENTRY(__up_wakeup) | ||
| 98 | CFI_STARTPROC | ||
| 99 | FRAME | ||
| 100 | pushl %edx | ||
| 101 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 102 | CFI_REL_OFFSET edx,0 | ||
| 103 | pushl %ecx | ||
| 104 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 105 | CFI_REL_OFFSET ecx,0 | ||
| 106 | call __up | ||
| 107 | popl %ecx | ||
| 108 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 109 | CFI_RESTORE ecx | ||
| 110 | popl %edx | ||
| 111 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 112 | CFI_RESTORE edx | ||
| 113 | ENDFRAME | ||
| 114 | ret | ||
| 115 | CFI_ENDPROC | ||
| 116 | END(__up_wakeup) | ||
| 117 | |||
| 118 | /* | ||
| 119 | * rw spinlock fallbacks | ||
| 120 | */ | ||
| 121 | #ifdef CONFIG_SMP | ||
| 122 | ENTRY(__write_lock_failed) | ||
| 123 | CFI_STARTPROC simple | ||
| 124 | FRAME | ||
| 125 | 2: LOCK_PREFIX | ||
| 126 | addl $ RW_LOCK_BIAS,(%eax) | ||
| 127 | 1: rep; nop | ||
| 128 | cmpl $ RW_LOCK_BIAS,(%eax) | ||
| 129 | jne 1b | ||
| 130 | LOCK_PREFIX | ||
| 131 | subl $ RW_LOCK_BIAS,(%eax) | ||
| 132 | jnz 2b | ||
| 133 | ENDFRAME | ||
| 134 | ret | ||
| 135 | CFI_ENDPROC | ||
| 136 | END(__write_lock_failed) | ||
| 137 | |||
| 138 | ENTRY(__read_lock_failed) | ||
| 139 | CFI_STARTPROC | ||
| 140 | FRAME | ||
| 141 | 2: LOCK_PREFIX | ||
| 142 | incl (%eax) | ||
| 143 | 1: rep; nop | ||
| 144 | cmpl $1,(%eax) | ||
| 145 | js 1b | ||
| 146 | LOCK_PREFIX | ||
| 147 | decl (%eax) | ||
| 148 | js 2b | ||
| 149 | ENDFRAME | ||
| 150 | ret | ||
| 151 | CFI_ENDPROC | ||
| 152 | END(__read_lock_failed) | ||
| 153 | |||
| 154 | #endif | ||
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 374d61a19439..6289779ca67c 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile | |||
| @@ -4,7 +4,7 @@ obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o | 5 | obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o |
| 6 | 6 | ||
| 7 | subarch-obj-y = lib/bitops.o kernel/semaphore.o | 7 | subarch-obj-y = lib/bitops.o lib/semaphore.o |
| 8 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o | 8 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o |
| 9 | subarch-obj-$(CONFIG_MODULES) += kernel/module.o | 9 | subarch-obj-$(CONFIG_MODULES) += kernel/module.o |
| 10 | 10 | ||
diff --git a/include/asm-i386/frame.i b/include/asm-i386/frame.i new file mode 100644 index 000000000000..4d68ddce18b6 --- /dev/null +++ b/include/asm-i386/frame.i | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #include <linux/config.h> | ||
| 2 | #include <asm/dwarf2.h> | ||
| 3 | |||
| 4 | /* The annotation hides the frame from the unwinder and makes it look | ||
| 5 | like a ordinary ebp save/restore. This avoids some special cases for | ||
| 6 | frame pointer later */ | ||
| 7 | #ifdef CONFIG_FRAME_POINTER | ||
| 8 | .macro FRAME | ||
| 9 | pushl %ebp | ||
| 10 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 11 | CFI_REL_OFFSET ebp,0 | ||
| 12 | movl %esp,%ebp | ||
| 13 | .endm | ||
| 14 | .macro ENDFRAME | ||
| 15 | popl %ebp | ||
| 16 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 17 | CFI_RESTORE ebp | ||
| 18 | .endm | ||
| 19 | #else | ||
| 20 | .macro FRAME | ||
| 21 | .endm | ||
| 22 | .macro ENDFRAME | ||
| 23 | .endm | ||
| 24 | #endif | ||
diff --git a/include/asm-um/alternative-asm.i b/include/asm-um/alternative-asm.i new file mode 100644 index 000000000000..cae9faca132f --- /dev/null +++ b/include/asm-um/alternative-asm.i | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef __UM_ALTERNATIVE_ASM_I | ||
| 2 | #define __UM_ALTERNATIVE_ASM_I | ||
| 3 | |||
| 4 | #include "asm/arch/alternative-asm.i" | ||
| 5 | |||
| 6 | #endif | ||
diff --git a/include/asm-um/frame.i b/include/asm-um/frame.i new file mode 100644 index 000000000000..09d5dca5d928 --- /dev/null +++ b/include/asm-um/frame.i | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef __UM_FRAME_I | ||
| 2 | #define __UM_FRAME_I | ||
| 3 | |||
| 4 | #include "asm/arch/frame.i" | ||
| 5 | |||
| 6 | #endif | ||
