Merge branch 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
Linus Torvalds [Mon, 1 Oct 2012 18:15:17 +0000 (11:15 -0700)]
Pull x86/microcode changes from Ingo Molnar:
 "The biggest changes are to AMD microcode patching: add code for
  caching all microcode patches which belong to the current family on
  which we're running, in the kernel.

  We look up the patch needed for each core from the cache at
  patch-application time instead of holding a single patch per-system"

* 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, microcode, AMD: Fix use after free in free_cache()
  x86, microcode, AMD: Rewrite patch application procedure
  x86, microcode, AMD: Add a small, per-family patches cache
  x86, microcode, AMD: Add reverse equiv table search
  x86, microcode: Add a refresh firmware flag to ->request_microcode_fw
  x86, microcode, AMD: Read CPUID(1).EAX on the correct cpu
  x86, microcode, AMD: Check before applying a patch
  x86, microcode, AMD: Remove useless get_ucode_data wrapper
  x86, microcode: Straighten out Kconfig text
  x86, microcode: Cleanup cpu hotplug notifier callback
  x86, microcode: Drop uci->mc check on resume path
  x86, microcode: Save an indentation level in reload_for_cpu

1  2 
arch/x86/Kconfig
arch/x86/kernel/microcode_core.c

diff --combined arch/x86/Kconfig
@@@ -7,13 -7,11 +7,13 @@@ config 64BI
          Say no to build a 32-bit kernel - formerly known as i386
  
  config X86_32
 -      def_bool !64BIT
 +      def_bool y
 +      depends on !64BIT
        select CLKSRC_I8253
  
  config X86_64
 -      def_bool 64BIT
 +      def_bool y
 +      depends on 64BIT
        select X86_DEV_DMA_OPS
  
  ### Arch settings
@@@ -38,7 -36,6 +38,7 @@@ config X8
        select HAVE_KRETPROBES
        select HAVE_OPTPROBES
        select HAVE_FTRACE_MCOUNT_RECORD
 +      select HAVE_FENTRY if X86_64
        select HAVE_C_RECORDMCOUNT
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_TRACER
@@@ -63,8 -60,6 +63,8 @@@
        select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS
        select HAVE_PERF_EVENTS_NMI
 +      select HAVE_PERF_REGS
 +      select HAVE_PERF_USER_STACK_DUMP
        select ANON_INODES
        select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
        select HAVE_CMPXCHG_LOCAL if !M386
        select KTIME_SCALAR if X86_32
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
 +      select HAVE_RCU_USER_QS if X86_64
 +      select HAVE_IRQ_TIME_ACCOUNTING
  
  config INSTRUCTION_DECODER
 -      def_bool (KPROBES || PERF_EVENTS || UPROBES)
 +      def_bool y
 +      depends on KPROBES || PERF_EVENTS || UPROBES
  
  config OUTPUT_FORMAT
        string
@@@ -135,15 -127,13 +135,15 @@@ config SBU
        bool
  
  config NEED_DMA_MAP_STATE
 -       def_bool (X86_64 || INTEL_IOMMU || DMA_API_DEBUG)
 +      def_bool y
 +      depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG
  
  config NEED_SG_DMA_LENGTH
        def_bool y
  
  config GENERIC_ISA_DMA
 -      def_bool ISA_DMA_API
 +      def_bool y
 +      depends on ISA_DMA_API
  
  config GENERIC_BUG
        def_bool y
@@@ -160,16 -150,13 +160,16 @@@ config GENERIC_GPI
        bool
  
  config ARCH_MAY_HAVE_PC_FDC
 -      def_bool ISA_DMA_API
 +      def_bool y
 +      depends on ISA_DMA_API
  
  config RWSEM_GENERIC_SPINLOCK
 -      def_bool !X86_XADD
 +      def_bool y
 +      depends on !X86_XADD
  
  config RWSEM_XCHGADD_ALGORITHM
 -      def_bool X86_XADD
 +      def_bool y
 +      depends on X86_XADD
  
  config GENERIC_CALIBRATE_DELAY
        def_bool y
@@@ -759,14 -746,13 +759,14 @@@ config SWIOTL
        def_bool y if X86_64
        ---help---
          Support for software bounce buffers used on x86-64 systems
 -        which don't have a hardware IOMMU (e.g. the current generation
 -        of Intel's x86-64 CPUs). Using this PCI devices which can only
 -        access 32-bits of memory can be used on systems with more than
 -        3 GB of memory. If unsure, say Y.
 +        which don't have a hardware IOMMU. Using this PCI devices
 +        which can only access 32-bits of memory can be used on systems
 +        with more than 3 GB of memory.
 +        If unsure, say Y.
  
  config IOMMU_HELPER
 -      def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU)
 +      def_bool y
 +      depends on CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU
  
  config MAXSMP
        bool "Enable Maximum number of SMP Processors and NUMA Nodes"
@@@ -810,6 -796,17 +810,6 @@@ config SCHED_M
          making when dealing with multi-core CPU chips at a cost of slightly
          increased overhead in some places. If unsure say N here.
  
 -config IRQ_TIME_ACCOUNTING
 -      bool "Fine granularity task level IRQ time accounting"
 -      default n
 -      ---help---
 -        Select this option to enable fine granularity task irq time
 -        accounting. This is done by reading a timestamp on each
 -        transitions between softirq and hardirq state, so there can be a
 -        small performance impact.
 -
 -        If in doubt, say N here.
 -
  source "kernel/Kconfig.preempt"
  
  config X86_UP_APIC
@@@ -874,7 -871,6 +874,7 @@@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQ
  
  config X86_MCE
        bool "Machine Check / overheating reporting"
 +      default y
        ---help---
          Machine Check support allows the processor to notify the
          kernel if it detects a problem (e.g. overheating, data corruption).
@@@ -986,25 -982,25 +986,25 @@@ config X86_REBOOTFIXUP
          Say N otherwise.
  
  config MICROCODE
-       tristate "/dev/cpu/microcode - microcode support"
+       tristate "CPU microcode loading support"
        select FW_LOADER
        ---help---
          If you say Y here, you will be able to update the microcode on
          certain Intel and AMD processors. The Intel support is for the
-         IA32 family, e.g. Pentium Pro, Pentium II, Pentium III,
-         Pentium 4, Xeon etc. The AMD support is for family 0x10 and
-         0x11 processors, e.g. Opteron, Phenom and Turion 64 Ultra.
-         You will obviously need the actual microcode binary data itself
-         which is not shipped with the Linux kernel.
+         IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4,
+         Xeon etc. The AMD support is for families 0x10 and later. You will
+         obviously need the actual microcode binary data itself which is not
+         shipped with the Linux kernel.
  
          This option selects the general module only, you need to select
          at least one vendor specific module as well.
  
-         To compile this driver as a module, choose M here: the
-         module will be called microcode.
+         To compile this driver as a module, choose M here: the module
+         will be called microcode.
  
  config MICROCODE_INTEL
-       bool "Intel microcode patch loading support"
+       bool "Intel microcode loading support"
        depends on MICROCODE
        default MICROCODE
        select FW_LOADER
          <http://www.urbanmyth.org/microcode/>.
  
  config MICROCODE_AMD
-       bool "AMD microcode patch loading support"
+       bool "AMD microcode loading support"
        depends on MICROCODE
        select FW_LOADER
        ---help---
@@@ -1163,12 -1159,10 +1163,12 @@@ config X86_PA
          consumes more pagetable space per process.
  
  config ARCH_PHYS_ADDR_T_64BIT
 -      def_bool X86_64 || X86_PAE
 +      def_bool y
 +      depends on X86_64 || X86_PAE
  
  config ARCH_DMA_ADDR_T_64BIT
 -      def_bool X86_64 || HIGHMEM64G
 +      def_bool y
 +      depends on X86_64 || HIGHMEM64G
  
  config DIRECT_GBPAGES
        bool "Enable 1GB pages for kernel pagetables" if EXPERT
@@@ -1291,8 -1285,8 +1291,8 @@@ config ARCH_SELECT_MEMORY_MODE
        depends on ARCH_SPARSEMEM_ENABLE
  
  config ARCH_MEMORY_PROBE
 -      def_bool X86_64
 -      depends on MEMORY_HOTPLUG
 +      def_bool y
 +      depends on X86_64 && MEMORY_HOTPLUG
  
  config ARCH_PROC_KCORE_TEXT
        def_bool y
@@@ -1981,6 -1975,7 +1981,6 @@@ config PCI_MMCONFI
  
  config PCI_CNB20LE_QUIRK
        bool "Read CNB20LE Host Bridge Windows" if EXPERT
 -      default n
        depends on PCI && EXPERIMENTAL
        help
          Read the PCI windows out of the CNB20LE host bridge. This allows
@@@ -2191,18 -2186,18 +2191,18 @@@ config COMPA
        depends on IA32_EMULATION || X86_X32
        select ARCH_WANT_OLD_COMPAT_IPC
  
 +if COMPAT
  config COMPAT_FOR_U64_ALIGNMENT
 -      def_bool COMPAT
 -      depends on X86_64
 +      def_bool y
  
  config SYSVIPC_COMPAT
        def_bool y
 -      depends on COMPAT && SYSVIPC
 +      depends on SYSVIPC
  
  config KEYS_COMPAT
 -      bool
 -      depends on COMPAT && KEYS
 -      default y
 +      def_bool y
 +      depends on KEYS
 +endif
  
  endmenu
  
@@@ -225,9 -225,6 +225,9 @@@ static ssize_t microcode_write(struct f
        if (do_microcode_update(buf, len) == 0)
                ret = (ssize_t)len;
  
 +      if (ret > 0)
 +              perf_check_microcode();
 +
        mutex_unlock(&microcode_mutex);
        put_online_cpus();
  
@@@ -279,19 -276,18 +279,18 @@@ static struct platform_device   *microcod
  static int reload_for_cpu(int cpu)
  {
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+       enum ucode_state ustate;
        int err = 0;
  
-       if (uci->valid) {
-               enum ucode_state ustate;
-               ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev);
-               if (ustate == UCODE_OK)
-                       apply_microcode_on_target(cpu);
-               else
-                       if (ustate == UCODE_ERROR)
-                               err = -EINVAL;
-       }
+       if (!uci->valid)
+               return err;
  
+       ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, true);
+       if (ustate == UCODE_OK)
+               apply_microcode_on_target(cpu);
+       else
+               if (ustate == UCODE_ERROR)
+                       err = -EINVAL;
        return err;
  }
  
@@@ -373,18 -369,15 +372,15 @@@ static void microcode_fini_cpu(int cpu
  
  static enum ucode_state microcode_resume_cpu(int cpu)
  {
-       struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-       if (!uci->mc)
-               return UCODE_NFOUND;
        pr_debug("CPU%d updated upon resume\n", cpu);
-       apply_microcode_on_target(cpu);
+       if (apply_microcode_on_target(cpu))
+               return UCODE_ERROR;
  
        return UCODE_OK;
  }
  
- static enum ucode_state microcode_init_cpu(int cpu)
+ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
  {
        enum ucode_state ustate;
  
        if (system_state != SYSTEM_RUNNING)
                return UCODE_NFOUND;
  
-       ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev);
+       ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev,
+                                                    refresh_fw);
  
        if (ustate == UCODE_OK) {
                pr_debug("CPU%d updated upon init\n", cpu);
  static enum ucode_state microcode_update_cpu(int cpu)
  {
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-       enum ucode_state ustate;
  
        if (uci->valid)
-               ustate = microcode_resume_cpu(cpu);
-       else
-               ustate = microcode_init_cpu(cpu);
+               return microcode_resume_cpu(cpu);
  
-       return ustate;
+       return microcode_init_cpu(cpu, false);
  }
  
  static int mc_device_add(struct device *dev, struct subsys_interface *sif)
        if (err)
                return err;
  
-       if (microcode_init_cpu(cpu) == UCODE_ERROR)
+       if (microcode_init_cpu(cpu, true) == UCODE_ERROR)
                return -EINVAL;
  
        return err;
@@@ -480,34 -471,41 +474,41 @@@ mc_cpu_callback(struct notifier_block *
        struct device *dev;
  
        dev = get_cpu_device(cpu);
-       switch (action) {
+       switch (action & ~CPU_TASKS_FROZEN) {
        case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
                microcode_update_cpu(cpu);
-       case CPU_DOWN_FAILED:
-       case CPU_DOWN_FAILED_FROZEN:
                pr_debug("CPU%d added\n", cpu);
+               /*
+                * "break" is missing on purpose here because we want to fall
+                * through in order to create the sysfs group.
+                */
+       case CPU_DOWN_FAILED:
                if (sysfs_create_group(&dev->kobj, &mc_attr_group))
                        pr_err("Failed to create group for CPU%d\n", cpu);
                break;
        case CPU_DOWN_PREPARE:
-       case CPU_DOWN_PREPARE_FROZEN:
                /* Suspend is in progress, only remove the interface */
                sysfs_remove_group(&dev->kobj, &mc_attr_group);
                pr_debug("CPU%d removed\n", cpu);
                break;
  
        /*
+        * case CPU_DEAD:
+        *
         * When a CPU goes offline, don't free up or invalidate the copy of
         * the microcode in kernel memory, so that we can reuse it when the
         * CPU comes back online without unnecessarily requesting the userspace
         * for it again.
         */
-       case CPU_UP_CANCELED_FROZEN:
-               /* The CPU refused to come up during a system resume */
-               microcode_fini_cpu(cpu);
-               break;
        }
+       /* The CPU refused to come up during a system resume */
+       if (action == CPU_UP_CANCELED_FROZEN)
+               microcode_fini_cpu(cpu);
        return NOTIFY_OK;
  }