Skip to content
  • Fenghua Yu's avatar
    x86/umwait: Fix error handling in umwait_init() · e7409258
    Fenghua Yu authored
    
    
    Currently, failure of cpuhp_setup_state() is ignored and the syscore ops
    and the control interfaces can still be added even after the failure. But,
    this error handling will cause a few issues:
    
    1. The CPUs may have different values in the IA32_UMWAIT_CONTROL
       MSR because there is no way to roll back the control MSR on
       the CPUs which already set the MSR before the failure.
    
    2. If the sysfs interface is added successfully, there will be a mismatch
       between the global control value and the control MSR:
       - The interface shows the default global control value. But,
         the control MSR is not set to the value because the CPU online
         function, which is supposed to set the MSR to the value,
         is not installed.
       - If the sysadmin changes the global control value through
         the interface, the control MSR on all current online CPUs is
         set to the new value. But, the control MSR on newly onlined CPUs
         after the value change will not be set to the new value due to
         lack of the CPU online function.
    
    3. On resume from suspend/hibernation, the boot CPU restores the control
       MSR to the global control value through the syscore ops. But, the
       control MSR on all APs is not set due to lake of the CPU online
       function.
    
    To solve the issues and enforce consistent behavior on the failure
    of the CPU hotplug setup, make the following changes:
    
    1. Cache the original control MSR value which is configured by
       hardware or BIOS before kernel boot. This value is likely to
       be 0. But it could be a different number as well. Cache the
       control MSR only once before the MSR is changed.
    2. Add the CPU offline function so that the MSR is restored to the
       original control value on all CPUs on the failure.
    3. On the failure, exit from cpumait_init() so that the syscore ops
       and the control interfaces are not added.
    
    Reported-by: default avatarValdis Kletnieks <valdis.kletnieks@vt.edu>
    Suggested-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarFenghua Yu <fenghua.yu@intel.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Link: https://lkml.kernel.org/r/1565401237-60936-1-git-send-email-fenghua.yu@intel.com
    e7409258