]> Git Repo - J-linux.git/commitdiff
Merge tag 'fork-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux
authorLinus Torvalds <[email protected]>
Tue, 4 Aug 2020 21:47:45 +0000 (14:47 -0700)
committerLinus Torvalds <[email protected]>
Tue, 4 Aug 2020 21:47:45 +0000 (14:47 -0700)
Pull fork cleanups from Christian Brauner:
 "This is cleanup series from when we reworked a chunk of the process
  creation paths in the kernel and switched to struct
  {kernel_}clone_args.

  High-level this does two main things:

   - Remove the double export of both do_fork() and _do_fork() where
     do_fork() used the incosistent legacy clone calling convention.

     Now we only export _do_fork() which is based on struct
     kernel_clone_args.

   - Remove the copy_thread_tls()/copy_thread() split making the
     architecture specific HAVE_COYP_THREAD_TLS config option obsolete.

  This switches all remaining architectures to select
  HAVE_COPY_THREAD_TLS and thus to the copy_thread_tls() calling
  convention. The current split makes the process creation codepaths
  more convoluted than they need to be. Each architecture has their own
  copy_thread() function unless it selects HAVE_COPY_THREAD_TLS then it
  has a copy_thread_tls() function.

  The split is not needed anymore nowadays, all architectures support
  CLONE_SETTLS but quite a few of them never bothered to select
  HAVE_COPY_THREAD_TLS and instead simply continued to use copy_thread()
  and use the old calling convention. Removing this split cleans up the
  process creation codepaths and paves the way for implementing clone3()
  on such architectures since it requires the copy_thread_tls() calling
  convention.

  After having made each architectures support copy_thread_tls() this
  series simply renames that function back to copy_thread(). It also
  switches all architectures that call do_fork() directly over to
  _do_fork() and the struct kernel_clone_args calling convention. This
  is a corollary of switching the architectures that did not yet support
  it over to copy_thread_tls() since do_fork() is conditional on not
  supporting copy_thread_tls() (Mostly because it lacks a separate
  argument for tls which is trivial to fix but there's no need for this
  function to exist.).

  The do_fork() removal is in itself already useful as it allows to to
  remove the export of both do_fork() and _do_fork() we currently have
  in favor of only _do_fork(). This has already been discussed back when
  we added clone3(). The legacy clone() calling convention is - as is
  probably well-known - somewhat odd:

    #
    # ABI hall of shame
    #
    config CLONE_BACKWARDS
    config CLONE_BACKWARDS2
    config CLONE_BACKWARDS3

  that is aggravated by the fact that some architectures such as sparc
  follow the CLONE_BACKWARDSx calling convention but don't really select
  the corresponding config option since they call do_fork() directly.

  So do_fork() enforces a somewhat arbitrary calling convention in the
  first place that doesn't really help the individual architectures that
  deviate from it. They can thus simply be switched to _do_fork()
  enforcing a single calling convention. (I really hope that any new
  architectures will __not__ try to implement their own calling
  conventions...)

  Most architectures already have made a similar switch (m68k comes to
  mind).

  Overall this removes more code than it adds even with a good portion
  of added comments. It simplifies a chunk of arch specific assembly
  either by moving the code into C or by simply rewriting the assembly.

  Architectures that have been touched in non-trivial ways have all been
  actually boot and stress tested: sparc and ia64 have been tested with
  Debian 9 images. They are the two architectures which have been
  touched the most. All non-trivial changes to architectures have seen
  acks from the relevant maintainers. nios2 with a custom built
  buildroot image. h8300 I couldn't get something bootable to test on
  but the changes have been fairly automatic and I'm sure we'll hear
  people yell if I broke something there.

  All other architectures that have been touched in trivial ways have
  been compile tested for each single patch of the series via git rebase
  -x "make ..." v5.8-rc2. arm{64} and x86{_64} have been boot tested
  even though they have just been trivially touched (removal of the
  HAVE_COPY_THREAD_TLS macro from their Kconfig) because well they are
  basically "core architectures" and since it is trivial to get your
  hands on a useable image"

* tag 'fork-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
  arch: rename copy_thread_tls() back to copy_thread()
  arch: remove HAVE_COPY_THREAD_TLS
  unicore: switch to copy_thread_tls()
  sh: switch to copy_thread_tls()
  nds32: switch to copy_thread_tls()
  microblaze: switch to copy_thread_tls()
  hexagon: switch to copy_thread_tls()
  c6x: switch to copy_thread_tls()
  alpha: switch to copy_thread_tls()
  fork: remove do_fork()
  h8300: select HAVE_COPY_THREAD_TLS, switch to kernel_clone_args
  nios2: enable HAVE_COPY_THREAD_TLS, switch to kernel_clone_args
  ia64: enable HAVE_COPY_THREAD_TLS, switch to kernel_clone_args
  sparc: unconditionally enable HAVE_COPY_THREAD_TLS
  sparc: share process creation helpers between sparc and sparc64
  sparc64: enable HAVE_COPY_THREAD_TLS
  fork: fold legacy_clone_args_valid() into _do_fork()

1  2 
arch/arc/Kconfig
arch/arm/Kconfig
arch/arm64/Kconfig
arch/ia64/kernel/process.c
arch/riscv/Kconfig
arch/s390/Kconfig
arch/x86/Kconfig
arch/x86/kernel/process.c
arch/x86/kernel/unwind_frame.c
include/linux/sched/task.h
kernel/fork.c

diff --combined arch/arc/Kconfig
index 197896cfbd23e04d8c19bfbdddbb194e3a5aa209,1fa0b98ed9ce3d3da89f69cf98962778065325da..ba00c4e1e1c2719719c9bc4fe8e1cecf2312ccdf
@@@ -29,7 -29,6 +29,6 @@@ config AR
        select GENERIC_SMP_IDLE_THREAD
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
-       select HAVE_COPY_THREAD_TLS
        select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_FUTEX_CMPXCHG if FUTEX
@@@ -170,15 -169,6 +169,15 @@@ config ARC_CPU_H
  
  endchoice
  
 +config ARC_TUNE_MCPU
 +      string "Override default -mcpu compiler flag"
 +      default ""
 +      help
 +        Override default -mcpu=xxx compiler flag (which is set depending on
 +        the ISA version) with the specified value.
 +        NOTE: If specified flag isn't supported by current compiler the
 +        ISA default value will be used as a fallback.
 +
  config CPU_BIG_ENDIAN
        bool "Enable Big Endian Mode"
        help
@@@ -474,12 -464,6 +473,12 @@@ config ARC_IRQ_NO_AUTOSAV
          This is programmable and can be optionally disabled in which case
          software INTERRUPT_PROLOGUE/EPILGUE do the needed work
  
 +config ARC_LPB_DISABLE
 +      bool "Disable loop buffer (LPB)"
 +      help
 +        On HS cores, loop buffer (LPB) is programmable in runtime and can
 +        be optionally disabled.
 +
  endif # ISA_ARCV2
  
  endmenu   # "ARC CPU Configuration"
diff --combined arch/arm/Kconfig
index d54c413ad93757d65a4f0da5b0d9f01af06f9912,445b5ed693f08a690cd2979a54f6cf7d1c989145..c51eaeb1742b7805070d1556dbdd58ce5587841a
@@@ -72,7 -72,6 +72,6 @@@ config AR
        select HAVE_ARM_SMCCC if CPU_V7
        select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
        select HAVE_CONTEXT_TRACKING
-       select HAVE_COPY_THREAD_TLS
        select HAVE_C_RECORDMCOUNT
        select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
        select HAVE_DMA_CONTIGUOUS if MMU
@@@ -668,8 -667,6 +667,8 @@@ source "arch/arm/mach-mmp/Kconfig
  
  source "arch/arm/mach-moxart/Kconfig"
  
 +source "arch/arm/mach-mstar/Kconfig"
 +
  source "arch/arm/mach-mv78xx0/Kconfig"
  
  source "arch/arm/mach-mvebu/Kconfig"
diff --combined arch/arm64/Kconfig
index 73aee7290cdfe8d333fad7ae374c01d65f5df443,de93e965727d6dcd24f16485fd529500eaad73ba..e11b4ea061279ea161a0ed713c8d6a20800a3693
@@@ -118,7 -118,6 +118,7 @@@ config ARM6
        select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select GENERIC_GETTIMEOFDAY
 +      select GENERIC_VDSO_TIME_NS
        select HANDLE_DOMAIN_IRQ
        select HARDIRQS_SW_RESEND
        select HAVE_PCI
        select HAVE_CMPXCHG_DOUBLE
        select HAVE_CMPXCHG_LOCAL
        select HAVE_CONTEXT_TRACKING
-       select HAVE_COPY_THREAD_TLS
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS
@@@ -1328,8 -1326,6 +1327,8 @@@ config SWP_EMULATIO
          ARMv8 obsoletes the use of A32 SWP/SWPB instructions such that
          they are always undefined. Say Y here to enable software
          emulation of these instructions for userspace using LDXR/STXR.
 +        This feature can be controlled at runtime with the abi.swp
 +        sysctl which is disabled by default.
  
          In some older versions of glibc [<=2.8] SWP is used during futex
          trylock() operations with the assumption that the code will not
@@@ -1356,8 -1352,7 +1355,8 @@@ config CP15_BARRIER_EMULATIO
          Say Y here to enable software emulation of these
          instructions for AArch32 userspace code. When this option is
          enabled, CP15 barrier usage is traced which can help
 -        identify software that needs updating.
 +        identify software that needs updating. This feature can be
 +        controlled at runtime with the abi.cp15_barrier sysctl.
  
          If unsure, say Y
  
@@@ -1368,8 -1363,7 +1367,8 @@@ config SETEND_EMULATIO
          AArch32 EL0, and is deprecated in ARMv8.
  
          Say Y here to enable software emulation of the instruction
 -        for AArch32 userspace code.
 +        for AArch32 userspace code. This feature can be controlled
 +        at runtime with the abi.setend sysctl.
  
          Note: All the cpus on the system must have mixed endian support at EL0
          for this feature to be enabled. If a new CPU - which doesn't support mixed
@@@ -1523,9 -1517,9 +1522,9 @@@ config ARM64_PTR_AUT
        default y
        depends on !KVM || ARM64_VHE
        depends on (CC_HAS_SIGN_RETURN_ADDRESS || CC_HAS_BRANCH_PROT_PAC_RET) && AS_HAS_PAC
 -      # GCC 9.1 and later inserts a .note.gnu.property section note for PAC
 +      # Modern compilers insert a .note.gnu.property section note for PAC
        # which is only understood by binutils starting with version 2.33.1.
 -      depends on !CC_IS_GCC || GCC_VERSION < 90100 || LD_VERSION >= 233010000
 +      depends on LD_IS_LLD || LD_VERSION >= 233010000 || (CC_IS_GCC && GCC_VERSION < 90100)
        depends on !CC_IS_CLANG || AS_HAS_CFI_NEGATE_RA_STATE
        depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS)
        help
@@@ -1601,20 -1595,6 +1600,20 @@@ config ARM64_AMU_EXT
          correctly reflect reality. Most commonly, the value read will be 0,
          indicating that the counter is not enabled.
  
 +config AS_HAS_ARMV8_4
 +      def_bool $(cc-option,-Wa$(comma)-march=armv8.4-a)
 +
 +config ARM64_TLB_RANGE
 +      bool "Enable support for tlbi range feature"
 +      default y
 +      depends on AS_HAS_ARMV8_4
 +      help
 +        ARMv8.4-TLBI provides TLBI invalidation instruction that apply to a
 +        range of input addresses.
 +
 +        The feature introduces new assembly instructions, and they were
 +        support when binutils >= 2.30.
 +
  endmenu
  
  menu "ARMv8.5 architectural features"
index da55b41ae33e6ae2ebe743615fbb7aa63ea4bde7,9cedb56c3fda68ae2a0b2547592c08f9b9beab9b..7a4de9d994c5a65d8ffc977928adc0ed294da0ce
@@@ -296,7 -296,7 +296,7 @@@ ia64_load_extra (struct task_struct *ta
                pfm_load_regs(task);
  
        info = __this_cpu_read(pfm_syst_info);
-       if (info & PFM_CPUINFO_SYST_WIDE) 
+       if (info & PFM_CPUINFO_SYST_WIDE)
                pfm_syst_wide_update_task(task, info, 1);
  #endif
  }
   *
   *    <clone syscall>         <some kernel call frames>
   *    sys_clone                  :
-  *    do_fork                 do_fork
+  *    _do_fork                _do_fork
   *    copy_thread             copy_thread
   *
   * This means that the stack layout is as follows:
   * so there is nothing to worry about.
   */
  int
- copy_thread(unsigned long clone_flags,
-            unsigned long user_stack_base, unsigned long user_stack_size,
-            struct task_struct *p)
+ copy_thread(unsigned long clone_flags, unsigned long user_stack_base,
+           unsigned long user_stack_size, struct task_struct *p, unsigned long tls)
  {
        extern char ia64_ret_from_clone;
        struct switch_stack *child_stack, *stack;
        rbs_size = stack->ar_bspstore - rbs;
        memcpy((void *) child_rbs, (void *) rbs, rbs_size);
        if (clone_flags & CLONE_SETTLS)
-               child_ptregs->r13 = regs->r16;  /* see sys_clone2() in entry.S */
+               child_ptregs->r13 = tls;
        if (user_stack_base) {
                child_ptregs->r12 = user_stack_base + user_stack_size - 16;
                child_ptregs->ar_bspstore = user_stack_base;
        return retval;
  }
  
+ asmlinkage long ia64_clone(unsigned long clone_flags, unsigned long stack_start,
+                          unsigned long stack_size, unsigned long parent_tidptr,
+                          unsigned long child_tidptr, unsigned long tls)
+ {
+       struct kernel_clone_args args = {
+               .flags          = (lower_32_bits(clone_flags) & ~CSIGNAL),
+               .pidfd          = (int __user *)parent_tidptr,
+               .child_tid      = (int __user *)child_tidptr,
+               .parent_tid     = (int __user *)parent_tidptr,
+               .exit_signal    = (lower_32_bits(clone_flags) & CSIGNAL),
+               .stack          = stack_start,
+               .stack_size     = stack_size,
+               .tls            = tls,
+       };
+       return _do_fork(&args);
+ }
  static void
  do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
  {
        unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm;
 -      unsigned long uninitialized_var(ip);    /* GCC be quiet */
 +      unsigned long ip;
        elf_greg_t *dst = arg;
        struct pt_regs *pt;
        char nat;
diff --combined arch/riscv/Kconfig
index 3230c1d48562662575ca20926bc1bd7b0c1102f3,f6a3a2bea3d892fba4957d061952effdf6d652f3..6c4bce7cad8a2a5b915c936ff68bc8990e236978
@@@ -23,8 -23,6 +23,8 @@@ config RISC
        select ARCH_HAS_SET_DIRECT_MAP
        select ARCH_HAS_SET_MEMORY
        select ARCH_HAS_STRICT_KERNEL_RWX if MMU
 +      select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
 +      select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
        select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
        select ARCH_WANT_FRAME_POINTERS
        select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
@@@ -54,7 -52,6 +54,6 @@@
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ASM_MODVERSIONS
-       select HAVE_COPY_THREAD_TLS
        select HAVE_DMA_CONTIGUOUS if MMU
        select HAVE_EBPF_JIT if MMU
        select HAVE_FUTEX_CMPXCHG if FUTEX
diff --combined arch/s390/Kconfig
index 9cfd8de907cbe561a768dd537e6e3c2c2864c67a,959969759453a989e54909e0e8d62e58724dcf9a..e55debeeef9ad652fed08a78a88f8b5cb620cb7f
@@@ -102,6 -102,7 +102,6 @@@ config S39
        select ARCH_INLINE_WRITE_UNLOCK_BH
        select ARCH_INLINE_WRITE_UNLOCK_IRQ
        select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
 -      select ARCH_KEEP_MEMBLOCK
        select ARCH_STACKWALK
        select ARCH_SUPPORTS_ATOMIC_RMW
        select ARCH_SUPPORTS_NUMA_BALANCING
        select HAVE_ARCH_JUMP_LABEL_RELATIVE
        select HAVE_ARCH_KASAN
        select HAVE_ARCH_KASAN_VMALLOC
 +      select CLOCKSOURCE_VALIDATE_LAST_CYCLE
        select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_SOFT_DIRTY
        select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES
        select HAVE_CMPXCHG_DOUBLE
        select HAVE_CMPXCHG_LOCAL
-       select HAVE_COPY_THREAD_TLS
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
        select HAVE_FENTRY
        select HAVE_FTRACE_MCOUNT_RECORD
 +      select HAVE_FUNCTION_ERROR_INJECTION
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_TRACER
        select HAVE_FUTEX_CMPXCHG if FUTEX
@@@ -627,6 -625,10 +626,6 @@@ config ARCH_ENABLE_MEMORY_HOTREMOV
  config ARCH_ENABLE_SPLIT_PMD_PTLOCK
        def_bool y
  
 -config FORCE_MAX_ZONEORDER
 -      int
 -      default "9"
 -
  config MAX_PHYSMEM_BITS
        int "Maximum size of supported physical memory in bits (42-53)"
        range 42 53
diff --combined arch/x86/Kconfig
index 812baf2983f03e044afb3d22aed45d00fb4ea1b8,214b8bf39bbeb9be468dc3f315325c0bb33f5126..addb27d68c6ee98a5029161a6ec238ce6ed58a64
@@@ -67,7 -67,7 +67,7 @@@ config X8
        select ARCH_HAS_FILTER_PGPROT
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_GCOV_PROFILE_ALL
 -      select ARCH_HAS_KCOV                    if X86_64
 +      select ARCH_HAS_KCOV                    if X86_64 && STACK_VALIDATION
        select ARCH_HAS_MEM_ENCRYPT
        select ARCH_HAS_MEMBARRIER_SYNC_CORE
        select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
        select HAVE_CMPXCHG_DOUBLE
        select HAVE_CMPXCHG_LOCAL
        select HAVE_CONTEXT_TRACKING            if X86_64
-       select HAVE_COPY_THREAD_TLS
        select HAVE_C_RECORDMCOUNT
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_LZO
        select HAVE_KERNEL_XZ
 +      select HAVE_KERNEL_ZSTD
        select HAVE_KPROBES
        select HAVE_KPROBES_ON_FTRACE
        select HAVE_FUNCTION_ERROR_INJECTION
@@@ -1293,6 -1291,7 +1292,6 @@@ config MICROCOD
        bool "CPU microcode loading support"
        default y
        depends on CPU_SUP_AMD || CPU_SUP_INTEL
 -      select FW_LOADER
        help
          If you say Y here, you will be able to update the microcode on
          Intel and AMD processors. The Intel support is for the IA32 family,
@@@ -1314,6 -1313,7 +1313,6 @@@ config MICROCODE_INTE
        bool "Intel microcode loading support"
        depends on MICROCODE
        default MICROCODE
 -      select FW_LOADER
        help
          This options enables microcode patch loading support for Intel
          processors.
  config MICROCODE_AMD
        bool "AMD microcode loading support"
        depends on MICROCODE
 -      select FW_LOADER
        help
          If you select this option, microcode patch loading support for AMD
          processors will be enabled.
index fe67dbd76e5179911dfae10bdb2ecb2d11e6e8a1,b35cd50ed0dcab70a78ab24a87ff6a5b03bc13de..4298634d3f85e0241106ca25818377b27ad24518
@@@ -121,8 -121,8 +121,8 @@@ static int set_new_tls(struct task_stru
                return do_set_thread_area_64(p, ARCH_SET_FS, tls);
  }
  
- int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
-                   unsigned long arg, struct task_struct *p, unsigned long tls)
+ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
+               struct task_struct *p, unsigned long tls)
  {
        struct inactive_task_frame *frame;
        struct fork_frame *fork_frame;
@@@ -322,6 -322,20 +322,6 @@@ void arch_setup_new_exec(void
  }
  
  #ifdef CONFIG_X86_IOPL_IOPERM
 -static inline void tss_invalidate_io_bitmap(struct tss_struct *tss)
 -{
 -      /*
 -       * Invalidate the I/O bitmap by moving io_bitmap_base outside the
 -       * TSS limit so any subsequent I/O access from user space will
 -       * trigger a #GP.
 -       *
 -       * This is correct even when VMEXIT rewrites the TSS limit
 -       * to 0x67 as the only requirement is that the base points
 -       * outside the limit.
 -       */
 -      tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_INVALID;
 -}
 -
  static inline void switch_to_bitmap(unsigned long tifp)
  {
        /*
         * user mode.
         */
        if (tifp & _TIF_IO_BITMAP)
 -              tss_invalidate_io_bitmap(this_cpu_ptr(&cpu_tss_rw));
 +              tss_invalidate_io_bitmap();
  }
  
  static void tss_copy_io_bitmap(struct tss_struct *tss, struct io_bitmap *iobm)
@@@ -366,7 -380,7 +366,7 @@@ void native_tss_update_io_bitmap(void
        u16 *base = &tss->x86_tss.io_bitmap_base;
  
        if (!test_thread_flag(TIF_IO_BITMAP)) {
 -              tss_invalidate_io_bitmap(tss);
 +              native_tss_invalidate_io_bitmap();
                return;
        }
  
index e40b4942157fb8e7aa8c93896a66244784c52eb8,3070fd6561bea394d4d235faccaa449d11fb15f4..d7c44b257f7f4ea66bf4a49333fccb32f2c55d08
@@@ -269,13 -269,13 +269,13 @@@ bool unwind_next_frame(struct unwind_st
                /*
                 * kthreads (other than the boot CPU's idle thread) have some
                 * partial regs at the end of their stack which were placed
-                * there by copy_thread_tls().  But the regs don't have any
+                * there by copy_thread().  But the regs don't have any
                 * useful information, so we can skip them.
                 *
                 * This user_mode() check is slightly broader than a PF_KTHREAD
                 * check because it also catches the awkward situation where a
                 * newly forked kthread transitions into a user task by calling
 -               * do_execve(), which eventually clears PF_KTHREAD.
 +               * kernel_execve(), which eventually clears PF_KTHREAD.
                 */
                if (!user_mode(regs))
                        goto the_end;
index 27b4fa454c8046d7ad7d4765955483db329dfd4b,b6253f2ea96a4d5d867e542459418475eceb638b..ae3060f0b0c9d1a632f956bf170bce1149f86a44
@@@ -55,7 -55,6 +55,7 @@@ extern asmlinkage void schedule_tail(st
  extern void init_idle(struct task_struct *idle, int cpu);
  
  extern int sched_fork(unsigned long clone_flags, struct task_struct *p);
 +extern void sched_post_fork(struct task_struct *p);
  extern void sched_dead(struct task_struct *p);
  
  void __noreturn do_task_dead(void);
@@@ -66,22 -65,9 +66,9 @@@ extern void fork_init(void)
  
  extern void release_task(struct task_struct * p);
  
- #ifdef CONFIG_HAVE_COPY_THREAD_TLS
- extern int copy_thread_tls(unsigned long, unsigned long, unsigned long,
-                       struct task_struct *, unsigned long);
- #else
  extern int copy_thread(unsigned long, unsigned long, unsigned long,
-                       struct task_struct *);
+                      struct task_struct *, unsigned long);
  
- /* Architectures that haven't opted into copy_thread_tls get the tls argument
-  * via pt_regs, so ignore the tls argument passed via C. */
- static inline int copy_thread_tls(
-               unsigned long clone_flags, unsigned long sp, unsigned long arg,
-               struct task_struct *p, unsigned long tls)
- {
-       return copy_thread(clone_flags, sp, arg, p);
- }
- #endif
  extern void flush_thread(void);
  
  #ifdef CONFIG_HAVE_EXIT_THREAD
@@@ -97,8 -83,6 +84,6 @@@ extern void exit_files(struct task_stru
  extern void exit_itimers(struct signal_struct *);
  
  extern long _do_fork(struct kernel_clone_args *kargs);
- extern bool legacy_clone_args_valid(const struct kernel_clone_args *kargs);
- extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *);
  struct task_struct *fork_idle(int);
  struct mm_struct *copy_init_mm(void);
  extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
@@@ -127,12 -111,6 +112,12 @@@ static inline void put_task_struct(stru
                __put_task_struct(t);
  }
  
 +static inline void put_task_struct_many(struct task_struct *t, int nr)
 +{
 +      if (refcount_sub_and_test(nr, &t->usage))
 +              __put_task_struct(t);
 +}
 +
  void put_task_struct_rcu_user(struct task_struct *task);
  
  #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT
diff --combined kernel/fork.c
index 40996d2a56b9c5d314ca02da6c02e76f98812bf0,790841eb0a217482827ab355deaa1e97ff0a8bb1..b7da9000dfb1f813196e6b25961bb25efb4e6d4e
@@@ -359,13 -359,7 +359,13 @@@ struct vm_area_struct *vm_area_dup(stru
        struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
  
        if (new) {
 -              *new = *orig;
 +              ASSERT_EXCLUSIVE_WRITER(orig->vm_flags);
 +              ASSERT_EXCLUSIVE_WRITER(orig->vm_file);
 +              /*
 +               * orig->shared.rb may be modified concurrently, but the clone
 +               * will be reinitialized.
 +               */
 +              *new = data_race(*orig);
                INIT_LIST_HEAD(&new->anon_vma_chain);
                new->vm_next = new->vm_prev = NULL;
        }
@@@ -479,6 -473,7 +479,6 @@@ void free_task(struct task_struct *tsk
  #endif
        rt_mutex_debug_task_free(tsk);
        ftrace_graph_exit_task(tsk);
 -      put_seccomp_filter(tsk);
        arch_release_task_struct(tsk);
        if (tsk->flags & PF_KTHREAD)
                free_kthread_struct(tsk);
@@@ -1792,18 -1787,22 +1792,18 @@@ static void pidfd_show_fdinfo(struct se
   */
  static __poll_t pidfd_poll(struct file *file, struct poll_table_struct *pts)
  {
 -      struct task_struct *task;
        struct pid *pid = file->private_data;
        __poll_t poll_flags = 0;
  
        poll_wait(file, &pid->wait_pidfd, pts);
  
 -      rcu_read_lock();
 -      task = pid_task(pid, PIDTYPE_PID);
        /*
         * Inform pollers only when the whole thread group exits.
         * If the thread group leader exits before all other threads in the
         * group, then poll(2) should block, similar to the wait(2) family.
         */
 -      if (!task || (task->exit_state && thread_group_empty(task)))
 +      if (thread_group_exited(pid))
                poll_flags = EPOLLIN | EPOLLRDNORM;
 -      rcu_read_unlock();
  
        return poll_flags;
  }
@@@ -1955,8 -1954,8 +1955,8 @@@ static __latent_entropy struct task_str
  
        rt_mutex_init_task(p);
  
 +      lockdep_assert_irqs_enabled();
  #ifdef CONFIG_PROVE_LOCKING
 -      DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
        DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
  #endif
        retval = -EAGAIN;
         * to stop root fork bombs.
         */
        retval = -EAGAIN;
 -      if (nr_threads >= max_threads)
 +      if (data_race(nr_threads >= max_threads))
                goto bad_fork_cleanup_count;
  
        delayacct_tsk_init(p);  /* Must remain after dup_task_struct() */
        seqcount_init(&p->mems_allowed_seq);
  #endif
  #ifdef CONFIG_TRACE_IRQFLAGS
 -      p->irq_events = 0;
 -      p->hardirqs_enabled = 0;
 -      p->hardirq_enable_ip = 0;
 -      p->hardirq_enable_event = 0;
 -      p->hardirq_disable_ip = _THIS_IP_;
 -      p->hardirq_disable_event = 0;
 -      p->softirqs_enabled = 1;
 -      p->softirq_enable_ip = _THIS_IP_;
 -      p->softirq_enable_event = 0;
 -      p->softirq_disable_ip = 0;
 -      p->softirq_disable_event = 0;
 -      p->hardirq_context = 0;
 -      p->softirq_context = 0;
 +      memset(&p->irqtrace, 0, sizeof(p->irqtrace));
 +      p->irqtrace.hardirq_disable_ip  = _THIS_IP_;
 +      p->irqtrace.softirq_enable_ip   = _THIS_IP_;
 +      p->softirqs_enabled             = 1;
 +      p->softirq_context              = 0;
  #endif
  
        p->pagefault_disabled = 0;
        retval = copy_io(clone_flags, p);
        if (retval)
                goto bad_fork_cleanup_namespaces;
-       retval = copy_thread_tls(clone_flags, args->stack, args->stack_size, p,
-                                args->tls);
+       retval = copy_thread(clone_flags, args->stack, args->stack_size, p, args->tls);
        if (retval)
                goto bad_fork_cleanup_io;
  
        write_unlock_irq(&tasklist_lock);
  
        proc_fork_connector(p);
 +      sched_post_fork(p);
        cgroup_post_fork(p, args);
        perf_event_fork(p);
  
@@@ -2416,6 -2421,20 +2415,20 @@@ long _do_fork(struct kernel_clone_args 
        int trace = 0;
        long nr;
  
+       /*
+        * For legacy clone() calls, CLONE_PIDFD uses the parent_tid argument
+        * to return the pidfd. Hence, CLONE_PIDFD and CLONE_PARENT_SETTID are
+        * mutually exclusive. With clone3() CLONE_PIDFD has grown a separate
+        * field in struct clone_args and it still doesn't make sense to have
+        * them both point at the same memory location. Performing this check
+        * here has the advantage that we don't need to have a separate helper
+        * to check for legacy clone().
+        */
+       if ((args->flags & CLONE_PIDFD) &&
+           (args->flags & CLONE_PARENT_SETTID) &&
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
        /*
         * Determine whether and which event to report to ptracer.  When
         * called from kernel_thread or CLONE_UNTRACED is explicitly
        return nr;
  }
  
- bool legacy_clone_args_valid(const struct kernel_clone_args *kargs)
- {
-       /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */
-       if ((kargs->flags & CLONE_PIDFD) &&
-           (kargs->flags & CLONE_PARENT_SETTID))
-               return false;
-       return true;
- }
- #ifndef CONFIG_HAVE_COPY_THREAD_TLS
- /* For compatibility with architectures that call do_fork directly rather than
-  * using the syscall entry points below. */
- long do_fork(unsigned long clone_flags,
-             unsigned long stack_start,
-             unsigned long stack_size,
-             int __user *parent_tidptr,
-             int __user *child_tidptr)
- {
-       struct kernel_clone_args args = {
-               .flags          = (lower_32_bits(clone_flags) & ~CSIGNAL),
-               .pidfd          = parent_tidptr,
-               .child_tid      = child_tidptr,
-               .parent_tid     = parent_tidptr,
-               .exit_signal    = (lower_32_bits(clone_flags) & CSIGNAL),
-               .stack          = stack_start,
-               .stack_size     = stack_size,
-       };
-       if (!legacy_clone_args_valid(&args))
-               return -EINVAL;
-       return _do_fork(&args);
- }
- #endif
  /*
   * Create a kernel thread.
   */
@@@ -2587,24 -2570,12 +2564,12 @@@ SYSCALL_DEFINE5(clone, unsigned long, c
                .tls            = tls,
        };
  
-       if (!legacy_clone_args_valid(&args))
-               return -EINVAL;
        return _do_fork(&args);
  }
  #endif
  
  #ifdef __ARCH_WANT_SYS_CLONE3
  
- /*
-  * copy_thread implementations handle CLONE_SETTLS by reading the TLS value from
-  * the registers containing the syscall arguments for clone. This doesn't work
-  * with clone3 since the TLS value is passed in clone_args instead.
-  */
- #ifndef CONFIG_HAVE_COPY_THREAD_TLS
- #error clone3 requires copy_thread_tls support in arch
- #endif
  noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
                                              struct clone_args __user *uargs,
                                              size_t usize)
@@@ -2919,7 -2890,7 +2884,7 @@@ static int unshare_fd(unsigned long uns
  /*
   * unshare allows a process to 'unshare' part of the process
   * context which was originally shared using clone.  copy_*
-  * functions used by do_fork() cannot be used here directly
+  * functions used by _do_fork() cannot be used here directly
   * because they modify an inactive task_struct that is being
   * constructed. Here we are modifying the current, active,
   * task_struct.
This page took 0.145793 seconds and 4 git commands to generate.