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 0(%esi), %eax 28 jne .Lnot_same 29 cmpl 4(%esi), %edx 30 jne .Lnot_same 31 32 movl %ebx, 0(%esi) 33 movl %ecx, 4(%esi) 34 35 orl $X86_EFLAGS_ZF, (%esp) 36 37 popfl 38 RET 39 40.Lnot_same: 41 movl 0(%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 56SYM_FUNC_START(this_cpu_cmpxchg8b_emu) 57 58 pushfl 59 cli 60 61 cmpl PER_CPU_VAR(0(%esi)), %eax 62 jne .Lnot_same2 63 cmpl PER_CPU_VAR(4(%esi)), %edx 64 jne .Lnot_same2 65 66 movl %ebx, PER_CPU_VAR(0(%esi)) 67 movl %ecx, PER_CPU_VAR(4(%esi)) 68 69 orl $X86_EFLAGS_ZF, (%esp) 70 71 popfl 72 RET 73 74.Lnot_same2: 75 movl PER_CPU_VAR(0(%esi)), %eax 76 movl PER_CPU_VAR(4(%esi)), %edx 77 78 andl $(~X86_EFLAGS_ZF), (%esp) 79 80 popfl 81 RET 82 83SYM_FUNC_END(this_cpu_cmpxchg8b_emu) 84 85#endif 86