Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/lib/semaphore_32.S
10818 views
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 <[email protected]>
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
38
ENTRY(__write_lock_failed)
39
CFI_STARTPROC
40
FRAME
41
2: LOCK_PREFIX
42
addl $ RW_LOCK_BIAS,(%eax)
43
1: 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
54
ENTRY(__read_lock_failed)
55
CFI_STARTPROC
56
FRAME
57
2: LOCK_PREFIX
58
incl (%eax)
59
1: 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 */
75
ENTRY(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
88
ENTRY(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
98
ENTRY(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
106
1: ret
107
CFI_ENDPROC
108
ENDPROC(call_rwsem_wake)
109
110
/* Fix up special calling conventions */
111
ENTRY(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
125
126