Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 #include <linux/linkage.h>
0003 #include <asm/percpu.h>
0004 
0005 .text
0006 
0007 /*
0008  * Inputs:
0009  * %rsi : memory location to compare
0010  * %rax : low 64 bits of old value
0011  * %rdx : high 64 bits of old value
0012  * %rbx : low 64 bits of new value
0013  * %rcx : high 64 bits of new value
0014  * %al  : Operation successful
0015  */
0016 SYM_FUNC_START(this_cpu_cmpxchg16b_emu)
0017 
0018 #
0019 # Emulate 'cmpxchg16b %gs:(%rsi)' except we return the result in %al not
0020 # via the ZF.  Caller will access %al to get result.
0021 #
0022 # Note that this is only useful for a cpuops operation.  Meaning that we
0023 # do *not* have a fully atomic operation but just an operation that is
0024 # *atomic* on a single cpu (as provided by the this_cpu_xx class of
0025 # macros).
0026 #
0027     pushfq
0028     cli
0029 
0030     cmpq PER_CPU_VAR((%rsi)), %rax
0031     jne .Lnot_same
0032     cmpq PER_CPU_VAR(8(%rsi)), %rdx
0033     jne .Lnot_same
0034 
0035     movq %rbx, PER_CPU_VAR((%rsi))
0036     movq %rcx, PER_CPU_VAR(8(%rsi))
0037 
0038     popfq
0039     mov $1, %al
0040     RET
0041 
0042 .Lnot_same:
0043     popfq
0044     xor %al,%al
0045     RET
0046 
0047 SYM_FUNC_END(this_cpu_cmpxchg16b_emu)