Merge tag 'x86_urgent_for_5.8_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 28 Jun 2020 17:35:01 +0000 (10:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 28 Jun 2020 17:35:01 +0000 (10:35 -0700)
Pull x86 fixes from Borislav Petkov:

 - AMD Memory bandwidth counter width fix, by Babu Moger.

 - Use the proper length type in the 32-bit truncate() syscall variant,
   by Jiri Slaby.

 - Reinit IA32_FEAT_CTL during wakeup to fix the case where after
   resume, VMXON would #GP due to VMX not being properly enabled, by
   Sean Christopherson.

 - Fix a static checker warning in the resctrl code, by Dan Carpenter.

 - Add a CR4 pinning mask for bits which cannot change after boot, by
   Kees Cook.

 - Align the start of the loop of __clear_user() to 16 bytes, to improve
   performance on AMD zen1 and zen2 microarchitectures, by Matt Fleming.

* tag 'x86_urgent_for_5.8_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/asm/64: Align start of __clear_user() loop to 16-bytes
  x86/cpu: Use pinning mask for CR4 bits needing to be 0
  x86/resctrl: Fix a NULL vs IS_ERR() static checker warning in rdt_cdp_peer_get()
  x86/cpu: Reinitialize IA32_FEAT_CTL MSR on BSP during wakeup
  syscalls: Fix offset type of ksys_ftruncate()
  x86/resctrl: Fix memory bandwidth counter width for AMD

arch/x86/include/asm/cpu.h
arch/x86/kernel/cpu/centaur.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpu.h
arch/x86/kernel/cpu/resctrl/core.c
arch/x86/kernel/cpu/resctrl/internal.h
arch/x86/kernel/cpu/resctrl/rdtgroup.c
arch/x86/kernel/cpu/zhaoxin.c
arch/x86/lib/usercopy_64.c
arch/x86/power/cpu.c
include/linux/syscalls.h

index dd17c2da1af5ff5e0bb5b8cc61be2ced8159037c..da78ccbd493b77e30c0b56a2fa8c7267835ffdfb 100644 (file)
@@ -58,4 +58,9 @@ static inline bool handle_guest_split_lock(unsigned long ip)
        return false;
 }
 #endif
+#ifdef CONFIG_IA32_FEAT_CTL
+void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
+#else
+static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {}
+#endif
 #endif /* _ASM_X86_CPU_H */
index 426792565d864f0d3c93b900003c86abcda97adf..c5cf336e50776df0e3512132a973c6362d8773c2 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/sched.h>
 #include <linux/sched/clock.h>
 
+#include <asm/cpu.h>
 #include <asm/cpufeature.h>
 #include <asm/e820/api.h>
 #include <asm/mtrr.h>
index 043d93cdcaad29cf55e76072540fe34b7c72f0d5..95c090a45b4b4a9cc5cf463176183378743cb93f 100644 (file)
@@ -347,6 +347,9 @@ out:
        cr4_clear_bits(X86_CR4_UMIP);
 }
 
+/* These bits should not change their value after CPU init is finished. */
+static const unsigned long cr4_pinned_mask =
+       X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP | X86_CR4_FSGSBASE;
 static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning);
 static unsigned long cr4_pinned_bits __ro_after_init;
 
@@ -371,20 +374,20 @@ EXPORT_SYMBOL(native_write_cr0);
 
 void native_write_cr4(unsigned long val)
 {
-       unsigned long bits_missing = 0;
+       unsigned long bits_changed = 0;
 
 set_register:
        asm volatile("mov %0,%%cr4": "+r" (val), "+m" (cr4_pinned_bits));
 
        if (static_branch_likely(&cr_pinning)) {
-               if (unlikely((val & cr4_pinned_bits) != cr4_pinned_bits)) {
-                       bits_missing = ~val & cr4_pinned_bits;
-                       val |= bits_missing;
+               if (unlikely((val & cr4_pinned_mask) != cr4_pinned_bits)) {
+                       bits_changed = (val & cr4_pinned_mask) ^ cr4_pinned_bits;
+                       val = (val & ~cr4_pinned_mask) | cr4_pinned_bits;
                        goto set_register;
                }
-               /* Warn after we've set the missing bits. */
-               WARN_ONCE(bits_missing, "CR4 bits went missing: %lx!?\n",
-                         bits_missing);
+               /* Warn after we've corrected the changed bits. */
+               WARN_ONCE(bits_changed, "pinned CR4 bits changed: 0x%lx!?\n",
+                         bits_changed);
        }
 }
 #if IS_MODULE(CONFIG_LKDTM)
@@ -419,7 +422,7 @@ void cr4_init(void)
        if (boot_cpu_has(X86_FEATURE_PCID))
                cr4 |= X86_CR4_PCIDE;
        if (static_branch_likely(&cr_pinning))
-               cr4 |= cr4_pinned_bits;
+               cr4 = (cr4 & ~cr4_pinned_mask) | cr4_pinned_bits;
 
        __write_cr4(cr4);
 
@@ -434,10 +437,7 @@ void cr4_init(void)
  */
 static void __init setup_cr_pinning(void)
 {
-       unsigned long mask;
-
-       mask = (X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP);
-       cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & mask;
+       cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & cr4_pinned_mask;
        static_key_enable(&cr_pinning.key);
 }
 
index fb538fccd24c0a17d3786f5932bad0db45f3fcce..9d033693519aa51930a2b959209dfa3a37496dd7 100644 (file)
@@ -81,8 +81,4 @@ extern void update_srbds_msr(void);
 
 extern u64 x86_read_arch_cap_msr(void);
 
-#ifdef CONFIG_IA32_FEAT_CTL
-void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
-#endif
-
 #endif /* ARCH_X86_CPU_H */
index 12f967c6b603426995ff5ab45f29ef7593074574..6a9df71c1b9eae85312c15caac83ea59b8936ef6 100644 (file)
@@ -981,10 +981,10 @@ void resctrl_cpu_detect(struct cpuinfo_x86 *c)
 
                c->x86_cache_max_rmid  = ecx;
                c->x86_cache_occ_scale = ebx;
-               if (c->x86_vendor == X86_VENDOR_INTEL)
-                       c->x86_cache_mbm_width_offset = eax & 0xff;
-               else
-                       c->x86_cache_mbm_width_offset = -1;
+               c->x86_cache_mbm_width_offset = eax & 0xff;
+
+               if (c->x86_vendor == X86_VENDOR_AMD && !c->x86_cache_mbm_width_offset)
+                       c->x86_cache_mbm_width_offset = MBM_CNTR_WIDTH_OFFSET_AMD;
        }
 }
 
index f20a47d120b1bc5c5d869dbb6485f18fe8d1b75c..5ffa32256b3b269a579791270c10c23a17fb7108 100644 (file)
@@ -37,6 +37,7 @@
 #define MBA_IS_LINEAR                  0x4
 #define MBA_MAX_MBPS                   U32_MAX
 #define MAX_MBA_BW_AMD                 0x800
+#define MBM_CNTR_WIDTH_OFFSET_AMD      20
 
 #define RMID_VAL_ERROR                 BIT_ULL(63)
 #define RMID_VAL_UNAVAIL               BIT_ULL(62)
index 23b4b61319d3f8be81b05f66d86b04ec56f93a02..3f844f14fc0a63ec822b4538739d6210c1d0f14c 100644 (file)
@@ -1117,6 +1117,7 @@ static int rdt_cdp_peer_get(struct rdt_resource *r, struct rdt_domain *d,
        _d_cdp = rdt_find_domain(_r_cdp, d->id, NULL);
        if (WARN_ON(IS_ERR_OR_NULL(_d_cdp))) {
                _r_cdp = NULL;
+               _d_cdp = NULL;
                ret = -EINVAL;
        }
 
index df1358ba622bddf133be2b5a1ac179f57ef4295f..05fa4ef634902293e3286705134168b40d812932 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/sched.h>
 #include <linux/sched/clock.h>
 
+#include <asm/cpu.h>
 #include <asm/cpufeature.h>
 
 #include "cpu.h"
index fff28c6f73a212716c5d623c2810b2779ee899f0..b0dfac3d3df712e8db9b5ccf87287d0fb1ca244f 100644 (file)
@@ -24,6 +24,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size)
        asm volatile(
                "       testq  %[size8],%[size8]\n"
                "       jz     4f\n"
+               "       .align 16\n"
                "0:     movq $0,(%[dst])\n"
                "       addq   $8,%[dst]\n"
                "       decl %%ecx ; jnz   0b\n"
index 7c65102debaff2d9cf5d9ee498698e3013f7d7fc..db1378c6ff2621dcf5b5363424b79d63aea67991 100644 (file)
@@ -193,6 +193,8 @@ static void fix_processor_context(void)
  */
 static void notrace __restore_processor_state(struct saved_context *ctxt)
 {
+       struct cpuinfo_x86 *c;
+
        if (ctxt->misc_enable_saved)
                wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable);
        /*
@@ -263,6 +265,10 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
        mtrr_bp_restore();
        perf_restore_debug_store();
        msr_restore_context(ctxt);
+
+       c = &cpu_data(smp_processor_id());
+       if (cpu_has(c, X86_FEATURE_MSR_IA32_FEAT_CTL))
+               init_ia32_feat_ctl(c);
 }
 
 /* Needed by apm.c */
index 7c354c2955f51e78fbfd638dd3109f30a9398e0f..b951a87da9877c4c664c7244760a39bd87b83589 100644 (file)
@@ -1360,7 +1360,7 @@ static inline long ksys_lchown(const char __user *filename, uid_t user,
 
 extern long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 
-static inline long ksys_ftruncate(unsigned int fd, unsigned long length)
+static inline long ksys_ftruncate(unsigned int fd, loff_t length)
 {
        return do_sys_ftruncate(fd, length, 1);
 }