Hi, This patch implements this_cpu_cmpxchg16b_emu() for UML. As I'm not an amd64 assembly guru I'm not sure whether the assembly part is correct. Can someone please review it?
Especially I'm unsure which register have to be saved before each call to C functions. Thanks, //richard >From 202b0efe024d7c0500e7c11f0aa105f7a1fafb9b Mon Sep 17 00:00:00 2001 From: Richard Weinberger <rich...@nod.at> Date: Mon, 11 Apr 2011 19:22:38 +0200 Subject: [PATCH] um: Implement this_cpu_cmpxchg16b_emu() Commit 8a5ec0ba "Lockless (and preemptless) fastpaths for slub" makes use of this_cpu_cmpxchg_double() which needs this_cpu_cmpxchg16b_emu() on x86_64. User Mode Linux has to serve this function too. Reported-by: Sergei Trofimovich <sly...@gmail.com> Signed-off-by: Richard Weinberger <rich...@nod.at> --- arch/um/sys-x86_64/Makefile | 2 +- arch/um/sys-x86_64/cmpxchg16b_emu.S | 72 ++++++++++++++++++++++++++++++++ arch/um/sys-x86_64/cmpxchg16b_helper.c | 22 ++++++++++ 3 files changed, 95 insertions(+), 1 deletions(-) create mode 100644 arch/um/sys-x86_64/cmpxchg16b_emu.S create mode 100644 arch/um/sys-x86_64/cmpxchg16b_helper.c diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index c1ea9eb..9a66afe 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -6,7 +6,7 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ - sysrq.o ksyms.o tls.o + sysrq.o ksyms.o tls.o cmpxchg16b_emu.o cmpxchg16b_helper.o subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ lib/rwsem_64.o diff --git a/arch/um/sys-x86_64/cmpxchg16b_emu.S b/arch/um/sys-x86_64/cmpxchg16b_emu.S new file mode 100644 index 0000000..170b6fa --- /dev/null +++ b/arch/um/sys-x86_64/cmpxchg16b_emu.S @@ -0,0 +1,72 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * Copyright 2011 Richard Weinberger <rich...@nod.at> + * Mostly copied from arch/x86/lib/cmpxchg16b_emu.S + * + */ +#include <linux/linkage.h> +#include <asm/alternative-asm.h> +#include <asm/frame.h> +#include <asm/dwarf2.h> + +.text + +/* + * Inputs: + * %rsi : memory location to compare + * %rax : low 64 bits of old value + * %rdx : high 64 bits of old value + * %rbx : low 64 bits of new value + * %rcx : high 64 bits of new value + * %al : Operation successful + */ +ENTRY(this_cpu_cmpxchg16b_emu) +CFI_STARTPROC + +# +# Emulate 'cmpxchg16b %gs:(%rsi)' except we return the result in %al not +# via the ZF. Caller will access %al to get result. +# +# Note that this is only useful for a cpuops operation. Meaning that we +# do *not* have a fully atomic operation but just an operation that is +# *atomic* on a single cpu (as provided by the this_cpu_xx class of +# macros). +# +this_cpu_cmpxchg16b_emu: + pushq %rdi + pushq %rax + pushq %rdx + call arch_local_irq_save_asm + movq %rax, %rdi + popq %rdx + popq %rax + + cmpq (%rsi), %rax + jne not_same + cmpq 8(%rsi), %rdx + jne not_same + + movq %rbx, (%rsi) + movq %rcx, 8(%rsi) + + mov $1, %al + jmp out + + not_same: + xor %al,%al + + out: + pushq %rax + pushq %rdx + call arch_local_irq_restore_asm + popq %rdx + popq %rax + popq %rdi + ret +CFI_ENDPROC + +ENDPROC(this_cpu_cmpxchg16b_emu) diff --git a/arch/um/sys-x86_64/cmpxchg16b_helper.c b/arch/um/sys-x86_64/cmpxchg16b_helper.c new file mode 100644 index 0000000..b7e665c --- /dev/null +++ b/arch/um/sys-x86_64/cmpxchg16b_helper.c @@ -0,0 +1,22 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * Copyright 2011 Richard Weinberger <rich...@nod.at> + * + */ + +#include <linux/linkage.h> +#include <asm/system.h> + +asmlinkage unsigned long arch_local_irq_save_asm(void) +{ + return arch_local_irq_save(); +} + +asmlinkage void arch_local_irq_restore_asm(unsigned long flags) +{ + arch_local_irq_restore(flags); +} -- 1.7.4.2 ------------------------------------------------------------------------------ Forrester Wave Report - Recovery time is now measured in hours and minutes not days. Key insights are discussed in the 2010 Forrester Wave Report as part of an in-depth evaluation of disaster recovery service providers. Forrester found the best-in-class provider in terms of services and vision. Read this report now! http://p.sf.net/sfu/ibm-webcastpromo _______________________________________________ User-mode-linux-devel mailing list User-mode-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel