0001
0002 #include <linux/linkage.h>
0003 #include <asm/percpu.h>
0004
0005 .text
0006
0007
0008
0009
0010
0011
0012
0013
0014
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)