Skip to content

Commit

Permalink
Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/tip/linux-2.6-tip

* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: Fix write lock scalability 64-bit issue
  x86: Unify rwsem assembly implementation
  x86: Unify rwlock assembly implementation
  x86, asm: Fix binutils 2.16 issue with __USER32_CS
  x86, asm: Cleanup thunk_64.S
  x86, asm: Flip RESTORE_ARGS arguments logic
  x86, asm: Flip SAVE_ARGS arguments logic
  x86, asm: Thin down SAVE/RESTORE_* asm macros
  • Loading branch information
torvalds committed Jul 23, 2011
2 parents 2c9e88a + a750036 commit eb47418
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 324 deletions.
2 changes: 1 addition & 1 deletion arch/um/sys-i386/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \

obj-$(CONFIG_BINFMT_ELF) += elfcore.o

subarch-obj-y = lib/semaphore_32.o lib/string_32.o
subarch-obj-y = lib/rwsem.o lib/string_32.o
subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
subarch-obj-$(CONFIG_MODULES) += kernel/module.o

Expand Down
2 changes: 1 addition & 1 deletion arch/um/sys-x86_64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
sysrq.o ksyms.o tls.o

subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \
lib/rwsem_64.o
lib/rwsem.o
subarch-obj-$(CONFIG_MODULES) += kernel/module.o

ldt-y = ../sys-i386/ldt.o
Expand Down
10 changes: 5 additions & 5 deletions arch/x86/ia32/ia32entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ ENTRY(ia32_sysenter_target)
CFI_REL_OFFSET rip,0
pushq_cfi %rax
cld
SAVE_ARGS 0,0,1
SAVE_ARGS 0,1,0
/* no need to do an access_ok check here because rbp has been
32bit zero extended */
1: movl (%rbp),%ebp
Expand Down Expand Up @@ -173,7 +173,7 @@ sysexit_from_sys_call:
andl $~0x200,EFLAGS-R11(%rsp)
movl RIP-R11(%rsp),%edx /* User %eip */
CFI_REGISTER rip,rdx
RESTORE_ARGS 1,24,1,1,1,1
RESTORE_ARGS 0,24,0,0,0,0
xorq %r8,%r8
xorq %r9,%r9
xorq %r10,%r10
Expand Down Expand Up @@ -289,7 +289,7 @@ ENTRY(ia32_cstar_target)
* disabled irqs and here we enable it straight after entry:
*/
ENABLE_INTERRUPTS(CLBR_NONE)
SAVE_ARGS 8,1,1
SAVE_ARGS 8,0,0
movl %eax,%eax /* zero extension */
movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
movq %rcx,RIP-ARGOFFSET(%rsp)
Expand Down Expand Up @@ -328,7 +328,7 @@ cstar_dispatch:
jnz sysretl_audit
sysretl_from_sys_call:
andl $~TS_COMPAT,TI_status(%r10)
RESTORE_ARGS 1,-ARG_SKIP,1,1,1
RESTORE_ARGS 0,-ARG_SKIP,0,0,0
movl RIP-ARGOFFSET(%rsp),%ecx
CFI_REGISTER rip,rcx
movl EFLAGS-ARGOFFSET(%rsp),%r11d
Expand Down Expand Up @@ -419,7 +419,7 @@ ENTRY(ia32_syscall)
cld
/* note the registers are not zero extended to the sf.
this could be a problem. */
SAVE_ARGS 0,0,1
SAVE_ARGS 0,1,0
GET_THREAD_INFO(%r10)
orl $TS_COMPAT,TI_status(%r10)
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
Expand Down
5 changes: 4 additions & 1 deletion arch/x86/include/asm/asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

#ifdef __ASSEMBLY__
# define __ASM_FORM(x) x
# define __ASM_FORM_COMMA(x) x,
# define __ASM_EX_SEC .section __ex_table, "a"
#else
# define __ASM_FORM(x) " " #x " "
# define __ASM_FORM_COMMA(x) " " #x ","
# define __ASM_EX_SEC " .section __ex_table,\"a\"\n"
#endif

Expand All @@ -15,7 +17,8 @@
# define __ASM_SEL(a,b) __ASM_FORM(b)
#endif

#define __ASM_SIZE(inst) __ASM_SEL(inst##l, inst##q)
#define __ASM_SIZE(inst, ...) __ASM_SEL(inst##l##__VA_ARGS__, \
inst##q##__VA_ARGS__)
#define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg)

#define _ASM_PTR __ASM_SEL(.long, .quad)
Expand Down
130 changes: 52 additions & 78 deletions arch/x86/include/asm/calling.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ For 32-bit we have the following conventions - kernel is built with
*/

#include "dwarf2.h"

/*
* 64-bit system call stack frame layout defines and helpers, for
Expand Down Expand Up @@ -84,72 +85,57 @@ For 32-bit we have the following conventions - kernel is built with
#define ARGOFFSET R11
#define SWFRAME ORIG_RAX

.macro SAVE_ARGS addskip=0, norcx=0, nor891011=0
.macro SAVE_ARGS addskip=0, save_rcx=1, save_r891011=1
subq $9*8+\addskip, %rsp
CFI_ADJUST_CFA_OFFSET 9*8+\addskip
movq %rdi, 8*8(%rsp)
CFI_REL_OFFSET rdi, 8*8
movq %rsi, 7*8(%rsp)
CFI_REL_OFFSET rsi, 7*8
movq %rdx, 6*8(%rsp)
CFI_REL_OFFSET rdx, 6*8
.if \norcx
.else
movq %rcx, 5*8(%rsp)
CFI_REL_OFFSET rcx, 5*8
movq_cfi rdi, 8*8
movq_cfi rsi, 7*8
movq_cfi rdx, 6*8

.if \save_rcx
movq_cfi rcx, 5*8
.endif
movq %rax, 4*8(%rsp)
CFI_REL_OFFSET rax, 4*8
.if \nor891011
.else
movq %r8, 3*8(%rsp)
CFI_REL_OFFSET r8, 3*8
movq %r9, 2*8(%rsp)
CFI_REL_OFFSET r9, 2*8
movq %r10, 1*8(%rsp)
CFI_REL_OFFSET r10, 1*8
movq %r11, (%rsp)
CFI_REL_OFFSET r11, 0*8

movq_cfi rax, 4*8

.if \save_r891011
movq_cfi r8, 3*8
movq_cfi r9, 2*8
movq_cfi r10, 1*8
movq_cfi r11, 0*8
.endif

.endm

#define ARG_SKIP (9*8)

.macro RESTORE_ARGS skiprax=0, addskip=0, skiprcx=0, skipr11=0, \
skipr8910=0, skiprdx=0
.if \skipr11
.else
movq (%rsp), %r11
CFI_RESTORE r11
.macro RESTORE_ARGS rstor_rax=1, addskip=0, rstor_rcx=1, rstor_r11=1, \
rstor_r8910=1, rstor_rdx=1
.if \rstor_r11
movq_cfi_restore 0*8, r11
.endif
.if \skipr8910
.else
movq 1*8(%rsp), %r10
CFI_RESTORE r10
movq 2*8(%rsp), %r9
CFI_RESTORE r9
movq 3*8(%rsp), %r8
CFI_RESTORE r8

.if \rstor_r8910
movq_cfi_restore 1*8, r10
movq_cfi_restore 2*8, r9
movq_cfi_restore 3*8, r8
.endif
.if \skiprax
.else
movq 4*8(%rsp), %rax
CFI_RESTORE rax

.if \rstor_rax
movq_cfi_restore 4*8, rax
.endif
.if \skiprcx
.else
movq 5*8(%rsp), %rcx
CFI_RESTORE rcx

.if \rstor_rcx
movq_cfi_restore 5*8, rcx
.endif
.if \skiprdx
.else
movq 6*8(%rsp), %rdx
CFI_RESTORE rdx

.if \rstor_rdx
movq_cfi_restore 6*8, rdx
.endif
movq 7*8(%rsp), %rsi
CFI_RESTORE rsi
movq 8*8(%rsp), %rdi
CFI_RESTORE rdi

movq_cfi_restore 7*8, rsi
movq_cfi_restore 8*8, rdi

.if ARG_SKIP+\addskip > 0
addq $ARG_SKIP+\addskip, %rsp
CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
Expand All @@ -176,33 +162,21 @@ For 32-bit we have the following conventions - kernel is built with
.macro SAVE_REST
subq $REST_SKIP, %rsp
CFI_ADJUST_CFA_OFFSET REST_SKIP
movq %rbx, 5*8(%rsp)
CFI_REL_OFFSET rbx, 5*8
movq %rbp, 4*8(%rsp)
CFI_REL_OFFSET rbp, 4*8
movq %r12, 3*8(%rsp)
CFI_REL_OFFSET r12, 3*8
movq %r13, 2*8(%rsp)
CFI_REL_OFFSET r13, 2*8
movq %r14, 1*8(%rsp)
CFI_REL_OFFSET r14, 1*8
movq %r15, (%rsp)
CFI_REL_OFFSET r15, 0*8
movq_cfi rbx, 5*8
movq_cfi rbp, 4*8
movq_cfi r12, 3*8
movq_cfi r13, 2*8
movq_cfi r14, 1*8
movq_cfi r15, 0*8
.endm

.macro RESTORE_REST
movq (%rsp), %r15
CFI_RESTORE r15
movq 1*8(%rsp), %r14
CFI_RESTORE r14
movq 2*8(%rsp), %r13
CFI_RESTORE r13
movq 3*8(%rsp), %r12
CFI_RESTORE r12
movq 4*8(%rsp), %rbp
CFI_RESTORE rbp
movq 5*8(%rsp), %rbx
CFI_RESTORE rbx
movq_cfi_restore 0*8, r15
movq_cfi_restore 1*8, r14
movq_cfi_restore 2*8, r13
movq_cfi_restore 3*8, r12
movq_cfi_restore 4*8, rbp
movq_cfi_restore 5*8, rbx
addq $REST_SKIP, %rsp
CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
.endm
Expand All @@ -214,7 +188,7 @@ For 32-bit we have the following conventions - kernel is built with

.macro RESTORE_ALL addskip=0
RESTORE_REST
RESTORE_ARGS 0, \addskip
RESTORE_ARGS 1, \addskip
.endm

.macro icebp
Expand Down
11 changes: 6 additions & 5 deletions arch/x86/include/asm/frame.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
#ifdef __ASSEMBLY__

#include <asm/asm.h>
#include <asm/dwarf2.h>

/* The annotation hides the frame from the unwinder and makes it look
like a ordinary ebp save/restore. This avoids some special cases for
frame pointer later */
#ifdef CONFIG_FRAME_POINTER
.macro FRAME
pushl_cfi %ebp
CFI_REL_OFFSET ebp,0
movl %esp,%ebp
__ASM_SIZE(push,_cfi) %__ASM_REG(bp)
CFI_REL_OFFSET __ASM_REG(bp), 0
__ASM_SIZE(mov) %__ASM_REG(sp), %__ASM_REG(bp)
.endm
.macro ENDFRAME
popl_cfi %ebp
CFI_RESTORE ebp
__ASM_SIZE(pop,_cfi) %__ASM_REG(bp)
CFI_RESTORE __ASM_REG(bp)
.endm
#else
.macro FRAME
Expand Down
43 changes: 42 additions & 1 deletion arch/x86/include/asm/rwlock.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,48 @@
#ifndef _ASM_X86_RWLOCK_H
#define _ASM_X86_RWLOCK_H

#define RW_LOCK_BIAS 0x01000000
#include <asm/asm.h>

#if CONFIG_NR_CPUS <= 2048

#ifndef __ASSEMBLY__
typedef union {
s32 lock;
s32 write;
} arch_rwlock_t;
#endif

#define RW_LOCK_BIAS 0x00100000
#define READ_LOCK_SIZE(insn) __ASM_FORM(insn##l)
#define READ_LOCK_ATOMIC(n) atomic_##n
#define WRITE_LOCK_ADD(n) __ASM_FORM_COMMA(addl n)
#define WRITE_LOCK_SUB(n) __ASM_FORM_COMMA(subl n)
#define WRITE_LOCK_CMP RW_LOCK_BIAS

#else /* CONFIG_NR_CPUS > 2048 */

#include <linux/const.h>

#ifndef __ASSEMBLY__
typedef union {
s64 lock;
struct {
u32 read;
s32 write;
};
} arch_rwlock_t;
#endif

#define RW_LOCK_BIAS (_AC(1,L) << 32)
#define READ_LOCK_SIZE(insn) __ASM_FORM(insn##q)
#define READ_LOCK_ATOMIC(n) atomic64_##n
#define WRITE_LOCK_ADD(n) __ASM_FORM(incl)
#define WRITE_LOCK_SUB(n) __ASM_FORM(decl)
#define WRITE_LOCK_CMP 1

#endif /* CONFIG_NR_CPUS */

#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }

/* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
#define GDT_ENTRY_DEFAULT_USER32_CS 4
#define GDT_ENTRY_DEFAULT_USER_DS 5
#define GDT_ENTRY_DEFAULT_USER_CS 6
#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS * 8 + 3)
#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8+3)
#define __USER32_DS __USER_DS

#define GDT_ENTRY_TSS 8 /* needs two entries */
Expand Down
Loading

0 comments on commit eb47418

Please sign in to comment.