Commit | Line | Data |
---|---|---|
b886d83c | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
79e1dd05 | 2 | |
94ea9c05 | 3 | #include <linux/export.h> |
79e1dd05 | 4 | #include <linux/linkage.h> |
6d12c8d3 PZ |
5 | #include <asm/percpu.h> |
6 | #include <asm/processor-flags.h> | |
79e1dd05 | 7 | |
79e1dd05 AV |
8 | .text |
9 | ||
6d12c8d3 PZ |
10 | #ifndef CONFIG_X86_CMPXCHG64 |
11 | ||
79e1dd05 | 12 | /* |
6d12c8d3 PZ |
13 | * Emulate 'cmpxchg8b (%esi)' on UP |
14 | * | |
79e1dd05 AV |
15 | * Inputs: |
16 | * %esi : memory location to compare | |
17 | * %eax : low 32 bits of old value | |
18 | * %edx : high 32 bits of old value | |
19 | * %ebx : low 32 bits of new value | |
20 | * %ecx : high 32 bits of new value | |
21 | */ | |
6dcc5627 | 22 | SYM_FUNC_START(cmpxchg8b_emu) |
79e1dd05 | 23 | |
131484c8 | 24 | pushfl |
79e1dd05 AV |
25 | cli |
26 | ||
59bec00a | 27 | cmpl (%esi), %eax |
6d12c8d3 PZ |
28 | jne .Lnot_same |
29 | cmpl 4(%esi), %edx | |
30 | jne .Lnot_same | |
31 | ||
59bec00a | 32 | movl %ebx, (%esi) |
6d12c8d3 | 33 | movl %ecx, 4(%esi) |
79e1dd05 | 34 | |
6d12c8d3 | 35 | orl $X86_EFLAGS_ZF, (%esp) |
79e1dd05 | 36 | |
131484c8 | 37 | popfl |
f94909ce | 38 | RET |
79e1dd05 | 39 | |
5f1d919a | 40 | .Lnot_same: |
59bec00a | 41 | movl (%esi), %eax |
6d12c8d3 PZ |
42 | movl 4(%esi), %edx |
43 | ||
44 | andl $(~X86_EFLAGS_ZF), (%esp) | |
79e1dd05 | 45 | |
131484c8 | 46 | popfl |
f94909ce | 47 | RET |
79e1dd05 | 48 | |
6dcc5627 | 49 | SYM_FUNC_END(cmpxchg8b_emu) |
784d5699 | 50 | EXPORT_SYMBOL(cmpxchg8b_emu) |
6d12c8d3 PZ |
51 | |
52 | #endif | |
53 | ||
54 | #ifndef CONFIG_UML | |
55 | ||
59bec00a UB |
56 | /* |
57 | * Emulate 'cmpxchg8b %fs:(%rsi)' | |
58 | * | |
59 | * Inputs: | |
60 | * %esi : memory location to compare | |
61 | * %eax : low 32 bits of old value | |
62 | * %edx : high 32 bits of old value | |
63 | * %ebx : low 32 bits of new value | |
64 | * %ecx : high 32 bits of new value | |
65 | * | |
66 | * Notably this is not LOCK prefixed and is not safe against NMIs | |
67 | */ | |
6d12c8d3 PZ |
68 | SYM_FUNC_START(this_cpu_cmpxchg8b_emu) |
69 | ||
70 | pushfl | |
71 | cli | |
72 | ||
59bec00a | 73 | cmpl __percpu (%esi), %eax |
6d12c8d3 | 74 | jne .Lnot_same2 |
59bec00a | 75 | cmpl __percpu 4(%esi), %edx |
6d12c8d3 PZ |
76 | jne .Lnot_same2 |
77 | ||
59bec00a UB |
78 | movl %ebx, __percpu (%esi) |
79 | movl %ecx, __percpu 4(%esi) | |
6d12c8d3 PZ |
80 | |
81 | orl $X86_EFLAGS_ZF, (%esp) | |
82 | ||
83 | popfl | |
84 | RET | |
85 | ||
86 | .Lnot_same2: | |
59bec00a UB |
87 | movl __percpu (%esi), %eax |
88 | movl __percpu 4(%esi), %edx | |
6d12c8d3 PZ |
89 | |
90 | andl $(~X86_EFLAGS_ZF), (%esp) | |
91 | ||
92 | popfl | |
93 | RET | |
94 | ||
95 | SYM_FUNC_END(this_cpu_cmpxchg8b_emu) | |
96 | ||
97 | #endif |