162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <linux/linkage.h> 462306a36Sopenharmony_ci#include <asm/export.h> 562306a36Sopenharmony_ci#include <asm/percpu.h> 662306a36Sopenharmony_ci#include <asm/processor-flags.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci.text 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef CONFIG_X86_CMPXCHG64 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* 1362306a36Sopenharmony_ci * Emulate 'cmpxchg8b (%esi)' on UP 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * Inputs: 1662306a36Sopenharmony_ci * %esi : memory location to compare 1762306a36Sopenharmony_ci * %eax : low 32 bits of old value 1862306a36Sopenharmony_ci * %edx : high 32 bits of old value 1962306a36Sopenharmony_ci * %ebx : low 32 bits of new value 2062306a36Sopenharmony_ci * %ecx : high 32 bits of new value 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ciSYM_FUNC_START(cmpxchg8b_emu) 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci pushfl 2562306a36Sopenharmony_ci cli 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci cmpl 0(%esi), %eax 2862306a36Sopenharmony_ci jne .Lnot_same 2962306a36Sopenharmony_ci cmpl 4(%esi), %edx 3062306a36Sopenharmony_ci jne .Lnot_same 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci movl %ebx, 0(%esi) 3362306a36Sopenharmony_ci movl %ecx, 4(%esi) 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci orl $X86_EFLAGS_ZF, (%esp) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci popfl 3862306a36Sopenharmony_ci RET 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci.Lnot_same: 4162306a36Sopenharmony_ci movl 0(%esi), %eax 4262306a36Sopenharmony_ci movl 4(%esi), %edx 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci andl $(~X86_EFLAGS_ZF), (%esp) 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci popfl 4762306a36Sopenharmony_ci RET 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ciSYM_FUNC_END(cmpxchg8b_emu) 5062306a36Sopenharmony_ciEXPORT_SYMBOL(cmpxchg8b_emu) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#endif 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#ifndef CONFIG_UML 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciSYM_FUNC_START(this_cpu_cmpxchg8b_emu) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci pushfl 5962306a36Sopenharmony_ci cli 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci cmpl PER_CPU_VAR(0(%esi)), %eax 6262306a36Sopenharmony_ci jne .Lnot_same2 6362306a36Sopenharmony_ci cmpl PER_CPU_VAR(4(%esi)), %edx 6462306a36Sopenharmony_ci jne .Lnot_same2 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci movl %ebx, PER_CPU_VAR(0(%esi)) 6762306a36Sopenharmony_ci movl %ecx, PER_CPU_VAR(4(%esi)) 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci orl $X86_EFLAGS_ZF, (%esp) 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci popfl 7262306a36Sopenharmony_ci RET 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci.Lnot_same2: 7562306a36Sopenharmony_ci movl PER_CPU_VAR(0(%esi)), %eax 7662306a36Sopenharmony_ci movl PER_CPU_VAR(4(%esi)), %edx 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci andl $(~X86_EFLAGS_ZF), (%esp) 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci popfl 8162306a36Sopenharmony_ci RET 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ciSYM_FUNC_END(this_cpu_cmpxchg8b_emu) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#endif 86