1/* SPDX-License-Identifier: GPL-2.0-only */ 2 3#include <linux/export.h> 4#include <linux/linkage.h> 5#include <asm/percpu.h> 6#include <asm/processor-flags.h> 7 8.text 9 10#ifndef CONFIG_X86_CMPXCHG64 11 12/* 13 * Emulate 'cmpxchg8b (%esi)' on UP 14 * 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 */ 22SYM_FUNC_START(cmpxchg8b_emu) 23 24 pushfl 25 cli 26 27 cmpl (%esi), %eax 28 jne .Lnot_same 29 cmpl 4(%esi), %edx 30 jne .Lnot_same 31 32 movl %ebx, (%esi) 33 movl %ecx, 4(%esi) 34 35 orl $X86_EFLAGS_ZF, (%esp) 36 37 popfl 38 RET 39 40.Lnot_same: 41 movl (%esi), %eax 42 movl 4(%esi), %edx 43 44 andl $(~X86_EFLAGS_ZF), (%esp) 45 46 popfl 47 RET 48 49SYM_FUNC_END(cmpxchg8b_emu) 50EXPORT_SYMBOL(cmpxchg8b_emu) 51 52#endif 53 54#ifndef CONFIG_UML 55 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 */ 68SYM_FUNC_START(this_cpu_cmpxchg8b_emu) 69 70 pushfl 71 cli 72 73 cmpl __percpu (%esi), %eax 74 jne .Lnot_same2 75 cmpl __percpu 4(%esi), %edx 76 jne .Lnot_same2 77 78 movl %ebx, __percpu (%esi) 79 movl %ecx, __percpu 4(%esi) 80 81 orl $X86_EFLAGS_ZF, (%esp) 82 83 popfl 84 RET 85 86.Lnot_same2: 87 movl __percpu (%esi), %eax 88 movl __percpu 4(%esi), %edx 89 90 andl $(~X86_EFLAGS_ZF), (%esp) 91 92 popfl 93 RET 94 95SYM_FUNC_END(this_cpu_cmpxchg8b_emu) 96 97#endif 98