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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'powerpc-5.13-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:

- Fix breakage of strace (and other ptracers etc.) when using the new
scv ABI (Power9 or later with glibc >= 2.33).

- Fix early_ioremap() on 64-bit, which broke booting on some machines.

Thanks to Dmitry V. Levin, Nicholas Piggin, Alexey Kardashevskiy, and
Christophe Leroy.

* tag 'powerpc-5.13-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/64s/syscall: Fix ptrace syscall info with scv syscalls
powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls
powerpc: Fix early setup to make early_ioremap() work

+82 -46
+10
Documentation/powerpc/syscall64-abi.rst
··· 109 109 110 110 scv 0 syscalls will always behave as PPC_FEATURE2_HTM_NOSC. 111 111 112 + ptrace 113 + ------ 114 + When ptracing system calls (PTRACE_SYSCALL), the pt_regs.trap value contains 115 + the system call type that can be used to distinguish between sc and scv 0 116 + system calls, and the different register conventions can be accounted for. 117 + 118 + If the value of (pt_regs.trap & 0xfff0) is 0xc00 then the system call was 119 + performed with the sc instruction, if it is 0x3000 then the system call was 120 + performed with the scv 0 instruction. 121 + 112 122 vsyscall 113 123 ======== 114 124
+26 -19
arch/powerpc/include/asm/ptrace.h
··· 19 19 #ifndef _ASM_POWERPC_PTRACE_H 20 20 #define _ASM_POWERPC_PTRACE_H 21 21 22 + #include <linux/err.h> 22 23 #include <uapi/asm/ptrace.h> 23 24 #include <asm/asm-const.h> 24 25 ··· 153 152 long do_syscall_trace_enter(struct pt_regs *regs); 154 153 void do_syscall_trace_leave(struct pt_regs *regs); 155 154 156 - #define kernel_stack_pointer(regs) ((regs)->gpr[1]) 157 - static inline int is_syscall_success(struct pt_regs *regs) 158 - { 159 - return !(regs->ccr & 0x10000000); 160 - } 161 - 162 - static inline long regs_return_value(struct pt_regs *regs) 163 - { 164 - if (is_syscall_success(regs)) 165 - return regs->gpr[3]; 166 - else 167 - return -regs->gpr[3]; 168 - } 169 - 170 - static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) 171 - { 172 - regs->gpr[3] = rc; 173 - } 174 - 175 155 #ifdef __powerpc64__ 176 156 #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1) 177 157 #else ··· 215 233 static __always_inline void set_trap_norestart(struct pt_regs *regs) 216 234 { 217 235 regs->trap |= 0x1; 236 + } 237 + 238 + #define kernel_stack_pointer(regs) ((regs)->gpr[1]) 239 + static inline int is_syscall_success(struct pt_regs *regs) 240 + { 241 + if (trap_is_scv(regs)) 242 + return !IS_ERR_VALUE((unsigned long)regs->gpr[3]); 243 + else 244 + return !(regs->ccr & 0x10000000); 245 + } 246 + 247 + static inline long regs_return_value(struct pt_regs *regs) 248 + { 249 + if (trap_is_scv(regs)) 250 + return regs->gpr[3]; 251 + 252 + if (is_syscall_success(regs)) 253 + return regs->gpr[3]; 254 + else 255 + return -regs->gpr[3]; 256 + } 257 + 258 + static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) 259 + { 260 + regs->gpr[3] = rc; 218 261 } 219 262 220 263 #define arch_has_single_step() (1)
+26 -16
arch/powerpc/include/asm/syscall.h
··· 41 41 static inline long syscall_get_error(struct task_struct *task, 42 42 struct pt_regs *regs) 43 43 { 44 - /* 45 - * If the system call failed, 46 - * regs->gpr[3] contains a positive ERRORCODE. 47 - */ 48 - return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0; 44 + if (trap_is_scv(regs)) { 45 + unsigned long error = regs->gpr[3]; 46 + 47 + return IS_ERR_VALUE(error) ? error : 0; 48 + } else { 49 + /* 50 + * If the system call failed, 51 + * regs->gpr[3] contains a positive ERRORCODE. 52 + */ 53 + return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0; 54 + } 49 55 } 50 56 51 57 static inline long syscall_get_return_value(struct task_struct *task, ··· 64 58 struct pt_regs *regs, 65 59 int error, long val) 66 60 { 67 - /* 68 - * In the general case it's not obvious that we must deal with CCR 69 - * here, as the syscall exit path will also do that for us. However 70 - * there are some places, eg. the signal code, which check ccr to 71 - * decide if the value in r3 is actually an error. 72 - */ 73 - if (error) { 74 - regs->ccr |= 0x10000000L; 75 - regs->gpr[3] = error; 61 + if (trap_is_scv(regs)) { 62 + regs->gpr[3] = (long) error ?: val; 76 63 } else { 77 - regs->ccr &= ~0x10000000L; 78 - regs->gpr[3] = val; 64 + /* 65 + * In the general case it's not obvious that we must deal with 66 + * CCR here, as the syscall exit path will also do that for us. 67 + * However there are some places, eg. the signal code, which 68 + * check ccr to decide if the value in r3 is actually an error. 69 + */ 70 + if (error) { 71 + regs->ccr |= 0x10000000L; 72 + regs->gpr[3] = error; 73 + } else { 74 + regs->ccr &= ~0x10000000L; 75 + regs->gpr[3] = val; 76 + } 79 77 } 80 78 } 81 79
+2 -2
arch/powerpc/kernel/setup_64.c
··· 369 369 apply_feature_fixups(); 370 370 setup_feature_keys(); 371 371 372 - early_ioremap_setup(); 373 - 374 372 /* Initialize the hash table or TLB handling */ 375 373 early_init_mmu(); 374 + 375 + early_ioremap_setup(); 376 376 377 377 /* 378 378 * After firmware and early platform setup code has set things up,
+18 -9
tools/testing/selftests/seccomp/seccomp_bpf.c
··· 1753 1753 # define SYSCALL_RET_SET(_regs, _val) \ 1754 1754 do { \ 1755 1755 typeof(_val) _result = (_val); \ 1756 - /* \ 1757 - * A syscall error is signaled by CR0 SO bit \ 1758 - * and the code is stored as a positive value. \ 1759 - */ \ 1760 - if (_result < 0) { \ 1761 - SYSCALL_RET(_regs) = -_result; \ 1762 - (_regs).ccr |= 0x10000000; \ 1763 - } else { \ 1756 + if ((_regs.trap & 0xfff0) == 0x3000) { \ 1757 + /* \ 1758 + * scv 0 system call uses -ve result \ 1759 + * for error, so no need to adjust. \ 1760 + */ \ 1764 1761 SYSCALL_RET(_regs) = _result; \ 1765 - (_regs).ccr &= ~0x10000000; \ 1762 + } else { \ 1763 + /* \ 1764 + * A syscall error is signaled by the \ 1765 + * CR0 SO bit and the code is stored as \ 1766 + * a positive value. \ 1767 + */ \ 1768 + if (_result < 0) { \ 1769 + SYSCALL_RET(_regs) = -_result; \ 1770 + (_regs).ccr |= 0x10000000; \ 1771 + } else { \ 1772 + SYSCALL_RET(_regs) = _result; \ 1773 + (_regs).ccr &= ~0x10000000; \ 1774 + } \ 1766 1775 } \ 1767 1776 } while (0) 1768 1777 # define SYSCALL_RET_SET_ON_PTRACE_EXIT