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.7-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:

- A fix for unrecoverable SLB faults in the interrupt exit path,
introduced by the recent rewrite of interrupt exit in C.

- Four fixes for our KUAP (Kernel Userspace Access Prevention) support
on 64-bit. These are all fairly minor with the exception of the
change to evaluate the get/put_user() arguments before we enable user
access, which reduces the amount of code we run with user access
enabled.

- A fix for our secure boot IMA rules, if enforcement of module
signatures is enabled at runtime rather than build time.

- A fix to our 32-bit VDSO clock_getres() which wasn't falling back to
the syscall for unknown clocks.

- A build fix for CONFIG_PPC_KUAP_DEBUG on 32-bit BookS, and another
for 40x.

Thanks to: Christophe Leroy, Hugh Dickins, Nicholas Piggin, Aurelien
Jarno, Mimi Zohar, Nayna Jain.

* tag 'powerpc-5.7-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/40x: Make more space for system call exception
powerpc/vdso32: Fallback on getres syscall when clock is unknown
powerpc/32s: Fix build failure with CONFIG_PPC_KUAP_DEBUG
powerpc/ima: Fix secure boot rules in ima arch policy
powerpc/64s/kuap: Restore AMR in fast_interrupt_return
powerpc/64s/kuap: Restore AMR in system reset exception
powerpc/64/kuap: Move kuap checks out of MSR[RI]=0 regions of exit code
powerpc/64s: Fix unrecoverable SLB crashes due to preemption check
powerpc/uaccess: Evaluate macro arguments once, before user access is allowed

+78 -33
+1 -1
arch/powerpc/include/asm/book3s/32/kup.h
··· 75 75 76 76 .macro kuap_check current, gpr 77 77 #ifdef CONFIG_PPC_KUAP_DEBUG 78 - lwz \gpr2, KUAP(thread) 78 + lwz \gpr, KUAP(thread) 79 79 999: twnei \gpr, 0 80 80 EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) 81 81 #endif
+19 -1
arch/powerpc/include/asm/hw_irq.h
··· 250 250 } \ 251 251 } while(0) 252 252 253 + static inline bool __lazy_irq_pending(u8 irq_happened) 254 + { 255 + return !!(irq_happened & ~PACA_IRQ_HARD_DIS); 256 + } 257 + 258 + /* 259 + * Check if a lazy IRQ is pending. Should be called with IRQs hard disabled. 260 + */ 253 261 static inline bool lazy_irq_pending(void) 254 262 { 255 - return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS); 263 + return __lazy_irq_pending(get_paca()->irq_happened); 264 + } 265 + 266 + /* 267 + * Check if a lazy IRQ is pending, with no debugging checks. 268 + * Should be called with IRQs hard disabled. 269 + * For use in RI disabled code or other constrained situations. 270 + */ 271 + static inline bool lazy_irq_pending_nocheck(void) 272 + { 273 + return __lazy_irq_pending(local_paca->irq_happened); 256 274 } 257 275 258 276 /*
+35 -14
arch/powerpc/include/asm/uaccess.h
··· 166 166 ({ \ 167 167 long __pu_err; \ 168 168 __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ 169 + __typeof__(*(ptr)) __pu_val = (x); \ 170 + __typeof__(size) __pu_size = (size); \ 171 + \ 169 172 if (!is_kernel_addr((unsigned long)__pu_addr)) \ 170 173 might_fault(); \ 171 - __chk_user_ptr(ptr); \ 174 + __chk_user_ptr(__pu_addr); \ 172 175 if (do_allow) \ 173 - __put_user_size((x), __pu_addr, (size), __pu_err); \ 176 + __put_user_size(__pu_val, __pu_addr, __pu_size, __pu_err); \ 174 177 else \ 175 - __put_user_size_allowed((x), __pu_addr, (size), __pu_err); \ 178 + __put_user_size_allowed(__pu_val, __pu_addr, __pu_size, __pu_err); \ 179 + \ 176 180 __pu_err; \ 177 181 }) 178 182 ··· 184 180 ({ \ 185 181 long __pu_err = -EFAULT; \ 186 182 __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ 183 + __typeof__(*(ptr)) __pu_val = (x); \ 184 + __typeof__(size) __pu_size = (size); \ 185 + \ 187 186 might_fault(); \ 188 - if (access_ok(__pu_addr, size)) \ 189 - __put_user_size((x), __pu_addr, (size), __pu_err); \ 187 + if (access_ok(__pu_addr, __pu_size)) \ 188 + __put_user_size(__pu_val, __pu_addr, __pu_size, __pu_err); \ 189 + \ 190 190 __pu_err; \ 191 191 }) 192 192 ··· 198 190 ({ \ 199 191 long __pu_err; \ 200 192 __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ 201 - __chk_user_ptr(ptr); \ 202 - __put_user_size((x), __pu_addr, (size), __pu_err); \ 193 + __typeof__(*(ptr)) __pu_val = (x); \ 194 + __typeof__(size) __pu_size = (size); \ 195 + \ 196 + __chk_user_ptr(__pu_addr); \ 197 + __put_user_size(__pu_val, __pu_addr, __pu_size, __pu_err); \ 198 + \ 203 199 __pu_err; \ 204 200 }) 205 201 ··· 295 283 long __gu_err; \ 296 284 __long_type(*(ptr)) __gu_val; \ 297 285 __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ 298 - __chk_user_ptr(ptr); \ 286 + __typeof__(size) __gu_size = (size); \ 287 + \ 288 + __chk_user_ptr(__gu_addr); \ 299 289 if (!is_kernel_addr((unsigned long)__gu_addr)) \ 300 290 might_fault(); \ 301 291 barrier_nospec(); \ 302 292 if (do_allow) \ 303 - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ 293 + __get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \ 304 294 else \ 305 - __get_user_size_allowed(__gu_val, __gu_addr, (size), __gu_err); \ 295 + __get_user_size_allowed(__gu_val, __gu_addr, __gu_size, __gu_err); \ 306 296 (x) = (__typeof__(*(ptr)))__gu_val; \ 297 + \ 307 298 __gu_err; \ 308 299 }) 309 300 ··· 315 300 long __gu_err = -EFAULT; \ 316 301 __long_type(*(ptr)) __gu_val = 0; \ 317 302 __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ 303 + __typeof__(size) __gu_size = (size); \ 304 + \ 318 305 might_fault(); \ 319 - if (access_ok(__gu_addr, (size))) { \ 306 + if (access_ok(__gu_addr, __gu_size)) { \ 320 307 barrier_nospec(); \ 321 - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ 308 + __get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \ 322 309 } \ 323 310 (x) = (__force __typeof__(*(ptr)))__gu_val; \ 311 + \ 324 312 __gu_err; \ 325 313 }) 326 314 ··· 332 314 long __gu_err; \ 333 315 __long_type(*(ptr)) __gu_val; \ 334 316 __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ 335 - __chk_user_ptr(ptr); \ 317 + __typeof__(size) __gu_size = (size); \ 318 + \ 319 + __chk_user_ptr(__gu_addr); \ 336 320 barrier_nospec(); \ 337 - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ 321 + __get_user_size(__gu_val, __gu_addr, __gu_size, __gu_err); \ 338 322 (x) = (__force __typeof__(*(ptr)))__gu_val; \ 323 + \ 339 324 __gu_err; \ 340 325 }) 341 326
+3 -1
arch/powerpc/kernel/entry_64.S
··· 472 472 #ifdef CONFIG_PPC_BOOK3S 473 473 /* 474 474 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not 475 - * touched, AMR not set, no exit work created, then this can be used. 475 + * touched, no exit work created, then this can be used. 476 476 */ 477 477 .balign IFETCH_ALIGN_BYTES 478 478 .globl fast_interrupt_return 479 479 fast_interrupt_return: 480 480 _ASM_NOKPROBE_SYMBOL(fast_interrupt_return) 481 + kuap_check_amr r3, r4 481 482 ld r4,_MSR(r1) 482 483 andi. r0,r4,MSR_PR 483 484 bne .Lfast_user_interrupt_return 485 + kuap_restore_amr r3 484 486 andi. r0,r4,MSR_RI 485 487 li r3,0 /* 0 return value, no EMULATE_STACK_STORE */ 486 488 bne+ .Lfast_kernel_interrupt_return
+1
arch/powerpc/kernel/exceptions-64s.S
··· 971 971 ld r10,SOFTE(r1) 972 972 stb r10,PACAIRQSOFTMASK(r13) 973 973 974 + kuap_restore_amr r10 974 975 EXCEPTION_RESTORE_REGS 975 976 RFI_TO_USER_OR_KERNEL 976 977
+2 -1
arch/powerpc/kernel/head_40x.S
··· 344 344 /* 0x0C00 - System Call Exception */ 345 345 START_EXCEPTION(0x0C00, SystemCall) 346 346 SYSCALL_ENTRY 0xc00 347 + /* Trap_0D is commented out to get more space for system call exception */ 347 348 348 - EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD) 349 + /* EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD) */ 349 350 EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_STD) 350 351 EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_STD) 351 352
+3 -3
arch/powerpc/kernel/ima_arch.c
··· 19 19 * to be stored as an xattr or as an appended signature. 20 20 * 21 21 * To avoid duplicate signature verification as much as possible, the IMA 22 - * policy rule for module appraisal is added only if CONFIG_MODULE_SIG_FORCE 22 + * policy rule for module appraisal is added only if CONFIG_MODULE_SIG 23 23 * is not enabled. 24 24 */ 25 25 static const char *const secure_rules[] = { 26 26 "appraise func=KEXEC_KERNEL_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", 27 - #ifndef CONFIG_MODULE_SIG_FORCE 27 + #ifndef CONFIG_MODULE_SIG 28 28 "appraise func=MODULE_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", 29 29 #endif 30 30 NULL ··· 50 50 "measure func=KEXEC_KERNEL_CHECK template=ima-modsig", 51 51 "measure func=MODULE_CHECK template=ima-modsig", 52 52 "appraise func=KEXEC_KERNEL_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", 53 - #ifndef CONFIG_MODULE_SIG_FORCE 53 + #ifndef CONFIG_MODULE_SIG 54 54 "appraise func=MODULE_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", 55 55 #endif 56 56 NULL
+11 -9
arch/powerpc/kernel/syscall_64.c
··· 35 35 BUG_ON(!FULL_REGS(regs)); 36 36 BUG_ON(regs->softe != IRQS_ENABLED); 37 37 38 + kuap_check_amr(); 39 + 38 40 account_cpu_user_entry(); 39 41 40 42 #ifdef CONFIG_PPC_SPLPAR ··· 48 46 accumulate_stolen_time(); 49 47 } 50 48 #endif 51 - 52 - kuap_check_amr(); 53 49 54 50 /* 55 51 * This is not required for the syscall exit path, but makes the ··· 116 116 unsigned long *ti_flagsp = &current_thread_info()->flags; 117 117 unsigned long ti_flags; 118 118 unsigned long ret = 0; 119 + 120 + kuap_check_amr(); 119 121 120 122 regs->result = r3; 121 123 ··· 191 189 192 190 /* This pattern matches prep_irq_for_idle */ 193 191 __hard_EE_RI_disable(); 194 - if (unlikely(lazy_irq_pending())) { 192 + if (unlikely(lazy_irq_pending_nocheck())) { 195 193 __hard_RI_enable(); 196 194 trace_hardirqs_off(); 197 195 local_paca->irq_happened |= PACA_IRQ_HARD_DIS; ··· 205 203 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 206 204 local_paca->tm_scratch = regs->msr; 207 205 #endif 208 - 209 - kuap_check_amr(); 210 206 211 207 account_cpu_user_exit(); 212 208 ··· 227 227 BUG_ON(!(regs->msr & MSR_PR)); 228 228 BUG_ON(!FULL_REGS(regs)); 229 229 BUG_ON(regs->softe != IRQS_ENABLED); 230 + 231 + kuap_check_amr(); 230 232 231 233 local_irq_save(flags); 232 234 ··· 266 264 267 265 trace_hardirqs_on(); 268 266 __hard_EE_RI_disable(); 269 - if (unlikely(lazy_irq_pending())) { 267 + if (unlikely(lazy_irq_pending_nocheck())) { 270 268 __hard_RI_enable(); 271 269 trace_hardirqs_off(); 272 270 local_paca->irq_happened |= PACA_IRQ_HARD_DIS; ··· 294 292 local_paca->tm_scratch = regs->msr; 295 293 #endif 296 294 297 - kuap_check_amr(); 298 - 299 295 account_cpu_user_exit(); 300 296 301 297 return ret; ··· 312 312 unrecoverable_exception(regs); 313 313 BUG_ON(regs->msr & MSR_PR); 314 314 BUG_ON(!FULL_REGS(regs)); 315 + 316 + kuap_check_amr(); 315 317 316 318 if (unlikely(*ti_flagsp & _TIF_EMULATE_STACK_STORE)) { 317 319 clear_bits(_TIF_EMULATE_STACK_STORE, ti_flagsp); ··· 336 334 337 335 trace_hardirqs_on(); 338 336 __hard_EE_RI_disable(); 339 - if (unlikely(lazy_irq_pending())) { 337 + if (unlikely(lazy_irq_pending_nocheck())) { 340 338 __hard_RI_enable(); 341 339 irq_soft_mask_set(IRQS_ALL_DISABLED); 342 340 trace_hardirqs_off();
+3 -3
arch/powerpc/kernel/vdso32/gettimeofday.S
··· 218 218 blr 219 219 220 220 /* 221 - * invalid clock 221 + * syscall fallback 222 222 */ 223 223 99: 224 - li r3, EINVAL 225 - crset so 224 + li r0,__NR_clock_getres 225 + sc 226 226 blr 227 227 .cfi_endproc 228 228 V_FUNCTION_END(__kernel_clock_getres)