Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 Oct 2018 14:24:22 +0000 (15:24 +0100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 Oct 2018 14:24:22 +0000 (15:24 +0100)
Pull x86 asm updates from Ingo Molnar:
 "The main changes in this cycle were the fsgsbase related preparatory
  patches from Chang S. Bae - but there's also an optimized
  memcpy_flushcache() and a cleanup for the __cmpxchg_double() assembly
  glue"

* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/fsgsbase/64: Clean up various details
  x86/segments: Introduce the 'CPUNODE' naming to better document the segment limit CPU/node NR trick
  x86/vdso: Initialize the CPU/node NR segment descriptor earlier
  x86/vdso: Introduce helper functions for CPU and node number
  x86/segments/64: Rename the GDT PER_CPU entry to CPU_NUMBER
  x86/fsgsbase/64: Factor out FS/GS segment loading from __switch_to()
  x86/fsgsbase/64: Convert the ELF core dump code to the new FSGSBASE helpers
  x86/fsgsbase/64: Make ptrace use the new FS/GS base helpers
  x86/fsgsbase/64: Introduce FS/GS base helper functions
  x86/fsgsbase/64: Fix ptrace() to read the FS/GS base accurately
  x86/asm: Use CC_SET()/CC_OUT() in __cmpxchg_double()
  x86/asm: Optimize memcpy_flushcache()

1  2 
arch/x86/include/asm/elf.h
arch/x86/kernel/cpu/common.c
arch/x86/lib/usercopy_64.c

index a357031d85b59e778b21f1431b0fc1a327443841,1527ec351036992e68097c54afee247573b7cf16..69c0f892e310a37a9f8bd543227a73104616b5df
@@@ -10,6 -10,7 +10,7 @@@
  #include <asm/ptrace.h>
  #include <asm/user.h>
  #include <asm/auxvec.h>
+ #include <asm/fsgsbase.h>
  
  typedef unsigned long elf_greg_t;
  
@@@ -62,7 -63,8 +63,7 @@@ typedef struct user_fxsr_struct elf_fpx
  #define R_X86_64_PC16         13      /* 16 bit sign extended pc relative */
  #define R_X86_64_8            14      /* Direct 8 bit sign extended  */
  #define R_X86_64_PC8          15      /* 8 bit sign extended pc relative */
 -
 -#define R_X86_64_NUM          16
 +#define R_X86_64_PC64         24      /* Place relative 64-bit signed */
  
  /*
   * These are used to set parameters in the core dumps.
@@@ -204,7 -206,6 +205,6 @@@ void set_personality_ia32(bool)
  
  #define ELF_CORE_COPY_REGS(pr_reg, regs)                      \
  do {                                                          \
-       unsigned long base;                                     \
        unsigned v;                                             \
        (pr_reg)[0] = (regs)->r15;                              \
        (pr_reg)[1] = (regs)->r14;                              \
        (pr_reg)[18] = (regs)->flags;                           \
        (pr_reg)[19] = (regs)->sp;                              \
        (pr_reg)[20] = (regs)->ss;                              \
-       rdmsrl(MSR_FS_BASE, base); (pr_reg)[21] = base;         \
-       rdmsrl(MSR_KERNEL_GS_BASE, base); (pr_reg)[22] = base;  \
+       (pr_reg)[21] = x86_fsbase_read_cpu();                   \
+       (pr_reg)[22] = x86_gsbase_read_cpu_inactive();          \
        asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v;       \
        asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v;       \
        asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v;       \
index 10e5ccfa9278025c3a04ecbbd94e3e2cfe7a1583,7da587f4af528604bfec441d567d1c9a1094bf25..0b99a7fae6be8a7dae6f3c045f3b8f76abaccb86
@@@ -949,11 -949,11 +949,11 @@@ static void identify_cpu_without_cpuid(
  }
  
  static const __initconst struct x86_cpu_id cpu_no_speculation[] = {
 -      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_CEDARVIEW,   X86_FEATURE_ANY },
 -      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_CLOVERVIEW,  X86_FEATURE_ANY },
 -      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_LINCROFT,    X86_FEATURE_ANY },
 -      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_PENWELL,     X86_FEATURE_ANY },
 -      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_PINEVIEW,    X86_FEATURE_ANY },
 +      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_SALTWELL,    X86_FEATURE_ANY },
 +      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_SALTWELL_TABLET,     X86_FEATURE_ANY },
 +      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_BONNELL_MID, X86_FEATURE_ANY },
 +      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_SALTWELL_MID,        X86_FEATURE_ANY },
 +      { X86_VENDOR_INTEL,     6, INTEL_FAM6_ATOM_BONNELL,     X86_FEATURE_ANY },
        { X86_VENDOR_CENTAUR,   5 },
        { X86_VENDOR_INTEL,     5 },
        { X86_VENDOR_NSC,       5 },
@@@ -968,10 -968,10 +968,10 @@@ static const __initconst struct x86_cpu
  
  /* Only list CPUs which speculate but are non susceptible to SSB */
  static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = {
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT1     },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT      },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_AIRMONT         },
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT    },
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_MERRIFIELD      },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT_X    },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT_MID  },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_CORE_YONAH           },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_XEON_PHI_KNL         },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_XEON_PHI_KNM         },
  
  static const __initconst struct x86_cpu_id cpu_no_l1tf[] = {
        /* in addition to cpu_no_speculation */
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT1     },
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT    },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT      },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT_X    },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_AIRMONT         },
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_MERRIFIELD      },
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_MOOREFIELD      },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_SILVERMONT_MID  },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_AIRMONT_MID     },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_GOLDMONT        },
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_DENVERTON       },
 -      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_GEMINI_LAKE     },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_GOLDMONT_X      },
 +      { X86_VENDOR_INTEL,     6,      INTEL_FAM6_ATOM_GOLDMONT_PLUS   },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_XEON_PHI_KNL         },
        { X86_VENDOR_INTEL,     6,      INTEL_FAM6_XEON_PHI_KNM         },
        {}
@@@ -1669,6 -1669,29 +1669,29 @@@ static void wait_for_master_cpu(int cpu
  #endif
  }
  
+ #ifdef CONFIG_X86_64
+ static void setup_getcpu(int cpu)
+ {
+       unsigned long cpudata = vdso_encode_cpunode(cpu, early_cpu_to_node(cpu));
+       struct desc_struct d = { };
+       if (static_cpu_has(X86_FEATURE_RDTSCP))
+               write_rdtscp_aux(cpudata);
+       /* Store CPU and node number in limit. */
+       d.limit0 = cpudata;
+       d.limit1 = cpudata >> 16;
+       d.type = 5;             /* RO data, expand down, accessed */
+       d.dpl = 3;              /* Visible to user code */
+       d.s = 1;                /* Not a system segment */
+       d.p = 1;                /* Present */
+       d.d = 1;                /* 32-bit */
+       write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_CPUNODE, &d, DESCTYPE_S);
+ }
+ #endif
  /*
   * cpu_init() initializes state that is per-CPU. Some data is already
   * initialized (naturally) in the bootstrap process, such as the GDT
@@@ -1706,6 -1729,7 +1729,7 @@@ void cpu_init(void
            early_cpu_to_node(cpu) != NUMA_NO_NODE)
                set_numa_node(early_cpu_to_node(cpu));
  #endif
+       setup_getcpu(cpu);
  
        me = current;
  
index fefe64436398fc3c7e688bf3f7d4eeb97a1c4963,c50a1d815a37d29b5ace0c0c506a329da16e95dc..1bd837cdc4b197483a7b694a9084151db8e27770
@@@ -37,8 -37,8 +37,8 @@@ unsigned long __clear_user(void __user 
                "3:     lea 0(%[size1],%[size8],8),%[size8]\n"
                "       jmp 2b\n"
                ".previous\n"
 -              _ASM_EXTABLE(0b,3b)
 -              _ASM_EXTABLE(1b,2b)
 +              _ASM_EXTABLE_UA(0b, 3b)
 +              _ASM_EXTABLE_UA(1b, 2b)
                : [size8] "=&c"(size), [dst] "=&D" (__d0)
                : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr));
        clac();
@@@ -153,7 -153,7 +153,7 @@@ long __copy_user_flushcache(void *dst, 
        return rc;
  }
  
- void memcpy_flushcache(void *_dst, const void *_src, size_t size)
+ void __memcpy_flushcache(void *_dst, const void *_src, size_t size)
  {
        unsigned long dest = (unsigned long) _dst;
        unsigned long source = (unsigned long) _src;
                clean_cache_range((void *) dest, size);
        }
  }
- EXPORT_SYMBOL_GPL(memcpy_flushcache);
+ EXPORT_SYMBOL_GPL(__memcpy_flushcache);
  
  void memcpy_page_flushcache(char *to, struct page *page, size_t offset,
                size_t len)