1/* 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 \ 26 pushq %rdi; \ 27 pushq %rsi; \ 28 pushq %rcx; \ 29 pushq %r8; \ 30 pushq %r9; \ 31 pushq %r10; \ 32 pushq %r11 33 34#define restore_common_regs \ 35 popq %r11; \ 36 popq %r10; \ 37 popq %r9; \ 38 popq %r8; \ 39 popq %rcx; \ 40 popq %rsi; \ 41 popq %rdi 42 43/* Fix up special calling conventions */ 44ENTRY(call_rwsem_down_read_failed) 45 save_common_regs 46 pushq %rdx 47 movq %rax,%rdi 48 call rwsem_down_read_failed 49 popq %rdx 50 restore_common_regs 51 ret 52 ENDPROC(call_rwsem_down_read_failed) 53 54ENTRY(call_rwsem_down_write_failed) 55 save_common_regs 56 movq %rax,%rdi 57 call rwsem_down_write_failed 58 restore_common_regs 59 ret 60 ENDPROC(call_rwsem_down_write_failed) 61 62ENTRY(call_rwsem_wake) 63 decl %edx /* do nothing if still outstanding active readers */ 64 jnz 1f 65 save_common_regs 66 movq %rax,%rdi 67 call rwsem_wake 68 restore_common_regs 691: ret 70 ENDPROC(call_rwsem_wake) 71 72/* Fix up special calling conventions */ 73ENTRY(call_rwsem_downgrade_wake) 74 save_common_regs 75 pushq %rdx 76 movq %rax,%rdi 77 call rwsem_downgrade_wake 78 popq %rdx 79 restore_common_regs 80 ret 81 ENDPROC(call_rwsem_downgrade_wake) 82