From: Greg Kroah-Hartman Date: Wed, 3 Aug 2016 06:05:43 +0000 (+0200) Subject: 4.6-stable patches X-Git-Tag: v3.14.75~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b79579a58ddda840d3ffb0fa8e77954cf6749a8;p=thirdparty%2Fkernel%2Fstable-queue.git 4.6-stable patches added patches: 9p-use-file_dentry.patch block-fix-use-after-free-in-sys_ioprio_get.patch clk-at91-fix-clk_programmable_set_parent.patch clk-rockchip-initialize-flags-of-clk_init_data-in-mmc-phase-clock.patch cpufreq-avoid-false-positive-warn_on-s-in-cpufreq_update_policy.patch devpts-fix-null-pointer-dereference-on-failed-memory-allocation.patch ext4-verify-extent-header-depth.patch init-kconfig-keep-expert-users-menu-together.patch lockd-unregister-notifier-blocks-if-the-service-fails-to-come-up-completely.patch mmc-block-fix-free-of-uninitialized-idata-buf.patch mmc-block-fix-packed-command-header-endianness.patch namespace-update-event-counter-when-umounting-a-deleted-dentry.patch platform-chrome-cros_ec_dev-double-fetch-bug-in-ioctl.patch qeth-delete-napi-struct-when-removing-a-qeth-device.patch sched-fair-fix-effective_load-to-consistently-use-smoothed-load.patch spi-rockchip-signal-unfinished-dma-transfers.patch spi-sun4i-fix-fifo-limit.patch spi-sunxi-fix-transfer-timeout.patch --- diff --git a/queue-4.6/9p-use-file_dentry.patch b/queue-4.6/9p-use-file_dentry.patch new file mode 100644 index 00000000000..c7299164268 --- /dev/null +++ b/queue-4.6/9p-use-file_dentry.patch @@ -0,0 +1,56 @@ +From b403f0e37a11f84f7ceaf40b0075499e5bcfd220 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Wed, 29 Jun 2016 10:54:23 +0200 +Subject: 9p: use file_dentry() + +From: Miklos Szeredi + +commit b403f0e37a11f84f7ceaf40b0075499e5bcfd220 upstream. + +v9fs may be used as lower layer of overlayfs and accessing f_path.dentry +can lead to a crash. In this case it's a NULL pointer dereference in +p9_fid_create(). + +Fix by replacing direct access of file->f_path.dentry with the +file_dentry() accessor, which will always return a native object. + +Reported-by: Alessio Igor Bogani +Signed-off-by: Miklos Szeredi +Tested-by: Alessio Igor Bogani +Fixes: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay and f_inode to the underlay") +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/9p/vfs_file.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/9p/vfs_file.c ++++ b/fs/9p/vfs_file.c +@@ -74,7 +74,7 @@ int v9fs_file_open(struct inode *inode, + v9fs_proto_dotu(v9ses)); + fid = file->private_data; + if (!fid) { +- fid = v9fs_fid_clone(file->f_path.dentry); ++ fid = v9fs_fid_clone(file_dentry(file)); + if (IS_ERR(fid)) + return PTR_ERR(fid); + +@@ -100,7 +100,7 @@ int v9fs_file_open(struct inode *inode, + * because we want write after unlink usecase + * to work. + */ +- fid = v9fs_writeback_fid(file->f_path.dentry); ++ fid = v9fs_writeback_fid(file_dentry(file)); + if (IS_ERR(fid)) { + err = PTR_ERR(fid); + mutex_unlock(&v9inode->v_mutex); +@@ -516,7 +516,7 @@ v9fs_mmap_file_mmap(struct file *filp, s + * because we want write after unlink usecase + * to work. + */ +- fid = v9fs_writeback_fid(filp->f_path.dentry); ++ fid = v9fs_writeback_fid(file_dentry(filp)); + if (IS_ERR(fid)) { + retval = PTR_ERR(fid); + mutex_unlock(&v9inode->v_mutex); diff --git a/queue-4.6/block-fix-use-after-free-in-sys_ioprio_get.patch b/queue-4.6/block-fix-use-after-free-in-sys_ioprio_get.patch new file mode 100644 index 00000000000..319c3a1d2df --- /dev/null +++ b/queue-4.6/block-fix-use-after-free-in-sys_ioprio_get.patch @@ -0,0 +1,123 @@ +From 8ba8682107ee2ca3347354e018865d8e1967c5f4 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Fri, 1 Jul 2016 00:39:35 -0700 +Subject: block: fix use-after-free in sys_ioprio_get() + +From: Omar Sandoval + +commit 8ba8682107ee2ca3347354e018865d8e1967c5f4 upstream. + +get_task_ioprio() accesses the task->io_context without holding the task +lock and thus can race with exit_io_context(), leading to a +use-after-free. The reproducer below hits this within a few seconds on +my 4-core QEMU VM: + +#define _GNU_SOURCE +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + pid_t pid, child; + long nproc, i; + + /* ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)); */ + syscall(SYS_ioprio_set, 1, 0, 0x6000); + + nproc = sysconf(_SC_NPROCESSORS_ONLN); + + for (i = 0; i < nproc; i++) { + pid = fork(); + assert(pid != -1); + if (pid == 0) { + for (;;) { + pid = fork(); + assert(pid != -1); + if (pid == 0) { + _exit(0); + } else { + child = wait(NULL); + assert(child == pid); + } + } + } + + pid = fork(); + assert(pid != -1); + if (pid == 0) { + for (;;) { + /* ioprio_get(IOPRIO_WHO_PGRP, 0); */ + syscall(SYS_ioprio_get, 2, 0); + } + } + } + + for (;;) { + /* ioprio_get(IOPRIO_WHO_PGRP, 0); */ + syscall(SYS_ioprio_get, 2, 0); + } + + return 0; +} + +This gets us KASAN dumps like this: + +[ 35.526914] ================================================================== +[ 35.530009] BUG: KASAN: out-of-bounds in get_task_ioprio+0x7b/0x90 at addr ffff880066f34e6c +[ 35.530009] Read of size 2 by task ioprio-gpf/363 +[ 35.530009] ============================================================================= +[ 35.530009] BUG blkdev_ioc (Not tainted): kasan: bad access detected +[ 35.530009] ----------------------------------------------------------------------------- + +[ 35.530009] Disabling lock debugging due to kernel taint +[ 35.530009] INFO: Allocated in create_task_io_context+0x2b/0x370 age=0 cpu=0 pid=360 +[ 35.530009] ___slab_alloc+0x55d/0x5a0 +[ 35.530009] __slab_alloc.isra.20+0x2b/0x40 +[ 35.530009] kmem_cache_alloc_node+0x84/0x200 +[ 35.530009] create_task_io_context+0x2b/0x370 +[ 35.530009] get_task_io_context+0x92/0xb0 +[ 35.530009] copy_process.part.8+0x5029/0x5660 +[ 35.530009] _do_fork+0x155/0x7e0 +[ 35.530009] SyS_clone+0x19/0x20 +[ 35.530009] do_syscall_64+0x195/0x3a0 +[ 35.530009] return_from_SYSCALL_64+0x0/0x6a +[ 35.530009] INFO: Freed in put_io_context+0xe7/0x120 age=0 cpu=0 pid=1060 +[ 35.530009] __slab_free+0x27b/0x3d0 +[ 35.530009] kmem_cache_free+0x1fb/0x220 +[ 35.530009] put_io_context+0xe7/0x120 +[ 35.530009] put_io_context_active+0x238/0x380 +[ 35.530009] exit_io_context+0x66/0x80 +[ 35.530009] do_exit+0x158e/0x2b90 +[ 35.530009] do_group_exit+0xe5/0x2b0 +[ 35.530009] SyS_exit_group+0x1d/0x20 +[ 35.530009] entry_SYSCALL_64_fastpath+0x1a/0xa4 +[ 35.530009] INFO: Slab 0xffffea00019bcd00 objects=20 used=4 fp=0xffff880066f34ff0 flags=0x1fffe0000004080 +[ 35.530009] INFO: Object 0xffff880066f34e58 @offset=3672 fp=0x0000000000000001 +[ 35.530009] ================================================================== + +Fix it by grabbing the task lock while we poke at the io_context. + +Reported-by: Dmitry Vyukov +Signed-off-by: Omar Sandoval +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/ioprio.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/block/ioprio.c ++++ b/block/ioprio.c +@@ -150,8 +150,10 @@ static int get_task_ioprio(struct task_s + if (ret) + goto out; + ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM); ++ task_lock(p); + if (p->io_context) + ret = p->io_context->ioprio; ++ task_unlock(p); + out: + return ret; + } diff --git a/queue-4.6/clk-at91-fix-clk_programmable_set_parent.patch b/queue-4.6/clk-at91-fix-clk_programmable_set_parent.patch new file mode 100644 index 00000000000..701f18a7713 --- /dev/null +++ b/queue-4.6/clk-at91-fix-clk_programmable_set_parent.patch @@ -0,0 +1,38 @@ +From f96423f483b1a7854270335b319e8d1cdd6f3585 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Mon, 18 Jul 2016 09:49:12 +0200 +Subject: clk: at91: fix clk_programmable_set_parent() + +From: Boris Brezillon + +commit f96423f483b1a7854270335b319e8d1cdd6f3585 upstream. + +Since commit 1bdf02326b71e ("clk: at91: make use of syscon/regmap +internally"), clk_programmable_set_parent() is always selecting the +first parent (AKA slow_clk), no matter what's passed in the 'index' +parameter. + +Fix that by initializing the pckr variable to the index value. + +Signed-off-by: Boris Brezillon +Reported-by: Hans Verkuil +Fixes: 1bdf02326b71e ("clk: at91: make use of syscon/regmap internally") +Signed-off-by: Michael Turquette +Link: lkml.kernel.org/r/1468828152-18389-1-git-send-email-boris.brezillon@free-electrons.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/at91/clk-programmable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/at91/clk-programmable.c ++++ b/drivers/clk/at91/clk-programmable.c +@@ -99,7 +99,7 @@ static int clk_programmable_set_parent(s + struct clk_programmable *prog = to_clk_programmable(hw); + const struct clk_programmable_layout *layout = prog->layout; + unsigned int mask = layout->css_mask; +- unsigned int pckr = 0; ++ unsigned int pckr = index; + + if (layout->have_slck_mck) + mask |= AT91_PMC_CSSMCK_MCK; diff --git a/queue-4.6/clk-rockchip-initialize-flags-of-clk_init_data-in-mmc-phase-clock.patch b/queue-4.6/clk-rockchip-initialize-flags-of-clk_init_data-in-mmc-phase-clock.patch new file mode 100644 index 00000000000..0159cb835ff --- /dev/null +++ b/queue-4.6/clk-rockchip-initialize-flags-of-clk_init_data-in-mmc-phase-clock.patch @@ -0,0 +1,31 @@ +From 595144c1141c951a3c6bb9004ae6a2bc29aad66f Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner +Date: Tue, 17 May 2016 20:57:50 +0200 +Subject: clk: rockchip: initialize flags of clk_init_data in mmc-phase clock + +From: Heiko Stuebner + +commit 595144c1141c951a3c6bb9004ae6a2bc29aad66f upstream. + +The flags element of clk_init_data was never initialized for mmc- +phase-clocks resulting in the element containing a random value +and thus possibly enabling unwanted clock flags. + +Fixes: 89bf26cbc1a0 ("clk: rockchip: Add support for the mmc clock phases using the framework") +Signed-off-by: Heiko Stuebner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/rockchip/clk-mmc-phase.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/clk/rockchip/clk-mmc-phase.c ++++ b/drivers/clk/rockchip/clk-mmc-phase.c +@@ -153,6 +153,7 @@ struct clk *rockchip_clk_register_mmc(co + return ERR_PTR(-ENOMEM); + + init.name = name; ++ init.flags = 0; + init.num_parents = num_parents; + init.parent_names = parent_names; + init.ops = &rockchip_mmc_clk_ops; diff --git a/queue-4.6/cpufreq-avoid-false-positive-warn_on-s-in-cpufreq_update_policy.patch b/queue-4.6/cpufreq-avoid-false-positive-warn_on-s-in-cpufreq_update_policy.patch new file mode 100644 index 00000000000..5887ef338b2 --- /dev/null +++ b/queue-4.6/cpufreq-avoid-false-positive-warn_on-s-in-cpufreq_update_policy.patch @@ -0,0 +1,38 @@ +From 742c87bf27d3b715820da6f8a81d6357adbf18f8 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Tue, 28 Jun 2016 03:29:29 +0200 +Subject: cpufreq: Avoid false-positive WARN_ON()s in cpufreq_update_policy() + +From: Rafael J. Wysocki + +commit 742c87bf27d3b715820da6f8a81d6357adbf18f8 upstream. + +CPU notifications from the firmware coming in when cpufreq is +suspended cause cpufreq_update_current_freq() to return 0 which +triggers the WARN_ON() in cpufreq_update_policy() for no reason. + +Avoid that by checking cpufreq_suspended before calling +cpufreq_update_current_freq(). + +Fixes: c9d9c929e674 (cpufreq: Abort cpufreq_update_current_freq() for cpufreq_suspended set) +Signed-off-by: Rafael J. Wysocki +Acked-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/cpufreq.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -2169,6 +2169,10 @@ int cpufreq_update_policy(unsigned int c + * -> ask driver for current freq and notify governors about a change + */ + if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { ++ if (cpufreq_suspended) { ++ ret = -EAGAIN; ++ goto unlock; ++ } + new_policy.cur = cpufreq_update_current_freq(policy); + if (WARN_ON(!new_policy.cur)) { + ret = -EIO; diff --git a/queue-4.6/devpts-fix-null-pointer-dereference-on-failed-memory-allocation.patch b/queue-4.6/devpts-fix-null-pointer-dereference-on-failed-memory-allocation.patch new file mode 100644 index 00000000000..795057f615e --- /dev/null +++ b/queue-4.6/devpts-fix-null-pointer-dereference-on-failed-memory-allocation.patch @@ -0,0 +1,91 @@ +From 5353ed8deedee9e5acb9f896e9032158f5d998de Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 20 Jun 2016 15:40:27 +0100 +Subject: devpts: fix null pointer dereference on failed memory allocation + +From: Colin Ian King + +commit 5353ed8deedee9e5acb9f896e9032158f5d998de upstream. + +An ENOMEM when creating a pair tty in tty_ldisc_setup causes a null +pointer dereference in devpts_kill_index because tty->link->driver_data +is NULL. The oops was triggered with the pty stressor in stress-ng when +in a low memory condition. + +tty_init_dev tries to clean up a tty_ldisc_setup ENOMEM error by calling +release_tty, however, this ultimately tries to clean up the NULL pair'd +tty in pty_unix98_remove, triggering the Oops. + +Add check to pty_unix98_remove to only clean up fsi if it is not NULL. + +Ooops: + +[ 23.020961] Oops: 0000 [#1] SMP +[ 23.020976] Modules linked in: ppdev snd_hda_codec_generic snd_hda_intel snd_hda_codec parport_pc snd_hda_core snd_hwdep parport snd_pcm input_leds joydev snd_timer serio_raw snd soundcore i2c_piix4 mac_hid ib_iser rdma_cm iw_cm ib_cm ib_core configfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 btrfs raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel qxl aes_x86_64 ttm lrw gf128mul glue_helper ablk_helper drm_kms_helper cryptd syscopyarea sysfillrect psmouse sysimgblt floppy fb_sys_fops drm pata_acpi jitterentropy_rng drbg ansi_cprng +[ 23.020978] CPU: 0 PID: 1452 Comm: stress-ng-pty Not tainted 4.7.0-rc4+ #2 +[ 23.020978] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 +[ 23.020979] task: ffff88007ba30000 ti: ffff880078ea8000 task.ti: ffff880078ea8000 +[ 23.020981] RIP: 0010:[] [] ida_remove+0x1f/0x120 +[ 23.020981] RSP: 0018:ffff880078eabb60 EFLAGS: 00010a03 +[ 23.020982] RAX: 4444444444444567 RBX: 0000000000000000 RCX: 000000000000001f +[ 23.020982] RDX: 000000000000014c RSI: 000000000000026f RDI: 0000000000000000 +[ 23.020982] RBP: ffff880078eabb70 R08: 0000000000000004 R09: 0000000000000036 +[ 23.020983] R10: 000000000000026f R11: 0000000000000000 R12: 000000000000026f +[ 23.020983] R13: 000000000000026f R14: ffff88007c944b40 R15: 000000000000026f +[ 23.020984] FS: 00007f9a2f3cc700(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000 +[ 23.020984] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 23.020985] CR2: 0000000000000010 CR3: 000000006c81b000 CR4: 00000000001406f0 +[ 23.020988] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 23.020988] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[ 23.020988] Stack: +[ 23.020989] 0000000000000000 000000000000026f ffff880078eabb90 ffffffff812a5a99 +[ 23.020990] 0000000000000000 00000000fffffff4 ffff880078eabba8 ffffffff814f9cbe +[ 23.020991] ffff88007965c800 ffff880078eabbc8 ffffffff814eef43 fffffffffffffff4 +[ 23.020991] Call Trace: +[ 23.021000] [] devpts_kill_index+0x29/0x50 +[ 23.021002] [] pty_unix98_remove+0x2e/0x50 +[ 23.021006] [] release_tty+0xb3/0x1b0 +[ 23.021007] [] tty_init_dev+0xd4/0x1c0 +[ 23.021011] [] ptmx_open+0xae/0x190 +[ 23.021013] [] chrdev_open+0xbf/0x1b0 +[ 23.021015] [] do_dentry_open+0x203/0x310 +[ 23.021016] [] ? cdev_put+0x30/0x30 +[ 23.021017] [] vfs_open+0x54/0x80 +[ 23.021018] [] ? may_open+0x8c/0x100 +[ 23.021019] [] path_openat+0x2eb/0x1440 +[ 23.021020] [] ? putname+0x54/0x60 +[ 23.021022] [] ? n_tty_ioctl_helper+0x27/0x100 +[ 23.021023] [] do_filp_open+0x91/0x100 +[ 23.021024] [] ? getname_flags+0x56/0x1f0 +[ 23.021026] [] ? __alloc_fd+0x46/0x190 +[ 23.021027] [] do_sys_open+0x124/0x210 +[ 23.021028] [] SyS_open+0x1e/0x20 +[ 23.021035] [] entry_SYSCALL_64_fastpath+0x1e/0xa8 +[ 23.021044] Code: 63 28 45 31 e4 eb dd 0f 1f 44 00 00 55 4c 63 d6 48 ba 89 88 88 88 88 88 88 88 4c 89 d0 b9 1f 00 00 00 48 f7 e2 48 89 e5 41 54 53 <8b> 47 10 48 89 fb 8d 3c c5 00 00 00 00 48 c1 ea 09 b8 01 00 00 +[ 23.021045] RIP [] ida_remove+0x1f/0x120 +[ 23.021045] RSP +[ 23.021046] CR2: 0000000000000010 + +Signed-off-by: Colin Ian King +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/pty.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -667,8 +667,11 @@ static void pty_unix98_remove(struct tty + fsi = tty->driver_data; + else + fsi = tty->link->driver_data; +- devpts_kill_index(fsi, tty->index); +- devpts_put_ref(fsi); ++ ++ if (fsi) { ++ devpts_kill_index(fsi, tty->index); ++ devpts_put_ref(fsi); ++ } + } + + static const struct tty_operations ptm_unix98_ops = { diff --git a/queue-4.6/ext4-verify-extent-header-depth.patch b/queue-4.6/ext4-verify-extent-header-depth.patch new file mode 100644 index 00000000000..2940b08b6c5 --- /dev/null +++ b/queue-4.6/ext4-verify-extent-header-depth.patch @@ -0,0 +1,74 @@ +From 7bc9491645118c9461bd21099c31755ff6783593 Mon Sep 17 00:00:00 2001 +From: Vegard Nossum +Date: Fri, 15 Jul 2016 00:22:07 -0400 +Subject: ext4: verify extent header depth + +From: Vegard Nossum + +commit 7bc9491645118c9461bd21099c31755ff6783593 upstream. + +Although the extent tree depth of 5 should enough be for the worst +case of 2*32 extents of length 1, the extent tree code does not +currently to merge nodes which are less than half-full with a sibling +node, or to shrink the tree depth if possible. So it's possible, at +least in theory, for the tree depth to be greater than 5. However, +even in the worst case, a tree depth of 32 is highly unlikely, and if +the file system is maliciously corrupted, an insanely large eh_depth +can cause memory allocation failures that will trigger kernel warnings +(here, eh_depth = 65280): + + JBD2: ext4.exe wants too many credits credits:195849 rsv_credits:0 max:256 + ------------[ cut here ]------------ + WARNING: CPU: 0 PID: 50 at fs/jbd2/transaction.c:293 start_this_handle+0x569/0x580 + CPU: 0 PID: 50 Comm: ext4.exe Not tainted 4.7.0-rc5+ #508 + Stack: + 604a8947 625badd8 0002fd09 00000000 + 60078643 00000000 62623910 601bf9bc + 62623970 6002fc84 626239b0 900000125 + Call Trace: + [<6001c2dc>] show_stack+0xdc/0x1a0 + [<601bf9bc>] dump_stack+0x2a/0x2e + [<6002fc84>] __warn+0x114/0x140 + [<6002fdff>] warn_slowpath_null+0x1f/0x30 + [<60165829>] start_this_handle+0x569/0x580 + [<60165d4e>] jbd2__journal_start+0x11e/0x220 + [<60146690>] __ext4_journal_start_sb+0x60/0xa0 + [<60120a81>] ext4_truncate+0x131/0x3a0 + [<60123677>] ext4_setattr+0x757/0x840 + [<600d5d0f>] notify_change+0x16f/0x2a0 + [<600b2b16>] do_truncate+0x76/0xc0 + [<600c3e56>] path_openat+0x806/0x1300 + [<600c55c9>] do_filp_open+0x89/0xf0 + [<600b4074>] do_sys_open+0x134/0x1e0 + [<600b4140>] SyS_open+0x20/0x30 + [<6001ea68>] handle_syscall+0x88/0x90 + [<600295fd>] userspace+0x3fd/0x500 + [<6001ac55>] fork_handler+0x85/0x90 + + ---[ end trace 08b0b88b6387a244 ]--- + +[ Commit message modified and the extent tree depath check changed +from 5 to 32 -- tytso ] + +Cc: Darrick J. Wong +Signed-off-by: Vegard Nossum +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/extents.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -469,6 +469,10 @@ static int __ext4_ext_check(const char * + error_msg = "invalid extent entries"; + goto corrupted; + } ++ if (unlikely(depth > 32)) { ++ error_msg = "too large eh_depth"; ++ goto corrupted; ++ } + /* Verify checksum on non-root extent tree nodes */ + if (ext_depth(inode) != depth && + !ext4_extent_block_csum_verify(inode, eh)) { diff --git a/queue-4.6/init-kconfig-keep-expert-users-menu-together.patch b/queue-4.6/init-kconfig-keep-expert-users-menu-together.patch new file mode 100644 index 00000000000..a5202080e2e --- /dev/null +++ b/queue-4.6/init-kconfig-keep-expert-users-menu-together.patch @@ -0,0 +1,37 @@ +From 076501ff6ba265a473689c112eda9f1f34f620b5 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Wed, 6 Jul 2016 16:06:53 -0700 +Subject: init/Kconfig: keep Expert users menu together + +From: Randy Dunlap + +commit 076501ff6ba265a473689c112eda9f1f34f620b5 upstream. + +The "expert" menu was broken (split) such that all entries in it after +KALLSYMS were displayed in the "General setup" area instead of in the +"Expert users" area. Fix this by adding one kconfig dependency. + +Yes, the Expert users menu is fragile. Problems like this have happened +several times in the past. I will attempt to isolate the Expert users +menu if there is interest in that. + +Fixes: 4d5d5664c900 ("x86: kallsyms: disable absolute percpu symbols on !SMP") +Signed-off-by: Randy Dunlap +Cc: Ard Biesheuvel +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + init/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1423,6 +1423,7 @@ config KALLSYMS_ALL + + config KALLSYMS_ABSOLUTE_PERCPU + bool ++ depends on KALLSYMS + default X86_64 && SMP + + config KALLSYMS_BASE_RELATIVE diff --git a/queue-4.6/lockd-unregister-notifier-blocks-if-the-service-fails-to-come-up-completely.patch b/queue-4.6/lockd-unregister-notifier-blocks-if-the-service-fails-to-come-up-completely.patch new file mode 100644 index 00000000000..b545ff3b693 --- /dev/null +++ b/queue-4.6/lockd-unregister-notifier-blocks-if-the-service-fails-to-come-up-completely.patch @@ -0,0 +1,64 @@ +From cb7d224f82e41d82518e7f9ea271d215d4d08e6e Mon Sep 17 00:00:00 2001 +From: Scott Mayhew +Date: Thu, 30 Jun 2016 10:39:32 -0400 +Subject: lockd: unregister notifier blocks if the service fails to come up completely + +From: Scott Mayhew + +commit cb7d224f82e41d82518e7f9ea271d215d4d08e6e upstream. + +If the lockd service fails to start up then we need to be sure that the +notifier blocks are not registered, otherwise a subsequent start of the +service could cause the same notifier to be registered twice, leading to +soft lockups. + +Signed-off-by: Scott Mayhew +Fixes: 0751ddf77b6a "lockd: Register callbacks on the inetaddr_chain..." +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/lockd/svc.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/fs/lockd/svc.c ++++ b/fs/lockd/svc.c +@@ -335,12 +335,17 @@ static struct notifier_block lockd_inet6 + }; + #endif + +-static void lockd_svc_exit_thread(void) ++static void lockd_unregister_notifiers(void) + { + unregister_inetaddr_notifier(&lockd_inetaddr_notifier); + #if IS_ENABLED(CONFIG_IPV6) + unregister_inet6addr_notifier(&lockd_inet6addr_notifier); + #endif ++} ++ ++static void lockd_svc_exit_thread(void) ++{ ++ lockd_unregister_notifiers(); + svc_exit_thread(nlmsvc_rqst); + } + +@@ -462,7 +467,7 @@ int lockd_up(struct net *net) + * Note: svc_serv structures have an initial use count of 1, + * so we exit through here on both success and failure. + */ +-err_net: ++err_put: + svc_destroy(serv); + err_create: + mutex_unlock(&nlmsvc_mutex); +@@ -470,7 +475,9 @@ err_create: + + err_start: + lockd_down_net(serv, net); +- goto err_net; ++err_net: ++ lockd_unregister_notifiers(); ++ goto err_put; + } + EXPORT_SYMBOL_GPL(lockd_up); + diff --git a/queue-4.6/mmc-block-fix-free-of-uninitialized-idata-buf.patch b/queue-4.6/mmc-block-fix-free-of-uninitialized-idata-buf.patch new file mode 100644 index 00000000000..66e44f698cb --- /dev/null +++ b/queue-4.6/mmc-block-fix-free-of-uninitialized-idata-buf.patch @@ -0,0 +1,37 @@ +From bfe5b1b1e013f7b1c0fd2ac3b3c8c380114b3fb9 Mon Sep 17 00:00:00 2001 +From: Ville Viinikka +Date: Fri, 8 Jul 2016 18:27:02 +0300 +Subject: mmc: block: fix free of uninitialized 'idata->buf' + +From: Ville Viinikka + +commit bfe5b1b1e013f7b1c0fd2ac3b3c8c380114b3fb9 upstream. + +Set 'idata->buf' to NULL so that it never gets returned without +initialization. This fixes a bug where mmc_blk_ioctl_cmd() would +free both 'idata' and 'idata->buf' but 'idata->buf' was returned +uninitialized. + +Fixes: 1ff8950c0433 ("mmc: block: change to use kmalloc when copy data from userspace") +Signed-off-by: Ville Viinikka +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/card/block.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -352,8 +352,10 @@ static struct mmc_blk_ioc_data *mmc_blk_ + goto idata_err; + } + +- if (!idata->buf_bytes) ++ if (!idata->buf_bytes) { ++ idata->buf = NULL; + return idata; ++ } + + idata->buf = kmalloc(idata->buf_bytes, GFP_KERNEL); + if (!idata->buf) { diff --git a/queue-4.6/mmc-block-fix-packed-command-header-endianness.patch b/queue-4.6/mmc-block-fix-packed-command-header-endianness.patch new file mode 100644 index 00000000000..78dc4880690 --- /dev/null +++ b/queue-4.6/mmc-block-fix-packed-command-header-endianness.patch @@ -0,0 +1,59 @@ +From f68381a70bb2b26c31b13fdaf67c778f92fd32b4 Mon Sep 17 00:00:00 2001 +From: Taras Kondratiuk +Date: Wed, 13 Jul 2016 22:05:38 +0000 +Subject: mmc: block: fix packed command header endianness + +From: Taras Kondratiuk + +commit f68381a70bb2b26c31b13fdaf67c778f92fd32b4 upstream. + +The code that fills packed command header assumes that CPU runs in +little-endian mode. Hence the header is malformed in big-endian mode +and causes MMC data transfer errors: + +[ 563.200828] mmcblk0: error -110 transferring data, sector 2048, nr 8, cmd response 0x900, card status 0xc40 +[ 563.219647] mmcblk0: packed cmd failed, nr 2, sectors 16, failure index: -1 + +Convert header data to LE. + +Signed-off-by: Taras Kondratiuk +Fixes: ce39f9d17c14 ("mmc: support packed write command for eMMC4.5 devices") +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/card/block.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -1762,8 +1762,8 @@ static void mmc_blk_packed_hdr_wrq_prep( + + packed_cmd_hdr = packed->cmd_hdr; + memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr)); +- packed_cmd_hdr[0] = (packed->nr_entries << 16) | +- (PACKED_CMD_WR << 8) | PACKED_CMD_VER; ++ packed_cmd_hdr[0] = cpu_to_le32((packed->nr_entries << 16) | ++ (PACKED_CMD_WR << 8) | PACKED_CMD_VER); + hdr_blocks = mmc_large_sector(card) ? 8 : 1; + + /* +@@ -1777,14 +1777,14 @@ static void mmc_blk_packed_hdr_wrq_prep( + ((brq->data.blocks * brq->data.blksz) >= + card->ext_csd.data_tag_unit_size); + /* Argument of CMD23 */ +- packed_cmd_hdr[(i * 2)] = ++ packed_cmd_hdr[(i * 2)] = cpu_to_le32( + (do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) | + (do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) | +- blk_rq_sectors(prq); ++ blk_rq_sectors(prq)); + /* Argument of CMD18 or CMD25 */ +- packed_cmd_hdr[((i * 2)) + 1] = ++ packed_cmd_hdr[((i * 2)) + 1] = cpu_to_le32( + mmc_card_blockaddr(card) ? +- blk_rq_pos(prq) : blk_rq_pos(prq) << 9; ++ blk_rq_pos(prq) : blk_rq_pos(prq) << 9); + packed->blocks += blk_rq_sectors(prq); + i++; + } diff --git a/queue-4.6/namespace-update-event-counter-when-umounting-a-deleted-dentry.patch b/queue-4.6/namespace-update-event-counter-when-umounting-a-deleted-dentry.patch new file mode 100644 index 00000000000..6f1aa83ca52 --- /dev/null +++ b/queue-4.6/namespace-update-event-counter-when-umounting-a-deleted-dentry.patch @@ -0,0 +1,41 @@ +From e06b933e6ded42384164d28a2060b7f89243b895 Mon Sep 17 00:00:00 2001 +From: Andrey Ulanov +Date: Fri, 15 Apr 2016 14:24:41 -0700 +Subject: namespace: update event counter when umounting a deleted dentry + +From: Andrey Ulanov + +commit e06b933e6ded42384164d28a2060b7f89243b895 upstream. + +- m_start() in fs/namespace.c expects that ns->event is incremented each + time a mount added or removed from ns->list. +- umount_tree() removes items from the list but does not increment event + counter, expecting that it's done before the function is called. +- There are some codepaths that call umount_tree() without updating + "event" counter. e.g. from __detach_mounts(). +- When this happens m_start may reuse a cached mount structure that no + longer belongs to ns->list (i.e. use after free which usually leads + to infinite loop). + +This change fixes the above problem by incrementing global event counter +before invoking umount_tree(). + +Change-Id: I622c8e84dcb9fb63542372c5dbf0178ee86bb589 +Signed-off-by: Andrey Ulanov +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1562,6 +1562,7 @@ void __detach_mounts(struct dentry *dent + goto out_unlock; + + lock_mount_hash(); ++ event++; + while (!hlist_empty(&mp->m_list)) { + mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); + if (mnt->mnt.mnt_flags & MNT_UMOUNT) { diff --git a/queue-4.6/platform-chrome-cros_ec_dev-double-fetch-bug-in-ioctl.patch b/queue-4.6/platform-chrome-cros_ec_dev-double-fetch-bug-in-ioctl.patch new file mode 100644 index 00000000000..d6b9616de2f --- /dev/null +++ b/queue-4.6/platform-chrome-cros_ec_dev-double-fetch-bug-in-ioctl.patch @@ -0,0 +1,52 @@ +From 096cdc6f52225835ff503f987a0d68ef770bb78e Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 21 Jun 2016 16:58:46 +0300 +Subject: platform/chrome: cros_ec_dev - double fetch bug in ioctl + +From: Dan Carpenter + +commit 096cdc6f52225835ff503f987a0d68ef770bb78e upstream. + +We verify "u_cmd.outsize" and "u_cmd.insize" but we need to make sure +that those values have not changed between the two copy_from_user() +calls. Otherwise it could lead to a buffer overflow. + +Additionally, cros_ec_cmd_xfer() can set s_cmd->insize to a lower value. +We should use the new smaller value so we don't copy too much data to +the user. + +Reported-by: Pengfei Wang +Fixes: a841178445bb ('mfd: cros_ec: Use a zero-length array for command data') +Signed-off-by: Dan Carpenter +Reviewed-by: Kees Cook +Tested-by: Gwendal Grignou +Signed-off-by: Olof Johansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/chrome/cros_ec_dev.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/platform/chrome/cros_ec_dev.c ++++ b/drivers/platform/chrome/cros_ec_dev.c +@@ -147,13 +147,19 @@ static long ec_device_ioctl_xcmd(struct + goto exit; + } + ++ if (u_cmd.outsize != s_cmd->outsize || ++ u_cmd.insize != s_cmd->insize) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ + s_cmd->command += ec->cmd_offset; + ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd); + /* Only copy data to userland if data was received. */ + if (ret < 0) + goto exit; + +- if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + u_cmd.insize)) ++ if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize)) + ret = -EFAULT; + exit: + kfree(s_cmd); diff --git a/queue-4.6/qeth-delete-napi-struct-when-removing-a-qeth-device.patch b/queue-4.6/qeth-delete-napi-struct-when-removing-a-qeth-device.patch new file mode 100644 index 00000000000..6a658e263a6 --- /dev/null +++ b/queue-4.6/qeth-delete-napi-struct-when-removing-a-qeth-device.patch @@ -0,0 +1,45 @@ +From 7831b4ff0d926e0deeaabef9db8800ed069a2757 Mon Sep 17 00:00:00 2001 +From: Ursula Braun +Date: Mon, 4 Jul 2016 14:07:16 +0200 +Subject: qeth: delete napi struct when removing a qeth device + +From: Ursula Braun + +commit 7831b4ff0d926e0deeaabef9db8800ed069a2757 upstream. + +A qeth_card contains a napi_struct linked to the net_device during +device probing. This struct must be deleted when removing the qeth +device, otherwise Panic on oops can occur when qeth devices are +repeatedly removed and added. + +Fixes: a1c3ed4c9ca ("qeth: NAPI support for l2 and l3 discipline") +Signed-off-by: Ursula Braun +Tested-by: Alexander Klein +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/net/qeth_l2_main.c | 1 + + drivers/s390/net/qeth_l3_main.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -1051,6 +1051,7 @@ static void qeth_l2_remove_device(struct + qeth_l2_set_offline(cgdev); + + if (card->dev) { ++ netif_napi_del(&card->napi); + unregister_netdev(card->dev); + card->dev = NULL; + } +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -3226,6 +3226,7 @@ static void qeth_l3_remove_device(struct + qeth_l3_set_offline(cgdev); + + if (card->dev) { ++ netif_napi_del(&card->napi); + unregister_netdev(card->dev); + card->dev = NULL; + } diff --git a/queue-4.6/sched-fair-fix-effective_load-to-consistently-use-smoothed-load.patch b/queue-4.6/sched-fair-fix-effective_load-to-consistently-use-smoothed-load.patch new file mode 100644 index 00000000000..cce2323b90e --- /dev/null +++ b/queue-4.6/sched-fair-fix-effective_load-to-consistently-use-smoothed-load.patch @@ -0,0 +1,82 @@ +From 7dd4912594daf769a46744848b05bd5bc6d62469 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Fri, 24 Jun 2016 15:53:54 +0200 +Subject: sched/fair: Fix effective_load() to consistently use smoothed load + +From: Peter Zijlstra + +commit 7dd4912594daf769a46744848b05bd5bc6d62469 upstream. + +Starting with the following commit: + + fde7d22e01aa ("sched/fair: Fix overly small weight for interactive group entities") + +calc_tg_weight() doesn't compute the right value as expected by effective_load(). + +The difference is in the 'correction' term. In order to ensure \Sum +rw_j >= rw_i we cannot use tg->load_avg directly, since that might be +lagging a correction on the current cfs_rq->avg.load_avg value. +Therefore we use tg->load_avg - cfs_rq->tg_load_avg_contrib + +cfs_rq->avg.load_avg. + +Now, per the referenced commit, calc_tg_weight() doesn't use +cfs_rq->avg.load_avg, as is later used in @w, but uses +cfs_rq->load.weight instead. + +So stop using calc_tg_weight() and do it explicitly. + +The effects of this bug are wake_affine() making randomly +poor choices in cgroup-intense workloads. + +Signed-off-by: Peter Zijlstra (Intel) +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: fde7d22e01aa ("sched/fair: Fix overly small weight for interactive group entities") +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched/fair.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -687,8 +687,6 @@ void init_entity_runnable_average(struct + /* when this task enqueue'ed, it will contribute to its cfs_rq's load_avg */ + } + +-static inline unsigned long cfs_rq_runnable_load_avg(struct cfs_rq *cfs_rq); +-static inline unsigned long cfs_rq_load_avg(struct cfs_rq *cfs_rq); + #else + void init_entity_runnable_average(struct sched_entity *se) + { +@@ -4822,19 +4820,24 @@ static long effective_load(struct task_g + return wl; + + for_each_sched_entity(se) { +- long w, W; ++ struct cfs_rq *cfs_rq = se->my_q; ++ long W, w = cfs_rq_load_avg(cfs_rq); + +- tg = se->my_q->tg; ++ tg = cfs_rq->tg; + + /* + * W = @wg + \Sum rw_j + */ +- W = wg + calc_tg_weight(tg, se->my_q); ++ W = wg + atomic_long_read(&tg->load_avg); ++ ++ /* Ensure \Sum rw_j >= rw_i */ ++ W -= cfs_rq->tg_load_avg_contrib; ++ W += w; + + /* + * w = rw_i + @wl + */ +- w = cfs_rq_load_avg(se->my_q) + wl; ++ w += wl; + + /* + * wl = S * s'_i; see (2) diff --git a/queue-4.6/series b/queue-4.6/series index 3e1dec41ea5..bf5bc4284b4 100644 --- a/queue-4.6/series +++ b/queue-4.6/series @@ -53,3 +53,21 @@ power_supply-power_supply_read_temp-only-if-use_cnt-0.patch locks-use-file_inode.patch revert-ecryptfs-forbid-opening-files-without-mmap-handler.patch ecryptfs-don-t-allow-mmap-when-the-lower-fs-doesn-t-support-it.patch +ext4-verify-extent-header-depth.patch +9p-use-file_dentry.patch +cpufreq-avoid-false-positive-warn_on-s-in-cpufreq_update_policy.patch +devpts-fix-null-pointer-dereference-on-failed-memory-allocation.patch +namespace-update-event-counter-when-umounting-a-deleted-dentry.patch +spi-rockchip-signal-unfinished-dma-transfers.patch +spi-sunxi-fix-transfer-timeout.patch +spi-sun4i-fix-fifo-limit.patch +clk-rockchip-initialize-flags-of-clk_init_data-in-mmc-phase-clock.patch +clk-at91-fix-clk_programmable_set_parent.patch +lockd-unregister-notifier-blocks-if-the-service-fails-to-come-up-completely.patch +platform-chrome-cros_ec_dev-double-fetch-bug-in-ioctl.patch +qeth-delete-napi-struct-when-removing-a-qeth-device.patch +init-kconfig-keep-expert-users-menu-together.patch +block-fix-use-after-free-in-sys_ioprio_get.patch +mmc-block-fix-free-of-uninitialized-idata-buf.patch +mmc-block-fix-packed-command-header-endianness.patch +sched-fair-fix-effective_load-to-consistently-use-smoothed-load.patch diff --git a/queue-4.6/spi-rockchip-signal-unfinished-dma-transfers.patch b/queue-4.6/spi-rockchip-signal-unfinished-dma-transfers.patch new file mode 100644 index 00000000000..440408ccc71 --- /dev/null +++ b/queue-4.6/spi-rockchip-signal-unfinished-dma-transfers.patch @@ -0,0 +1,48 @@ +From 4dc0dd83603f05dc3ae152af33ecb15104c313f3 Mon Sep 17 00:00:00 2001 +From: Tomeu Vizoso +Date: Wed, 8 Jun 2016 09:32:51 +0200 +Subject: spi: rockchip: Signal unfinished DMA transfers + +From: Tomeu Vizoso + +commit 4dc0dd83603f05dc3ae152af33ecb15104c313f3 upstream. + +When using DMA, the transfer_one callback should return 1 because the +transfer hasn't finished yet. + +A previous commit changed the function to return 0 when the DMA channels +were correctly prepared. + +This manifested in Veyron boards with this message: + +[ 1.983605] cros-ec-spi spi0.0: EC failed to respond in time + +Fixes: ea9849113343 ("spi: rockchip: check return value of dmaengine_prep_slave_sg") +Signed-off-by: Tomeu Vizoso +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/spi/spi-rockchip.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/spi/spi-rockchip.c ++++ b/drivers/spi/spi-rockchip.c +@@ -578,7 +578,7 @@ static int rockchip_spi_transfer_one( + struct spi_device *spi, + struct spi_transfer *xfer) + { +- int ret = 1; ++ int ret = 0; + struct rockchip_spi *rs = spi_master_get_devdata(master); + + WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && +@@ -627,6 +627,8 @@ static int rockchip_spi_transfer_one( + spi_enable_chip(rs, 1); + ret = rockchip_spi_prepare_dma(rs); + } ++ /* successful DMA prepare means the transfer is in progress */ ++ ret = ret ? ret : 1; + } else { + spi_enable_chip(rs, 1); + ret = rockchip_spi_pio_transfer(rs); diff --git a/queue-4.6/spi-sun4i-fix-fifo-limit.patch b/queue-4.6/spi-sun4i-fix-fifo-limit.patch new file mode 100644 index 00000000000..dad25802845 --- /dev/null +++ b/queue-4.6/spi-sun4i-fix-fifo-limit.patch @@ -0,0 +1,52 @@ +From 6d9fe44bd73d567d04d3a68a2d2fa521ab9532f2 Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Mon, 13 Jun 2016 17:46:49 +0000 +Subject: spi: sun4i: fix FIFO limit + +From: Michal Suchanek + +commit 6d9fe44bd73d567d04d3a68a2d2fa521ab9532f2 upstream. + +When testing SPI without DMA I noticed that filling the FIFO on the +spi controller causes timeout. + +Always leave room for one byte in the FIFO. + +Signed-off-by: Michal Suchanek +Acked-by: Maxime Ripard +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/spi/spi-sun4i.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/spi/spi-sun4i.c ++++ b/drivers/spi/spi-sun4i.c +@@ -180,7 +180,10 @@ static int sun4i_spi_transfer_one(struct + + /* We don't support transfer larger than the FIFO */ + if (tfr->len > SUN4I_FIFO_DEPTH) +- return -EINVAL; ++ return -EMSGSIZE; ++ ++ if (tfr->tx_buf && tfr->len >= SUN4I_FIFO_DEPTH) ++ return -EMSGSIZE; + + reinit_completion(&sspi->done); + sspi->tx_buf = tfr->tx_buf; +@@ -270,8 +273,12 @@ static int sun4i_spi_transfer_one(struct + sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); + sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); + +- /* Fill the TX FIFO */ +- sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); ++ /* ++ * Fill the TX FIFO ++ * Filling the FIFO fully causes timeout for some reason ++ * at least on spi2 on A10s ++ */ ++ sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1); + + /* Enable the interrupts */ + sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); diff --git a/queue-4.6/spi-sunxi-fix-transfer-timeout.patch b/queue-4.6/spi-sunxi-fix-transfer-timeout.patch new file mode 100644 index 00000000000..801adf19eb7 --- /dev/null +++ b/queue-4.6/spi-sunxi-fix-transfer-timeout.patch @@ -0,0 +1,80 @@ +From 719bd6542044efd9b338a53dba1bef45f40ca169 Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Mon, 13 Jun 2016 17:46:49 +0000 +Subject: spi: sunxi: fix transfer timeout + +From: Michal Suchanek + +commit 719bd6542044efd9b338a53dba1bef45f40ca169 upstream. + +The trasfer timeout is fixed at 1000 ms. Reading a 4Mbyte flash over +1MHz SPI bus takes way longer than that. Calculate the timeout from the +actual time the transfer is supposed to take and multiply by 2 for good +measure. + +Signed-off-by: Michal Suchanek +Acked-by: Maxime Ripard +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/spi/spi-sun4i.c | 10 +++++++++- + drivers/spi/spi-sun6i.c | 10 +++++++++- + 2 files changed, 18 insertions(+), 2 deletions(-) + +--- a/drivers/spi/spi-sun4i.c ++++ b/drivers/spi/spi-sun4i.c +@@ -173,6 +173,7 @@ static int sun4i_spi_transfer_one(struct + { + struct sun4i_spi *sspi = spi_master_get_devdata(master); + unsigned int mclk_rate, div, timeout; ++ unsigned int start, end, tx_time; + unsigned int tx_len = 0; + int ret = 0; + u32 reg; +@@ -279,9 +280,16 @@ static int sun4i_spi_transfer_one(struct + reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); + sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH); + ++ tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); ++ start = jiffies; + timeout = wait_for_completion_timeout(&sspi->done, +- msecs_to_jiffies(1000)); ++ msecs_to_jiffies(tx_time)); ++ end = jiffies; + if (!timeout) { ++ dev_warn(&master->dev, ++ "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", ++ dev_name(&spi->dev), tfr->len, tfr->speed_hz, ++ jiffies_to_msecs(end - start), tx_time); + ret = -ETIMEDOUT; + goto out; + } +--- a/drivers/spi/spi-sun6i.c ++++ b/drivers/spi/spi-sun6i.c +@@ -160,6 +160,7 @@ static int sun6i_spi_transfer_one(struct + { + struct sun6i_spi *sspi = spi_master_get_devdata(master); + unsigned int mclk_rate, div, timeout; ++ unsigned int start, end, tx_time; + unsigned int tx_len = 0; + int ret = 0; + u32 reg; +@@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct + reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); + sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); + ++ tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U); ++ start = jiffies; + timeout = wait_for_completion_timeout(&sspi->done, +- msecs_to_jiffies(1000)); ++ msecs_to_jiffies(tx_time)); ++ end = jiffies; + if (!timeout) { ++ dev_warn(&master->dev, ++ "%s: timeout transferring %u bytes@%iHz for %i(%i)ms", ++ dev_name(&spi->dev), tfr->len, tfr->speed_hz, ++ jiffies_to_msecs(end - start), tx_time); + ret = -ETIMEDOUT; + goto out; + }