Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/current: Implement current with inline assembly

Implement current with an inline assembly, which makes use of the
ALTERNATIVE macro, to read current from lowcore. Provide an alternative
instruction with a different offset in case lowcore is relocated.

This replaces sequences of two instructions with one instruction.

Before:
100076: a5 1e 00 00 llilh %r1,0
10007a: e3 40 13 40 00 04 lg %r4,832(%r1)

After:
100076: e3 10 03 40 00 04 lg %r1,832

Kernel image size change:
add/remove: 3/17 grow/shrink: 166/2204 up/down: 7122/-24594 (-17472)

Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>

authored by

Heiko Carstens and committed by
Vasily Gorbik
65c07e91 430693c8

+17 -1
+17 -1
arch/s390/include/asm/current.h
··· 11 11 #define _S390_CURRENT_H 12 12 13 13 #include <asm/lowcore.h> 14 + #include <asm/machine.h> 14 15 15 16 struct task_struct; 16 17 17 - #define current ((struct task_struct *const)get_lowcore()->current_task) 18 + static __always_inline struct task_struct *get_current(void) 19 + { 20 + unsigned long ptr, lc_current; 21 + 22 + lc_current = offsetof(struct lowcore, current_task); 23 + asm_inline( 24 + ALTERNATIVE(" lg %[ptr],%[offzero](%%r0)\n", 25 + " lg %[ptr],%[offalt](%%r0)\n", 26 + ALT_FEATURE(MFEATURE_LOWCORE)) 27 + : [ptr] "=d" (ptr) 28 + : [offzero] "i" (lc_current), 29 + [offalt] "i" (lc_current + LOWCORE_ALT_ADDRESS)); 30 + return (struct task_struct *)ptr; 31 + } 32 + 33 + #define current get_current() 18 34 19 35 #endif /* !(_S390_CURRENT_H) */