From: Greg Kroah-Hartman Date: Sun, 9 Jun 2019 10:10:42 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v5.1.9~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a28f1d187f52c5eece4d7d8c4c2058688245ff0;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch fuse-fallocate-fix-return-with-locked-inode.patch genwqe-prevent-an-integer-overflow-in-the-ioctl.patch mips-pistachio-build-uimage.gz-by-default.patch parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch --- diff --git a/queue-4.9/drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch b/queue-4.9/drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch new file mode 100644 index 00000000000..8c0ec685158 --- /dev/null +++ b/queue-4.9/drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch @@ -0,0 +1,60 @@ +From 7c420636860a719049fae9403e2c87804f53bdde Mon Sep 17 00:00:00 2001 +From: Patrik Jakobsson +Date: Tue, 16 Apr 2019 13:46:07 +0200 +Subject: drm/gma500/cdv: Check vbt config bits when detecting lvds panels + +From: Patrik Jakobsson + +commit 7c420636860a719049fae9403e2c87804f53bdde upstream. + +Some machines have an lvds child device in vbt even though a panel is +not attached. To make detection more reliable we now also check the lvds +config bits available in the vbt. + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1665766 +Cc: stable@vger.kernel.org +Reviewed-by: Hans de Goede +Signed-off-by: Patrik Jakobsson +Link: https://patchwork.freedesktop.org/patch/msgid/20190416114607.1072-1-patrik.r.jakobsson@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/gma500/cdv_intel_lvds.c | 3 +++ + drivers/gpu/drm/gma500/intel_bios.c | 3 +++ + drivers/gpu/drm/gma500/psb_drv.h | 1 + + 3 files changed, 7 insertions(+) + +--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c ++++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c +@@ -609,6 +609,9 @@ void cdv_intel_lvds_init(struct drm_devi + int pipe; + u8 pin; + ++ if (!dev_priv->lvds_enabled_in_vbt) ++ return; ++ + pin = GMBUS_PORT_PANEL; + if (!lvds_is_present_in_vbt(dev, &pin)) { + DRM_DEBUG_KMS("LVDS is not present in VBT\n"); +--- a/drivers/gpu/drm/gma500/intel_bios.c ++++ b/drivers/gpu/drm/gma500/intel_bios.c +@@ -436,6 +436,9 @@ parse_driver_features(struct drm_psb_pri + if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) + dev_priv->edp.support = 1; + ++ dev_priv->lvds_enabled_in_vbt = driver->lvds_config != 0; ++ DRM_DEBUG_KMS("LVDS VBT config bits: 0x%x\n", driver->lvds_config); ++ + /* This bit means to use 96Mhz for DPLL_A or not */ + if (driver->primary_lfp_id) + dev_priv->dplla_96mhz = true; +--- a/drivers/gpu/drm/gma500/psb_drv.h ++++ b/drivers/gpu/drm/gma500/psb_drv.h +@@ -538,6 +538,7 @@ struct drm_psb_private { + int lvds_ssc_freq; + bool is_lvds_on; + bool is_mipi_on; ++ bool lvds_enabled_in_vbt; + u32 mipi_ctrl_display; + + unsigned int core_freq; diff --git a/queue-4.9/fuse-fallocate-fix-return-with-locked-inode.patch b/queue-4.9/fuse-fallocate-fix-return-with-locked-inode.patch new file mode 100644 index 00000000000..4aac1572731 --- /dev/null +++ b/queue-4.9/fuse-fallocate-fix-return-with-locked-inode.patch @@ -0,0 +1,36 @@ +From 35d6fcbb7c3e296a52136347346a698a35af3fda Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Mon, 27 May 2019 11:42:07 +0200 +Subject: fuse: fallocate: fix return with locked inode + +From: Miklos Szeredi + +commit 35d6fcbb7c3e296a52136347346a698a35af3fda upstream. + +Do the proper cleanup in case the size check fails. + +Tested with xfstests:generic/228 + +Reported-by: kbuild test robot +Reported-by: Dan Carpenter +Fixes: 0cbade024ba5 ("fuse: honor RLIMIT_FSIZE in fuse_file_fallocate") +Cc: Liu Bo +Cc: # v3.5 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -2965,7 +2965,7 @@ static long fuse_file_fallocate(struct f + offset + length > i_size_read(inode)) { + err = inode_newsize_ok(inode, offset + length); + if (err) +- return err; ++ goto out; + } + + if (!(mode & FALLOC_FL_KEEP_SIZE)) diff --git a/queue-4.9/genwqe-prevent-an-integer-overflow-in-the-ioctl.patch b/queue-4.9/genwqe-prevent-an-integer-overflow-in-the-ioctl.patch new file mode 100644 index 00000000000..6e2aeecc6ca --- /dev/null +++ b/queue-4.9/genwqe-prevent-an-integer-overflow-in-the-ioctl.patch @@ -0,0 +1,57 @@ +From 110080cea0d0e4dfdb0b536e7f8a5633ead6a781 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 7 May 2019 11:36:34 +0300 +Subject: genwqe: Prevent an integer overflow in the ioctl + +From: Dan Carpenter + +commit 110080cea0d0e4dfdb0b536e7f8a5633ead6a781 upstream. + +There are a couple potential integer overflows here. + + round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE); + +The first thing is that the "m->size + (...)" addition could overflow, +and the second is that round_up() overflows to zero if the result is +within PAGE_SIZE of the type max. + +In this code, the "m->size" variable is an u64 but we're saving the +result in "map_size" which is an unsigned long and genwqe_user_vmap() +takes an unsigned long as well. So I have used ULONG_MAX as the upper +bound. From a practical perspective unsigned long is fine/better than +trying to change all the types to u64. + +Fixes: eaf4722d4645 ("GenWQE Character device and DDCB queue") +Signed-off-by: Dan Carpenter +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/genwqe/card_dev.c | 2 ++ + drivers/misc/genwqe/card_utils.c | 4 ++++ + 2 files changed, 6 insertions(+) + +--- a/drivers/misc/genwqe/card_dev.c ++++ b/drivers/misc/genwqe/card_dev.c +@@ -782,6 +782,8 @@ static int genwqe_pin_mem(struct genwqe_ + + if ((m->addr == 0x0) || (m->size == 0)) + return -EINVAL; ++ if (m->size > ULONG_MAX - PAGE_SIZE - (m->addr & ~PAGE_MASK)) ++ return -EINVAL; + + map_addr = (m->addr & PAGE_MASK); + map_size = round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE); +--- a/drivers/misc/genwqe/card_utils.c ++++ b/drivers/misc/genwqe/card_utils.c +@@ -582,6 +582,10 @@ int genwqe_user_vmap(struct genwqe_dev * + /* determine space needed for page_list. */ + data = (unsigned long)uaddr; + offs = offset_in_page(data); ++ if (size > ULONG_MAX - PAGE_SIZE - offs) { ++ m->size = 0; /* mark unused and not added */ ++ return -EINVAL; ++ } + m->nr_pages = DIV_ROUND_UP(offs + size, PAGE_SIZE); + + m->page_list = kcalloc(m->nr_pages, diff --git a/queue-4.9/mips-pistachio-build-uimage.gz-by-default.patch b/queue-4.9/mips-pistachio-build-uimage.gz-by-default.patch new file mode 100644 index 00000000000..b6e873edb4f --- /dev/null +++ b/queue-4.9/mips-pistachio-build-uimage.gz-by-default.patch @@ -0,0 +1,47 @@ +From e4f2d1af7163becb181419af9dece9206001e0a6 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Tue, 28 May 2019 17:21:26 +0000 +Subject: MIPS: pistachio: Build uImage.gz by default +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paul Burton + +commit e4f2d1af7163becb181419af9dece9206001e0a6 upstream. + +The pistachio platform uses the U-Boot bootloader & generally boots a +kernel in the uImage format. As such it's useful to build one when +building the kernel, but to do so currently requires the user to +manually specify a uImage target on the make command line. + +Make uImage.gz the pistachio platform's default build target, so that +the default is to build a kernel image that we can actually boot on a +board such as the MIPS Creator Ci40. + +Marked for stable backport as far as v4.1 where pistachio support was +introduced. This is primarily useful for CI systems such as kernelci.org +which will benefit from us building a suitable image which can then be +booted as part of automated testing, extending our test coverage to the +affected stable branches. + +Signed-off-by: Paul Burton +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Kevin Hilman +Tested-by: Kevin Hilman +URL: https://groups.io/g/kernelci/message/388 +Cc: stable@vger.kernel.org # v4.1+ +Cc: linux-mips@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/pistachio/Platform | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/mips/pistachio/Platform ++++ b/arch/mips/pistachio/Platform +@@ -6,3 +6,4 @@ cflags-$(CONFIG_MACH_PISTACHIO) += \ + -I$(srctree)/arch/mips/include/asm/mach-pistachio + load-$(CONFIG_MACH_PISTACHIO) += 0xffffffff80400000 + zload-$(CONFIG_MACH_PISTACHIO) += 0xffffffff81000000 ++all-$(CONFIG_MACH_PISTACHIO) := uImage.gz diff --git a/queue-4.9/parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch b/queue-4.9/parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch new file mode 100644 index 00000000000..ce5dfed5add --- /dev/null +++ b/queue-4.9/parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch @@ -0,0 +1,58 @@ +From 63923d2c3800919774f5c651d503d1dd2adaddd5 Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Mon, 27 May 2019 20:15:14 -0400 +Subject: parisc: Use implicit space register selection for loading the coherence index of I/O pdirs + +From: John David Anglin + +commit 63923d2c3800919774f5c651d503d1dd2adaddd5 upstream. + +We only support I/O to kernel space. Using %sr1 to load the coherence +index may be racy unless interrupts are disabled. This patch changes the +code used to load the coherence index to use implicit space register +selection. This saves one instruction and eliminates the race. + +Tested on rp3440, c8000 and c3750. + +Signed-off-by: John David Anglin +Cc: stable@vger.kernel.org +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/parisc/ccio-dma.c | 4 +--- + drivers/parisc/sba_iommu.c | 3 +-- + 2 files changed, 2 insertions(+), 5 deletions(-) + +--- a/drivers/parisc/ccio-dma.c ++++ b/drivers/parisc/ccio-dma.c +@@ -563,8 +563,6 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_ + /* We currently only support kernel addresses */ + BUG_ON(sid != KERNEL_SPACE); + +- mtsp(sid,1); +- + /* + ** WORD 1 - low order word + ** "hints" parm includes the VALID bit! +@@ -595,7 +593,7 @@ ccio_io_pdir_entry(u64 *pdir_ptr, space_ + ** Grab virtual index [0:11] + ** Deposit virt_idx bits into I/O PDIR word + */ +- asm volatile ("lci %%r0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); ++ asm volatile ("lci %%r0(%1), %0" : "=r" (ci) : "r" (vba)); + asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci)); + asm volatile ("depw %1,15,12,%0" : "+r" (pa) : "r" (ci)); + +--- a/drivers/parisc/sba_iommu.c ++++ b/drivers/parisc/sba_iommu.c +@@ -573,8 +573,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t + pa = virt_to_phys(vba); + pa &= IOVP_MASK; + +- mtsp(sid,1); +- asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); ++ asm("lci 0(%1), %0" : "=r" (ci) : "r" (vba)); + pa |= (ci >> PAGE_SHIFT) & 0xff; /* move CI (8 bits) into lowest byte */ + + pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */ diff --git a/queue-4.9/rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch b/queue-4.9/rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch new file mode 100644 index 00000000000..27b87fbed9e --- /dev/null +++ b/queue-4.9/rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch @@ -0,0 +1,67 @@ +From 66be4e66a7f422128748e3c3ef6ee72b20a6197b Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Mon, 3 Jun 2019 13:26:20 -0700 +Subject: rcu: locking and unlocking need to always be at least barriers + +From: Linus Torvalds + +commit 66be4e66a7f422128748e3c3ef6ee72b20a6197b upstream. + +Herbert Xu pointed out that commit bb73c52bad36 ("rcu: Don't disable +preemption for Tiny and Tree RCU readers") was incorrect in making the +preempt_disable/enable() be conditional on CONFIG_PREEMPT_COUNT. + +If CONFIG_PREEMPT_COUNT isn't enabled, the preemption enable/disable is +a no-op, but still is a compiler barrier. + +And RCU locking still _needs_ that compiler barrier. + +It is simply fundamentally not true that RCU locking would be a complete +no-op: we still need to guarantee (for example) that things that can +trap and cause preemption cannot migrate into the RCU locked region. + +The way we do that is by making it a barrier. + +See for example commit 386afc91144b ("spinlocks and preemption points +need to be at least compiler barriers") from back in 2013 that had +similar issues with spinlocks that become no-ops on UP: they must still +constrain the compiler from moving other operations into the critical +region. + +Now, it is true that a lot of RCU operations already use READ_ONCE() and +WRITE_ONCE() (which in practice likely would never be re-ordered wrt +anything remotely interesting), but it is also true that that is not +globally the case, and that it's not even necessarily always possible +(ie bitfields etc). + +Reported-by: Herbert Xu +Fixes: bb73c52bad36 ("rcu: Don't disable preemption for Tiny and Tree RCU readers") +Cc: stable@kernel.org +Cc: Boqun Feng +Cc: Paul E. McKenney +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/rcupdate.h | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/include/linux/rcupdate.h ++++ b/include/linux/rcupdate.h +@@ -306,14 +306,12 @@ void synchronize_rcu(void); + + static inline void __rcu_read_lock(void) + { +- if (IS_ENABLED(CONFIG_PREEMPT_COUNT)) +- preempt_disable(); ++ preempt_disable(); + } + + static inline void __rcu_read_unlock(void) + { +- if (IS_ENABLED(CONFIG_PREEMPT_COUNT)) +- preempt_enable(); ++ preempt_enable(); + } + + static inline void synchronize_rcu(void) diff --git a/queue-4.9/revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch b/queue-4.9/revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch new file mode 100644 index 00000000000..2fd7713f130 --- /dev/null +++ b/queue-4.9/revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch @@ -0,0 +1,84 @@ +From e98f09bcf3691350c589c1770532600132bad960 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Sun, 9 Jun 2019 12:02:32 +0200 +Subject: Revert "MIPS: perf: ath79: Fix perfcount IRQ assignment" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Greg Kroah-Hartman + +This reverts commit f9b1baac265600a61d36ebaf9ba657119303b5b5 which is +commit a1e8783db8e0d58891681bc1e6d9ada66eae8e20 upstream. + +Petr writes: + Karl has reported to me today, that he's experiencing weird + reboot hang on his devices with 4.9.180 kernel and that he has + bisected it down to my backported patch. + + I would like to kindly ask you for removal of this patch. This + patch should be reverted from all stable kernels up to 5.1, + because perf counters were not broken on those kernels, and this + patch won't work on the ath79 legacy IRQ code anyway, it needs + new irqchip driver which was enabled on ath79 with commit + 51fa4f8912c0 ("MIPS: ath79: drop legacy IRQ code"). + +Reported-by: Petr Štetiar +Cc: Kevin 'ldir' Darbyshire-Bryant +Cc: John Crispin +Cc: Marc Zyngier +Cc: Paul Burton +Cc: linux-mips@vger.kernel.org +Cc: Ralf Baechle +Cc: James Hogan +Cc: Thomas Gleixner +Cc: Jason Cooper +Cc: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/ath79/setup.c | 6 ++++++ + drivers/irqchip/irq-ath79-misc.c | 11 ----------- + 2 files changed, 6 insertions(+), 11 deletions(-) + +--- a/arch/mips/ath79/setup.c ++++ b/arch/mips/ath79/setup.c +@@ -183,6 +183,12 @@ const char *get_system_type(void) + return ath79_sys_type; + } + ++int get_c0_perfcount_int(void) ++{ ++ return ATH79_MISC_IRQ(5); ++} ++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); ++ + unsigned int get_c0_compare_int(void) + { + return CP0_LEGACY_COMPARE_IRQ; +--- a/drivers/irqchip/irq-ath79-misc.c ++++ b/drivers/irqchip/irq-ath79-misc.c +@@ -22,15 +22,6 @@ + #define AR71XX_RESET_REG_MISC_INT_ENABLE 4 + + #define ATH79_MISC_IRQ_COUNT 32 +-#define ATH79_MISC_PERF_IRQ 5 +- +-static int ath79_perfcount_irq; +- +-int get_c0_perfcount_int(void) +-{ +- return ath79_perfcount_irq; +-} +-EXPORT_SYMBOL_GPL(get_c0_perfcount_int); + + static void ath79_misc_irq_handler(struct irq_desc *desc) + { +@@ -122,8 +113,6 @@ static void __init ath79_misc_intc_domai + { + void __iomem *base = domain->host_data; + +- ath79_perfcount_irq = irq_create_mapping(domain, ATH79_MISC_PERF_IRQ); +- + /* Disable and clear all interrupts */ + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); diff --git a/queue-4.9/series b/queue-4.9/series index 8914c4e1ab1..78c39364e45 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -68,3 +68,11 @@ ipv6-fix-efault-on-sendto-with-icmpv6-and-hdrincl.patch ipv6-use-read_once-for-inet-hdrincl-as-in-ipv4.patch revert-fib_rules-fix-error-in-backport-of-e9919a24d302-fib_rules-return-0.patch revert-fib_rules-return-0-directly-if-an-exactly-same-rule-exists-when-nlm_f_excl-not-supplied.patch +rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch +parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch +fuse-fallocate-fix-return-with-locked-inode.patch +x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch +mips-pistachio-build-uimage.gz-by-default.patch +revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch +genwqe-prevent-an-integer-overflow-in-the-ioctl.patch +drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch diff --git a/queue-4.9/x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch b/queue-4.9/x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch new file mode 100644 index 00000000000..08cb4f30f2b --- /dev/null +++ b/queue-4.9/x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch @@ -0,0 +1,188 @@ +From ec527c318036a65a083ef68d8ba95789d2212246 Mon Sep 17 00:00:00 2001 +From: Jiri Kosina +Date: Thu, 30 May 2019 00:09:39 +0200 +Subject: x86/power: Fix 'nosmt' vs hibernation triple fault during resume + +From: Jiri Kosina + +commit ec527c318036a65a083ef68d8ba95789d2212246 upstream. + +As explained in + + 0cc3cd21657b ("cpu/hotplug: Boot HT siblings at least once") + +we always, no matter what, have to bring up x86 HT siblings during boot at +least once in order to avoid first MCE bringing the system to its knees. + +That means that whenever 'nosmt' is supplied on the kernel command-line, +all the HT siblings are as a result sitting in mwait or cpudile after +going through the online-offline cycle at least once. + +This causes a serious issue though when a kernel, which saw 'nosmt' on its +commandline, is going to perform resume from hibernation: if the resume +from the hibernated image is successful, cr3 is flipped in order to point +to the address space of the kernel that is being resumed, which in turn +means that all the HT siblings are all of a sudden mwaiting on address +which is no longer valid. + +That results in triple fault shortly after cr3 is switched, and machine +reboots. + +Fix this by always waking up all the SMT siblings before initiating the +'restore from hibernation' process; this guarantees that all the HT +siblings will be properly carried over to the resumed kernel waiting in +resume_play_dead(), and acted upon accordingly afterwards, based on the +target kernel configuration. + +Symmetricaly, the resumed kernel has to push the SMT siblings to mwait +again in case it has SMT disabled; this means it has to online all +the siblings when resuming (so that they come out of hlt) and offline +them again to let them reach mwait. + +Cc: 4.19+ # v4.19+ +Debugged-by: Thomas Gleixner +Fixes: 0cc3cd21657b ("cpu/hotplug: Boot HT siblings at least once") +Signed-off-by: Jiri Kosina +Acked-by: Pavel Machek +Reviewed-by: Thomas Gleixner +Reviewed-by: Josh Poimboeuf +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/power/cpu.c | 10 ++++++++++ + arch/x86/power/hibernate_64.c | 33 +++++++++++++++++++++++++++++++++ + include/linux/cpu.h | 4 ++++ + kernel/cpu.c | 4 ++-- + kernel/power/hibernate.c | 9 +++++++++ + 5 files changed, 58 insertions(+), 2 deletions(-) + +--- a/arch/x86/power/cpu.c ++++ b/arch/x86/power/cpu.c +@@ -292,7 +292,17 @@ int hibernate_resume_nonboot_cpu_disable + * address in its instruction pointer may not be possible to resolve + * any more at that point (the page tables used by it previously may + * have been overwritten by hibernate image data). ++ * ++ * First, make sure that we wake up all the potentially disabled SMT ++ * threads which have been initially brought up and then put into ++ * mwait/cpuidle sleep. ++ * Those will be put to proper (not interfering with hibernation ++ * resume) sleep afterwards, and the resumed kernel will decide itself ++ * what to do with them. + */ ++ ret = cpuhp_smt_enable(); ++ if (ret) ++ return ret; + smp_ops.play_dead = resume_play_dead; + ret = disable_nonboot_cpus(); + smp_ops.play_dead = play_dead; +--- a/arch/x86/power/hibernate_64.c ++++ b/arch/x86/power/hibernate_64.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -218,3 +219,35 @@ int arch_hibernation_header_restore(void + restore_cr3 = rdr->cr3; + return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL; + } ++ ++int arch_resume_nosmt(void) ++{ ++ int ret = 0; ++ /* ++ * We reached this while coming out of hibernation. This means ++ * that SMT siblings are sleeping in hlt, as mwait is not safe ++ * against control transition during resume (see comment in ++ * hibernate_resume_nonboot_cpu_disable()). ++ * ++ * If the resumed kernel has SMT disabled, we have to take all the ++ * SMT siblings out of hlt, and offline them again so that they ++ * end up in mwait proper. ++ * ++ * Called with hotplug disabled. ++ */ ++ cpu_hotplug_enable(); ++ if (cpu_smt_control == CPU_SMT_DISABLED || ++ cpu_smt_control == CPU_SMT_FORCE_DISABLED) { ++ enum cpuhp_smt_control old = cpu_smt_control; ++ ++ ret = cpuhp_smt_enable(); ++ if (ret) ++ goto out; ++ ret = cpuhp_smt_disable(old); ++ if (ret) ++ goto out; ++ } ++out: ++ cpu_hotplug_disable(); ++ return ret; ++} +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -271,11 +271,15 @@ extern enum cpuhp_smt_control cpu_smt_co + extern void cpu_smt_disable(bool force); + extern void cpu_smt_check_topology_early(void); + extern void cpu_smt_check_topology(void); ++extern int cpuhp_smt_enable(void); ++extern int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval); + #else + # define cpu_smt_control (CPU_SMT_ENABLED) + static inline void cpu_smt_disable(bool force) { } + static inline void cpu_smt_check_topology_early(void) { } + static inline void cpu_smt_check_topology(void) { } ++static inline int cpuhp_smt_enable(void) { return 0; } ++static inline int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { return 0; } + #endif + + /* +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1995,7 +1995,7 @@ static void cpuhp_online_cpu_device(unsi + kobject_uevent(&dev->kobj, KOBJ_ONLINE); + } + +-static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) ++int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) + { + int cpu, ret = 0; + +@@ -2029,7 +2029,7 @@ static int cpuhp_smt_disable(enum cpuhp_ + return ret; + } + +-static int cpuhp_smt_enable(void) ++int cpuhp_smt_enable(void) + { + int cpu, ret = 0; + +--- a/kernel/power/hibernate.c ++++ b/kernel/power/hibernate.c +@@ -256,6 +256,11 @@ void swsusp_show_speed(ktime_t start, kt + kps / 1000, (kps % 1000) / 10); + } + ++__weak int arch_resume_nosmt(void) ++{ ++ return 0; ++} ++ + /** + * create_image - Create a hibernation image. + * @platform_mode: Whether or not to use the platform driver. +@@ -322,6 +327,10 @@ static int create_image(int platform_mod + Enable_cpus: + enable_nonboot_cpus(); + ++ /* Allow architectures to do nosmt-specific post-resume dances */ ++ if (!in_suspend) ++ error = arch_resume_nosmt(); ++ + Platform_finish: + platform_finish(platform_mode); +