1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <linux/export.h>
4 #include <linux/linkage.h>
5 #include <asm/percpu.h>
6 #include <asm/processor-flags.h>
10 #ifndef CONFIG_X86_CMPXCHG64
13 * Emulate 'cmpxchg8b (%esi)' on UP
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
22 SYM_FUNC_START(cmpxchg8b_emu)
35 orl $X86_EFLAGS_ZF, (%esp)
44 andl $(~X86_EFLAGS_ZF), (%esp)
49 SYM_FUNC_END(cmpxchg8b_emu)
50 EXPORT_SYMBOL(cmpxchg8b_emu)
57 * Emulate 'cmpxchg8b %fs:(%rsi)'
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
66 * Notably this is not LOCK prefixed and is not safe against NMIs
68 SYM_FUNC_START(this_cpu_cmpxchg8b_emu)
73 cmpl __percpu (%esi), %eax
75 cmpl __percpu 4(%esi), %edx
78 movl %ebx, __percpu (%esi)
79 movl %ecx, __percpu 4(%esi)
81 orl $X86_EFLAGS_ZF, (%esp)
87 movl __percpu (%esi), %eax
88 movl __percpu 4(%esi), %edx
90 andl $(~X86_EFLAGS_ZF), (%esp)
95 SYM_FUNC_END(this_cpu_cmpxchg8b_emu)