blob: 67743977398b6485286aaedad76e9b24e4e54230 [file] [log] [blame]
Linus Torvaldsbafaecd2010-01-12 18:16:42 -08001/*
2 * x86-64 rwsem wrappers
3 *
4 * This interfaces the inline asm code to the slow-path
5 * C routines. We need to save the call-clobbered regs
6 * that the asm does not mark as clobbered, and move the
7 * argument from %rax to %rdi.
8 *
9 * NOTE! We don't need to save %rax, because the functions
10 * will always return the semaphore pointer in %rax (which
11 * is also the input argument to these helpers)
12 *
13 * The following can clobber %rdx because the asm clobbers it:
14 * call_rwsem_down_write_failed
15 * call_rwsem_wake
16 * but %rdi, %rsi, %rcx, %r8-r11 always need saving.
17 */
18
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 \
Jan Beulich39f22052011-02-28 15:31:59 +000026 pushq_cfi %rdi; CFI_REL_OFFSET rdi, 0; \
27 pushq_cfi %rsi; CFI_REL_OFFSET rsi, 0; \
28 pushq_cfi %rcx; CFI_REL_OFFSET rcx, 0; \
29 pushq_cfi %r8; CFI_REL_OFFSET r8, 0; \
30 pushq_cfi %r9; CFI_REL_OFFSET r9, 0; \
31 pushq_cfi %r10; CFI_REL_OFFSET r10, 0; \
32 pushq_cfi %r11; CFI_REL_OFFSET r11, 0
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080033
34#define restore_common_regs \
Jan Beulich39f22052011-02-28 15:31:59 +000035 popq_cfi %r11; CFI_RESTORE r11; \
36 popq_cfi %r10; CFI_RESTORE r10; \
37 popq_cfi %r9; CFI_RESTORE r9; \
38 popq_cfi %r8; CFI_RESTORE r8; \
39 popq_cfi %rcx; CFI_RESTORE rcx; \
40 popq_cfi %rsi; CFI_RESTORE rsi; \
41 popq_cfi %rdi; CFI_RESTORE rdi
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080042
43/* Fix up special calling conventions */
44ENTRY(call_rwsem_down_read_failed)
Jan Beulich39f22052011-02-28 15:31:59 +000045 CFI_STARTPROC
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080046 save_common_regs
Jan Beulich39f22052011-02-28 15:31:59 +000047 pushq_cfi %rdx
48 CFI_REL_OFFSET rdx, 0
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080049 movq %rax,%rdi
50 call rwsem_down_read_failed
Jan Beulich39f22052011-02-28 15:31:59 +000051 popq_cfi %rdx
52 CFI_RESTORE rdx
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080053 restore_common_regs
54 ret
Jan Beulich39f22052011-02-28 15:31:59 +000055 CFI_ENDPROC
56ENDPROC(call_rwsem_down_read_failed)
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080057
58ENTRY(call_rwsem_down_write_failed)
Jan Beulich39f22052011-02-28 15:31:59 +000059 CFI_STARTPROC
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080060 save_common_regs
61 movq %rax,%rdi
62 call rwsem_down_write_failed
63 restore_common_regs
64 ret
Jan Beulich39f22052011-02-28 15:31:59 +000065 CFI_ENDPROC
66ENDPROC(call_rwsem_down_write_failed)
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080067
68ENTRY(call_rwsem_wake)
Jan Beulich39f22052011-02-28 15:31:59 +000069 CFI_STARTPROC
David Howellsa66f6372010-05-04 13:42:53 +010070 decl %edx /* do nothing if still outstanding active readers */
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080071 jnz 1f
72 save_common_regs
73 movq %rax,%rdi
74 call rwsem_wake
75 restore_common_regs
761: ret
Jan Beulich39f22052011-02-28 15:31:59 +000077 CFI_ENDPROC
78ENDPROC(call_rwsem_wake)
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080079
80/* Fix up special calling conventions */
81ENTRY(call_rwsem_downgrade_wake)
Jan Beulich39f22052011-02-28 15:31:59 +000082 CFI_STARTPROC
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080083 save_common_regs
Jan Beulich39f22052011-02-28 15:31:59 +000084 pushq_cfi %rdx
85 CFI_REL_OFFSET rdx, 0
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080086 movq %rax,%rdi
87 call rwsem_downgrade_wake
Jan Beulich39f22052011-02-28 15:31:59 +000088 popq_cfi %rdx
89 CFI_RESTORE rdx
Linus Torvaldsbafaecd2010-01-12 18:16:42 -080090 restore_common_regs
91 ret
Jan Beulich39f22052011-02-28 15:31:59 +000092 CFI_ENDPROC
93ENDPROC(call_rwsem_downgrade_wake)