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 'sparc-for-7.0-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/alarsson/linux-sparc

Pull sparc updates from Andreas Larsson:

- Hardcode uapi ioctls.h TC* constants to not rely upon struct termio
that has been dropped by glibc

- Fix bug for fork/clone and add support for clone3

- Add ARCH_HAS_CC_CAN_LINK

- API choice improvements and cleanup of unused variables

* tag 'sparc-for-7.0-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/alarsson/linux-sparc:
sparc: remove unused variable strtab
sparc64: fix unused variable warning
sparc: don't reference obsolete termio struct for TC* constants
sparc: vio: Replace snprintf with strscpy in vio_create_one
sparc: Add architecture support for clone3
sparc: Synchronize user stack on fork and clone
sparc: Implement ARCH_HAS_CC_CAN_LINK

+119 -43
+11
arch/sparc/Kconfig
··· 13 13 config SPARC 14 14 bool 15 15 default y 16 + select ARCH_HAS_CC_CAN_LINK 16 17 select ARCH_HAS_CPU_CACHE_ALIASING 17 18 select ARCH_HAS_DMA_OPS 18 19 select ARCH_MIGHT_HAVE_PC_PARPORT if SPARC64 && PCI ··· 475 474 select HAVE_UID16 476 475 select ARCH_WANT_OLD_COMPAT_IPC 477 476 select COMPAT_OLD_SIGACTION 477 + 478 + config ARCH_CC_CAN_LINK 479 + bool 480 + default $(cc_can_link_user,-m64) if 64BIT 481 + default $(cc_can_link_user,-m32) 482 + 483 + config ARCH_USERFLAGS 484 + string 485 + default "-m64" if 64BIT 486 + default "-m32" 478 487 479 488 source "drivers/sbus/char/Kconfig"
+1
arch/sparc/include/asm/syscalls.h
··· 7 7 asmlinkage long sparc_fork(struct pt_regs *regs); 8 8 asmlinkage long sparc_vfork(struct pt_regs *regs); 9 9 asmlinkage long sparc_clone(struct pt_regs *regs); 10 + asmlinkage long sparc_clone3(struct pt_regs *regs); 10 11 11 12 #endif /* _SPARC64_SYSCALLS_H */
-2
arch/sparc/include/asm/unistd.h
··· 49 49 #define __ARCH_WANT_COMPAT_STAT 50 50 #endif 51 51 52 - #define __ARCH_BROKEN_SYS_CLONE3 53 - 54 52 #ifdef __32bit_syscall_numbers__ 55 53 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, 56 54 * it never had the plain ones and there is no value to adding those
+4 -4
arch/sparc/include/uapi/asm/ioctls.h
··· 5 5 #include <asm/ioctl.h> 6 6 7 7 /* Big T */ 8 - #define TCGETA _IOR('T', 1, struct termio) 9 - #define TCSETA _IOW('T', 2, struct termio) 10 - #define TCSETAW _IOW('T', 3, struct termio) 11 - #define TCSETAF _IOW('T', 4, struct termio) 8 + #define TCGETA 0x40125401 /* _IOR('T', 1, struct termio) */ 9 + #define TCSETA 0x80125402 /* _IOW('T', 2, struct termio) */ 10 + #define TCSETAW 0x80125403 /* _IOW('T', 3, struct termio) */ 11 + #define TCSETAF 0x80125404 /* _IOW('T', 4, struct termio) */ 12 12 #define TCSBRK _IO('T', 5) 13 13 #define TCXONC _IO('T', 6) 14 14 #define TCFLSH _IO('T', 7)
+15
arch/sparc/kernel/entry.S
··· 907 907 jmpl %l1 + %lo(sparc_vfork), %g0 908 908 add %sp, STACKFRAME_SZ, %o0 909 909 910 + .globl __sys_clone3, flush_patch_five 911 + __sys_clone3: 912 + mov %o7, %l5 913 + flush_patch_five: 914 + FLUSH_ALL_KERNEL_WINDOWS; 915 + ld [%curptr + TI_TASK], %o4 916 + rd %psr, %g4 917 + WRITE_PAUSE 918 + rd %wim, %g5 919 + WRITE_PAUSE 920 + std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr] 921 + add %sp, STACKFRAME_SZ, %o0 922 + call sparc_clone3 923 + mov %l5, %o7 924 + 910 925 .align 4 911 926 linux_sparc_ni_syscall: 912 927 sethi %hi(sys_ni_syscall), %l7
+1
arch/sparc/kernel/kernel.h
··· 18 18 asmlinkage long sparc_clone(struct pt_regs *regs); 19 19 asmlinkage long sparc_fork(struct pt_regs *regs); 20 20 asmlinkage long sparc_vfork(struct pt_regs *regs); 21 + asmlinkage long sparc_clone3(struct pt_regs *regs); 21 22 22 23 #ifdef CONFIG_SPARC64 23 24 /* setup_64.c */
-2
arch/sparc/kernel/module.c
··· 29 29 { 30 30 unsigned int symidx; 31 31 Elf_Sym *sym; 32 - char *strtab; 33 32 int i; 34 33 35 34 for (symidx = 0; sechdrs[symidx].sh_type != SHT_SYMTAB; symidx++) { ··· 38 39 } 39 40 } 40 41 sym = (Elf_Sym *)sechdrs[symidx].sh_addr; 41 - strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr; 42 42 43 43 for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) { 44 44 if (sym[i].st_shndx == SHN_UNDEF) {
+38 -14
arch/sparc/kernel/process.c
··· 12 12 #include <linux/sched/task.h> 13 13 #include <linux/sched/task_stack.h> 14 14 #include <linux/signal.h> 15 + #include <linux/syscalls.h> 15 16 16 17 #include "kernel.h" 17 18 18 19 asmlinkage long sparc_fork(struct pt_regs *regs) 19 20 { 20 - unsigned long orig_i1 = regs->u_regs[UREG_I1]; 21 + unsigned long orig_i1; 21 22 long ret; 22 23 struct kernel_clone_args args = { 23 24 .exit_signal = SIGCHLD, 24 - /* Reuse the parent's stack for the child. */ 25 - .stack = regs->u_regs[UREG_FP], 26 25 }; 26 + 27 + synchronize_user_stack(); 28 + 29 + orig_i1 = regs->u_regs[UREG_I1]; 30 + /* Reuse the parent's stack for the child. */ 31 + args.stack = regs->u_regs[UREG_FP]; 27 32 28 33 ret = kernel_clone(&args); 29 34 ··· 45 40 46 41 asmlinkage long sparc_vfork(struct pt_regs *regs) 47 42 { 48 - unsigned long orig_i1 = regs->u_regs[UREG_I1]; 43 + unsigned long orig_i1; 49 44 long ret; 50 - 51 45 struct kernel_clone_args args = { 52 46 .flags = CLONE_VFORK | CLONE_VM, 53 47 .exit_signal = SIGCHLD, 54 - /* Reuse the parent's stack for the child. */ 55 - .stack = regs->u_regs[UREG_FP], 56 48 }; 49 + 50 + synchronize_user_stack(); 51 + 52 + orig_i1 = regs->u_regs[UREG_I1]; 53 + /* Reuse the parent's stack for the child. */ 54 + args.stack = regs->u_regs[UREG_FP]; 57 55 58 56 ret = kernel_clone(&args); 59 57 ··· 73 65 74 66 asmlinkage long sparc_clone(struct pt_regs *regs) 75 67 { 76 - unsigned long orig_i1 = regs->u_regs[UREG_I1]; 77 - unsigned int flags = lower_32_bits(regs->u_regs[UREG_I0]); 68 + unsigned long orig_i1; 69 + unsigned int flags; 78 70 long ret; 71 + struct kernel_clone_args args = {0}; 79 72 80 - struct kernel_clone_args args = { 81 - .flags = (flags & ~CSIGNAL), 82 - .exit_signal = (flags & CSIGNAL), 83 - .tls = regs->u_regs[UREG_I3], 84 - }; 73 + synchronize_user_stack(); 74 + 75 + orig_i1 = regs->u_regs[UREG_I1]; 76 + flags = lower_32_bits(regs->u_regs[UREG_I0]); 77 + args.flags = (flags & ~CSIGNAL); 78 + args.exit_signal = (flags & CSIGNAL); 79 + args.tls = regs->u_regs[UREG_I3]; 85 80 86 81 #ifdef CONFIG_COMPAT 87 82 if (test_thread_flag(TIF_32BIT)) { ··· 118 107 regs->u_regs[UREG_I1] = orig_i1; 119 108 120 109 return ret; 110 + } 111 + 112 + asmlinkage long sparc_clone3(struct pt_regs *regs) 113 + { 114 + unsigned long sz; 115 + struct clone_args __user *cl_args; 116 + 117 + synchronize_user_stack(); 118 + 119 + cl_args = (struct clone_args __user *)regs->u_regs[UREG_I0]; 120 + sz = regs->u_regs[UREG_I1]; 121 + 122 + return sys_clone3(cl_args, sz); 121 123 }
+17 -6
arch/sparc/kernel/process_32.c
··· 247 247 * Parent --> %o0 == childs pid, %o1 == 0 248 248 * Child --> %o0 == parents pid, %o1 == 1 249 249 * 250 + * clone3() - Uses regular kernel return value conventions 251 + * 250 252 * NOTE: We have a separate fork kpsr/kwim because 251 253 * the parent could change these values between 252 254 * sys_fork invocation and when we reach here ··· 263 261 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 264 262 { 265 263 u64 clone_flags = args->flags; 266 - unsigned long sp = args->stack; 267 264 unsigned long tls = args->tls; 268 265 struct thread_info *ti = task_thread_info(p); 269 266 struct pt_regs *childregs, *regs = current_pt_regs(); 270 267 char *new_stack; 268 + unsigned long sp = args->stack ? args->stack : regs->u_regs[UREG_FP]; 271 269 272 270 #ifndef CONFIG_SMP 273 271 if(last_task_used_math == current) { ··· 352 350 childregs->psr &= ~PSR_EF; 353 351 clear_tsk_thread_flag(p, TIF_USEDFPU); 354 352 #endif 353 + /* Handle return value conventions */ 354 + if (regs->u_regs[UREG_G1] == __NR_clone3) { 355 + /* clone3() - use regular kernel return value convention */ 355 356 356 - /* Set the return value for the child. */ 357 - childregs->u_regs[UREG_I0] = current->pid; 358 - childregs->u_regs[UREG_I1] = 1; 357 + /* Set the return value for the child. */ 358 + childregs->u_regs[UREG_I0] = 0; 359 + } else { 360 + /* clone()/fork() - use SunOS return value convention */ 359 361 360 - /* Set the return value for the parent. */ 361 - regs->u_regs[UREG_I1] = 0; 362 + /* Set the return value for the child. */ 363 + childregs->u_regs[UREG_I0] = current->pid; 364 + childregs->u_regs[UREG_I1] = 1; 365 + 366 + /* Set the return value for the parent. */ 367 + regs->u_regs[UREG_I1] = 0; 368 + } 362 369 363 370 if (clone_flags & CLONE_SETTLS) 364 371 childregs->u_regs[UREG_G7] = tls;
+21 -6
arch/sparc/kernel/process_64.c
··· 564 564 * under SunOS are nothing short of bletcherous: 565 565 * Parent --> %o0 == childs pid, %o1 == 0 566 566 * Child --> %o0 == parents pid, %o1 == 1 567 + * 568 + * clone3() - Uses regular kernel return value conventions 567 569 */ 568 570 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) 569 571 { 570 572 u64 clone_flags = args->flags; 571 - unsigned long sp = args->stack; 572 573 unsigned long tls = args->tls; 573 574 struct thread_info *t = task_thread_info(p); 574 575 struct pt_regs *regs = current_pt_regs(); 575 576 struct sparc_stackf *parent_sf; 576 577 unsigned long child_stack_sz; 577 578 char *child_trap_frame; 579 + unsigned long sp = args->stack ? args->stack : regs->u_regs[UREG_FP]; 578 580 579 581 /* Calculate offset to stack_frame & pt_regs */ 580 582 child_stack_sz = (STACKFRAME_SZ + TRACEREG_SZ); ··· 618 616 if (t->utraps) 619 617 t->utraps[0]++; 620 618 621 - /* Set the return value for the child. */ 622 - t->kregs->u_regs[UREG_I0] = current->pid; 623 - t->kregs->u_regs[UREG_I1] = 1; 619 + /* Handle return value conventions */ 620 + if (regs->u_regs[UREG_G1] == __NR_clone3) { 621 + /* clone3() - use regular kernel return value convention */ 624 622 625 - /* Set the second return value for the parent. */ 626 - regs->u_regs[UREG_I1] = 0; 623 + /* Set the return value for the child. */ 624 + t->kregs->u_regs[UREG_I0] = 0; 625 + 626 + /* Clear g1 to indicate user thread */ 627 + t->kregs->u_regs[UREG_G1] = 0; 628 + } else { 629 + /* clone()/fork() - use SunOS return value convention */ 630 + 631 + /* Set the return value for the child. */ 632 + t->kregs->u_regs[UREG_I0] = current->pid; 633 + t->kregs->u_regs[UREG_I1] = 1; 634 + 635 + /* Set the second return value for the parent. */ 636 + regs->u_regs[UREG_I1] = 0; 637 + } 627 638 628 639 if (clone_flags & CLONE_SETTLS) 629 640 t->kregs->u_regs[UREG_G7] = tls;
+8
arch/sparc/kernel/syscalls.S
··· 103 103 ba,pt %xcc, sparc_clone 104 104 add %sp, PTREGS_OFF, %o0 105 105 106 + .align 32 107 + __sys_clone3: 108 + flushw 109 + ba,pt %xcc, sparc_clone3 110 + add %sp, PTREGS_OFF, %o0 111 + 106 112 .globl ret_from_fork 107 113 ret_from_fork: 108 114 /* Clear current_thread_info()->new_child. */ ··· 119 113 brnz,pt %o0, ret_sys_call 120 114 ldx [%g6 + TI_FLAGS], %l0 121 115 ldx [%sp + PTREGS_OFF + PT_V9_G1], %l1 116 + brz,pt %l1, ret_sys_call 117 + nop 122 118 call %l1 123 119 ldx [%sp + PTREGS_OFF + PT_V9_G2], %o0 124 120 ba,pt %xcc, ret_sys_call
+1 -1
arch/sparc/kernel/syscalls/syscall.tbl
··· 480 480 432 common fsmount sys_fsmount 481 481 433 common fspick sys_fspick 482 482 434 common pidfd_open sys_pidfd_open 483 - # 435 reserved for clone3 483 + 435 common clone3 __sys_clone3 484 484 436 common close_range sys_close_range 485 485 437 common openat2 sys_openat2 486 486 438 common pidfd_getfd sys_pidfd_getfd
+2 -2
arch/sparc/kernel/vio.c
··· 12 12 13 13 #include <linux/kernel.h> 14 14 #include <linux/slab.h> 15 + #include <linux/string.h> 15 16 #include <linux/irq.h> 16 17 #include <linux/export.h> 17 18 #include <linux/init.h> ··· 379 378 * the parent doesn't require the MD node info. 380 379 */ 381 380 if (node_name != NULL) { 382 - (void) snprintf(vdev->node_name, VIO_MAX_NAME_LEN, "%s", 383 - node_name); 381 + strscpy(vdev->node_name, node_name); 384 382 385 383 err = mdesc_get_node_info(hp, mp, node_name, 386 384 &vdev->md_node_info);
-6
arch/sparc/mm/init_64.c
··· 358 358 bool __init arch_hugetlb_valid_size(unsigned long size) 359 359 { 360 360 unsigned int hugepage_shift = ilog2(size); 361 - unsigned short hv_pgsz_idx; 362 361 unsigned int hv_pgsz_mask; 363 362 364 363 switch (hugepage_shift) { 365 364 case HPAGE_16GB_SHIFT: 366 365 hv_pgsz_mask = HV_PGSZ_MASK_16GB; 367 - hv_pgsz_idx = HV_PGSZ_IDX_16GB; 368 366 pud_huge_patch(); 369 367 break; 370 368 case HPAGE_2GB_SHIFT: 371 369 hv_pgsz_mask = HV_PGSZ_MASK_2GB; 372 - hv_pgsz_idx = HV_PGSZ_IDX_2GB; 373 370 break; 374 371 case HPAGE_256MB_SHIFT: 375 372 hv_pgsz_mask = HV_PGSZ_MASK_256MB; 376 - hv_pgsz_idx = HV_PGSZ_IDX_256MB; 377 373 break; 378 374 case HPAGE_SHIFT: 379 375 hv_pgsz_mask = HV_PGSZ_MASK_4MB; 380 - hv_pgsz_idx = HV_PGSZ_IDX_4MB; 381 376 break; 382 377 case HPAGE_64K_SHIFT: 383 378 hv_pgsz_mask = HV_PGSZ_MASK_64K; 384 - hv_pgsz_idx = HV_PGSZ_IDX_64K; 385 379 break; 386 380 default: 387 381 hv_pgsz_mask = 0;