accel/amdxdna: use modern PM helpers
[drm/drm-misc.git] / arch / x86 / lib / cmpxchg16b_emu.S
blob4fb44894ad87593266f9de2b8c71ddbad2166cbe
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #include <linux/linkage.h>
3 #include <asm/percpu.h>
4 #include <asm/processor-flags.h>
6 .text
8 /*
9  * Emulate 'cmpxchg16b %gs:(%rsi)'
10  *
11  * Inputs:
12  * %rsi : memory location to compare
13  * %rax : low 64 bits of old value
14  * %rdx : high 64 bits of old value
15  * %rbx : low 64 bits of new value
16  * %rcx : high 64 bits of new value
17  *
18  * Notably this is not LOCK prefixed and is not safe against NMIs
19  */
20 SYM_FUNC_START(this_cpu_cmpxchg16b_emu)
22         pushfq
23         cli
25         /* if (*ptr == old) */
26         cmpq    __percpu (%rsi), %rax
27         jne     .Lnot_same
28         cmpq    __percpu 8(%rsi), %rdx
29         jne     .Lnot_same
31         /* *ptr = new */
32         movq    %rbx, __percpu (%rsi)
33         movq    %rcx, __percpu 8(%rsi)
35         /* set ZF in EFLAGS to indicate success */
36         orl     $X86_EFLAGS_ZF, (%rsp)
38         popfq
39         RET
41 .Lnot_same:
42         /* *ptr != old */
44         /* old = *ptr */
45         movq    __percpu (%rsi), %rax
46         movq    __percpu 8(%rsi), %rdx
48         /* clear ZF in EFLAGS to indicate failure */
49         andl    $(~X86_EFLAGS_ZF), (%rsp)
51         popfq
52         RET
54 SYM_FUNC_END(this_cpu_cmpxchg16b_emu)