Skip to content

Commit 7fa95f9

Browse files
npigginmpe
authored andcommitted
powerpc/64s: system call support for scv/rfscv instructions
Add support for the scv instruction on POWER9 and later CPUs. For now this implements the zeroth scv vector 'scv 0', as identical to 'sc' system calls, with the exception that LR is not preserved, nor are volatile CR registers, and error is not indicated with CR0[SO], but by returning a negative errno. rfscv is implemented to return from scv type system calls. It can not be used to return from sc system calls because those are defined to preserve LR. getpid syscall throughput on POWER9 is improved by 26% (428 to 318 cycles), largely due to reducing mtmsr and mtspr. Signed-off-by: Nicholas Piggin <[email protected]> [mpe: Fix ppc64e build] Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b2dc297 commit 7fa95f9

File tree

20 files changed

+421
-44
lines changed

20 files changed

+421
-44
lines changed

Documentation/powerpc/syscall64-abi.rst

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,39 @@ Power Architecture 64-bit Linux system call ABI
55
syscall
66
=======
77

8+
Invocation
9+
----------
10+
The syscall is made with the sc instruction, and returns with execution
11+
continuing at the instruction following the sc instruction.
12+
13+
If PPC_FEATURE2_SCV appears in the AT_HWCAP2 ELF auxiliary vector, the
14+
scv 0 instruction is an alternative that may provide better performance,
15+
with some differences to calling sequence.
16+
817
syscall calling sequence\ [1]_ matches the Power Architecture 64-bit ELF ABI
918
specification C function calling sequence, including register preservation
1019
rules, with the following differences.
1120

1221
.. [1] Some syscalls (typically low-level management functions) may have
1322
different calling sequences (e.g., rt_sigreturn).
1423
15-
Parameters and return value
16-
---------------------------
24+
Parameters
25+
----------
1726
The system call number is specified in r0.
1827

1928
There is a maximum of 6 integer parameters to a syscall, passed in r3-r8.
2029

21-
Both a return value and a return error code are returned. cr0.SO is the return
22-
error code, and r3 is the return value or error code. When cr0.SO is clear,
23-
the syscall succeeded and r3 is the return value. When cr0.SO is set, the
24-
syscall failed and r3 is the error code that generally corresponds to errno.
30+
Return value
31+
------------
32+
- For the sc instruction, both a value and an error condition are returned.
33+
cr0.SO is the error condition, and r3 is the return value. When cr0.SO is
34+
clear, the syscall succeeded and r3 is the return value. When cr0.SO is set,
35+
the syscall failed and r3 is the error value (that normally corresponds to
36+
errno).
37+
38+
- For the scv 0 instruction, the return value indicates failure if it is
39+
-4095..-1 (i.e., it is >= -MAX_ERRNO (-4095) as an unsigned comparison),
40+
in which case the error value is the negated return value.
2541

2642
Stack
2743
-----
@@ -34,22 +50,23 @@ Register preservation rules match the ELF ABI calling sequence with the
3450
following differences:
3551

3652
=========== ============= ========================================
53+
--- For the sc instruction, differences with the ELF ABI ---
3754
r0 Volatile (System call number.)
3855
r3 Volatile (Parameter 1, and return value.)
3956
r4-r8 Volatile (Parameters 2-6.)
40-
cr0 Volatile (cr0.SO is the return error condition)
57+
cr0 Volatile (cr0.SO is the return error condition.)
4158
cr1, cr5-7 Nonvolatile
4259
lr Nonvolatile
60+
61+
--- For the scv 0 instruction, differences with the ELF ABI ---
62+
r0 Volatile (System call number.)
63+
r3 Volatile (Parameter 1, and return value.)
64+
r4-r8 Volatile (Parameters 2-6.)
4365
=========== ============= ========================================
4466

4567
All floating point and vector data registers as well as control and status
4668
registers are nonvolatile.
4769

48-
Invocation
49-
----------
50-
The syscall is performed with the sc instruction, and returns with execution
51-
continuing at the instruction following the sc instruction.
52-
5370
Transactional Memory
5471
--------------------
5572
Syscall behavior can change if the processor is in transactional or suspended
@@ -75,6 +92,7 @@ auxiliary vector.
7592
returning to the caller. This case is not well defined or supported, so this
7693
behavior should not be relied upon.
7794

95+
scv 0 syscalls will always behave as PPC_FEATURE2_HTM_NOSC.
7896

7997
vsyscall
8098
========

arch/powerpc/include/asm/asm-prototypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ unsigned long __init early_init(unsigned long dt_ptr);
9898
void __init machine_init(u64 dt_ptr);
9999
#endif
100100
long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8, unsigned long r0, struct pt_regs *regs);
101-
notrace unsigned long syscall_exit_prepare(unsigned long r3, struct pt_regs *regs);
101+
notrace unsigned long syscall_exit_prepare(unsigned long r3, struct pt_regs *regs, long scv);
102102
notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned long msr);
103103
notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsigned long msr);
104104

arch/powerpc/include/asm/exception-64s.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@
123123
hrfid; \
124124
b hrfi_flush_fallback
125125

126+
#define RFSCV_TO_USER \
127+
STF_EXIT_BARRIER_SLOT; \
128+
RFI_FLUSH_SLOT; \
129+
RFSCV; \
130+
b rfscv_flush_fallback
131+
126132
#endif /* __ASSEMBLY__ */
127133

128134
#endif /* _ASM_POWERPC_EXCEPTION_H */

arch/powerpc/include/asm/head-64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ end_##sname:
128128
.if ((start) % (size) != 0); \
129129
.error "Fixed section exception vector misalignment"; \
130130
.endif; \
131-
.if ((size) != 0x20) && ((size) != 0x80) && ((size) != 0x100); \
131+
.if ((size) != 0x20) && ((size) != 0x80) && ((size) != 0x100) && ((size) != 0x1000); \
132132
.error "Fixed section exception vector bad size"; \
133133
.endif; \
134134
.if (start) < sname##_start; \

arch/powerpc/include/asm/ppc_asm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
755755
#define N_SLINE 68
756756
#define N_SO 100
757757

758+
#define RFSCV .long 0x4c0000a4
759+
758760
/*
759761
* Create an endian fixup trampoline
760762
*

arch/powerpc/include/asm/ptrace.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,14 @@ static inline void set_trap(struct pt_regs *regs, unsigned long val)
222222
regs->trap = (regs->trap & TRAP_FLAGS_MASK) | (val & ~TRAP_FLAGS_MASK);
223223
}
224224

225+
static inline bool trap_is_scv(struct pt_regs *regs)
226+
{
227+
return (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && TRAP(regs) == 0x3000);
228+
}
229+
225230
static inline bool trap_is_syscall(struct pt_regs *regs)
226231
{
227-
return TRAP(regs) == 0xc00;
232+
return (trap_is_scv(regs) || TRAP(regs) == 0xc00);
228233
}
229234

230235
static inline bool trap_norestart(struct pt_regs *regs)

arch/powerpc/include/asm/setup.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ void setup_panic(void);
3030
#define ARCH_PANIC_TIMEOUT 180
3131

3232
#ifdef CONFIG_PPC_PSERIES
33-
extern void pseries_enable_reloc_on_exc(void);
33+
extern bool pseries_enable_reloc_on_exc(void);
3434
extern void pseries_disable_reloc_on_exc(void);
3535
extern void pseries_big_endian_exceptions(void);
3636
extern void pseries_little_endian_exceptions(void);
3737
#else
38-
static inline void pseries_enable_reloc_on_exc(void) {}
38+
static inline bool pseries_enable_reloc_on_exc(void) { return false; }
3939
static inline void pseries_disable_reloc_on_exc(void) {}
4040
static inline void pseries_big_endian_exceptions(void) {}
4141
static inline void pseries_little_endian_exceptions(void) {}

arch/powerpc/include/asm/sstep.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum instruction_type {
4040
CACHEOP,
4141
BARRIER,
4242
SYSCALL,
43+
SYSCALL_VECTORED_0,
4344
MFMSR,
4445
MTMSR,
4546
RFI,

arch/powerpc/kernel/cpu_setup_power.S

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ _GLOBAL(__setup_cpu_power10)
9898

9999
_GLOBAL(__setup_cpu_power9)
100100
mflr r11
101-
bl __init_FSCR
101+
bl __init_FSCR_power9
102102
1: bl __init_PMU
103103
bl __init_hvmode_206
104104
mtlr r11
@@ -128,7 +128,7 @@ _GLOBAL(__restore_cpu_power10)
128128

129129
_GLOBAL(__restore_cpu_power9)
130130
mflr r11
131-
bl __init_FSCR
131+
bl __init_FSCR_power9
132132
1: bl __init_PMU
133133
mfmsr r3
134134
rldicl. r0,r3,4,63
@@ -198,6 +198,12 @@ __init_FSCR_power10:
198198
mtspr SPRN_FSCR, r3
199199
// fall through
200200

201+
__init_FSCR_power9:
202+
mfspr r3, SPRN_FSCR
203+
ori r3, r3, FSCR_SCV
204+
mtspr SPRN_FSCR, r3
205+
// fall through
206+
201207
__init_FSCR:
202208
mfspr r3,SPRN_FSCR
203209
ori r3,r3,FSCR_TAR|FSCR_EBB

arch/powerpc/kernel/cputable.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ extern void __restore_cpu_e6500(void);
120120
#define COMMON_USER2_POWER9 (COMMON_USER2_POWER8 | \
121121
PPC_FEATURE2_ARCH_3_00 | \
122122
PPC_FEATURE2_HAS_IEEE128 | \
123-
PPC_FEATURE2_DARN )
123+
PPC_FEATURE2_DARN | \
124+
PPC_FEATURE2_SCV)
124125
#define COMMON_USER_POWER10 COMMON_USER_POWER9
125126
#define COMMON_USER2_POWER10 (COMMON_USER2_POWER9 | \
126127
PPC_FEATURE2_ARCH_3_1 | \

arch/powerpc/kernel/dt_cpu_ftrs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ static struct dt_cpu_feature_match __initdata
587587
{"little-endian", feat_enable_le, CPU_FTR_REAL_LE},
588588
{"smt", feat_enable_smt, 0},
589589
{"interrupt-facilities", feat_enable, 0},
590+
{"system-call-vectored", feat_enable, 0},
590591
{"timer-facilities", feat_enable, 0},
591592
{"timer-facilities-v3", feat_enable, 0},
592593
{"debug-facilities", feat_enable, 0},

0 commit comments

Comments
 (0)