From 43befe8d8d0ee4866dc88cde923673956905f289 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 9 Jun 2019 12:10:58 +0200 Subject: [PATCH] 4.14-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 i2c-xiic-add-max_read_len-quirk.patch mips-bounds-check-virt_addr_valid.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 pstore-convert-buf_lock-to-semaphore.patch pstore-ram-run-without-kernel-crash-dump-region.patch pstore-remove-needless-lock-during-console-writes.patch rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch test_firmware-use-correct-snprintf-limit.patch x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch --- ...nfig-bits-when-detecting-lvds-panels.patch | 60 +++++ ...llocate-fix-return-with-locked-inode.patch | 36 +++ ...ent-an-integer-overflow-in-the-ioctl.patch | 57 +++++ .../i2c-xiic-add-max_read_len-quirk.patch | 49 ++++ .../mips-bounds-check-virt_addr_valid.patch | 76 ++++++ ...pistachio-build-uimage.gz-by-default.patch | 47 ++++ ...ing-the-coherence-index-of-i-o-pdirs.patch | 58 +++++ ...pstore-convert-buf_lock-to-semaphore.patch | 242 ++++++++++++++++++ ...run-without-kernel-crash-dump-region.patch | 106 ++++++++ ...-needless-lock-during-console-writes.patch | 61 +++++ ...-need-to-always-be-at-least-barriers.patch | 67 +++++ ...f-ath79-fix-perfcount-irq-assignment.patch | 84 ++++++ queue-4.14/series | 14 + ..._firmware-use-correct-snprintf-limit.patch | 68 +++++ ...bernation-triple-fault-during-resume.patch | 187 ++++++++++++++ 15 files changed, 1212 insertions(+) create mode 100644 queue-4.14/drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch create mode 100644 queue-4.14/fuse-fallocate-fix-return-with-locked-inode.patch create mode 100644 queue-4.14/genwqe-prevent-an-integer-overflow-in-the-ioctl.patch create mode 100644 queue-4.14/i2c-xiic-add-max_read_len-quirk.patch create mode 100644 queue-4.14/mips-bounds-check-virt_addr_valid.patch create mode 100644 queue-4.14/mips-pistachio-build-uimage.gz-by-default.patch create mode 100644 queue-4.14/parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch create mode 100644 queue-4.14/pstore-convert-buf_lock-to-semaphore.patch create mode 100644 queue-4.14/pstore-ram-run-without-kernel-crash-dump-region.patch create mode 100644 queue-4.14/pstore-remove-needless-lock-during-console-writes.patch create mode 100644 queue-4.14/rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch create mode 100644 queue-4.14/revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch create mode 100644 queue-4.14/test_firmware-use-correct-snprintf-limit.patch create mode 100644 queue-4.14/x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch diff --git a/queue-4.14/drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch b/queue-4.14/drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch new file mode 100644 index 00000000000..07d7a23778b --- /dev/null +++ b/queue-4.14/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 +@@ -594,6 +594,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.14/fuse-fallocate-fix-return-with-locked-inode.patch b/queue-4.14/fuse-fallocate-fix-return-with-locked-inode.patch new file mode 100644 index 00000000000..79dc8eb4496 --- /dev/null +++ b/queue-4.14/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 +@@ -2978,7 +2978,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.14/genwqe-prevent-an-integer-overflow-in-the-ioctl.patch b/queue-4.14/genwqe-prevent-an-integer-overflow-in-the-ioctl.patch new file mode 100644 index 00000000000..6e2aeecc6ca --- /dev/null +++ b/queue-4.14/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.14/i2c-xiic-add-max_read_len-quirk.patch b/queue-4.14/i2c-xiic-add-max_read_len-quirk.patch new file mode 100644 index 00000000000..f966636a06d --- /dev/null +++ b/queue-4.14/i2c-xiic-add-max_read_len-quirk.patch @@ -0,0 +1,49 @@ +From 49b809586730a77b57ce620b2f9689de765d790b Mon Sep 17 00:00:00 2001 +From: Robert Hancock +Date: Tue, 4 Jun 2019 15:55:51 -0600 +Subject: i2c: xiic: Add max_read_len quirk + +From: Robert Hancock + +commit 49b809586730a77b57ce620b2f9689de765d790b upstream. + +This driver does not support reading more than 255 bytes at once because +the register for storing the number of bytes to read is only 8 bits. Add +a max_read_len quirk to enforce this. + +This was found when using this driver with the SFP driver, which was +previously reading all 256 bytes in the SFP EEPROM in one transaction. +This caused a bunch of hard-to-debug errors in the xiic driver since the +driver/logic was treating the number of bytes to read as zero. +Rejecting transactions that aren't supported at least allows the problem +to be diagnosed more easily. + +Signed-off-by: Robert Hancock +Reviewed-by: Michal Simek +Signed-off-by: Wolfram Sang +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-xiic.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/i2c/busses/i2c-xiic.c ++++ b/drivers/i2c/busses/i2c-xiic.c +@@ -725,11 +725,16 @@ static const struct i2c_algorithm xiic_a + .functionality = xiic_func, + }; + ++static const struct i2c_adapter_quirks xiic_quirks = { ++ .max_read_len = 255, ++}; ++ + static const struct i2c_adapter xiic_adapter = { + .owner = THIS_MODULE, + .name = DRIVER_NAME, + .class = I2C_CLASS_DEPRECATED, + .algo = &xiic_algorithm, ++ .quirks = &xiic_quirks, + }; + + diff --git a/queue-4.14/mips-bounds-check-virt_addr_valid.patch b/queue-4.14/mips-bounds-check-virt_addr_valid.patch new file mode 100644 index 00000000000..3623bd14304 --- /dev/null +++ b/queue-4.14/mips-bounds-check-virt_addr_valid.patch @@ -0,0 +1,76 @@ +From 074a1e1167afd82c26f6d03a9a8b997d564bb241 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Tue, 28 May 2019 17:05:03 +0000 +Subject: MIPS: Bounds check virt_addr_valid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paul Burton + +commit 074a1e1167afd82c26f6d03a9a8b997d564bb241 upstream. + +The virt_addr_valid() function is meant to return true iff +virt_to_page() will return a valid struct page reference. This is true +iff the address provided is found within the unmapped address range +between PAGE_OFFSET & MAP_BASE, but we don't currently check for that +condition. Instead we simply mask the address to obtain what will be a +physical address if the virtual address is indeed in the desired range, +shift it to form a PFN & then call pfn_valid(). This can incorrectly +return true if called with a virtual address which, after masking, +happens to form a physical address corresponding to a valid PFN. + +For example we may vmalloc an address in the kernel mapped region +starting a MAP_BASE & obtain the virtual address: + + addr = 0xc000000000002000 + +When masked by virt_to_phys(), which uses __pa() & in turn CPHYSADDR(), +we obtain the following (bogus) physical address: + + addr = 0x2000 + +In a common system with PHYS_OFFSET=0 this will correspond to a valid +struct page which should really be accessed by virtual address +PAGE_OFFSET+0x2000, causing virt_addr_valid() to incorrectly return 1 +indicating that the original address corresponds to a struct page. + +This is equivalent to the ARM64 change made in commit ca219452c6b8 +("arm64: Correctly bounds check virt_addr_valid"). + +This fixes fallout when hardened usercopy is enabled caused by the +related commit 517e1fbeb65f ("mm/usercopy: Drop extra +is_vmalloc_or_module() check") which removed a check for the vmalloc +range that was present from the introduction of the hardened usercopy +feature. + +Signed-off-by: Paul Burton +References: ca219452c6b8 ("arm64: Correctly bounds check virt_addr_valid") +References: 517e1fbeb65f ("mm/usercopy: Drop extra is_vmalloc_or_module() check") +Reported-by: Julien Cristau +Reviewed-by: Philippe Mathieu-Daudé +Tested-by: YunQiang Su +URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=929366 +Cc: stable@vger.kernel.org # v4.12+ +Cc: linux-mips@vger.kernel.org +Cc: Yunqiang Su +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/mm/mmap.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/mips/mm/mmap.c ++++ b/arch/mips/mm/mmap.c +@@ -203,6 +203,11 @@ unsigned long arch_randomize_brk(struct + + int __virt_addr_valid(const volatile void *kaddr) + { ++ unsigned long vaddr = (unsigned long)vaddr; ++ ++ if ((vaddr < PAGE_OFFSET) || (vaddr >= MAP_BASE)) ++ return 0; ++ + return pfn_valid(PFN_DOWN(virt_to_phys(kaddr))); + } + EXPORT_SYMBOL_GPL(__virt_addr_valid); diff --git a/queue-4.14/mips-pistachio-build-uimage.gz-by-default.patch b/queue-4.14/mips-pistachio-build-uimage.gz-by-default.patch new file mode 100644 index 00000000000..b6e873edb4f --- /dev/null +++ b/queue-4.14/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.14/parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch b/queue-4.14/parisc-use-implicit-space-register-selection-for-loading-the-coherence-index-of-i-o-pdirs.patch new file mode 100644 index 00000000000..aac9cdb9c6a --- /dev/null +++ b/queue-4.14/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 +@@ -565,8 +565,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! +@@ -597,7 +595,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 +@@ -575,8 +575,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.14/pstore-convert-buf_lock-to-semaphore.patch b/queue-4.14/pstore-convert-buf_lock-to-semaphore.patch new file mode 100644 index 00000000000..0cd8b21a6df --- /dev/null +++ b/queue-4.14/pstore-convert-buf_lock-to-semaphore.patch @@ -0,0 +1,242 @@ +From ea84b580b95521644429cc6748b6c2bf27c8b0f3 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Fri, 30 Nov 2018 14:36:58 -0800 +Subject: pstore: Convert buf_lock to semaphore + +From: Kees Cook + +commit ea84b580b95521644429cc6748b6c2bf27c8b0f3 upstream. + +Instead of running with interrupts disabled, use a semaphore. This should +make it easier for backends that may need to sleep (e.g. EFI) when +performing a write: + +|BUG: sleeping function called from invalid context at kernel/sched/completion.c:99 +|in_atomic(): 1, irqs_disabled(): 1, pid: 2236, name: sig-xstate-bum +|Preemption disabled at: +|[] pstore_dump+0x72/0x330 +|CPU: 26 PID: 2236 Comm: sig-xstate-bum Tainted: G D 4.20.0-rc3 #45 +|Call Trace: +| dump_stack+0x4f/0x6a +| ___might_sleep.cold.91+0xd3/0xe4 +| __might_sleep+0x50/0x90 +| wait_for_completion+0x32/0x130 +| virt_efi_query_variable_info+0x14e/0x160 +| efi_query_variable_store+0x51/0x1a0 +| efivar_entry_set_safe+0xa3/0x1b0 +| efi_pstore_write+0x109/0x140 +| pstore_dump+0x11c/0x330 +| kmsg_dump+0xa4/0xd0 +| oops_exit+0x22/0x30 +... + +Reported-by: Sebastian Andrzej Siewior +Fixes: 21b3ddd39fee ("efi: Don't use spinlocks for efi vars") +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/nvram_64.c | 2 - + drivers/acpi/apei/erst.c | 1 + drivers/firmware/efi/efi-pstore.c | 4 --- + fs/pstore/platform.c | 44 +++++++++++++++++++------------------- + fs/pstore/ram.c | 1 + include/linux/pstore.h | 7 ++---- + 6 files changed, 27 insertions(+), 32 deletions(-) + +--- a/arch/powerpc/kernel/nvram_64.c ++++ b/arch/powerpc/kernel/nvram_64.c +@@ -566,8 +566,6 @@ static int nvram_pstore_init(void) + nvram_pstore_info.buf = oops_data; + nvram_pstore_info.bufsize = oops_data_sz; + +- spin_lock_init(&nvram_pstore_info.buf_lock); +- + rc = pstore_register(&nvram_pstore_info); + if (rc && (rc != -EPERM)) + /* Print error only when pstore.backend == nvram */ +--- a/drivers/acpi/apei/erst.c ++++ b/drivers/acpi/apei/erst.c +@@ -1175,7 +1175,6 @@ static int __init erst_init(void) + "Error Record Serialization Table (ERST) support is initialized.\n"); + + buf = kmalloc(erst_erange.size, GFP_KERNEL); +- spin_lock_init(&erst_info.buf_lock); + if (buf) { + erst_info.buf = buf + sizeof(struct cper_pstore_record); + erst_info.bufsize = erst_erange.size - +--- a/drivers/firmware/efi/efi-pstore.c ++++ b/drivers/firmware/efi/efi-pstore.c +@@ -258,8 +258,7 @@ static int efi_pstore_write(struct pstor + efi_name[i] = name[i]; + + ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES, +- !pstore_cannot_block_path(record->reason), +- record->size, record->psi->buf); ++ preemptible(), record->size, record->psi->buf); + + if (record->reason == KMSG_DUMP_OOPS) + efivar_run_worker(); +@@ -368,7 +367,6 @@ static __init int efivars_pstore_init(vo + return -ENOMEM; + + efi_pstore_info.bufsize = 1024; +- spin_lock_init(&efi_pstore_info.buf_lock); + + if (pstore_register(&efi_pstore_info)) { + kfree(efi_pstore_info.buf); +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -129,26 +129,27 @@ static const char *get_reason_str(enum k + } + } + +-bool pstore_cannot_block_path(enum kmsg_dump_reason reason) ++/* ++ * Should pstore_dump() wait for a concurrent pstore_dump()? If ++ * not, the current pstore_dump() will report a failure to dump ++ * and return. ++ */ ++static bool pstore_cannot_wait(enum kmsg_dump_reason reason) + { +- /* +- * In case of NMI path, pstore shouldn't be blocked +- * regardless of reason. +- */ ++ /* In NMI path, pstore shouldn't block regardless of reason. */ + if (in_nmi()) + return true; + + switch (reason) { + /* In panic case, other cpus are stopped by smp_send_stop(). */ + case KMSG_DUMP_PANIC: +- /* Emergency restart shouldn't be blocked by spin lock. */ ++ /* Emergency restart shouldn't be blocked. */ + case KMSG_DUMP_EMERG: + return true; + default: + return false; + } + } +-EXPORT_SYMBOL_GPL(pstore_cannot_block_path); + + #ifdef CONFIG_PSTORE_ZLIB_COMPRESS + /* Derived from logfs_compress() */ +@@ -499,23 +500,23 @@ static void pstore_dump(struct kmsg_dump + unsigned long total = 0; + const char *why; + unsigned int part = 1; +- unsigned long flags = 0; +- int is_locked; + int ret; + + why = get_reason_str(reason); + +- if (pstore_cannot_block_path(reason)) { +- is_locked = spin_trylock_irqsave(&psinfo->buf_lock, flags); +- if (!is_locked) { +- pr_err("pstore dump routine blocked in %s path, may corrupt error record\n" +- , in_nmi() ? "NMI" : why); ++ if (down_trylock(&psinfo->buf_lock)) { ++ /* Failed to acquire lock: give up if we cannot wait. */ ++ if (pstore_cannot_wait(reason)) { ++ pr_err("dump skipped in %s path: may corrupt error record\n", ++ in_nmi() ? "NMI" : why); ++ return; ++ } ++ if (down_interruptible(&psinfo->buf_lock)) { ++ pr_err("could not grab semaphore?!\n"); + return; + } +- } else { +- spin_lock_irqsave(&psinfo->buf_lock, flags); +- is_locked = 1; + } ++ + oopscount++; + while (total < kmsg_bytes) { + char *dst; +@@ -532,7 +533,7 @@ static void pstore_dump(struct kmsg_dump + record.part = part; + record.buf = psinfo->buf; + +- if (big_oops_buf && is_locked) { ++ if (big_oops_buf) { + dst = big_oops_buf; + dst_size = big_oops_buf_sz; + } else { +@@ -550,7 +551,7 @@ static void pstore_dump(struct kmsg_dump + dst_size, &dump_size)) + break; + +- if (big_oops_buf && is_locked) { ++ if (big_oops_buf) { + zipped_len = pstore_compress(dst, psinfo->buf, + header_size + dump_size, + psinfo->bufsize); +@@ -573,8 +574,8 @@ static void pstore_dump(struct kmsg_dump + total += record.size; + part++; + } +- if (is_locked) +- spin_unlock_irqrestore(&psinfo->buf_lock, flags); ++ ++ up(&psinfo->buf_lock); + } + + static struct kmsg_dumper pstore_dumper = { +@@ -693,6 +694,7 @@ int pstore_register(struct pstore_info * + psi->write_user = pstore_write_user_compat; + psinfo = psi; + mutex_init(&psinfo->read_mutex); ++ sema_init(&psinfo->buf_lock, 1); + spin_unlock(&pstore_lock); + + if (owner && !try_module_get(owner)) { +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -812,7 +812,6 @@ static int ramoops_probe(struct platform + err = -ENOMEM; + goto fail_clear; + } +- spin_lock_init(&cxt->pstore.buf_lock); + + cxt->pstore.flags = PSTORE_FLAGS_DMESG; + if (cxt->console_size) +--- a/include/linux/pstore.h ++++ b/include/linux/pstore.h +@@ -26,7 +26,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + +@@ -88,7 +88,7 @@ struct pstore_record { + * @owner: module which is repsonsible for this backend driver + * @name: name of the backend driver + * +- * @buf_lock: spinlock to serialize access to @buf ++ * @buf_lock: semaphore to serialize access to @buf + * @buf: preallocated crash dump buffer + * @bufsize: size of @buf available for crash dump bytes (must match + * smallest number of bytes available for writing to a +@@ -173,7 +173,7 @@ struct pstore_info { + struct module *owner; + char *name; + +- spinlock_t buf_lock; ++ struct semaphore buf_lock; + char *buf; + size_t bufsize; + +@@ -199,7 +199,6 @@ struct pstore_info { + + extern int pstore_register(struct pstore_info *); + extern void pstore_unregister(struct pstore_info *); +-extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason); + + struct pstore_ftrace_record { + unsigned long ip; diff --git a/queue-4.14/pstore-ram-run-without-kernel-crash-dump-region.patch b/queue-4.14/pstore-ram-run-without-kernel-crash-dump-region.patch new file mode 100644 index 00000000000..1360700a3dd --- /dev/null +++ b/queue-4.14/pstore-ram-run-without-kernel-crash-dump-region.patch @@ -0,0 +1,106 @@ +From 8880fa32c557600f5f624084152668ed3c2ea51e Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 30 May 2019 23:37:29 -0700 +Subject: pstore/ram: Run without kernel crash dump region + +From: Kees Cook + +commit 8880fa32c557600f5f624084152668ed3c2ea51e upstream. + +The ram pstore backend has always had the crash dumper frontend enabled +unconditionally. However, it was possible to effectively disable it +by setting a record_size=0. All the machinery would run (storing dumps +to the temporary crash buffer), but 0 bytes would ultimately get stored +due to there being no przs allocated for dumps. Commit 89d328f637b9 +("pstore/ram: Correctly calculate usable PRZ bytes"), however, assumed +that there would always be at least one allocated dprz for calculating +the size of the temporary crash buffer. This was, of course, not the +case when record_size=0, and would lead to a NULL deref trying to find +the dprz buffer size: + +BUG: unable to handle kernel NULL pointer dereference at (null) +... +IP: ramoops_probe+0x285/0x37e (fs/pstore/ram.c:808) + + cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size; + +Instead, we need to only enable the frontends based on the success of the +prz initialization and only take the needed actions when those zones are +available. (This also fixes a possible error in detecting if the ftrace +frontend should be enabled.) + +Reported-and-tested-by: Yaro Slav +Fixes: 89d328f637b9 ("pstore/ram: Correctly calculate usable PRZ bytes") +Cc: stable@vger.kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/platform.c | 3 ++- + fs/pstore/ram.c | 36 +++++++++++++++++++++++------------- + 2 files changed, 25 insertions(+), 14 deletions(-) + +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -702,7 +702,8 @@ int pstore_register(struct pstore_info * + return -EINVAL; + } + +- allocate_buf_for_compression(); ++ if (psi->flags & PSTORE_FLAGS_DMESG) ++ allocate_buf_for_compression(); + + if (pstore_is_mounted()) + pstore_get_records(0); +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -801,26 +801,36 @@ static int ramoops_probe(struct platform + + cxt->pstore.data = cxt; + /* +- * Since bufsize is only used for dmesg crash dumps, it +- * must match the size of the dprz record (after PRZ header +- * and ECC bytes have been accounted for). ++ * Prepare frontend flags based on which areas are initialized. ++ * For ramoops_init_przs() cases, the "max count" variable tells ++ * if there are regions present. For ramoops_init_prz() cases, ++ * the single region size is how to check. + */ +- cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size; +- cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL); +- if (!cxt->pstore.buf) { +- pr_err("cannot allocate pstore crash dump buffer\n"); +- err = -ENOMEM; +- goto fail_clear; +- } +- +- cxt->pstore.flags = PSTORE_FLAGS_DMESG; ++ cxt->pstore.flags = 0; ++ if (cxt->max_dump_cnt) ++ cxt->pstore.flags |= PSTORE_FLAGS_DMESG; + if (cxt->console_size) + cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE; +- if (cxt->ftrace_size) ++ if (cxt->max_ftrace_cnt) + cxt->pstore.flags |= PSTORE_FLAGS_FTRACE; + if (cxt->pmsg_size) + cxt->pstore.flags |= PSTORE_FLAGS_PMSG; + ++ /* ++ * Since bufsize is only used for dmesg crash dumps, it ++ * must match the size of the dprz record (after PRZ header ++ * and ECC bytes have been accounted for). ++ */ ++ if (cxt->pstore.flags & PSTORE_FLAGS_DMESG) { ++ cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size; ++ cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL); ++ if (!cxt->pstore.buf) { ++ pr_err("cannot allocate pstore crash dump buffer\n"); ++ err = -ENOMEM; ++ goto fail_clear; ++ } ++ } ++ + err = pstore_register(&cxt->pstore); + if (err) { + pr_err("registering with pstore failed\n"); diff --git a/queue-4.14/pstore-remove-needless-lock-during-console-writes.patch b/queue-4.14/pstore-remove-needless-lock-during-console-writes.patch new file mode 100644 index 00000000000..59dd1cb5255 --- /dev/null +++ b/queue-4.14/pstore-remove-needless-lock-during-console-writes.patch @@ -0,0 +1,61 @@ +From b77fa617a2ff4d6beccad3d3d4b3a1f2d10368aa Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 1 Nov 2018 14:08:07 -0700 +Subject: pstore: Remove needless lock during console writes + +From: Kees Cook + +commit b77fa617a2ff4d6beccad3d3d4b3a1f2d10368aa upstream. + +Since the console writer does not use the preallocated crash dump buffer +any more, there is no reason to perform locking around it. + +Fixes: 70ad35db3321 ("pstore: Convert console write to use ->write_buf") +Signed-off-by: Kees Cook +Reviewed-by: Joel Fernandes (Google) +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/platform.c | 29 ++++++----------------------- + 1 file changed, 6 insertions(+), 23 deletions(-) + +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -597,31 +597,14 @@ static void pstore_unregister_kmsg(void) + #ifdef CONFIG_PSTORE_CONSOLE + static void pstore_console_write(struct console *con, const char *s, unsigned c) + { +- const char *e = s + c; ++ struct pstore_record record; + +- while (s < e) { +- struct pstore_record record; +- unsigned long flags; ++ pstore_record_init(&record, psinfo); ++ record.type = PSTORE_TYPE_CONSOLE; + +- pstore_record_init(&record, psinfo); +- record.type = PSTORE_TYPE_CONSOLE; +- +- if (c > psinfo->bufsize) +- c = psinfo->bufsize; +- +- if (oops_in_progress) { +- if (!spin_trylock_irqsave(&psinfo->buf_lock, flags)) +- break; +- } else { +- spin_lock_irqsave(&psinfo->buf_lock, flags); +- } +- record.buf = (char *)s; +- record.size = c; +- psinfo->write(&record); +- spin_unlock_irqrestore(&psinfo->buf_lock, flags); +- s += c; +- c = e - s; +- } ++ record.buf = (char *)s; ++ record.size = c; ++ psinfo->write(&record); + } + + static struct console pstore_console = { diff --git a/queue-4.14/rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch b/queue-4.14/rcu-locking-and-unlocking-need-to-always-be-at-least-barriers.patch new file mode 100644 index 00000000000..41266a093f6 --- /dev/null +++ b/queue-4.14/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 +@@ -79,14 +79,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.14/revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch b/queue-4.14/revert-mips-perf-ath79-fix-perfcount-irq-assignment.patch new file mode 100644 index 00000000000..8d6da1aee7f --- /dev/null +++ b/queue-4.14/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 9547d81ac3bc0d2b9729a28e7dd610007144a837 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.14/series b/queue-4.14/series index b6a9b6c2189..f082d3c412a 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -10,3 +10,17 @@ net-sfp-read-eeprom-in-maximum-16-byte-increments.patch ipv6-fix-the-check-before-getting-the-cookie-in-rt6_get_cookie.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 +pstore-remove-needless-lock-during-console-writes.patch +pstore-convert-buf_lock-to-semaphore.patch +pstore-ram-run-without-kernel-crash-dump-region.patch +x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch +i2c-xiic-add-max_read_len-quirk.patch +mips-bounds-check-virt_addr_valid.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 +test_firmware-use-correct-snprintf-limit.patch +drm-gma500-cdv-check-vbt-config-bits-when-detecting-lvds-panels.patch diff --git a/queue-4.14/test_firmware-use-correct-snprintf-limit.patch b/queue-4.14/test_firmware-use-correct-snprintf-limit.patch new file mode 100644 index 00000000000..392532b8012 --- /dev/null +++ b/queue-4.14/test_firmware-use-correct-snprintf-limit.patch @@ -0,0 +1,68 @@ +From bd17cc5a20ae9aaa3ed775f360b75ff93cd66a1d Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 15 May 2019 12:33:22 +0300 +Subject: test_firmware: Use correct snprintf() limit + +From: Dan Carpenter + +commit bd17cc5a20ae9aaa3ed775f360b75ff93cd66a1d upstream. + +The limit here is supposed to be how much of the page is left, but it's +just using PAGE_SIZE as the limit. + +The other thing to remember is that snprintf() returns the number of +bytes which would have been copied if we had had enough room. So that +means that if we run out of space then this code would end up passing a +negative value as the limit and the kernel would print an error message. +I have change the code to use scnprintf() which returns the number of +bytes that were successfully printed (not counting the NUL terminator). + +Fixes: c92316bf8e94 ("test_firmware: add batched firmware tests") +Signed-off-by: Dan Carpenter +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + lib/test_firmware.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/lib/test_firmware.c ++++ b/lib/test_firmware.c +@@ -222,30 +222,30 @@ static ssize_t config_show(struct device + + mutex_lock(&test_fw_mutex); + +- len += snprintf(buf, PAGE_SIZE, ++ len += scnprintf(buf, PAGE_SIZE - len, + "Custom trigger configuration for: %s\n", + dev_name(dev)); + + if (test_fw_config->name) +- len += snprintf(buf+len, PAGE_SIZE, ++ len += scnprintf(buf+len, PAGE_SIZE - len, + "name:\t%s\n", + test_fw_config->name); + else +- len += snprintf(buf+len, PAGE_SIZE, ++ len += scnprintf(buf+len, PAGE_SIZE - len, + "name:\tEMTPY\n"); + +- len += snprintf(buf+len, PAGE_SIZE, ++ len += scnprintf(buf+len, PAGE_SIZE - len, + "num_requests:\t%u\n", test_fw_config->num_requests); + +- len += snprintf(buf+len, PAGE_SIZE, ++ len += scnprintf(buf+len, PAGE_SIZE - len, + "send_uevent:\t\t%s\n", + test_fw_config->send_uevent ? + "FW_ACTION_HOTPLUG" : + "FW_ACTION_NOHOTPLUG"); +- len += snprintf(buf+len, PAGE_SIZE, ++ len += scnprintf(buf+len, PAGE_SIZE - len, + "sync_direct:\t\t%s\n", + test_fw_config->sync_direct ? "true" : "false"); +- len += snprintf(buf+len, PAGE_SIZE, ++ len += scnprintf(buf+len, PAGE_SIZE - len, + "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx); + + mutex_unlock(&test_fw_mutex); diff --git a/queue-4.14/x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch b/queue-4.14/x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch new file mode 100644 index 00000000000..82afbc3ec34 --- /dev/null +++ b/queue-4.14/x86-power-fix-nosmt-vs-hibernation-triple-fault-during-resume.patch @@ -0,0 +1,187 @@ +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 +@@ -299,7 +299,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 +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + #include + +@@ -347,3 +348,35 @@ int arch_hibernation_header_restore(void + + return 0; + } ++ ++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 +@@ -191,10 +191,14 @@ enum cpuhp_smt_control { + extern enum cpuhp_smt_control cpu_smt_control; + extern void cpu_smt_disable(bool force); + 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(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 +@@ -2054,7 +2054,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; + +@@ -2088,7 +2088,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 +@@ -258,6 +258,11 @@ void swsusp_show_speed(ktime_t start, kt + (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); + -- 2.47.2