1/* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; version 2 5 * of the License. 6 * 7 */ 8#include <linux/linkage.h> 9#include <asm/dwarf2.h> 10#include <asm/percpu.h> 11 12.text 13 14/* 15 * Inputs: 16 * %rsi : memory location to compare 17 * %rax : low 64 bits of old value 18 * %rdx : high 64 bits of old value 19 * %rbx : low 64 bits of new value 20 * %rcx : high 64 bits of new value 21 * %al : Operation successful 22 */ 23ENTRY(this_cpu_cmpxchg16b_emu) 24CFI_STARTPROC 25 26# 27# Emulate 'cmpxchg16b %gs:(%rsi)' except we return the result in %al not 28# via the ZF. Caller will access %al to get result. 29# 30# Note that this is only useful for a cpuops operation. Meaning that we 31# do *not* have a fully atomic operation but just an operation that is 32# *atomic* on a single cpu (as provided by the this_cpu_xx class of 33# macros). 34# 35 pushfq_cfi 36 cli 37 38 cmpq PER_CPU_VAR((%rsi)), %rax 39 jne .Lnot_same 40 cmpq PER_CPU_VAR(8(%rsi)), %rdx 41 jne .Lnot_same 42 43 movq %rbx, PER_CPU_VAR((%rsi)) 44 movq %rcx, PER_CPU_VAR(8(%rsi)) 45 46 CFI_REMEMBER_STATE 47 popfq_cfi 48 mov $1, %al 49 ret 50 51 CFI_RESTORE_STATE 52.Lnot_same: 53 popfq_cfi 54 xor %al,%al 55 ret 56 57CFI_ENDPROC 58 59ENDPROC(this_cpu_cmpxchg16b_emu) 60