From: Greg Kroah-Hartman Date: Sun, 18 Jun 2017 01:23:02 +0000 (+0800) Subject: 4.11-stable patches X-Git-Tag: v4.11.7~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8dd26c90e681e3675e24b545914f50dfc38eba5b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.11-stable patches added patches: iio-adc-meson-saradc-fix-potential-crash-in-meson_sar_adc_clear_fifo.patch iio-imu-inv_mpu6050-add-accel-lpf-setting-for-chip-mpu6500.patch mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch mm-numa-avoid-waiting-on-freed-migrated-pages.patch staging-iio-ad7152-fix-deadlock-in-ad7152_write_raw_samp_freq.patch swap-cond_resched-in-swap_cgroup_prepare.patch usb-gadget-fix-gpf-in-gadgetfs.patch usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch usb-xhci-fix-usb-3.1-supported-protocol-parsing.patch userfaultfd-shmem-handle-coredumping-in-handle_userfault.patch --- diff --git a/queue-4.11/iio-adc-meson-saradc-fix-potential-crash-in-meson_sar_adc_clear_fifo.patch b/queue-4.11/iio-adc-meson-saradc-fix-potential-crash-in-meson_sar_adc_clear_fifo.patch new file mode 100644 index 00000000000..65a49fca0b9 --- /dev/null +++ b/queue-4.11/iio-adc-meson-saradc-fix-potential-crash-in-meson_sar_adc_clear_fifo.patch @@ -0,0 +1,47 @@ +From 103a07d4278203d6299798cd74cdc4d209801cac Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 4 Jun 2017 15:28:23 +0200 +Subject: iio: adc: meson-saradc: fix potential crash in meson_sar_adc_clear_fifo + +From: Martin Blumenstingl + +commit 103a07d4278203d6299798cd74cdc4d209801cac upstream. + +meson_sar_adc_clear_fifo passes a 0 as value-pointer to regmap_read(). +In case of the meson-saradc driver this ends up in regmap_mmio_read(), +where the value-pointer is de-referenced unconditionally to assign the +value which was read. +Fix this by passing an actual pointer, even though all we want to do is +to discard the value. + +As a side-effect this fixes a sparse warning ("Using plain integer as +NULL pointer") as reported by Paolo Cretaro. + +Fixes: 3adbf3427330 ("iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs") +Reported-by: Paolo Cretaro +Signed-off-by: Martin Blumenstingl +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/meson_saradc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iio/adc/meson_saradc.c ++++ b/drivers/iio/adc/meson_saradc.c +@@ -440,13 +440,13 @@ static void meson_sar_adc_unlock(struct + static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev) + { + struct meson_sar_adc_priv *priv = iio_priv(indio_dev); +- int count; ++ unsigned int count, tmp; + + for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) { + if (!meson_sar_adc_get_fifo_count(indio_dev)) + break; + +- regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, 0); ++ regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp); + } + } + diff --git a/queue-4.11/iio-imu-inv_mpu6050-add-accel-lpf-setting-for-chip-mpu6500.patch b/queue-4.11/iio-imu-inv_mpu6050-add-accel-lpf-setting-for-chip-mpu6500.patch new file mode 100644 index 00000000000..cba53315df8 --- /dev/null +++ b/queue-4.11/iio-imu-inv_mpu6050-add-accel-lpf-setting-for-chip-mpu6500.patch @@ -0,0 +1,125 @@ +From 948588e25b8af5e66962ed3f53e1cae1656fa5af Mon Sep 17 00:00:00 2001 +From: Jean-Baptiste Maneyrol +Date: Mon, 29 May 2017 09:59:40 +0000 +Subject: iio: imu: inv_mpu6050: add accel lpf setting for chip >= MPU6500 + +From: Jean-Baptiste Maneyrol + +commit 948588e25b8af5e66962ed3f53e1cae1656fa5af upstream. + +Starting from MPU6500, accelerometer dlpf is set in a separate +register named ACCEL_CONFIG_2. +Add this new register in the map and set it for the corresponding +chips. + +Signed-off-by: Jean-Baptiste Maneyrol +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 39 ++++++++++++++++++++++++++--- + drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 3 ++ + 2 files changed, 39 insertions(+), 3 deletions(-) + +--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c ++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +@@ -41,6 +41,7 @@ static const int accel_scale[] = {598, 1 + static const struct inv_mpu6050_reg_map reg_set_6500 = { + .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV, + .lpf = INV_MPU6050_REG_CONFIG, ++ .accel_lpf = INV_MPU6500_REG_ACCEL_CONFIG_2, + .user_ctrl = INV_MPU6050_REG_USER_CTRL, + .fifo_en = INV_MPU6050_REG_FIFO_EN, + .gyro_config = INV_MPU6050_REG_GYRO_CONFIG, +@@ -205,6 +206,37 @@ int inv_mpu6050_set_power_itg(struct inv + EXPORT_SYMBOL_GPL(inv_mpu6050_set_power_itg); + + /** ++ * inv_mpu6050_set_lpf_regs() - set low pass filter registers, chip dependent ++ * ++ * MPU60xx/MPU9150 use only 1 register for accelerometer + gyroscope ++ * MPU6500 and above have a dedicated register for accelerometer ++ */ ++static int inv_mpu6050_set_lpf_regs(struct inv_mpu6050_state *st, ++ enum inv_mpu6050_filter_e val) ++{ ++ int result; ++ ++ result = regmap_write(st->map, st->reg->lpf, val); ++ if (result) ++ return result; ++ ++ switch (st->chip_type) { ++ case INV_MPU6050: ++ case INV_MPU6000: ++ case INV_MPU9150: ++ /* old chips, nothing to do */ ++ result = 0; ++ break; ++ default: ++ /* set accel lpf */ ++ result = regmap_write(st->map, st->reg->accel_lpf, val); ++ break; ++ } ++ ++ return result; ++} ++ ++/** + * inv_mpu6050_init_config() - Initialize hardware, disable FIFO. + * + * Initial configuration: +@@ -227,8 +259,7 @@ static int inv_mpu6050_init_config(struc + if (result) + return result; + +- d = INV_MPU6050_FILTER_20HZ; +- result = regmap_write(st->map, st->reg->lpf, d); ++ result = inv_mpu6050_set_lpf_regs(st, INV_MPU6050_FILTER_20HZ); + if (result) + return result; + +@@ -531,6 +562,8 @@ error_write_raw: + * would be alising. This function basically search for the + * correct low pass parameters based on the fifo rate, e.g, + * sampling frequency. ++ * ++ * lpf is set automatically when setting sampling rate to avoid any aliases. + */ + static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate) + { +@@ -546,7 +579,7 @@ static int inv_mpu6050_set_lpf(struct in + while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1)) + i++; + data = d[i]; +- result = regmap_write(st->map, st->reg->lpf, data); ++ result = inv_mpu6050_set_lpf_regs(st, data); + if (result) + return result; + st->chip_config.lpf = data; +--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h ++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +@@ -28,6 +28,7 @@ + * struct inv_mpu6050_reg_map - Notable registers. + * @sample_rate_div: Divider applied to gyro output rate. + * @lpf: Configures internal low pass filter. ++ * @accel_lpf: Configures accelerometer low pass filter. + * @user_ctrl: Enables/resets the FIFO. + * @fifo_en: Determines which data will appear in FIFO. + * @gyro_config: gyro config register. +@@ -47,6 +48,7 @@ + struct inv_mpu6050_reg_map { + u8 sample_rate_div; + u8 lpf; ++ u8 accel_lpf; + u8 user_ctrl; + u8 fifo_en; + u8 gyro_config; +@@ -187,6 +189,7 @@ struct inv_mpu6050_state { + #define INV_MPU6050_FIFO_THRESHOLD 500 + + /* mpu6500 registers */ ++#define INV_MPU6500_REG_ACCEL_CONFIG_2 0x1D + #define INV_MPU6500_REG_ACCEL_OFFSET 0x77 + + /* delay time in milliseconds */ diff --git a/queue-4.11/mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch b/queue-4.11/mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch new file mode 100644 index 00000000000..232dbf36c0c --- /dev/null +++ b/queue-4.11/mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch @@ -0,0 +1,54 @@ +From 7258ae5c5a2ce2f5969e8b18b881be40ab55433d Mon Sep 17 00:00:00 2001 +From: James Morse +Date: Fri, 16 Jun 2017 14:02:29 -0700 +Subject: mm/memory-failure.c: use compound_head() flags for huge pages + +From: James Morse + +commit 7258ae5c5a2ce2f5969e8b18b881be40ab55433d upstream. + +memory_failure() chooses a recovery action function based on the page +flags. For huge pages it uses the tail page flags which don't have +anything interesting set, resulting in: + +> Memory failure: 0x9be3b4: Unknown page state +> Memory failure: 0x9be3b4: recovery action for unknown page: Failed + +Instead, save a copy of the head page's flags if this is a huge page, +this means if there are no relevant flags for this tail page, we use the +head pages flags instead. This results in the me_huge_page() recovery +action being called: + +> Memory failure: 0x9b7969: recovery action for huge page: Delayed + +For hugepages that have not yet been allocated, this allows the hugepage +to be dequeued. + +Fixes: 524fca1e7356 ("HWPOISON: fix misjudgement of page_action() for errors on mlocked pages") +Link: http://lkml.kernel.org/r/20170524130204.21845-1-james.morse@arm.com +Signed-off-by: James Morse +Tested-by: Punit Agrawal +Acked-by: Punit Agrawal +Acked-by: Naoya Horiguchi +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memory-failure.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -1175,7 +1175,10 @@ int memory_failure(unsigned long pfn, in + * page_remove_rmap() in try_to_unmap_one(). So to determine page status + * correctly, we save a copy of the page flags at this time. + */ +- page_flags = p->flags; ++ if (PageHuge(p)) ++ page_flags = hpage->flags; ++ else ++ page_flags = p->flags; + + /* + * unpoison always clear PG_hwpoison inside page lock diff --git a/queue-4.11/mm-numa-avoid-waiting-on-freed-migrated-pages.patch b/queue-4.11/mm-numa-avoid-waiting-on-freed-migrated-pages.patch new file mode 100644 index 00000000000..415574b6fd4 --- /dev/null +++ b/queue-4.11/mm-numa-avoid-waiting-on-freed-migrated-pages.patch @@ -0,0 +1,90 @@ +From 3c226c637b69104f6b9f1c6ec5b08d7b741b3229 Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Fri, 16 Jun 2017 14:02:34 -0700 +Subject: mm: numa: avoid waiting on freed migrated pages + +From: Mark Rutland + +commit 3c226c637b69104f6b9f1c6ec5b08d7b741b3229 upstream. + +In do_huge_pmd_numa_page(), we attempt to handle a migrating thp pmd by +waiting until the pmd is unlocked before we return and retry. However, +we can race with migrate_misplaced_transhuge_page(): + + // do_huge_pmd_numa_page // migrate_misplaced_transhuge_page() + // Holds 0 refs on page // Holds 2 refs on page + + vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); + /* ... */ + if (pmd_trans_migrating(*vmf->pmd)) { + page = pmd_page(*vmf->pmd); + spin_unlock(vmf->ptl); + ptl = pmd_lock(mm, pmd); + if (page_count(page) != 2)) { + /* roll back */ + } + /* ... */ + mlock_migrate_page(new_page, page); + /* ... */ + spin_unlock(ptl); + put_page(page); + put_page(page); // page freed here + wait_on_page_locked(page); + goto out; + } + +This can result in the freed page having its waiters flag set +unexpectedly, which trips the PAGE_FLAGS_CHECK_AT_PREP checks in the +page alloc/free functions. This has been observed on arm64 KVM guests. + +We can avoid this by having do_huge_pmd_numa_page() take a reference on +the page before dropping the pmd lock, mirroring what we do in +__migration_entry_wait(). + +When we hit the race, migrate_misplaced_transhuge_page() will see the +reference and abort the migration, as it may do today in other cases. + +Fixes: b8916634b77bffb2 ("mm: Prevent parallel splits during THP migration") +Link: http://lkml.kernel.org/r/1497349722-6731-2-git-send-email-will.deacon@arm.com +Signed-off-by: Mark Rutland +Signed-off-by: Will Deacon +Acked-by: Steve Capper +Acked-by: Kirill A. Shutemov +Acked-by: Vlastimil Babka +Cc: Mel Gorman +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/huge_memory.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1412,8 +1412,11 @@ int do_huge_pmd_numa_page(struct vm_faul + */ + if (unlikely(pmd_trans_migrating(*vmf->pmd))) { + page = pmd_page(*vmf->pmd); ++ if (!get_page_unless_zero(page)) ++ goto out_unlock; + spin_unlock(vmf->ptl); + wait_on_page_locked(page); ++ put_page(page); + goto out; + } + +@@ -1445,9 +1448,12 @@ int do_huge_pmd_numa_page(struct vm_faul + + /* Migration could have started since the pmd_trans_migrating check */ + if (!page_locked) { ++ page_nid = -1; ++ if (!get_page_unless_zero(page)) ++ goto out_unlock; + spin_unlock(vmf->ptl); + wait_on_page_locked(page); +- page_nid = -1; ++ put_page(page); + goto out; + } + diff --git a/queue-4.11/series b/queue-4.11/series index 255e8077b5f..4220d597acb 100644 --- a/queue-4.11/series +++ b/queue-4.11/series @@ -54,3 +54,14 @@ usb-r8a66597-hcd-select-a-different-endpoint-on-timeout.patch usb-r8a66597-hcd-decrease-timeout.patch coda-restore-original-firmware-locations.patch drivers-misc-c2port-c2port-duramar2150.c-checking-for-null-instead-of-is_err.patch +usb-xhci-fix-usb-3.1-supported-protocol-parsing.patch +usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch +usb-gadget-fix-gpf-in-gadgetfs.patch +usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch +mm-memory-failure.c-use-compound_head-flags-for-huge-pages.patch +swap-cond_resched-in-swap_cgroup_prepare.patch +mm-numa-avoid-waiting-on-freed-migrated-pages.patch +userfaultfd-shmem-handle-coredumping-in-handle_userfault.patch +iio-imu-inv_mpu6050-add-accel-lpf-setting-for-chip-mpu6500.patch +staging-iio-ad7152-fix-deadlock-in-ad7152_write_raw_samp_freq.patch +iio-adc-meson-saradc-fix-potential-crash-in-meson_sar_adc_clear_fifo.patch diff --git a/queue-4.11/staging-iio-ad7152-fix-deadlock-in-ad7152_write_raw_samp_freq.patch b/queue-4.11/staging-iio-ad7152-fix-deadlock-in-ad7152_write_raw_samp_freq.patch new file mode 100644 index 00000000000..aeed2ead81e --- /dev/null +++ b/queue-4.11/staging-iio-ad7152-fix-deadlock-in-ad7152_write_raw_samp_freq.patch @@ -0,0 +1,47 @@ +From 95264c8c6a9040e84edda883dbbe9d193c41f46c Mon Sep 17 00:00:00 2001 +From: Alexey Khoroshilov +Date: Sat, 27 May 2017 01:53:04 +0300 +Subject: staging: iio: ad7152: Fix deadlock in ad7152_write_raw_samp_freq() + +From: Alexey Khoroshilov + +commit 95264c8c6a9040e84edda883dbbe9d193c41f46c upstream. + +ad7152_write_raw_samp_freq() is called by ad7152_write_raw() with +chip->state_lock held. So, there is unavoidable deadlock when +ad7152_write_raw_samp_freq() locks the mutex itself. + +The patch removes unneeded locking. + +Found by Linux Driver Verification project (linuxtesting.org). + +Signed-off-by: Alexey Khoroshilov +Fixes: 6572389bcc11 ("staging: iio: cdc: ad7152: Implement IIO_CHAN_INFO_SAMP_FREQ attribute") +Acked-by: Lars-Peter Clausen +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/iio/cdc/ad7152.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/drivers/staging/iio/cdc/ad7152.c ++++ b/drivers/staging/iio/cdc/ad7152.c +@@ -231,16 +231,12 @@ static int ad7152_write_raw_samp_freq(st + if (i >= ARRAY_SIZE(ad7152_filter_rate_table)) + i = ARRAY_SIZE(ad7152_filter_rate_table) - 1; + +- mutex_lock(&chip->state_lock); + ret = i2c_smbus_write_byte_data(chip->client, + AD7152_REG_CFG2, AD7152_CFG2_OSR(i)); +- if (ret < 0) { +- mutex_unlock(&chip->state_lock); ++ if (ret < 0) + return ret; +- } + + chip->filter_rate_setup = i; +- mutex_unlock(&chip->state_lock); + + return ret; + } diff --git a/queue-4.11/swap-cond_resched-in-swap_cgroup_prepare.patch b/queue-4.11/swap-cond_resched-in-swap_cgroup_prepare.patch new file mode 100644 index 00000000000..7309390b043 --- /dev/null +++ b/queue-4.11/swap-cond_resched-in-swap_cgroup_prepare.patch @@ -0,0 +1,40 @@ +From ef70762948dde012146926720b70e79736336764 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Fri, 16 Jun 2017 14:02:31 -0700 +Subject: swap: cond_resched in swap_cgroup_prepare() + +From: Yu Zhao + +commit ef70762948dde012146926720b70e79736336764 upstream. + +I saw need_resched() warnings when swapping on large swapfile (TBs) +because continuously allocating many pages in swap_cgroup_prepare() took +too long. + +We already cond_resched when freeing page in swap_cgroup_swapoff(). Do +the same for the page allocation. + +Link: http://lkml.kernel.org/r/20170604200109.17606-1-yuzhao@google.com +Signed-off-by: Yu Zhao +Acked-by: Michal Hocko +Acked-by: Vladimir Davydov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/swap_cgroup.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/mm/swap_cgroup.c ++++ b/mm/swap_cgroup.c +@@ -48,6 +48,9 @@ static int swap_cgroup_prepare(int type) + if (!page) + goto not_enough_page; + ctrl->map[idx] = page; ++ ++ if (!(idx % SWAP_CLUSTER_MAX)) ++ cond_resched(); + } + return 0; + not_enough_page: diff --git a/queue-4.11/usb-gadget-fix-gpf-in-gadgetfs.patch b/queue-4.11/usb-gadget-fix-gpf-in-gadgetfs.patch new file mode 100644 index 00000000000..2ce333deccd --- /dev/null +++ b/queue-4.11/usb-gadget-fix-gpf-in-gadgetfs.patch @@ -0,0 +1,92 @@ +From f50b878fed33e360d01dcdc31a8eeb1815d033d5 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 8 Jun 2017 13:55:59 -0400 +Subject: USB: gadget: fix GPF in gadgetfs + +From: Alan Stern + +commit f50b878fed33e360d01dcdc31a8eeb1815d033d5 upstream. + +A NULL-pointer dereference bug in gadgetfs was uncovered by syzkaller: + +> kasan: GPF could be caused by NULL-ptr deref or user memory access +> general protection fault: 0000 [#1] SMP KASAN +> Dumping ftrace buffer: +> (ftrace buffer empty) +> Modules linked in: +> CPU: 2 PID: 4820 Comm: syz-executor0 Not tainted 4.12.0-rc4+ #5 +> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +> task: ffff880039542dc0 task.stack: ffff88003bdd0000 +> RIP: 0010:__list_del_entry_valid+0x7e/0x170 lib/list_debug.c:51 +> RSP: 0018:ffff88003bdd6e50 EFLAGS: 00010246 +> RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000010000 +> RDX: 0000000000000000 RSI: ffffffff86504948 RDI: ffffffff86504950 +> RBP: ffff88003bdd6e68 R08: ffff880039542dc0 R09: ffffffff8778ce00 +> R10: ffff88003bdd6e68 R11: dffffc0000000000 R12: 0000000000000000 +> R13: dffffc0000000000 R14: 1ffff100077badd2 R15: ffffffff864d2e40 +> FS: 0000000000000000(0000) GS:ffff88006dc00000(0000) knlGS:0000000000000000 +> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +> CR2: 000000002014aff9 CR3: 0000000006022000 CR4: 00000000000006e0 +> Call Trace: +> __list_del_entry include/linux/list.h:116 [inline] +> list_del include/linux/list.h:124 [inline] +> usb_gadget_unregister_driver+0x166/0x4c0 drivers/usb/gadget/udc/core.c:1387 +> dev_release+0x80/0x160 drivers/usb/gadget/legacy/inode.c:1187 +> __fput+0x332/0x7f0 fs/file_table.c:209 +> ____fput+0x15/0x20 fs/file_table.c:245 +> task_work_run+0x19b/0x270 kernel/task_work.c:116 +> exit_task_work include/linux/task_work.h:21 [inline] +> do_exit+0x18a3/0x2820 kernel/exit.c:878 +> do_group_exit+0x149/0x420 kernel/exit.c:982 +> get_signal+0x77f/0x1780 kernel/signal.c:2318 +> do_signal+0xd2/0x2130 arch/x86/kernel/signal.c:808 +> exit_to_usermode_loop+0x1a7/0x240 arch/x86/entry/common.c:157 +> prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline] +> syscall_return_slowpath+0x3ba/0x410 arch/x86/entry/common.c:263 +> entry_SYSCALL_64_fastpath+0xbc/0xbe +> RIP: 0033:0x4461f9 +> RSP: 002b:00007fdac2b1ecf8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca +> RAX: fffffffffffffe00 RBX: 00000000007080c8 RCX: 00000000004461f9 +> RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000007080c8 +> RBP: 00000000007080a8 R08: 0000000000000000 R09: 0000000000000000 +> R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +> R13: 0000000000000000 R14: 00007fdac2b1f9c0 R15: 00007fdac2b1f700 +> Code: 00 00 00 00 ad de 49 39 c4 74 6a 48 b8 00 02 00 00 00 00 ad de +> 48 89 da 48 39 c3 74 74 48 c1 ea 03 48 b8 00 00 00 00 00 fc ff df <80> +> 3c 02 00 0f 85 92 00 00 00 48 8b 13 48 39 f2 75 66 49 8d 7c +> RIP: __list_del_entry_valid+0x7e/0x170 lib/list_debug.c:51 RSP: ffff88003bdd6e50 +> ---[ end trace 30e94b1eec4831c8 ]--- +> Kernel panic - not syncing: Fatal exception + +The bug was caused by dev_release() failing to turn off its +gadget_registered flag after unregistering the gadget driver. As a +result, when a later user closed the device file before writing a +valid set of descriptors, dev_release() thought the gadget had been +registered and tried to unregister it, even though it had not been. +This led to the NULL pointer dereference. + +The fix is simple: turn off the flag when the gadget is unregistered. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Andrey Konovalov +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1182,8 +1182,10 @@ dev_release (struct inode *inode, struct + + /* closing ep0 === shutdown all */ + +- if (dev->gadget_registered) ++ if (dev->gadget_registered) { + usb_gadget_unregister_driver (&gadgetfs_driver); ++ dev->gadget_registered = false; ++ } + + /* at this point "good" hardware has disconnected the + * device from USB; the host won't see it any more. diff --git a/queue-4.11/usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch b/queue-4.11/usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch new file mode 100644 index 00000000000..12628a84bc9 --- /dev/null +++ b/queue-4.11/usb-gadgetfs-dummy-hcd-net2280-fix-locking-for-callbacks.patch @@ -0,0 +1,262 @@ +From f16443a034c7aa359ddf6f0f9bc40d01ca31faea Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 13 Jun 2017 15:23:42 -0400 +Subject: USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks + +From: Alan Stern + +commit f16443a034c7aa359ddf6f0f9bc40d01ca31faea upstream. + +Using the syzkaller kernel fuzzer, Andrey Konovalov generated the +following error in gadgetfs: + +> BUG: KASAN: use-after-free in __lock_acquire+0x3069/0x3690 +> kernel/locking/lockdep.c:3246 +> Read of size 8 at addr ffff88003a2bdaf8 by task kworker/3:1/903 +> +> CPU: 3 PID: 903 Comm: kworker/3:1 Not tainted 4.12.0-rc4+ #35 +> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +> Workqueue: usb_hub_wq hub_event +> Call Trace: +> __dump_stack lib/dump_stack.c:16 [inline] +> dump_stack+0x292/0x395 lib/dump_stack.c:52 +> print_address_description+0x78/0x280 mm/kasan/report.c:252 +> kasan_report_error mm/kasan/report.c:351 [inline] +> kasan_report+0x230/0x340 mm/kasan/report.c:408 +> __asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:429 +> __lock_acquire+0x3069/0x3690 kernel/locking/lockdep.c:3246 +> lock_acquire+0x22d/0x560 kernel/locking/lockdep.c:3855 +> __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline] +> _raw_spin_lock+0x2f/0x40 kernel/locking/spinlock.c:151 +> spin_lock include/linux/spinlock.h:299 [inline] +> gadgetfs_suspend+0x89/0x130 drivers/usb/gadget/legacy/inode.c:1682 +> set_link_state+0x88e/0xae0 drivers/usb/gadget/udc/dummy_hcd.c:455 +> dummy_hub_control+0xd7e/0x1fb0 drivers/usb/gadget/udc/dummy_hcd.c:2074 +> rh_call_control drivers/usb/core/hcd.c:689 [inline] +> rh_urb_enqueue drivers/usb/core/hcd.c:846 [inline] +> usb_hcd_submit_urb+0x92f/0x20b0 drivers/usb/core/hcd.c:1650 +> usb_submit_urb+0x8b2/0x12c0 drivers/usb/core/urb.c:542 +> usb_start_wait_urb+0x148/0x5b0 drivers/usb/core/message.c:56 +> usb_internal_control_msg drivers/usb/core/message.c:100 [inline] +> usb_control_msg+0x341/0x4d0 drivers/usb/core/message.c:151 +> usb_clear_port_feature+0x74/0xa0 drivers/usb/core/hub.c:412 +> hub_port_disable+0x123/0x510 drivers/usb/core/hub.c:4177 +> hub_port_init+0x1ed/0x2940 drivers/usb/core/hub.c:4648 +> hub_port_connect drivers/usb/core/hub.c:4826 [inline] +> hub_port_connect_change drivers/usb/core/hub.c:4999 [inline] +> port_event drivers/usb/core/hub.c:5105 [inline] +> hub_event+0x1ae1/0x3d40 drivers/usb/core/hub.c:5185 +> process_one_work+0xc08/0x1bd0 kernel/workqueue.c:2097 +> process_scheduled_works kernel/workqueue.c:2157 [inline] +> worker_thread+0xb2b/0x1860 kernel/workqueue.c:2233 +> kthread+0x363/0x440 kernel/kthread.c:231 +> ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:424 +> +> Allocated by task 9958: +> save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59 +> save_stack+0x43/0xd0 mm/kasan/kasan.c:513 +> set_track mm/kasan/kasan.c:525 [inline] +> kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:617 +> kmem_cache_alloc_trace+0x87/0x280 mm/slub.c:2745 +> kmalloc include/linux/slab.h:492 [inline] +> kzalloc include/linux/slab.h:665 [inline] +> dev_new drivers/usb/gadget/legacy/inode.c:170 [inline] +> gadgetfs_fill_super+0x24f/0x540 drivers/usb/gadget/legacy/inode.c:1993 +> mount_single+0xf6/0x160 fs/super.c:1192 +> gadgetfs_mount+0x31/0x40 drivers/usb/gadget/legacy/inode.c:2019 +> mount_fs+0x9c/0x2d0 fs/super.c:1223 +> vfs_kern_mount.part.25+0xcb/0x490 fs/namespace.c:976 +> vfs_kern_mount fs/namespace.c:2509 [inline] +> do_new_mount fs/namespace.c:2512 [inline] +> do_mount+0x41b/0x2d90 fs/namespace.c:2834 +> SYSC_mount fs/namespace.c:3050 [inline] +> SyS_mount+0xb0/0x120 fs/namespace.c:3027 +> entry_SYSCALL_64_fastpath+0x1f/0xbe +> +> Freed by task 9960: +> save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59 +> save_stack+0x43/0xd0 mm/kasan/kasan.c:513 +> set_track mm/kasan/kasan.c:525 [inline] +> kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:590 +> slab_free_hook mm/slub.c:1357 [inline] +> slab_free_freelist_hook mm/slub.c:1379 [inline] +> slab_free mm/slub.c:2961 [inline] +> kfree+0xed/0x2b0 mm/slub.c:3882 +> put_dev+0x124/0x160 drivers/usb/gadget/legacy/inode.c:163 +> gadgetfs_kill_sb+0x33/0x60 drivers/usb/gadget/legacy/inode.c:2027 +> deactivate_locked_super+0x8d/0xd0 fs/super.c:309 +> deactivate_super+0x21e/0x310 fs/super.c:340 +> cleanup_mnt+0xb7/0x150 fs/namespace.c:1112 +> __cleanup_mnt+0x1b/0x20 fs/namespace.c:1119 +> task_work_run+0x1a0/0x280 kernel/task_work.c:116 +> exit_task_work include/linux/task_work.h:21 [inline] +> do_exit+0x18a8/0x2820 kernel/exit.c:878 +> do_group_exit+0x14e/0x420 kernel/exit.c:982 +> get_signal+0x784/0x1780 kernel/signal.c:2318 +> do_signal+0xd7/0x2130 arch/x86/kernel/signal.c:808 +> exit_to_usermode_loop+0x1ac/0x240 arch/x86/entry/common.c:157 +> prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline] +> syscall_return_slowpath+0x3ba/0x410 arch/x86/entry/common.c:263 +> entry_SYSCALL_64_fastpath+0xbc/0xbe +> +> The buggy address belongs to the object at ffff88003a2bdae0 +> which belongs to the cache kmalloc-1024 of size 1024 +> The buggy address is located 24 bytes inside of +> 1024-byte region [ffff88003a2bdae0, ffff88003a2bdee0) +> The buggy address belongs to the page: +> page:ffffea0000e8ae00 count:1 mapcount:0 mapping: (null) +> index:0x0 compound_mapcount: 0 +> flags: 0x100000000008100(slab|head) +> raw: 0100000000008100 0000000000000000 0000000000000000 0000000100170017 +> raw: ffffea0000ed3020 ffffea0000f5f820 ffff88003e80efc0 0000000000000000 +> page dumped because: kasan: bad access detected +> +> Memory state around the buggy address: +> ffff88003a2bd980: fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +> ffff88003a2bda00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +> >ffff88003a2bda80: fc fc fc fc fc fc fc fc fc fc fc fc fb fb fb fb +> ^ +> ffff88003a2bdb00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +> ffff88003a2bdb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +> ================================================================== + +What this means is that the gadgetfs_suspend() routine was trying to +access dev->lock after it had been deallocated. The root cause is a +race in the dummy_hcd driver; the dummy_udc_stop() routine can race +with the rest of the driver because it contains no locking. And even +when proper locking is added, it can still race with the +set_link_state() function because that function incorrectly drops the +private spinlock before invoking any gadget driver callbacks. + +The result of this race, as seen above, is that set_link_state() can +invoke a callback in gadgetfs even after gadgetfs has been unbound +from dummy_hcd's UDC and its private data structures have been +deallocated. + +include/linux/usb/gadget.h documents that the ->reset, ->disconnect, +->suspend, and ->resume callbacks may be invoked in interrupt context. +In general this is necessary, to prevent races with gadget driver +removal. This patch fixes dummy_hcd to retain the spinlock across +these calls, and it adds a spinlock acquisition to dummy_udc_stop() to +prevent the race. + +The net2280 driver makes the same mistake of dropping the private +spinlock for its ->disconnect and ->reset callback invocations. The +patch fixes it too. + +Lastly, since gadgetfs_suspend() may be invoked in interrupt context, +it cannot assume that interrupts are enabled when it runs. It must +use spin_lock_irqsave() instead of spin_lock_irq(). The patch fixes +that bug as well. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Andrey Konovalov +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/inode.c | 5 +++-- + drivers/usb/gadget/udc/dummy_hcd.c | 13 ++++--------- + drivers/usb/gadget/udc/net2280.c | 9 +-------- + 3 files changed, 8 insertions(+), 19 deletions(-) + +--- a/drivers/usb/gadget/legacy/inode.c ++++ b/drivers/usb/gadget/legacy/inode.c +@@ -1678,9 +1678,10 @@ static void + gadgetfs_suspend (struct usb_gadget *gadget) + { + struct dev_data *dev = get_gadget_data (gadget); ++ unsigned long flags; + + INFO (dev, "suspended from state %d\n", dev->state); +- spin_lock (&dev->lock); ++ spin_lock_irqsave(&dev->lock, flags); + switch (dev->state) { + case STATE_DEV_SETUP: // VERY odd... host died?? + case STATE_DEV_CONNECTED: +@@ -1691,7 +1692,7 @@ gadgetfs_suspend (struct usb_gadget *gad + default: + break; + } +- spin_unlock (&dev->lock); ++ spin_unlock_irqrestore(&dev->lock, flags); + } + + static struct usb_gadget_driver gadgetfs_driver = { +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -442,23 +442,16 @@ static void set_link_state(struct dummy_ + /* Report reset and disconnect events to the driver */ + if (dum->driver && (disconnect || reset)) { + stop_activity(dum); +- spin_unlock(&dum->lock); + if (reset) + usb_gadget_udc_reset(&dum->gadget, dum->driver); + else + dum->driver->disconnect(&dum->gadget); +- spin_lock(&dum->lock); + } + } else if (dum_hcd->active != dum_hcd->old_active) { +- if (dum_hcd->old_active && dum->driver->suspend) { +- spin_unlock(&dum->lock); ++ if (dum_hcd->old_active && dum->driver->suspend) + dum->driver->suspend(&dum->gadget); +- spin_lock(&dum->lock); +- } else if (!dum_hcd->old_active && dum->driver->resume) { +- spin_unlock(&dum->lock); ++ else if (!dum_hcd->old_active && dum->driver->resume) + dum->driver->resume(&dum->gadget); +- spin_lock(&dum->lock); +- } + } + + dum_hcd->old_status = dum_hcd->port_status; +@@ -983,7 +976,9 @@ static int dummy_udc_stop(struct usb_gad + struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); + struct dummy *dum = dum_hcd->dum; + ++ spin_lock_irq(&dum->lock); + dum->driver = NULL; ++ spin_unlock_irq(&dum->lock); + + return 0; + } +--- a/drivers/usb/gadget/udc/net2280.c ++++ b/drivers/usb/gadget/udc/net2280.c +@@ -2470,11 +2470,8 @@ static void stop_activity(struct net2280 + nuke(&dev->ep[i]); + + /* report disconnect; the driver is already quiesced */ +- if (driver) { +- spin_unlock(&dev->lock); ++ if (driver) + driver->disconnect(&dev->gadget); +- spin_lock(&dev->lock); +- } + + usb_reinit(dev); + } +@@ -3348,8 +3345,6 @@ next_endpoints: + BIT(PCI_RETRY_ABORT_INTERRUPT)) + + static void handle_stat1_irqs(struct net2280 *dev, u32 stat) +-__releases(dev->lock) +-__acquires(dev->lock) + { + struct net2280_ep *ep; + u32 tmp, num, mask, scratch; +@@ -3390,14 +3385,12 @@ __acquires(dev->lock) + if (disconnect || reset) { + stop_activity(dev, dev->driver); + ep0_start(dev); +- spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset + (&dev->gadget, dev->driver); + else + (dev->driver->disconnect) + (&dev->gadget); +- spin_lock(&dev->lock); + return; + } + } diff --git a/queue-4.11/usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch b/queue-4.11/usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch new file mode 100644 index 00000000000..bca03f81c3f --- /dev/null +++ b/queue-4.11/usb-xhci-asmedia-asm1042a-chipset-need-shorts-tx-quirk.patch @@ -0,0 +1,35 @@ +From d2f48f05cd2a2a0a708fbfa45f1a00a87660d937 Mon Sep 17 00:00:00 2001 +From: Corentin Labbe +Date: Fri, 9 Jun 2017 14:48:41 +0300 +Subject: usb: xhci: ASMedia ASM1042A chipset need shorts TX quirk + +From: Corentin Labbe + +commit d2f48f05cd2a2a0a708fbfa45f1a00a87660d937 upstream. + +When plugging an USB webcam I see the following message: +[106385.615559] xhci_hcd 0000:04:00.0: WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk? +[106390.583860] handle_tx_event: 913 callbacks suppressed + +With this patch applied, I get no more printing of this message. + +Signed-off-by: Corentin Labbe +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -201,6 +201,9 @@ static void xhci_pci_quirks(struct devic + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + pdev->device == 0x1042) + xhci->quirks |= XHCI_BROKEN_STREAMS; ++ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && ++ pdev->device == 0x1142) ++ xhci->quirks |= XHCI_TRUST_TX_LENGTH; + + if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) + xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; diff --git a/queue-4.11/usb-xhci-fix-usb-3.1-supported-protocol-parsing.patch b/queue-4.11/usb-xhci-fix-usb-3.1-supported-protocol-parsing.patch new file mode 100644 index 00000000000..1e19cc80027 --- /dev/null +++ b/queue-4.11/usb-xhci-fix-usb-3.1-supported-protocol-parsing.patch @@ -0,0 +1,71 @@ +From b72eb8435b25be3a1880264cf32ac91e626ba5ba Mon Sep 17 00:00:00 2001 +From: YD Tseng +Date: Fri, 9 Jun 2017 14:48:40 +0300 +Subject: usb: xhci: Fix USB 3.1 supported protocol parsing + +From: YD Tseng + +commit b72eb8435b25be3a1880264cf32ac91e626ba5ba upstream. + +xHCI host controllers can have both USB 3.1 and 3.0 extended speed +protocol lists. If the USB3.1 speed is parsed first and 3.0 second then +the minor revision supported will be overwritten by the 3.0 speeds and +the USB3 roothub will only show support for USB 3.0 speeds. + +This was the case with a xhci controller with the supported protocol +capability listed below. +In xhci-mem.c, the USB 3.1 speed is parsed first, the min_rev of usb3_rhub +is set as 0x10. And then USB 3.0 is parsed. However, the min_rev of +usb3_rhub will be changed to 0x00. If USB 3.1 device is connected behind +this host controller, the speed of USB 3.1 device just reports 5G speed +using lsusb. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 00 01 08 00 00 00 00 00 40 00 00 00 00 00 00 00 00 + 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 20 02 08 10 03 55 53 42 20 01 02 00 00 00 00 00 00 //USB 3.1 + 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 40 02 08 00 03 55 53 42 20 03 06 00 00 00 00 00 00 //USB 3.0 + 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 60 02 08 00 02 55 53 42 20 09 0E 19 00 00 00 00 00 //USB 2.0 + 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +This patch fixes the issue by only owerwriting the minor revision if +it is higher than the existing one. + +[reword commit message -Mathias] +Signed-off-by: YD Tseng +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -2128,11 +2128,12 @@ static void xhci_add_in_port(struct xhci + { + u32 temp, port_offset, port_count; + int i; +- u8 major_revision; ++ u8 major_revision, minor_revision; + struct xhci_hub *rhub; + + temp = readl(addr); + major_revision = XHCI_EXT_PORT_MAJOR(temp); ++ minor_revision = XHCI_EXT_PORT_MINOR(temp); + + if (major_revision == 0x03) { + rhub = &xhci->usb3_rhub; +@@ -2146,7 +2147,9 @@ static void xhci_add_in_port(struct xhci + return; + } + rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp); +- rhub->min_rev = XHCI_EXT_PORT_MINOR(temp); ++ ++ if (rhub->min_rev < minor_revision) ++ rhub->min_rev = minor_revision; + + /* Port offset and count in the third dword, see section 7.2 */ + temp = readl(addr + 2); diff --git a/queue-4.11/userfaultfd-shmem-handle-coredumping-in-handle_userfault.patch b/queue-4.11/userfaultfd-shmem-handle-coredumping-in-handle_userfault.patch new file mode 100644 index 00000000000..fc4f6d49419 --- /dev/null +++ b/queue-4.11/userfaultfd-shmem-handle-coredumping-in-handle_userfault.patch @@ -0,0 +1,85 @@ +From 64c2b20301f62c697352c8028c569b1b2bdd8e82 Mon Sep 17 00:00:00 2001 +From: Andrea Arcangeli +Date: Fri, 16 Jun 2017 14:02:37 -0700 +Subject: userfaultfd: shmem: handle coredumping in handle_userfault() + +From: Andrea Arcangeli + +commit 64c2b20301f62c697352c8028c569b1b2bdd8e82 upstream. + +Anon and hugetlbfs handle FOLL_DUMP set by get_dump_page() internally to +__get_user_pages(). + +shmem as opposed has no special FOLL_DUMP handling there so +handle_mm_fault() is invoked without mmap_sem and ends up calling +handle_userfault() that isn't expecting to be invoked without mmap_sem +held. + +This makes handle_userfault() fail immediately if invoked through +shmem_vm_ops->fault during coredumping and solves the problem. + +The side effect is a BUG_ON with no lock held triggered by the +coredumping process which exits. Only 4.11 is affected, pre-4.11 anon +memory holes are skipped in __get_user_pages by checking FOLL_DUMP +explicitly against empty pagetables (mm/gup.c:no_page_table()). + +It's zero cost as we already had a check for current->flags to prevent +futex to trigger userfaults during exit (PF_EXITING). + +Link: http://lkml.kernel.org/r/20170615214838.27429-1-aarcange@redhat.com +Signed-off-by: Andrea Arcangeli +Reported-by: "Dr. David Alan Gilbert" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/userfaultfd.c | 29 +++++++++++++++++++++-------- + 1 file changed, 21 insertions(+), 8 deletions(-) + +--- a/fs/userfaultfd.c ++++ b/fs/userfaultfd.c +@@ -340,9 +340,28 @@ int handle_userfault(struct vm_fault *vm + bool must_wait, return_to_userland; + long blocking_state; + +- BUG_ON(!rwsem_is_locked(&mm->mmap_sem)); +- + ret = VM_FAULT_SIGBUS; ++ ++ /* ++ * We don't do userfault handling for the final child pid update. ++ * ++ * We also don't do userfault handling during ++ * coredumping. hugetlbfs has the special ++ * follow_hugetlb_page() to skip missing pages in the ++ * FOLL_DUMP case, anon memory also checks for FOLL_DUMP with ++ * the no_page_table() helper in follow_page_mask(), but the ++ * shmem_vm_ops->fault method is invoked even during ++ * coredumping without mmap_sem and it ends up here. ++ */ ++ if (current->flags & (PF_EXITING|PF_DUMPCORE)) ++ goto out; ++ ++ /* ++ * Coredumping runs without mmap_sem so we can only check that ++ * the mmap_sem is held, if PF_DUMPCORE was not set. ++ */ ++ WARN_ON_ONCE(!rwsem_is_locked(&mm->mmap_sem)); ++ + ctx = vmf->vma->vm_userfaultfd_ctx.ctx; + if (!ctx) + goto out; +@@ -361,12 +380,6 @@ int handle_userfault(struct vm_fault *vm + goto out; + + /* +- * We don't do userfault handling for the final child pid update. +- */ +- if (current->flags & PF_EXITING) +- goto out; +- +- /* + * Check that we can return VM_FAULT_RETRY. + * + * NOTE: it should become possible to return VM_FAULT_RETRY