aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 20:02:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 20:02:24 -0400
commiteb47418dc56baaca33d270a868d8ddaa81150952 (patch)
tree16c0b09bacf3f6c25e5786afcfa741fa2a550ae5 /arch
parent2c9e88a1085b3183e5f92170a74980e5654f817b (diff)
parenta750036f35cda160ef77408ec92c3dc41f8feebb (diff)
Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: Fix write lock scalability 64-bit issue x86: Unify rwsem assembly implementation x86: Unify rwlock assembly implementation x86, asm: Fix binutils 2.16 issue with __USER32_CS x86, asm: Cleanup thunk_64.S x86, asm: Flip RESTORE_ARGS arguments logic x86, asm: Flip SAVE_ARGS arguments logic x86, asm: Thin down SAVE/RESTORE_* asm macros
Diffstat (limited to 'arch')
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-x86_64/Makefile2
-rw-r--r--arch/x86/ia32/ia32entry.S10
-rw-r--r--arch/x86/include/asm/asm.h5
-rw-r--r--arch/x86/include/asm/calling.h130
-rw-r--r--arch/x86/include/asm/frame.h11
-rw-r--r--arch/x86/include/asm/rwlock.h43
-rw-r--r--arch/x86/include/asm/segment.h2
-rw-r--r--arch/x86/include/asm/spinlock.h37
-rw-r--r--arch/x86/include/asm/spinlock_types.h6
-rw-r--r--arch/x86/kernel/entry_64.S6
-rw-r--r--arch/x86/lib/Makefile7
-rw-r--r--arch/x86/lib/rwlock.S44
-rw-r--r--arch/x86/lib/rwlock_64.S38
-rw-r--r--arch/x86/lib/rwsem.S (renamed from arch/x86/lib/rwsem_64.S)75
-rw-r--r--arch/x86/lib/semaphore_32.S124
-rw-r--r--arch/x86/lib/thunk_64.S45
17 files changed, 263 insertions, 324 deletions
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index b1da91c1b200..15587ed9a361 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -8,7 +8,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
8 8
9obj-$(CONFIG_BINFMT_ELF) += elfcore.o 9obj-$(CONFIG_BINFMT_ELF) += elfcore.o
10 10
11subarch-obj-y = lib/semaphore_32.o lib/string_32.o 11subarch-obj-y = lib/rwsem.o lib/string_32.o
12subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 12subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
13subarch-obj-$(CONFIG_MODULES) += kernel/module.o 13subarch-obj-$(CONFIG_MODULES) += kernel/module.o
14 14
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index c1ea9eb04466..61fc99a42e10 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -9,7 +9,7 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
9 sysrq.o ksyms.o tls.o 9 sysrq.o ksyms.o tls.o
10 10
11subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ 11subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \
12 lib/rwsem_64.o 12 lib/rwsem.o
13subarch-obj-$(CONFIG_MODULES) += kernel/module.o 13subarch-obj-$(CONFIG_MODULES) += kernel/module.o
14 14
15ldt-y = ../sys-i386/ldt.o 15ldt-y = ../sys-i386/ldt.o
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index c1870dddd322..a0e866d233ee 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -143,7 +143,7 @@ ENTRY(ia32_sysenter_target)
143 CFI_REL_OFFSET rip,0 143 CFI_REL_OFFSET rip,0
144 pushq_cfi %rax 144 pushq_cfi %rax
145 cld 145 cld
146 SAVE_ARGS 0,0,1 146 SAVE_ARGS 0,1,0
147 /* no need to do an access_ok check here because rbp has been 147 /* no need to do an access_ok check here because rbp has been
148 32bit zero extended */ 148 32bit zero extended */
1491: movl (%rbp),%ebp 1491: movl (%rbp),%ebp
@@ -173,7 +173,7 @@ sysexit_from_sys_call:
173 andl $~0x200,EFLAGS-R11(%rsp) 173 andl $~0x200,EFLAGS-R11(%rsp)
174 movl RIP-R11(%rsp),%edx /* User %eip */ 174 movl RIP-R11(%rsp),%edx /* User %eip */
175 CFI_REGISTER rip,rdx 175 CFI_REGISTER rip,rdx
176 RESTORE_ARGS 1,24,1,1,1,1 176 RESTORE_ARGS 0,24,0,0,0,0
177 xorq %r8,%r8 177 xorq %r8,%r8
178 xorq %r9,%r9 178 xorq %r9,%r9
179 xorq %r10,%r10 179 xorq %r10,%r10
@@ -289,7 +289,7 @@ ENTRY(ia32_cstar_target)
289 * disabled irqs and here we enable it straight after entry: 289 * disabled irqs and here we enable it straight after entry:
290 */ 290 */
291 ENABLE_INTERRUPTS(CLBR_NONE) 291 ENABLE_INTERRUPTS(CLBR_NONE)
292 SAVE_ARGS 8,1,1 292 SAVE_ARGS 8,0,0
293 movl %eax,%eax /* zero extension */ 293 movl %eax,%eax /* zero extension */
294 movq %rax,ORIG_RAX-ARGOFFSET(%rsp) 294 movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
295 movq %rcx,RIP-ARGOFFSET(%rsp) 295 movq %rcx,RIP-ARGOFFSET(%rsp)
@@ -328,7 +328,7 @@ cstar_dispatch:
328 jnz sysretl_audit 328 jnz sysretl_audit
329sysretl_from_sys_call: 329sysretl_from_sys_call:
330 andl $~TS_COMPAT,TI_status(%r10) 330 andl $~TS_COMPAT,TI_status(%r10)
331 RESTORE_ARGS 1,-ARG_SKIP,1,1,1 331 RESTORE_ARGS 0,-ARG_SKIP,0,0,0
332 movl RIP-ARGOFFSET(%rsp),%ecx 332 movl RIP-ARGOFFSET(%rsp),%ecx
333 CFI_REGISTER rip,rcx 333 CFI_REGISTER rip,rcx
334 movl EFLAGS-ARGOFFSET(%rsp),%r11d 334 movl EFLAGS-ARGOFFSET(%rsp),%r11d
@@ -419,7 +419,7 @@ ENTRY(ia32_syscall)
419 cld 419 cld
420 /* note the registers are not zero extended to the sf. 420 /* note the registers are not zero extended to the sf.
421 this could be a problem. */ 421 this could be a problem. */
422 SAVE_ARGS 0,0,1 422 SAVE_ARGS 0,1,0
423 GET_THREAD_INFO(%r10) 423 GET_THREAD_INFO(%r10)
424 orl $TS_COMPAT,TI_status(%r10) 424 orl $TS_COMPAT,TI_status(%r10)
425 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) 425 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index b3ed1e1460ff..9412d6558c88 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -3,9 +3,11 @@
3 3
4#ifdef __ASSEMBLY__ 4#ifdef __ASSEMBLY__
5# define __ASM_FORM(x) x 5# define __ASM_FORM(x) x
6# define __ASM_FORM_COMMA(x) x,
6# define __ASM_EX_SEC .section __ex_table, "a" 7# define __ASM_EX_SEC .section __ex_table, "a"
7#else 8#else
8# define __ASM_FORM(x) " " #x " " 9# define __ASM_FORM(x) " " #x " "
10# define __ASM_FORM_COMMA(x) " " #x ","
9# define __ASM_EX_SEC " .section __ex_table,\"a\"\n" 11# define __ASM_EX_SEC " .section __ex_table,\"a\"\n"
10#endif 12#endif
11 13
@@ -15,7 +17,8 @@
15# define __ASM_SEL(a,b) __ASM_FORM(b) 17# define __ASM_SEL(a,b) __ASM_FORM(b)
16#endif 18#endif
17 19
18#define __ASM_SIZE(inst) __ASM_SEL(inst##l, inst##q) 20#define __ASM_SIZE(inst, ...) __ASM_SEL(inst##l##__VA_ARGS__, \
21 inst##q##__VA_ARGS__)
19#define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg) 22#define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg)
20 23
21#define _ASM_PTR __ASM_SEL(.long, .quad) 24#define _ASM_PTR __ASM_SEL(.long, .quad)
diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h
index 30af5a832163..a9e3a740f697 100644
--- a/arch/x86/include/asm/calling.h
+++ b/arch/x86/include/asm/calling.h
@@ -46,6 +46,7 @@ For 32-bit we have the following conventions - kernel is built with
46 46
47*/ 47*/
48 48
49#include "dwarf2.h"
49 50
50/* 51/*
51 * 64-bit system call stack frame layout defines and helpers, for 52 * 64-bit system call stack frame layout defines and helpers, for
@@ -84,72 +85,57 @@ For 32-bit we have the following conventions - kernel is built with
84#define ARGOFFSET R11 85#define ARGOFFSET R11
85#define SWFRAME ORIG_RAX 86#define SWFRAME ORIG_RAX
86 87
87 .macro SAVE_ARGS addskip=0, norcx=0, nor891011=0 88 .macro SAVE_ARGS addskip=0, save_rcx=1, save_r891011=1
88 subq $9*8+\addskip, %rsp 89 subq $9*8+\addskip, %rsp
89 CFI_ADJUST_CFA_OFFSET 9*8+\addskip 90 CFI_ADJUST_CFA_OFFSET 9*8+\addskip
90 movq %rdi, 8*8(%rsp) 91 movq_cfi rdi, 8*8
91 CFI_REL_OFFSET rdi, 8*8 92 movq_cfi rsi, 7*8
92 movq %rsi, 7*8(%rsp) 93 movq_cfi rdx, 6*8
93 CFI_REL_OFFSET rsi, 7*8 94
94 movq %rdx, 6*8(%rsp) 95 .if \save_rcx
95 CFI_REL_OFFSET rdx, 6*8 96 movq_cfi rcx, 5*8
96 .if \norcx
97 .else
98 movq %rcx, 5*8(%rsp)
99 CFI_REL_OFFSET rcx, 5*8
100 .endif 97 .endif
101 movq %rax, 4*8(%rsp) 98
102 CFI_REL_OFFSET rax, 4*8 99 movq_cfi rax, 4*8
103 .if \nor891011 100
104 .else 101 .if \save_r891011
105 movq %r8, 3*8(%rsp) 102 movq_cfi r8, 3*8
106 CFI_REL_OFFSET r8, 3*8 103 movq_cfi r9, 2*8
107 movq %r9, 2*8(%rsp) 104 movq_cfi r10, 1*8
108 CFI_REL_OFFSET r9, 2*8 105 movq_cfi r11, 0*8
109 movq %r10, 1*8(%rsp)
110 CFI_REL_OFFSET r10, 1*8
111 movq %r11, (%rsp)
112 CFI_REL_OFFSET r11, 0*8
113 .endif 106 .endif
107
114 .endm 108 .endm
115 109
116#define ARG_SKIP (9*8) 110#define ARG_SKIP (9*8)
117 111
118 .macro RESTORE_ARGS skiprax=0, addskip=0, skiprcx=0, skipr11=0, \ 112 .macro RESTORE_ARGS rstor_rax=1, addskip=0, rstor_rcx=1, rstor_r11=1, \
119 skipr8910=0, skiprdx=0 113 rstor_r8910=1, rstor_rdx=1
120 .if \skipr11 114 .if \rstor_r11
121 .else 115 movq_cfi_restore 0*8, r11
122 movq (%rsp), %r11
123 CFI_RESTORE r11
124 .endif 116 .endif
125 .if \skipr8910 117
126 .else 118 .if \rstor_r8910
127 movq 1*8(%rsp), %r10 119 movq_cfi_restore 1*8, r10
128 CFI_RESTORE r10 120 movq_cfi_restore 2*8, r9
129 movq 2*8(%rsp), %r9 121 movq_cfi_restore 3*8, r8
130 CFI_RESTORE r9
131 movq 3*8(%rsp), %r8
132 CFI_RESTORE r8
133 .endif 122 .endif
134 .if \skiprax 123
135 .else 124 .if \rstor_rax
136 movq 4*8(%rsp), %rax 125 movq_cfi_restore 4*8, rax
137 CFI_RESTORE rax
138 .endif 126 .endif
139 .if \skiprcx 127
140 .else 128 .if \rstor_rcx
141 movq 5*8(%rsp), %rcx 129 movq_cfi_restore 5*8, rcx
142 CFI_RESTORE rcx
143 .endif 130 .endif
144 .if \skiprdx 131
145 .else 132 .if \rstor_rdx
146 movq 6*8(%rsp), %rdx 133 movq_cfi_restore 6*8, rdx
147 CFI_RESTORE rdx
148 .endif 134 .endif
149 movq 7*8(%rsp), %rsi 135
150 CFI_RESTORE rsi 136 movq_cfi_restore 7*8, rsi
151 movq 8*8(%rsp), %rdi 137 movq_cfi_restore 8*8, rdi
152 CFI_RESTORE rdi 138
153 .if ARG_SKIP+\addskip > 0 139 .if ARG_SKIP+\addskip > 0
154 addq $ARG_SKIP+\addskip, %rsp 140 addq $ARG_SKIP+\addskip, %rsp
155 CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip) 141 CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
@@ -176,33 +162,21 @@ For 32-bit we have the following conventions - kernel is built with
176 .macro SAVE_REST 162 .macro SAVE_REST
177 subq $REST_SKIP, %rsp 163 subq $REST_SKIP, %rsp
178 CFI_ADJUST_CFA_OFFSET REST_SKIP 164 CFI_ADJUST_CFA_OFFSET REST_SKIP
179 movq %rbx, 5*8(%rsp) 165 movq_cfi rbx, 5*8
180 CFI_REL_OFFSET rbx, 5*8 166 movq_cfi rbp, 4*8
181 movq %rbp, 4*8(%rsp) 167 movq_cfi r12, 3*8
182 CFI_REL_OFFSET rbp, 4*8 168 movq_cfi r13, 2*8
183 movq %r12, 3*8(%rsp) 169 movq_cfi r14, 1*8
184 CFI_REL_OFFSET r12, 3*8 170 movq_cfi r15, 0*8
185 movq %r13, 2*8(%rsp)
186 CFI_REL_OFFSET r13, 2*8
187 movq %r14, 1*8(%rsp)
188 CFI_REL_OFFSET r14, 1*8
189 movq %r15, (%rsp)
190 CFI_REL_OFFSET r15, 0*8
191 .endm 171 .endm
192 172
193 .macro RESTORE_REST 173 .macro RESTORE_REST
194 movq (%rsp), %r15 174 movq_cfi_restore 0*8, r15
195 CFI_RESTORE r15 175 movq_cfi_restore 1*8, r14
196 movq 1*8(%rsp), %r14 176 movq_cfi_restore 2*8, r13
197 CFI_RESTORE r14 177 movq_cfi_restore 3*8, r12
198 movq 2*8(%rsp), %r13 178 movq_cfi_restore 4*8, rbp
199 CFI_RESTORE r13 179 movq_cfi_restore 5*8, rbx
200 movq 3*8(%rsp), %r12
201 CFI_RESTORE r12
202 movq 4*8(%rsp), %rbp
203 CFI_RESTORE rbp
204 movq 5*8(%rsp), %rbx
205 CFI_RESTORE rbx
206 addq $REST_SKIP, %rsp 180 addq $REST_SKIP, %rsp
207 CFI_ADJUST_CFA_OFFSET -(REST_SKIP) 181 CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
208 .endm 182 .endm
@@ -214,7 +188,7 @@ For 32-bit we have the following conventions - kernel is built with
214 188
215 .macro RESTORE_ALL addskip=0 189 .macro RESTORE_ALL addskip=0
216 RESTORE_REST 190 RESTORE_REST
217 RESTORE_ARGS 0, \addskip 191 RESTORE_ARGS 1, \addskip
218 .endm 192 .endm
219 193
220 .macro icebp 194 .macro icebp
diff --git a/arch/x86/include/asm/frame.h b/arch/x86/include/asm/frame.h
index 2c6fc9e62812..3b629f47eb65 100644
--- a/arch/x86/include/asm/frame.h
+++ b/arch/x86/include/asm/frame.h
@@ -1,5 +1,6 @@
1#ifdef __ASSEMBLY__ 1#ifdef __ASSEMBLY__
2 2
3#include <asm/asm.h>
3#include <asm/dwarf2.h> 4#include <asm/dwarf2.h>
4 5
5/* The annotation hides the frame from the unwinder and makes it look 6/* The annotation hides the frame from the unwinder and makes it look
@@ -7,13 +8,13 @@
7 frame pointer later */ 8 frame pointer later */
8#ifdef CONFIG_FRAME_POINTER 9#ifdef CONFIG_FRAME_POINTER
9 .macro FRAME 10 .macro FRAME
10 pushl_cfi %ebp 11 __ASM_SIZE(push,_cfi) %__ASM_REG(bp)
11 CFI_REL_OFFSET ebp,0 12 CFI_REL_OFFSET __ASM_REG(bp), 0
12 movl %esp,%ebp 13 __ASM_SIZE(mov) %__ASM_REG(sp), %__ASM_REG(bp)
13 .endm 14 .endm
14 .macro ENDFRAME 15 .macro ENDFRAME
15 popl_cfi %ebp 16 __ASM_SIZE(pop,_cfi) %__ASM_REG(bp)
16 CFI_RESTORE ebp 17 CFI_RESTORE __ASM_REG(bp)
17 .endm 18 .endm
18#else 19#else
19 .macro FRAME 20 .macro FRAME
diff --git a/arch/x86/include/asm/rwlock.h b/arch/x86/include/asm/rwlock.h
index 6a8c0d645108..a5370a03d90c 100644
--- a/arch/x86/include/asm/rwlock.h
+++ b/arch/x86/include/asm/rwlock.h
@@ -1,7 +1,48 @@
1#ifndef _ASM_X86_RWLOCK_H 1#ifndef _ASM_X86_RWLOCK_H
2#define _ASM_X86_RWLOCK_H 2#define _ASM_X86_RWLOCK_H
3 3
4#define RW_LOCK_BIAS 0x01000000 4#include <asm/asm.h>
5
6#if CONFIG_NR_CPUS <= 2048
7
8#ifndef __ASSEMBLY__
9typedef union {
10 s32 lock;
11 s32 write;
12} arch_rwlock_t;
13#endif
14
15#define RW_LOCK_BIAS 0x00100000
16#define READ_LOCK_SIZE(insn) __ASM_FORM(insn##l)
17#define READ_LOCK_ATOMIC(n) atomic_##n
18#define WRITE_LOCK_ADD(n) __ASM_FORM_COMMA(addl n)
19#define WRITE_LOCK_SUB(n) __ASM_FORM_COMMA(subl n)
20#define WRITE_LOCK_CMP RW_LOCK_BIAS
21
22#else /* CONFIG_NR_CPUS > 2048 */
23
24#include <linux/const.h>
25
26#ifndef __ASSEMBLY__
27typedef union {
28 s64 lock;
29 struct {
30 u32 read;
31 s32 write;
32 };
33} arch_rwlock_t;
34#endif
35
36#define RW_LOCK_BIAS (_AC(1,L) << 32)
37#define READ_LOCK_SIZE(insn) __ASM_FORM(insn##q)
38#define READ_LOCK_ATOMIC(n) atomic64_##n
39#define WRITE_LOCK_ADD(n) __ASM_FORM(incl)
40#define WRITE_LOCK_SUB(n) __ASM_FORM(decl)
41#define WRITE_LOCK_CMP 1
42
43#endif /* CONFIG_NR_CPUS */
44
45#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
5 46
6/* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */ 47/* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */
7 48
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index cd84f7208f76..5e641715c3fe 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -162,7 +162,7 @@
162#define GDT_ENTRY_DEFAULT_USER32_CS 4 162#define GDT_ENTRY_DEFAULT_USER32_CS 4
163#define GDT_ENTRY_DEFAULT_USER_DS 5 163#define GDT_ENTRY_DEFAULT_USER_DS 5
164#define GDT_ENTRY_DEFAULT_USER_CS 6 164#define GDT_ENTRY_DEFAULT_USER_CS 6
165#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS * 8 + 3) 165#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8+3)
166#define __USER32_DS __USER_DS 166#define __USER32_DS __USER_DS
167 167
168#define GDT_ENTRY_TSS 8 /* needs two entries */ 168#define GDT_ENTRY_TSS 8 /* needs two entries */
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
index 3089f70c0c52..e9e51f710e6c 100644
--- a/arch/x86/include/asm/spinlock.h
+++ b/arch/x86/include/asm/spinlock.h
@@ -2,7 +2,6 @@
2#define _ASM_X86_SPINLOCK_H 2#define _ASM_X86_SPINLOCK_H
3 3
4#include <asm/atomic.h> 4#include <asm/atomic.h>
5#include <asm/rwlock.h>
6#include <asm/page.h> 5#include <asm/page.h>
7#include <asm/processor.h> 6#include <asm/processor.h>
8#include <linux/compiler.h> 7#include <linux/compiler.h>
@@ -234,7 +233,7 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
234 */ 233 */
235static inline int arch_read_can_lock(arch_rwlock_t *lock) 234static inline int arch_read_can_lock(arch_rwlock_t *lock)
236{ 235{
237 return (int)(lock)->lock > 0; 236 return lock->lock > 0;
238} 237}
239 238
240/** 239/**
@@ -243,12 +242,12 @@ static inline int arch_read_can_lock(arch_rwlock_t *lock)
243 */ 242 */
244static inline int arch_write_can_lock(arch_rwlock_t *lock) 243static inline int arch_write_can_lock(arch_rwlock_t *lock)
245{ 244{
246 return (lock)->lock == RW_LOCK_BIAS; 245 return lock->write == WRITE_LOCK_CMP;
247} 246}
248 247
249static inline void arch_read_lock(arch_rwlock_t *rw) 248static inline void arch_read_lock(arch_rwlock_t *rw)
250{ 249{
251 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" 250 asm volatile(LOCK_PREFIX READ_LOCK_SIZE(dec) " (%0)\n\t"
252 "jns 1f\n" 251 "jns 1f\n"
253 "call __read_lock_failed\n\t" 252 "call __read_lock_failed\n\t"
254 "1:\n" 253 "1:\n"
@@ -257,47 +256,55 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
257 256
258static inline void arch_write_lock(arch_rwlock_t *rw) 257static inline void arch_write_lock(arch_rwlock_t *rw)
259{ 258{
260 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" 259 asm volatile(LOCK_PREFIX WRITE_LOCK_SUB(%1) "(%0)\n\t"
261 "jz 1f\n" 260 "jz 1f\n"
262 "call __write_lock_failed\n\t" 261 "call __write_lock_failed\n\t"
263 "1:\n" 262 "1:\n"
264 ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); 263 ::LOCK_PTR_REG (&rw->write), "i" (RW_LOCK_BIAS)
264 : "memory");
265} 265}
266 266
267static inline int arch_read_trylock(arch_rwlock_t *lock) 267static inline int arch_read_trylock(arch_rwlock_t *lock)
268{ 268{
269 atomic_t *count = (atomic_t *)lock; 269 READ_LOCK_ATOMIC(t) *count = (READ_LOCK_ATOMIC(t) *)lock;
270 270
271 if (atomic_dec_return(count) >= 0) 271 if (READ_LOCK_ATOMIC(dec_return)(count) >= 0)
272 return 1; 272 return 1;
273 atomic_inc(count); 273 READ_LOCK_ATOMIC(inc)(count);
274 return 0; 274 return 0;
275} 275}
276 276
277static inline int arch_write_trylock(arch_rwlock_t *lock) 277static inline int arch_write_trylock(arch_rwlock_t *lock)
278{ 278{
279 atomic_t *count = (atomic_t *)lock; 279 atomic_t *count = (atomic_t *)&lock->write;
280 280
281 if (atomic_sub_and_test(RW_LOCK_BIAS, count)) 281 if (atomic_sub_and_test(WRITE_LOCK_CMP, count))
282 return 1; 282 return 1;
283 atomic_add(RW_LOCK_BIAS, count); 283 atomic_add(WRITE_LOCK_CMP, count);
284 return 0; 284 return 0;
285} 285}
286 286
287static inline void arch_read_unlock(arch_rwlock_t *rw) 287static inline void arch_read_unlock(arch_rwlock_t *rw)
288{ 288{
289 asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); 289 asm volatile(LOCK_PREFIX READ_LOCK_SIZE(inc) " %0"
290 :"+m" (rw->lock) : : "memory");
290} 291}
291 292
292static inline void arch_write_unlock(arch_rwlock_t *rw) 293static inline void arch_write_unlock(arch_rwlock_t *rw)
293{ 294{
294 asm volatile(LOCK_PREFIX "addl %1, %0" 295 asm volatile(LOCK_PREFIX WRITE_LOCK_ADD(%1) "%0"
295 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); 296 : "+m" (rw->write) : "i" (RW_LOCK_BIAS) : "memory");
296} 297}
297 298
298#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) 299#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
299#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) 300#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
300 301
302#undef READ_LOCK_SIZE
303#undef READ_LOCK_ATOMIC
304#undef WRITE_LOCK_ADD
305#undef WRITE_LOCK_SUB
306#undef WRITE_LOCK_CMP
307
301#define arch_spin_relax(lock) cpu_relax() 308#define arch_spin_relax(lock) cpu_relax()
302#define arch_read_relax(lock) cpu_relax() 309#define arch_read_relax(lock) cpu_relax()
303#define arch_write_relax(lock) cpu_relax() 310#define arch_write_relax(lock) cpu_relax()
diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h
index dcb48b2edc11..7c7a486fcb68 100644
--- a/arch/x86/include/asm/spinlock_types.h
+++ b/arch/x86/include/asm/spinlock_types.h
@@ -11,10 +11,6 @@ typedef struct arch_spinlock {
11 11
12#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } 12#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
13 13
14typedef struct { 14#include <asm/rwlock.h>
15 unsigned int lock;
16} arch_rwlock_t;
17
18#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
19 15
20#endif /* _ASM_X86_SPINLOCK_TYPES_H */ 16#endif /* _ASM_X86_SPINLOCK_TYPES_H */
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index d656f68371a4..d130b20a6b90 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -467,7 +467,7 @@ ENTRY(system_call_after_swapgs)
467 * and short: 467 * and short:
468 */ 468 */
469 ENABLE_INTERRUPTS(CLBR_NONE) 469 ENABLE_INTERRUPTS(CLBR_NONE)
470 SAVE_ARGS 8,1 470 SAVE_ARGS 8,0
471 movq %rax,ORIG_RAX-ARGOFFSET(%rsp) 471 movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
472 movq %rcx,RIP-ARGOFFSET(%rsp) 472 movq %rcx,RIP-ARGOFFSET(%rsp)
473 CFI_REL_OFFSET rip,RIP-ARGOFFSET 473 CFI_REL_OFFSET rip,RIP-ARGOFFSET
@@ -502,7 +502,7 @@ sysret_check:
502 TRACE_IRQS_ON 502 TRACE_IRQS_ON
503 movq RIP-ARGOFFSET(%rsp),%rcx 503 movq RIP-ARGOFFSET(%rsp),%rcx
504 CFI_REGISTER rip,rcx 504 CFI_REGISTER rip,rcx
505 RESTORE_ARGS 0,-ARG_SKIP,1 505 RESTORE_ARGS 1,-ARG_SKIP,0
506 /*CFI_REGISTER rflags,r11*/ 506 /*CFI_REGISTER rflags,r11*/
507 movq PER_CPU_VAR(old_rsp), %rsp 507 movq PER_CPU_VAR(old_rsp), %rsp
508 USERGS_SYSRET64 508 USERGS_SYSRET64
@@ -851,7 +851,7 @@ retint_restore_args: /* return to kernel space */
851 */ 851 */
852 TRACE_IRQS_IRETQ 852 TRACE_IRQS_IRETQ
853restore_args: 853restore_args:
854 RESTORE_ARGS 0,8,0 854 RESTORE_ARGS 1,8,1
855 855
856irq_return: 856irq_return:
857 INTERRUPT_RETURN 857 INTERRUPT_RETURN
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 6ba477342b8e..b00f6785da74 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -20,6 +20,8 @@ lib-y := delay.o
20lib-y += thunk_$(BITS).o 20lib-y += thunk_$(BITS).o
21lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o 21lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o
22lib-y += memcpy_$(BITS).o 22lib-y += memcpy_$(BITS).o
23lib-$(CONFIG_SMP) += rwlock.o
24lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
23lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o 25lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
24 26
25obj-y += msr.o msr-reg.o msr-reg-export.o 27obj-y += msr.o msr-reg.o msr-reg-export.o
@@ -29,7 +31,7 @@ ifeq ($(CONFIG_X86_32),y)
29 lib-y += atomic64_cx8_32.o 31 lib-y += atomic64_cx8_32.o
30 lib-y += checksum_32.o 32 lib-y += checksum_32.o
31 lib-y += strstr_32.o 33 lib-y += strstr_32.o
32 lib-y += semaphore_32.o string_32.o 34 lib-y += string_32.o
33 lib-y += cmpxchg.o 35 lib-y += cmpxchg.o
34ifneq ($(CONFIG_X86_CMPXCHG64),y) 36ifneq ($(CONFIG_X86_CMPXCHG64),y)
35 lib-y += cmpxchg8b_emu.o atomic64_386_32.o 37 lib-y += cmpxchg8b_emu.o atomic64_386_32.o
@@ -40,7 +42,6 @@ else
40 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o 42 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
41 lib-y += thunk_64.o clear_page_64.o copy_page_64.o 43 lib-y += thunk_64.o clear_page_64.o copy_page_64.o
42 lib-y += memmove_64.o memset_64.o 44 lib-y += memmove_64.o memset_64.o
43 lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o 45 lib-y += copy_user_64.o copy_user_nocache_64.o
44 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o
45 lib-y += cmpxchg16b_emu.o 46 lib-y += cmpxchg16b_emu.o
46endif 47endif
diff --git a/arch/x86/lib/rwlock.S b/arch/x86/lib/rwlock.S
new file mode 100644
index 000000000000..1cad22139c88
--- /dev/null
+++ b/arch/x86/lib/rwlock.S
@@ -0,0 +1,44 @@
1/* Slow paths of read/write spinlocks. */
2
3#include <linux/linkage.h>
4#include <asm/alternative-asm.h>
5#include <asm/frame.h>
6#include <asm/rwlock.h>
7
8#ifdef CONFIG_X86_32
9# define __lock_ptr eax
10#else
11# define __lock_ptr rdi
12#endif
13
14ENTRY(__write_lock_failed)
15 CFI_STARTPROC
16 FRAME
170: LOCK_PREFIX
18 WRITE_LOCK_ADD($RW_LOCK_BIAS) (%__lock_ptr)
191: rep; nop
20 cmpl $WRITE_LOCK_CMP, (%__lock_ptr)
21 jne 1b
22 LOCK_PREFIX
23 WRITE_LOCK_SUB($RW_LOCK_BIAS) (%__lock_ptr)
24 jnz 0b
25 ENDFRAME
26 ret
27 CFI_ENDPROC
28END(__write_lock_failed)
29
30ENTRY(__read_lock_failed)
31 CFI_STARTPROC
32 FRAME
330: LOCK_PREFIX
34 READ_LOCK_SIZE(inc) (%__lock_ptr)
351: rep; nop
36 READ_LOCK_SIZE(cmp) $1, (%__lock_ptr)
37 js 1b
38 LOCK_PREFIX
39 READ_LOCK_SIZE(dec) (%__lock_ptr)
40 js 0b
41 ENDFRAME
42 ret
43 CFI_ENDPROC
44END(__read_lock_failed)
diff --git a/arch/x86/lib/rwlock_64.S b/arch/x86/lib/rwlock_64.S
deleted file mode 100644
index 05ea55f71405..000000000000
--- a/arch/x86/lib/rwlock_64.S
+++ /dev/null
@@ -1,38 +0,0 @@
1/* Slow paths of read/write spinlocks. */
2
3#include <linux/linkage.h>
4#include <asm/rwlock.h>
5#include <asm/alternative-asm.h>
6#include <asm/dwarf2.h>
7
8/* rdi: pointer to rwlock_t */
9ENTRY(__write_lock_failed)
10 CFI_STARTPROC
11 LOCK_PREFIX
12 addl $RW_LOCK_BIAS,(%rdi)
131: rep
14 nop
15 cmpl $RW_LOCK_BIAS,(%rdi)
16 jne 1b
17 LOCK_PREFIX
18 subl $RW_LOCK_BIAS,(%rdi)
19 jnz __write_lock_failed
20 ret
21 CFI_ENDPROC
22END(__write_lock_failed)
23
24/* rdi: pointer to rwlock_t */
25ENTRY(__read_lock_failed)
26 CFI_STARTPROC
27 LOCK_PREFIX
28 incl (%rdi)
291: rep
30 nop
31 cmpl $1,(%rdi)
32 js 1b
33 LOCK_PREFIX
34 decl (%rdi)
35 js __read_lock_failed
36 ret
37 CFI_ENDPROC
38END(__read_lock_failed)
diff --git a/arch/x86/lib/rwsem_64.S b/arch/x86/lib/rwsem.S
index 67743977398b..5dff5f042468 100644
--- a/arch/x86/lib/rwsem_64.S
+++ b/arch/x86/lib/rwsem.S
@@ -1,4 +1,51 @@
1/* 1/*
2 * x86 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/linkage.h>
17#include <asm/alternative-asm.h>
18#include <asm/dwarf2.h>
19
20#define __ASM_HALF_REG(reg) __ASM_SEL(reg, e##reg)
21#define __ASM_HALF_SIZE(inst) __ASM_SEL(inst##w, inst##l)
22
23#ifdef CONFIG_X86_32
24
25/*
26 * The semaphore operations have a special calling sequence that
27 * allow us to do a simpler in-line version of them. These routines
28 * need to convert that sequence back into the C sequence when
29 * there is contention on the semaphore.
30 *
31 * %eax contains the semaphore pointer on entry. Save the C-clobbered
32 * registers (%eax, %edx and %ecx) except %eax whish is either a return
33 * value or just clobbered..
34 */
35
36#define save_common_regs \
37 pushl_cfi %ecx; CFI_REL_OFFSET ecx, 0
38
39#define restore_common_regs \
40 popl_cfi %ecx; CFI_RESTORE ecx
41
42 /* Avoid uglifying the argument copying x86-64 needs to do. */
43 .macro movq src, dst
44 .endm
45
46#else
47
48/*
2 * x86-64 rwsem wrappers 49 * x86-64 rwsem wrappers
3 * 50 *
4 * This interfaces the inline asm code to the slow-path 51 * This interfaces the inline asm code to the slow-path
@@ -16,12 +63,6 @@
16 * but %rdi, %rsi, %rcx, %r8-r11 always need saving. 63 * but %rdi, %rsi, %rcx, %r8-r11 always need saving.
17 */ 64 */
18 65
19#include <linux/linkage.h>
20#include <asm/rwlock.h>
21#include <asm/alternative-asm.h>
22#include <asm/frame.h>
23#include <asm/dwarf2.h>
24
25#define save_common_regs \ 66#define save_common_regs \
26 pushq_cfi %rdi; CFI_REL_OFFSET rdi, 0; \ 67 pushq_cfi %rdi; CFI_REL_OFFSET rdi, 0; \
27 pushq_cfi %rsi; CFI_REL_OFFSET rsi, 0; \ 68 pushq_cfi %rsi; CFI_REL_OFFSET rsi, 0; \
@@ -40,16 +81,18 @@
40 popq_cfi %rsi; CFI_RESTORE rsi; \ 81 popq_cfi %rsi; CFI_RESTORE rsi; \
41 popq_cfi %rdi; CFI_RESTORE rdi 82 popq_cfi %rdi; CFI_RESTORE rdi
42 83
84#endif
85
43/* Fix up special calling conventions */ 86/* Fix up special calling conventions */
44ENTRY(call_rwsem_down_read_failed) 87ENTRY(call_rwsem_down_read_failed)
45 CFI_STARTPROC 88 CFI_STARTPROC
46 save_common_regs 89 save_common_regs
47 pushq_cfi %rdx 90 __ASM_SIZE(push,_cfi) %__ASM_REG(dx)
48 CFI_REL_OFFSET rdx, 0 91 CFI_REL_OFFSET __ASM_REG(dx), 0
49 movq %rax,%rdi 92 movq %rax,%rdi
50 call rwsem_down_read_failed 93 call rwsem_down_read_failed
51 popq_cfi %rdx 94 __ASM_SIZE(pop,_cfi) %__ASM_REG(dx)
52 CFI_RESTORE rdx 95 CFI_RESTORE __ASM_REG(dx)
53 restore_common_regs 96 restore_common_regs
54 ret 97 ret
55 CFI_ENDPROC 98 CFI_ENDPROC
@@ -67,7 +110,8 @@ ENDPROC(call_rwsem_down_write_failed)
67 110
68ENTRY(call_rwsem_wake) 111ENTRY(call_rwsem_wake)
69 CFI_STARTPROC 112 CFI_STARTPROC
70 decl %edx /* do nothing if still outstanding active readers */ 113 /* do nothing if still outstanding active readers */
114 __ASM_HALF_SIZE(dec) %__ASM_HALF_REG(dx)
71 jnz 1f 115 jnz 1f
72 save_common_regs 116 save_common_regs
73 movq %rax,%rdi 117 movq %rax,%rdi
@@ -77,16 +121,15 @@ ENTRY(call_rwsem_wake)
77 CFI_ENDPROC 121 CFI_ENDPROC
78ENDPROC(call_rwsem_wake) 122ENDPROC(call_rwsem_wake)
79 123
80/* Fix up special calling conventions */
81ENTRY(call_rwsem_downgrade_wake) 124ENTRY(call_rwsem_downgrade_wake)
82 CFI_STARTPROC 125 CFI_STARTPROC
83 save_common_regs 126 save_common_regs
84 pushq_cfi %rdx 127 __ASM_SIZE(push,_cfi) %__ASM_REG(dx)
85 CFI_REL_OFFSET rdx, 0 128 CFI_REL_OFFSET __ASM_REG(dx), 0
86 movq %rax,%rdi 129 movq %rax,%rdi
87 call rwsem_downgrade_wake 130 call rwsem_downgrade_wake
88 popq_cfi %rdx 131 __ASM_SIZE(pop,_cfi) %__ASM_REG(dx)
89 CFI_RESTORE rdx 132 CFI_RESTORE __ASM_REG(dx)
90 restore_common_regs 133 restore_common_regs
91 ret 134 ret
92 CFI_ENDPROC 135 CFI_ENDPROC
diff --git a/arch/x86/lib/semaphore_32.S b/arch/x86/lib/semaphore_32.S
deleted file mode 100644
index 06691daa4108..000000000000
--- a/arch/x86/lib/semaphore_32.S
+++ /dev/null
@@ -1,124 +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
16#include <linux/linkage.h>
17#include <asm/rwlock.h>
18#include <asm/alternative-asm.h>
19#include <asm/frame.h>
20#include <asm/dwarf2.h>
21
22/*
23 * The semaphore operations have a special calling sequence that
24 * allow us to do a simpler in-line version of them. These routines
25 * need to convert that sequence back into the C sequence when
26 * there is contention on the semaphore.
27 *
28 * %eax contains the semaphore pointer on entry. Save the C-clobbered
29 * registers (%eax, %edx and %ecx) except %eax whish is either a return
30 * value or just clobbered..
31 */
32 .section .sched.text, "ax"
33
34/*
35 * rw spinlock fallbacks
36 */
37#ifdef CONFIG_SMP
38ENTRY(__write_lock_failed)
39 CFI_STARTPROC
40 FRAME
412: LOCK_PREFIX
42 addl $ RW_LOCK_BIAS,(%eax)
431: rep; nop
44 cmpl $ RW_LOCK_BIAS,(%eax)
45 jne 1b
46 LOCK_PREFIX
47 subl $ RW_LOCK_BIAS,(%eax)
48 jnz 2b
49 ENDFRAME
50 ret
51 CFI_ENDPROC
52 ENDPROC(__write_lock_failed)
53
54ENTRY(__read_lock_failed)
55 CFI_STARTPROC
56 FRAME
572: LOCK_PREFIX
58 incl (%eax)
591: rep; nop
60 cmpl $1,(%eax)
61 js 1b
62 LOCK_PREFIX
63 decl (%eax)
64 js 2b
65 ENDFRAME
66 ret
67 CFI_ENDPROC
68 ENDPROC(__read_lock_failed)
69
70#endif
71
72#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
73
74/* Fix up special calling conventions */
75ENTRY(call_rwsem_down_read_failed)
76 CFI_STARTPROC
77 pushl_cfi %ecx
78 CFI_REL_OFFSET ecx,0
79 pushl_cfi %edx
80 CFI_REL_OFFSET edx,0
81 call rwsem_down_read_failed
82 popl_cfi %edx
83 popl_cfi %ecx
84 ret
85 CFI_ENDPROC
86 ENDPROC(call_rwsem_down_read_failed)
87
88ENTRY(call_rwsem_down_write_failed)
89 CFI_STARTPROC
90 pushl_cfi %ecx
91 CFI_REL_OFFSET ecx,0
92 calll rwsem_down_write_failed
93 popl_cfi %ecx
94 ret
95 CFI_ENDPROC
96 ENDPROC(call_rwsem_down_write_failed)
97
98ENTRY(call_rwsem_wake)
99 CFI_STARTPROC
100 decw %dx /* do nothing if still outstanding active readers */
101 jnz 1f
102 pushl_cfi %ecx
103 CFI_REL_OFFSET ecx,0
104 call rwsem_wake
105 popl_cfi %ecx
1061: ret
107 CFI_ENDPROC
108 ENDPROC(call_rwsem_wake)
109
110/* Fix up special calling conventions */
111ENTRY(call_rwsem_downgrade_wake)
112 CFI_STARTPROC
113 pushl_cfi %ecx
114 CFI_REL_OFFSET ecx,0
115 pushl_cfi %edx
116 CFI_REL_OFFSET edx,0
117 call rwsem_downgrade_wake
118 popl_cfi %edx
119 popl_cfi %ecx
120 ret
121 CFI_ENDPROC
122 ENDPROC(call_rwsem_downgrade_wake)
123
124#endif
diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S
index 782b082c9ff7..a63efd6bb6a5 100644
--- a/arch/x86/lib/thunk_64.S
+++ b/arch/x86/lib/thunk_64.S
@@ -5,50 +5,41 @@
5 * Added trace_hardirqs callers - Copyright 2007 Steven Rostedt, Red Hat, Inc. 5 * Added trace_hardirqs callers - Copyright 2007 Steven Rostedt, Red Hat, Inc.
6 * Subject to the GNU public license, v.2. No warranty of any kind. 6 * Subject to the GNU public license, v.2. No warranty of any kind.
7 */ 7 */
8#include <linux/linkage.h>
9#include <asm/dwarf2.h>
10#include <asm/calling.h>
8 11
9 #include <linux/linkage.h> 12 /* rdi: arg1 ... normal C conventions. rax is saved/restored. */
10 #include <asm/dwarf2.h> 13 .macro THUNK name, func, put_ret_addr_in_rdi=0
11 #include <asm/calling.h>
12 #include <asm/rwlock.h>
13
14 /* rdi: arg1 ... normal C conventions. rax is saved/restored. */
15 .macro thunk name,func
16 .globl \name
17\name:
18 CFI_STARTPROC
19 SAVE_ARGS
20 call \func
21 jmp restore
22 CFI_ENDPROC
23 .endm
24
25#ifdef CONFIG_TRACE_IRQFLAGS
26 /* put return address in rdi (arg1) */
27 .macro thunk_ra name,func
28 .globl \name 14 .globl \name
29\name: 15\name:
30 CFI_STARTPROC 16 CFI_STARTPROC
17
18 /* this one pushes 9 elems, the next one would be %rIP */
31 SAVE_ARGS 19 SAVE_ARGS
32 /* SAVE_ARGS pushs 9 elements */ 20
33 /* the next element would be the rip */ 21 .if \put_ret_addr_in_rdi
34 movq 9*8(%rsp), %rdi 22 movq_cfi_restore 9*8, rdi
23 .endif
24
35 call \func 25 call \func
36 jmp restore 26 jmp restore
37 CFI_ENDPROC 27 CFI_ENDPROC
38 .endm 28 .endm
39 29
40 thunk_ra trace_hardirqs_on_thunk,trace_hardirqs_on_caller 30#ifdef CONFIG_TRACE_IRQFLAGS
41 thunk_ra trace_hardirqs_off_thunk,trace_hardirqs_off_caller 31 THUNK trace_hardirqs_on_thunk,trace_hardirqs_on_caller,1
32 THUNK trace_hardirqs_off_thunk,trace_hardirqs_off_caller,1
42#endif 33#endif
43 34
44#ifdef CONFIG_DEBUG_LOCK_ALLOC 35#ifdef CONFIG_DEBUG_LOCK_ALLOC
45 thunk lockdep_sys_exit_thunk,lockdep_sys_exit 36 THUNK lockdep_sys_exit_thunk,lockdep_sys_exit
46#endif 37#endif
47 38
48 /* SAVE_ARGS below is used only for the .cfi directives it contains. */ 39 /* SAVE_ARGS below is used only for the .cfi directives it contains. */
49 CFI_STARTPROC 40 CFI_STARTPROC
50 SAVE_ARGS 41 SAVE_ARGS
51restore: 42restore:
52 RESTORE_ARGS 43 RESTORE_ARGS
53 ret 44 ret
54 CFI_ENDPROC 45 CFI_ENDPROC