From: Greg Kroah-Hartman Date: Mon, 12 Jun 2017 09:06:30 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.57~23 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6a4ab54537b794f77b3e2de870c24a8da9071540;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: ahci-acer-sa5-271-ssd-not-detected-fix.patch cfq-iosched-fix-the-delay-of-cfq_group-s-vdisktime-under-iops-mode.patch cgroup-prevent-kill_css-from-being-called-more-than-once.patch cpufreq-cpufreq_register_driver-should-return-enodev-if-init-fails.patch dmaengine-ep93xx-always-start-from-base0.patch dmaengine-ep93xx-don-t-drain-the-transfers-in-terminate_all.patch dmaengine-mv_xor_v2-do-not-use-descriptors-not-acked-by-async_tx.patch dmaengine-mv_xor_v2-enable-xor-engine-after-its-configuration.patch dmaengine-mv_xor_v2-fix-tx_submit-implementation.patch dmaengine-mv_xor_v2-handle-mv_xor_v2_prep_sw_desc-error-properly.patch dmaengine-mv_xor_v2-properly-handle-wrapping-in-the-array-of-hw-descriptors.patch dmaengine-mv_xor_v2-remove-interrupt-coalescing.patch dmaengine-mv_xor_v2-set-dma-mask-to-40-bits.patch dmaengine-usb-dmac-fix-dmaor-ae-bit-definition.patch drm-fix-oops-xserver-hang-when-unplugging-usb-drm-devices.patch drm-msm-expose-our-reservation-object-when-exporting-a-dmabuf.patch ext4-fix-data-corruption-with-ext4_get_blocks_zero.patch ext4-fix-fdatasync-2-after-extent-manipulation-operations.patch ext4-fix-seek_hole.patch ext4-keep-existing-extra-fields-when-inode-expands.patch iio-adc-bcm_iproc_adc-swap-primary-and-secondary-isr-handler-s.patch iio-light-ltr501-fix-interchanged-als-ps-register-field.patch iio-proximity-as3935-fix-as3935_int-mask.patch iio-proximity-as3935-fix-iio_trigger_poll-issue.patch input-elantech-add-fujitsu-lifebook-e546-e557-to-force-crc_enabled.patch kvm-arm-arm64-vgic-v2-do-not-use-active-pending-state-for-a-hw-interrupt.patch kvm-arm-arm64-vgic-v3-do-not-use-active-pending-state-for-a-hw-interrupt.patch mei-make-sysfs-modalias-format-similar-as-uevent-modalias.patch staging-lustre-lov-remove-set_fs-call-from-lov_getstripe.patch target-re-add-check-to-reject-control-writes-with-overflow-data.patch usb-chipidea-debug-check-before-accessing-ci_role.patch usb-chipidea-udc-fix-null-pointer-dereference-if-udc_start-failed.patch usb-gadget-f_mass_storage-serialize-wake-and-sleep-execution.patch xen-privcmd-support-correctly-64kb-page-granularity-when-mapping-memory.patch --- diff --git a/queue-4.9/ahci-acer-sa5-271-ssd-not-detected-fix.patch b/queue-4.9/ahci-acer-sa5-271-ssd-not-detected-fix.patch new file mode 100644 index 00000000000..1a358c306e2 --- /dev/null +++ b/queue-4.9/ahci-acer-sa5-271-ssd-not-detected-fix.patch @@ -0,0 +1,88 @@ +From 8bfd174312629866efa535193d9e563768ff4307 Mon Sep 17 00:00:00 2001 +From: Sui Chen +Date: Tue, 9 May 2017 07:47:22 -0500 +Subject: ahci: Acer SA5-271 SSD Not Detected Fix + +From: Sui Chen + +commit 8bfd174312629866efa535193d9e563768ff4307 upstream. + +(Correction in this resend: fixed function name acer_sa5_271_workaround; fixed + the always-true condition in the function; fixed description.) + +On the Acer Switch Alpha 12 (model number: SA5-271), the internal SSD may not +get detected because the port_map and CAP.nr_ports combination causes the driver +to skip the port that is actually connected to the SSD. More specifically, +either all SATA ports are identified as DUMMY, or all ports get ``link down'' +and never get up again. + +This problem occurs occasionally. When this problem occurs, CAP may hold a +value of 0xC734FF00 or 0xC734FF01 and port_map may hold a value of 0x00 or 0x01. +When this problem does not occur, CAP holds a value of 0xC734FF02 and port_map +may hold a value of 0x07. Overriding the CAP value to 0xC734FF02 and port_map to +0x7 significantly reduces the occurrence of this problem. + +Link: https://bugzilla.kernel.org/attachment.cgi?id=253091 +Signed-off-by: Sui Chen +Tested-by: Damian Ivanov +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ahci.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -1362,6 +1362,40 @@ static inline void ahci_gtf_filter_worka + {} + #endif + ++/* ++ * On the Acer Aspire Switch Alpha 12, sometimes all SATA ports are detected ++ * as DUMMY, or detected but eventually get a "link down" and never get up ++ * again. When this happens, CAP.NP may hold a value of 0x00 or 0x01, and the ++ * port_map may hold a value of 0x00. ++ * ++ * Overriding CAP.NP to 0x02 and the port_map to 0x7 will reveal all 3 ports ++ * and can significantly reduce the occurrence of the problem. ++ * ++ * https://bugzilla.kernel.org/show_bug.cgi?id=189471 ++ */ ++static void acer_sa5_271_workaround(struct ahci_host_priv *hpriv, ++ struct pci_dev *pdev) ++{ ++ static const struct dmi_system_id sysids[] = { ++ { ++ .ident = "Acer Switch Alpha 12", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271") ++ }, ++ }, ++ { } ++ }; ++ ++ if (dmi_check_system(sysids)) { ++ dev_info(&pdev->dev, "enabling Acer Switch Alpha 12 workaround\n"); ++ if ((hpriv->saved_cap & 0xC734FF00) == 0xC734FF00) { ++ hpriv->port_map = 0x7; ++ hpriv->cap = 0xC734FF02; ++ } ++ } ++} ++ + #ifdef CONFIG_ARM64 + /* + * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently. +@@ -1597,6 +1631,10 @@ static int ahci_init_one(struct pci_dev + "online status unreliable, applying workaround\n"); + } + ++ ++ /* Acer SA5-271 workaround modifies private_data */ ++ acer_sa5_271_workaround(hpriv, pdev); ++ + /* CAP.NP sometimes indicate the index of the last enabled + * port, at other times, that of the last possible port, so + * determining the maximum port number requires looking at diff --git a/queue-4.9/cfq-iosched-fix-the-delay-of-cfq_group-s-vdisktime-under-iops-mode.patch b/queue-4.9/cfq-iosched-fix-the-delay-of-cfq_group-s-vdisktime-under-iops-mode.patch new file mode 100644 index 00000000000..c30bcdda442 --- /dev/null +++ b/queue-4.9/cfq-iosched-fix-the-delay-of-cfq_group-s-vdisktime-under-iops-mode.patch @@ -0,0 +1,75 @@ +From 5be6b75610cefd1e21b98a218211922c2feb6e08 Mon Sep 17 00:00:00 2001 +From: Hou Tao +Date: Wed, 1 Mar 2017 09:02:33 +0800 +Subject: cfq-iosched: fix the delay of cfq_group's vdisktime under iops mode + +From: Hou Tao + +commit 5be6b75610cefd1e21b98a218211922c2feb6e08 upstream. + +When adding a cfq_group into the cfq service tree, we use CFQ_IDLE_DELAY +as the delay of cfq_group's vdisktime if there have been other cfq_groups +already. + +When cfq is under iops mode, commit 9a7f38c42c2b ("cfq-iosched: Convert +from jiffies to nanoseconds") could result in a large iops delay and +lead to an abnormal io schedule delay for the added cfq_group. To fix +it, we just need to revert to the old CFQ_IDLE_DELAY value: HZ / 5 +when iops mode is enabled. + +Despite having the same value, the delay of a cfq_queue in idle class +and the delay of cfq_group are different things, so I define two new +macros for the delay of a cfq_group under time-slice mode and iops mode. + +Fixes: 9a7f38c42c2b ("cfq-iosched: Convert from jiffies to nanoseconds") +Signed-off-by: Hou Tao +Acked-by: Jan Kara +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/cfq-iosched.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -36,9 +36,13 @@ static const u64 cfq_target_latency = (u + static const int cfq_hist_divisor = 4; + + /* +- * offset from end of service tree ++ * offset from end of queue service tree for idle class + */ + #define CFQ_IDLE_DELAY (NSEC_PER_SEC / 5) ++/* offset from end of group service tree under time slice mode */ ++#define CFQ_SLICE_MODE_GROUP_DELAY (NSEC_PER_SEC / 5) ++/* offset from end of group service under IOPS mode */ ++#define CFQ_IOPS_MODE_GROUP_DELAY (HZ / 5) + + /* + * below this threshold, we consider thinktime immediate +@@ -1370,6 +1374,14 @@ cfq_group_service_tree_add(struct cfq_rb + cfqg->vfraction = max_t(unsigned, vfr, 1); + } + ++static inline u64 cfq_get_cfqg_vdisktime_delay(struct cfq_data *cfqd) ++{ ++ if (!iops_mode(cfqd)) ++ return CFQ_SLICE_MODE_GROUP_DELAY; ++ else ++ return CFQ_IOPS_MODE_GROUP_DELAY; ++} ++ + static void + cfq_group_notify_queue_add(struct cfq_data *cfqd, struct cfq_group *cfqg) + { +@@ -1389,7 +1401,8 @@ cfq_group_notify_queue_add(struct cfq_da + n = rb_last(&st->rb); + if (n) { + __cfqg = rb_entry_cfqg(n); +- cfqg->vdisktime = __cfqg->vdisktime + CFQ_IDLE_DELAY; ++ cfqg->vdisktime = __cfqg->vdisktime + ++ cfq_get_cfqg_vdisktime_delay(cfqd); + } else + cfqg->vdisktime = st->min_vdisktime; + cfq_group_service_tree_add(st, cfqg); diff --git a/queue-4.9/cgroup-prevent-kill_css-from-being-called-more-than-once.patch b/queue-4.9/cgroup-prevent-kill_css-from-being-called-more-than-once.patch new file mode 100644 index 00000000000..2a7a6f80345 --- /dev/null +++ b/queue-4.9/cgroup-prevent-kill_css-from-being-called-more-than-once.patch @@ -0,0 +1,47 @@ +From 33c35aa4817864e056fd772230b0c6b552e36ea2 Mon Sep 17 00:00:00 2001 +From: Waiman Long +Date: Mon, 15 May 2017 09:34:06 -0400 +Subject: cgroup: Prevent kill_css() from being called more than once + +From: Waiman Long + +commit 33c35aa4817864e056fd772230b0c6b552e36ea2 upstream. + +The kill_css() function may be called more than once under the condition +that the css was killed but not physically removed yet followed by the +removal of the cgroup that is hosting the css. This patch prevents any +harmm from being done when that happens. + +Signed-off-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/cgroup-defs.h | 1 + + kernel/cgroup.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/include/linux/cgroup-defs.h ++++ b/include/linux/cgroup-defs.h +@@ -46,6 +46,7 @@ enum { + CSS_ONLINE = (1 << 1), /* between ->css_online() and ->css_offline() */ + CSS_RELEASED = (1 << 2), /* refcnt reached zero, released */ + CSS_VISIBLE = (1 << 3), /* css is visible to userland */ ++ CSS_DYING = (1 << 4), /* css is dying */ + }; + + /* bits in struct cgroup flags field */ +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -5407,6 +5407,11 @@ static void kill_css(struct cgroup_subsy + { + lockdep_assert_held(&cgroup_mutex); + ++ if (css->flags & CSS_DYING) ++ return; ++ ++ css->flags |= CSS_DYING; ++ + /* + * This must happen before css is disassociated with its cgroup. + * See seq_css() for details. diff --git a/queue-4.9/cpufreq-cpufreq_register_driver-should-return-enodev-if-init-fails.patch b/queue-4.9/cpufreq-cpufreq_register_driver-should-return-enodev-if-init-fails.patch new file mode 100644 index 00000000000..a1108f7c93a --- /dev/null +++ b/queue-4.9/cpufreq-cpufreq_register_driver-should-return-enodev-if-init-fails.patch @@ -0,0 +1,33 @@ +From 6c77003677d5f1ce15f26d24360cb66c0bc07bb3 Mon Sep 17 00:00:00 2001 +From: David Arcari +Date: Fri, 26 May 2017 11:37:31 -0400 +Subject: cpufreq: cpufreq_register_driver() should return -ENODEV if init fails + +From: David Arcari + +commit 6c77003677d5f1ce15f26d24360cb66c0bc07bb3 upstream. + +For a driver that does not set the CPUFREQ_STICKY flag, if all of the +->init() calls fail, cpufreq_register_driver() should return an error. +This will prevent the driver from loading. + +Fixes: ce1bcfe94db8 (cpufreq: check cpufreq_policy_list instead of scanning policies for all CPUs) +Signed-off-by: David Arcari +Acked-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/cpufreq.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -2474,6 +2474,7 @@ int cpufreq_register_driver(struct cpufr + if (!(cpufreq_driver->flags & CPUFREQ_STICKY) && + list_empty(&cpufreq_policy_list)) { + /* if all ->init() calls failed, unregister */ ++ ret = -ENODEV; + pr_debug("%s: No CPU initialized for driver %s\n", __func__, + driver_data->name); + goto err_if_unreg; diff --git a/queue-4.9/dmaengine-ep93xx-always-start-from-base0.patch b/queue-4.9/dmaengine-ep93xx-always-start-from-base0.patch new file mode 100644 index 00000000000..e8859f71bee --- /dev/null +++ b/queue-4.9/dmaengine-ep93xx-always-start-from-base0.patch @@ -0,0 +1,34 @@ +From 0037ae47812b1f431cc602100d1d51f37d77b61e Mon Sep 17 00:00:00 2001 +From: Alexander Sverdlin +Date: Mon, 22 May 2017 16:05:22 +0200 +Subject: dmaengine: ep93xx: Always start from BASE0 + +From: Alexander Sverdlin + +commit 0037ae47812b1f431cc602100d1d51f37d77b61e upstream. + +The current buffer is being reset to zero on device_free_chan_resources() +but not on device_terminate_all(). It could happen that HW is restarted and +expects BASE0 to be used, but the driver is not synchronized and will start +from BASE1. One solution is to reset the buffer explicitly in +m2p_hw_setup(). + +Signed-off-by: Alexander Sverdlin +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/ep93xx_dma.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/dma/ep93xx_dma.c ++++ b/drivers/dma/ep93xx_dma.c +@@ -323,6 +323,8 @@ static int m2p_hw_setup(struct ep93xx_dm + | M2P_CONTROL_ENABLE; + m2p_set_control(edmac, control); + ++ edmac->buffer = 0; ++ + return 0; + } + diff --git a/queue-4.9/dmaengine-ep93xx-don-t-drain-the-transfers-in-terminate_all.patch b/queue-4.9/dmaengine-ep93xx-don-t-drain-the-transfers-in-terminate_all.patch new file mode 100644 index 00000000000..800d4c671fc --- /dev/null +++ b/queue-4.9/dmaengine-ep93xx-don-t-drain-the-transfers-in-terminate_all.patch @@ -0,0 +1,160 @@ +From 98f9de366fccee7572c646af226b2d4b4841e3b5 Mon Sep 17 00:00:00 2001 +From: Alexander Sverdlin +Date: Mon, 22 May 2017 16:05:23 +0200 +Subject: dmaengine: ep93xx: Don't drain the transfers in terminate_all() + +From: Alexander Sverdlin + +commit 98f9de366fccee7572c646af226b2d4b4841e3b5 upstream. + +Draining the transfers in terminate_all callback happens with IRQs disabled, +therefore induces huge latency: + + irqsoff latency trace v1.1.5 on 4.11.0 + -------------------------------------------------------------------- + latency: 39770 us, #57/57, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0) + ----------------- + | task: process-129 (uid:0 nice:0 policy:2 rt_prio:50) + ----------------- + => started at: _snd_pcm_stream_lock_irqsave + => ended at: snd_pcm_stream_unlock_irqrestore + + _------=> CPU# + / _-----=> irqs-off + | / _----=> need-resched + || / _---=> hardirq/softirq + ||| / _--=> preempt-depth + |||| / delay + cmd pid ||||| time | caller + \ / ||||| \ | / +process-129 0d.s. 3us : _snd_pcm_stream_lock_irqsave +process-129 0d.s1 9us : snd_pcm_stream_lock <-_snd_pcm_stream_lock_irqsave +process-129 0d.s1 15us : preempt_count_add <-snd_pcm_stream_lock +process-129 0d.s2 22us : preempt_count_add <-snd_pcm_stream_lock +process-129 0d.s3 32us : snd_pcm_update_hw_ptr0 <-snd_pcm_period_elapsed +process-129 0d.s3 41us : soc_pcm_pointer <-snd_pcm_update_hw_ptr0 +process-129 0d.s3 50us : dmaengine_pcm_pointer <-soc_pcm_pointer +process-129 0d.s3 58us+: snd_dmaengine_pcm_pointer_no_residue <-dmaengine_pcm_pointer +process-129 0d.s3 96us : update_audio_tstamp <-snd_pcm_update_hw_ptr0 +process-129 0d.s3 103us : snd_pcm_update_state <-snd_pcm_update_hw_ptr0 +process-129 0d.s3 112us : xrun <-snd_pcm_update_state +process-129 0d.s3 119us : snd_pcm_stop <-xrun +process-129 0d.s3 126us : snd_pcm_action <-snd_pcm_stop +process-129 0d.s3 134us : snd_pcm_action_single <-snd_pcm_action +process-129 0d.s3 141us : snd_pcm_pre_stop <-snd_pcm_action_single +process-129 0d.s3 150us : snd_pcm_do_stop <-snd_pcm_action_single +process-129 0d.s3 157us : soc_pcm_trigger <-snd_pcm_do_stop +process-129 0d.s3 166us : snd_dmaengine_pcm_trigger <-soc_pcm_trigger +process-129 0d.s3 175us : ep93xx_dma_terminate_all <-snd_dmaengine_pcm_trigger +process-129 0d.s3 182us : preempt_count_add <-ep93xx_dma_terminate_all +process-129 0d.s4 189us*: m2p_hw_shutdown <-ep93xx_dma_terminate_all +process-129 0d.s4 39472us : m2p_hw_setup <-ep93xx_dma_terminate_all + + ... rest skipped... + +process-129 0d.s. 40080us : + => ep93xx_dma_tasklet + => tasklet_action + => __do_softirq + => irq_exit + => __handle_domain_irq + => vic_handle_irq + => __irq_usr + => 0xb66c6668 + +Just abort the transfers and warn if the HW state is not what we expect. +Move draining into device_synchronize callback. + +Signed-off-by: Alexander Sverdlin +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/ep93xx_dma.c | 37 +++++++++++++++++++++++++++++++++---- + 1 file changed, 33 insertions(+), 4 deletions(-) + +--- a/drivers/dma/ep93xx_dma.c ++++ b/drivers/dma/ep93xx_dma.c +@@ -201,6 +201,7 @@ struct ep93xx_dma_engine { + struct dma_device dma_dev; + bool m2m; + int (*hw_setup)(struct ep93xx_dma_chan *); ++ void (*hw_synchronize)(struct ep93xx_dma_chan *); + void (*hw_shutdown)(struct ep93xx_dma_chan *); + void (*hw_submit)(struct ep93xx_dma_chan *); + int (*hw_interrupt)(struct ep93xx_dma_chan *); +@@ -333,21 +334,27 @@ static inline u32 m2p_channel_state(stru + return (readl(edmac->regs + M2P_STATUS) >> 4) & 0x3; + } + +-static void m2p_hw_shutdown(struct ep93xx_dma_chan *edmac) ++static void m2p_hw_synchronize(struct ep93xx_dma_chan *edmac) + { ++ unsigned long flags; + u32 control; + ++ spin_lock_irqsave(&edmac->lock, flags); + control = readl(edmac->regs + M2P_CONTROL); + control &= ~(M2P_CONTROL_STALLINT | M2P_CONTROL_NFBINT); + m2p_set_control(edmac, control); ++ spin_unlock_irqrestore(&edmac->lock, flags); + + while (m2p_channel_state(edmac) >= M2P_STATE_ON) +- cpu_relax(); ++ schedule(); ++} + ++static void m2p_hw_shutdown(struct ep93xx_dma_chan *edmac) ++{ + m2p_set_control(edmac, 0); + +- while (m2p_channel_state(edmac) == M2P_STATE_STALL) +- cpu_relax(); ++ while (m2p_channel_state(edmac) != M2P_STATE_IDLE) ++ dev_warn(chan2dev(edmac), "M2P: Not yet IDLE\n"); + } + + static void m2p_fill_desc(struct ep93xx_dma_chan *edmac) +@@ -1163,6 +1170,26 @@ fail: + } + + /** ++ * ep93xx_dma_synchronize - Synchronizes the termination of transfers to the ++ * current context. ++ * @chan: channel ++ * ++ * Synchronizes the DMA channel termination to the current context. When this ++ * function returns it is guaranteed that all transfers for previously issued ++ * descriptors have stopped and and it is safe to free the memory associated ++ * with them. Furthermore it is guaranteed that all complete callback functions ++ * for a previously submitted descriptor have finished running and it is safe to ++ * free resources accessed from within the complete callbacks. ++ */ ++static void ep93xx_dma_synchronize(struct dma_chan *chan) ++{ ++ struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); ++ ++ if (edmac->edma->hw_synchronize) ++ edmac->edma->hw_synchronize(edmac); ++} ++ ++/** + * ep93xx_dma_terminate_all - terminate all transactions + * @chan: channel + * +@@ -1325,6 +1352,7 @@ static int __init ep93xx_dma_probe(struc + dma_dev->device_prep_slave_sg = ep93xx_dma_prep_slave_sg; + dma_dev->device_prep_dma_cyclic = ep93xx_dma_prep_dma_cyclic; + dma_dev->device_config = ep93xx_dma_slave_config; ++ dma_dev->device_synchronize = ep93xx_dma_synchronize; + dma_dev->device_terminate_all = ep93xx_dma_terminate_all; + dma_dev->device_issue_pending = ep93xx_dma_issue_pending; + dma_dev->device_tx_status = ep93xx_dma_tx_status; +@@ -1342,6 +1370,7 @@ static int __init ep93xx_dma_probe(struc + } else { + dma_cap_set(DMA_PRIVATE, dma_dev->cap_mask); + ++ edma->hw_synchronize = m2p_hw_synchronize; + edma->hw_setup = m2p_hw_setup; + edma->hw_shutdown = m2p_hw_shutdown; + edma->hw_submit = m2p_hw_submit; diff --git a/queue-4.9/dmaengine-mv_xor_v2-do-not-use-descriptors-not-acked-by-async_tx.patch b/queue-4.9/dmaengine-mv_xor_v2-do-not-use-descriptors-not-acked-by-async_tx.patch new file mode 100644 index 00000000000..1e6be90da4d --- /dev/null +++ b/queue-4.9/dmaengine-mv_xor_v2-do-not-use-descriptors-not-acked-by-async_tx.patch @@ -0,0 +1,83 @@ +From bc473da1ed726c975ad47f8d7d27631de11356d8 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Fri, 5 May 2017 11:57:46 +0200 +Subject: dmaengine: mv_xor_v2: do not use descriptors not acked by async_tx + +From: Thomas Petazzoni + +commit bc473da1ed726c975ad47f8d7d27631de11356d8 upstream. + +Descriptors that have not been acknowledged by the async_tx layer +should not be re-used, so this commit adjusts the implementation of +mv_xor_v2_prep_sw_desc() to skip descriptors for which +async_tx_test_ack() is false. + +Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") +Signed-off-by: Thomas Petazzoni +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/mv_xor_v2.c | 32 ++++++++++++++++++++++---------- + 1 file changed, 22 insertions(+), 10 deletions(-) + +--- a/drivers/dma/mv_xor_v2.c ++++ b/drivers/dma/mv_xor_v2.c +@@ -344,6 +344,7 @@ static struct mv_xor_v2_sw_desc * + mv_xor_v2_prep_sw_desc(struct mv_xor_v2_device *xor_dev) + { + struct mv_xor_v2_sw_desc *sw_desc; ++ bool found = false; + + /* Lock the channel */ + spin_lock_bh(&xor_dev->lock); +@@ -355,19 +356,23 @@ mv_xor_v2_prep_sw_desc(struct mv_xor_v2_ + return NULL; + } + +- /* get a free SW descriptor from the SW DESQ */ +- sw_desc = list_first_entry(&xor_dev->free_sw_desc, +- struct mv_xor_v2_sw_desc, free_list); ++ list_for_each_entry(sw_desc, &xor_dev->free_sw_desc, free_list) { ++ if (async_tx_test_ack(&sw_desc->async_tx)) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) { ++ spin_unlock_bh(&xor_dev->lock); ++ return NULL; ++ } ++ + list_del(&sw_desc->free_list); + + /* Release the channel */ + spin_unlock_bh(&xor_dev->lock); + +- /* set the async tx descriptor */ +- dma_async_tx_descriptor_init(&sw_desc->async_tx, &xor_dev->dmachan); +- sw_desc->async_tx.tx_submit = mv_xor_v2_tx_submit; +- async_tx_ack(&sw_desc->async_tx); +- + return sw_desc; + } + +@@ -785,8 +790,15 @@ static int mv_xor_v2_probe(struct platfo + + /* add all SW descriptors to the free list */ + for (i = 0; i < MV_XOR_V2_DESC_NUM; i++) { +- xor_dev->sw_desq[i].idx = i; +- list_add(&xor_dev->sw_desq[i].free_list, ++ struct mv_xor_v2_sw_desc *sw_desc = ++ xor_dev->sw_desq + i; ++ sw_desc->idx = i; ++ dma_async_tx_descriptor_init(&sw_desc->async_tx, ++ &xor_dev->dmachan); ++ sw_desc->async_tx.tx_submit = mv_xor_v2_tx_submit; ++ async_tx_ack(&sw_desc->async_tx); ++ ++ list_add(&sw_desc->free_list, + &xor_dev->free_sw_desc); + } + diff --git a/queue-4.9/dmaengine-mv_xor_v2-enable-xor-engine-after-its-configuration.patch b/queue-4.9/dmaengine-mv_xor_v2-enable-xor-engine-after-its-configuration.patch new file mode 100644 index 00000000000..b97458332f1 --- /dev/null +++ b/queue-4.9/dmaengine-mv_xor_v2-enable-xor-engine-after-its-configuration.patch @@ -0,0 +1,45 @@ +From ab2c5f0a77fe49bdb6e307b397496373cb47d2c2 Mon Sep 17 00:00:00 2001 +From: Hanna Hawa +Date: Fri, 5 May 2017 11:57:47 +0200 +Subject: dmaengine: mv_xor_v2: enable XOR engine after its configuration + +From: Hanna Hawa + +commit ab2c5f0a77fe49bdb6e307b397496373cb47d2c2 upstream. + +The engine was enabled prior to its configuration, which isn't +correct. This patch relocates the activation of the XOR engine, to be +after the configuration of the XOR engine. + +Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") +Signed-off-by: Hanna Hawa +Signed-off-by: Thomas Petazzoni +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/mv_xor_v2.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/dma/mv_xor_v2.c ++++ b/drivers/dma/mv_xor_v2.c +@@ -653,9 +653,6 @@ static int mv_xor_v2_descq_init(struct m + writel((xor_dev->hw_desq & 0xFFFF00000000) >> 32, + xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_BAHR_OFF); + +- /* enable the DMA engine */ +- writel(0, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_STOP_OFF); +- + /* + * This is a temporary solution, until we activate the + * SMMU. Set the attributes for reading & writing data buffers +@@ -699,6 +696,9 @@ static int mv_xor_v2_descq_init(struct m + reg |= MV_XOR_V2_GLOB_PAUSE_AXI_TIME_DIS_VAL; + writel(reg, xor_dev->glob_base + MV_XOR_V2_GLOB_PAUSE); + ++ /* enable the DMA engine */ ++ writel(0, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_STOP_OFF); ++ + return 0; + } + diff --git a/queue-4.9/dmaengine-mv_xor_v2-fix-tx_submit-implementation.patch b/queue-4.9/dmaengine-mv_xor_v2-fix-tx_submit-implementation.patch new file mode 100644 index 00000000000..05ca1e847bc --- /dev/null +++ b/queue-4.9/dmaengine-mv_xor_v2-fix-tx_submit-implementation.patch @@ -0,0 +1,88 @@ +From 44d5887a8bf1e86915c8ff647337cb138149da82 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Fri, 5 May 2017 11:57:48 +0200 +Subject: dmaengine: mv_xor_v2: fix tx_submit() implementation + +From: Thomas Petazzoni + +commit 44d5887a8bf1e86915c8ff647337cb138149da82 upstream. + +The mv_xor_v2_tx_submit() gets the next available HW descriptor by +calling mv_xor_v2_get_desq_write_ptr(), which reads a HW register +telling the next available HW descriptor. This was working fine when HW +descriptors were issued for processing directly in tx_submit(). + +However, as part of the review process of the driver, a change was +requested to move the actual kick-off of HW descriptors processing to +->issue_pending(). Due to this, reading the HW register to know the next +available HW descriptor no longer works. + +So instead of using this HW register, we implemented a software index +pointing to the next available HW descriptor. + +Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") +Signed-off-by: Thomas Petazzoni +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/mv_xor_v2.c | 22 +++++----------------- + 1 file changed, 5 insertions(+), 17 deletions(-) + +--- a/drivers/dma/mv_xor_v2.c ++++ b/drivers/dma/mv_xor_v2.c +@@ -161,6 +161,7 @@ struct mv_xor_v2_device { + struct mv_xor_v2_sw_desc *sw_desq; + int desc_size; + unsigned int npendings; ++ unsigned int hw_queue_idx; + }; + + /** +@@ -214,18 +215,6 @@ static void mv_xor_v2_set_data_buffers(s + } + + /* +- * Return the next available index in the DESQ. +- */ +-static int mv_xor_v2_get_desq_write_ptr(struct mv_xor_v2_device *xor_dev) +-{ +- /* read the index for the next available descriptor in the DESQ */ +- u32 reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_ALLOC_OFF); +- +- return ((reg >> MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_SHIFT) +- & MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_MASK); +-} +- +-/* + * notify the engine of new descriptors, and update the available index. + */ + static void mv_xor_v2_add_desc_to_desq(struct mv_xor_v2_device *xor_dev, +@@ -306,7 +295,6 @@ static irqreturn_t mv_xor_v2_interrupt_h + static dma_cookie_t + mv_xor_v2_tx_submit(struct dma_async_tx_descriptor *tx) + { +- int desq_ptr; + void *dest_hw_desc; + dma_cookie_t cookie; + struct mv_xor_v2_sw_desc *sw_desc = +@@ -322,15 +310,15 @@ mv_xor_v2_tx_submit(struct dma_async_tx_ + spin_lock_bh(&xor_dev->lock); + cookie = dma_cookie_assign(tx); + +- /* get the next available slot in the DESQ */ +- desq_ptr = mv_xor_v2_get_desq_write_ptr(xor_dev); +- + /* copy the HW descriptor from the SW descriptor to the DESQ */ +- dest_hw_desc = xor_dev->hw_desq_virt + desq_ptr; ++ dest_hw_desc = xor_dev->hw_desq_virt + xor_dev->hw_queue_idx; + + memcpy(dest_hw_desc, &sw_desc->hw_desc, xor_dev->desc_size); + + xor_dev->npendings++; ++ xor_dev->hw_queue_idx++; ++ if (xor_dev->hw_queue_idx >= MV_XOR_V2_DESC_NUM) ++ xor_dev->hw_queue_idx = 0; + + spin_unlock_bh(&xor_dev->lock); + diff --git a/queue-4.9/dmaengine-mv_xor_v2-handle-mv_xor_v2_prep_sw_desc-error-properly.patch b/queue-4.9/dmaengine-mv_xor_v2-handle-mv_xor_v2_prep_sw_desc-error-properly.patch new file mode 100644 index 00000000000..9a923c9778d --- /dev/null +++ b/queue-4.9/dmaengine-mv_xor_v2-handle-mv_xor_v2_prep_sw_desc-error-properly.patch @@ -0,0 +1,52 @@ +From eb8df543e444492328f506adffc7dfe94111f1bd Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Fri, 5 May 2017 11:57:44 +0200 +Subject: dmaengine: mv_xor_v2: handle mv_xor_v2_prep_sw_desc() error properly + +From: Thomas Petazzoni + +commit eb8df543e444492328f506adffc7dfe94111f1bd upstream. + +The mv_xor_v2_prep_sw_desc() is called from a few different places in +the driver, but we never take into account the fact that it might +return NULL. This commit fixes that, ensuring that we don't panic if +there are no more descriptors available. + +Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") +Signed-off-by: Thomas Petazzoni +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/mv_xor_v2.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/dma/mv_xor_v2.c ++++ b/drivers/dma/mv_xor_v2.c +@@ -389,6 +389,8 @@ mv_xor_v2_prep_dma_memcpy(struct dma_cha + __func__, len, &src, &dest, flags); + + sw_desc = mv_xor_v2_prep_sw_desc(xor_dev); ++ if (!sw_desc) ++ return NULL; + + sw_desc->async_tx.flags = flags; + +@@ -443,6 +445,8 @@ mv_xor_v2_prep_dma_xor(struct dma_chan * + __func__, src_cnt, len, &dest, flags); + + sw_desc = mv_xor_v2_prep_sw_desc(xor_dev); ++ if (!sw_desc) ++ return NULL; + + sw_desc->async_tx.flags = flags; + +@@ -491,6 +495,8 @@ mv_xor_v2_prep_dma_interrupt(struct dma_ + container_of(chan, struct mv_xor_v2_device, dmachan); + + sw_desc = mv_xor_v2_prep_sw_desc(xor_dev); ++ if (!sw_desc) ++ return NULL; + + /* set the HW descriptor */ + hw_descriptor = &sw_desc->hw_desc; diff --git a/queue-4.9/dmaengine-mv_xor_v2-properly-handle-wrapping-in-the-array-of-hw-descriptors.patch b/queue-4.9/dmaengine-mv_xor_v2-properly-handle-wrapping-in-the-array-of-hw-descriptors.patch new file mode 100644 index 00000000000..0010a456b60 --- /dev/null +++ b/queue-4.9/dmaengine-mv_xor_v2-properly-handle-wrapping-in-the-array-of-hw-descriptors.patch @@ -0,0 +1,68 @@ +From 2aab4e18152cd30cb5d2f4c27629fc8a04aed979 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Fri, 5 May 2017 11:57:45 +0200 +Subject: dmaengine: mv_xor_v2: properly handle wrapping in the array of HW descriptors + +From: Thomas Petazzoni + +commit 2aab4e18152cd30cb5d2f4c27629fc8a04aed979 upstream. + +mv_xor_v2_tasklet() is looping over completed HW descriptors. Before the +loop, it initializes 'next_pending_hw_desc' to the first HW descriptor +to handle, and then the loop simply increments this point, without +taking care of wrapping when we reach the last HW descriptor. The +'pending_ptr' index was being wrapped back to 0 at the end, but it +wasn't used in each iteration of the loop to calculate +next_pending_hw_desc. + +This commit fixes that, and makes next_pending_hw_desc a variable local +to the loop itself. + +Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") +Signed-off-by: Thomas Petazzoni +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/mv_xor_v2.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/dma/mv_xor_v2.c ++++ b/drivers/dma/mv_xor_v2.c +@@ -560,7 +560,6 @@ static void mv_xor_v2_tasklet(unsigned l + { + struct mv_xor_v2_device *xor_dev = (struct mv_xor_v2_device *) data; + int pending_ptr, num_of_pending, i; +- struct mv_xor_v2_descriptor *next_pending_hw_desc = NULL; + struct mv_xor_v2_sw_desc *next_pending_sw_desc = NULL; + + dev_dbg(xor_dev->dmadev.dev, "%s %d\n", __func__, __LINE__); +@@ -568,17 +567,10 @@ static void mv_xor_v2_tasklet(unsigned l + /* get the pending descriptors parameters */ + num_of_pending = mv_xor_v2_get_pending_params(xor_dev, &pending_ptr); + +- /* next HW descriptor */ +- next_pending_hw_desc = xor_dev->hw_desq_virt + pending_ptr; +- + /* loop over free descriptors */ + for (i = 0; i < num_of_pending; i++) { +- +- if (pending_ptr > MV_XOR_V2_DESC_NUM) +- pending_ptr = 0; +- +- if (next_pending_sw_desc != NULL) +- next_pending_hw_desc++; ++ struct mv_xor_v2_descriptor *next_pending_hw_desc = ++ xor_dev->hw_desq_virt + pending_ptr; + + /* get the SW descriptor related to the HW descriptor */ + next_pending_sw_desc = +@@ -614,6 +606,8 @@ static void mv_xor_v2_tasklet(unsigned l + + /* increment the next descriptor */ + pending_ptr++; ++ if (pending_ptr >= MV_XOR_V2_DESC_NUM) ++ pending_ptr = 0; + } + + if (num_of_pending != 0) { diff --git a/queue-4.9/dmaengine-mv_xor_v2-remove-interrupt-coalescing.patch b/queue-4.9/dmaengine-mv_xor_v2-remove-interrupt-coalescing.patch new file mode 100644 index 00000000000..d7467a8c199 --- /dev/null +++ b/queue-4.9/dmaengine-mv_xor_v2-remove-interrupt-coalescing.patch @@ -0,0 +1,73 @@ +From 9dd4f319bac25334a869d9276b19eac9e478fd33 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Fri, 5 May 2017 11:57:49 +0200 +Subject: dmaengine: mv_xor_v2: remove interrupt coalescing + +From: Thomas Petazzoni + +commit 9dd4f319bac25334a869d9276b19eac9e478fd33 upstream. + +The current implementation of interrupt coalescing doesn't work, because +it doesn't configure the coalescing timer, which is needed to make sure +we get an interrupt at some point. + +As a fix for stable, we simply remove the interrupt coalescing +functionality. It will be re-introduced properly in a future commit. + +Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") +Signed-off-by: Thomas Petazzoni +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/mv_xor_v2.c | 25 ------------------------- + 1 file changed, 25 deletions(-) + +--- a/drivers/dma/mv_xor_v2.c ++++ b/drivers/dma/mv_xor_v2.c +@@ -246,22 +246,6 @@ static int mv_xor_v2_set_desc_size(struc + return MV_XOR_V2_EXT_DESC_SIZE; + } + +-/* +- * Set the IMSG threshold +- */ +-static inline +-void mv_xor_v2_set_imsg_thrd(struct mv_xor_v2_device *xor_dev, int thrd_val) +-{ +- u32 reg; +- +- reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); +- +- reg &= (~MV_XOR_V2_DMA_IMSG_THRD_MASK << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); +- reg |= (thrd_val << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); +- +- writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); +-} +- + static irqreturn_t mv_xor_v2_interrupt_handler(int irq, void *data) + { + struct mv_xor_v2_device *xor_dev = data; +@@ -277,12 +261,6 @@ static irqreturn_t mv_xor_v2_interrupt_h + if (!ndescs) + return IRQ_NONE; + +- /* +- * Update IMSG threshold, to disable new IMSG interrupts until +- * end of the tasklet +- */ +- mv_xor_v2_set_imsg_thrd(xor_dev, MV_XOR_V2_DESC_NUM); +- + /* schedule a tasklet to handle descriptors callbacks */ + tasklet_schedule(&xor_dev->irq_tasklet); + +@@ -607,9 +585,6 @@ static void mv_xor_v2_tasklet(unsigned l + /* free the descriptores */ + mv_xor_v2_free_desc_from_desq(xor_dev, num_of_pending); + } +- +- /* Update IMSG threshold, to enable new IMSG interrupts */ +- mv_xor_v2_set_imsg_thrd(xor_dev, 0); + } + + /* diff --git a/queue-4.9/dmaengine-mv_xor_v2-set-dma-mask-to-40-bits.patch b/queue-4.9/dmaengine-mv_xor_v2-set-dma-mask-to-40-bits.patch new file mode 100644 index 00000000000..59612c7c9ba --- /dev/null +++ b/queue-4.9/dmaengine-mv_xor_v2-set-dma-mask-to-40-bits.patch @@ -0,0 +1,34 @@ +From b2d3c270f9f2fb82518ac500a9849c3aaf503852 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Fri, 5 May 2017 11:57:50 +0200 +Subject: dmaengine: mv_xor_v2: set DMA mask to 40 bits + +From: Thomas Petazzoni + +commit b2d3c270f9f2fb82518ac500a9849c3aaf503852 upstream. + +The XORv2 engine on Armada 7K/8K can only access the first 40 bits of +the physical address space, so the DMA mask must be set accordingly. + +Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") +Signed-off-by: Thomas Petazzoni +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/mv_xor_v2.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/dma/mv_xor_v2.c ++++ b/drivers/dma/mv_xor_v2.c +@@ -693,6 +693,10 @@ static int mv_xor_v2_probe(struct platfo + + platform_set_drvdata(pdev, xor_dev); + ++ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); ++ if (ret) ++ return ret; ++ + xor_dev->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) + return -EPROBE_DEFER; diff --git a/queue-4.9/dmaengine-usb-dmac-fix-dmaor-ae-bit-definition.patch b/queue-4.9/dmaengine-usb-dmac-fix-dmaor-ae-bit-definition.patch new file mode 100644 index 00000000000..f69b2a10af9 --- /dev/null +++ b/queue-4.9/dmaengine-usb-dmac-fix-dmaor-ae-bit-definition.patch @@ -0,0 +1,34 @@ +From 9a445bbb1607d9f14556a532453dd86d1b7e381e Mon Sep 17 00:00:00 2001 +From: Hiroyuki Yokoyama +Date: Mon, 15 May 2017 17:49:52 +0900 +Subject: dmaengine: usb-dmac: Fix DMAOR AE bit definition + +From: Hiroyuki Yokoyama + +commit 9a445bbb1607d9f14556a532453dd86d1b7e381e upstream. + +This patch fixes the register definition of AE (Address Error flag) bit. + +Fixes: 0c1c8ff32fa2 ("dmaengine: usb-dmac: Add Renesas USB DMA Controller (USB-DMAC) driver") +Signed-off-by: Hiroyuki Yokoyama +[Shimoda: add Fixes and Cc tags in the commit log] +Signed-off-by: Yoshihiro Shimoda +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/sh/usb-dmac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/dma/sh/usb-dmac.c ++++ b/drivers/dma/sh/usb-dmac.c +@@ -117,7 +117,7 @@ struct usb_dmac { + #define USB_DMASWR 0x0008 + #define USB_DMASWR_SWR (1 << 0) + #define USB_DMAOR 0x0060 +-#define USB_DMAOR_AE (1 << 2) ++#define USB_DMAOR_AE (1 << 1) + #define USB_DMAOR_DME (1 << 0) + + #define USB_DMASAR 0x0000 diff --git a/queue-4.9/drm-fix-oops-xserver-hang-when-unplugging-usb-drm-devices.patch b/queue-4.9/drm-fix-oops-xserver-hang-when-unplugging-usb-drm-devices.patch new file mode 100644 index 00000000000..2c17b73b690 --- /dev/null +++ b/queue-4.9/drm-fix-oops-xserver-hang-when-unplugging-usb-drm-devices.patch @@ -0,0 +1,153 @@ +From 75fb636324a839c2c31be9f81644034c6142e469 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 1 Jun 2017 13:54:30 +0200 +Subject: drm: Fix oops + Xserver hang when unplugging USB drm devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +commit 75fb636324a839c2c31be9f81644034c6142e469 upstream. + +commit a39be606f99d ("drm: Do a full device unregister when unplugging") +causes backtraces like this one when unplugging an usb drm device while +it is in use: + +usb 2-3: USB disconnect, device number 25 +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 242 at drivers/gpu/drm/drm_mode_config.c:424 + drm_mode_config_cleanup+0x220/0x280 [drm] +... +RIP: 0010:drm_mode_config_cleanup+0x220/0x280 [drm] +... +Call Trace: + gm12u320_modeset_cleanup+0xe/0x10 [gm12u320] + gm12u320_driver_unload+0x35/0x70 [gm12u320] + drm_dev_unregister+0x3c/0xe0 [drm] + drm_unplug_dev+0x12/0x60 [drm] + gm12u320_usb_disconnect+0x36/0x40 [gm12u320] + usb_unbind_interface+0x72/0x280 + device_release_driver_internal+0x158/0x210 + device_release_driver+0x12/0x20 + bus_remove_device+0x104/0x180 + device_del+0x1d2/0x350 + usb_disable_device+0x9f/0x270 + usb_disconnect+0xc6/0x260 +... +[drm:drm_mode_config_cleanup [drm]] *ERROR* connector Unknown-1 leaked! +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 242 at drivers/gpu/drm/drm_mode_config.c:458 + drm_mode_config_cleanup+0x268/0x280 [drm] +... + +---[ end trace 80df975dae439ed6 ]--- +general protection fault: 0000 [#1] SMP +... +Call Trace: + ? __switch_to+0x225/0x450 + drm_mode_rmfb_work_fn+0x55/0x70 [drm] + process_one_work+0x193/0x3c0 + worker_thread+0x4a/0x3a0 +... +RIP: drm_framebuffer_remove+0x62/0x3f0 [drm] RSP: ffffb776c39dfd98 +---[ end trace 80df975dae439ed7 ]--- + +After which the system is unusable this is caused by drm_dev_unregister +getting called immediately on unplug, which calls the drivers unload +function which calls drm_mode_config_cleanup which removes the framebuffer +object while userspace is still holding a reference to it. + +Reverting commit a39be606f99d ("drm: Do a full device unregister +when unplugging") leads to the following oops on unplug instead, +when userspace closes the last fd referencing the drm_dev: + +sysfs group 'power' not found for kobject 'card1-Unknown-1' +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 2459 at fs/sysfs/group.c:237 + sysfs_remove_group+0x80/0x90 +... +RIP: 0010:sysfs_remove_group+0x80/0x90 +... +Call Trace: + dpm_sysfs_remove+0x57/0x60 + device_del+0xfd/0x350 + device_unregister+0x1a/0x60 + drm_sysfs_connector_remove+0x39/0x50 [drm] + drm_connector_unregister+0x5a/0x70 [drm] + drm_connector_unregister_all+0x45/0xa0 [drm] + drm_modeset_unregister_all+0x12/0x30 [drm] + drm_dev_unregister+0xca/0xe0 [drm] + drm_put_dev+0x32/0x60 [drm] + drm_release+0x2f3/0x380 [drm] + __fput+0xdf/0x1e0 +... +---[ end trace ecfb91ac85688bbe ]--- +BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8 +IP: down_write+0x1f/0x40 +... +Call Trace: + debugfs_remove_recursive+0x55/0x1b0 + drm_debugfs_connector_remove+0x21/0x40 [drm] + drm_connector_unregister+0x62/0x70 [drm] + drm_connector_unregister_all+0x45/0xa0 [drm] + drm_modeset_unregister_all+0x12/0x30 [drm] + drm_dev_unregister+0xca/0xe0 [drm] + drm_put_dev+0x32/0x60 [drm] + drm_release+0x2f3/0x380 [drm] + __fput+0xdf/0x1e0 +... +---[ end trace ecfb91ac85688bbf ]--- + +This is caused by the revert moving back to drm_unplug_dev calling +drm_minor_unregister which does: + + device_del(minor->kdev); + dev_set_drvdata(minor->kdev, NULL); /* safety belt */ + drm_debugfs_cleanup(minor); + +Causing the sysfs entries to already be removed even though we still +have references to them in e.g. drm_connector. + +Note we must call drm_minor_unregister to notify userspace of the unplug +of the device, so calling drm_dev_unregister is not completely wrong the +problem is that drm_dev_unregister does too much. + +This commit fixes drm_unplug_dev by not only reverting +commit a39be606f99d ("drm: Do a full device unregister when unplugging") +but by also adding a call to drm_modeset_unregister_all before the +drm_minor_unregister calls to make sure all sysfs entries are removed +before calling device_del(minor->kdev) thereby also fixing the second +set of oopses caused by just reverting the commit. + +Fixes: a39be606f99d ("drm: Do a full device unregister when unplugging") +Cc: Chris Wilson +Cc: Jeffy +Cc: Marco Diego Aurélio Mesquita +Reported-by: Marco Diego Aurélio Mesquita +Signed-off-by: Hans de Goede +Reviewed-by: Chris Wilson +Signed-off-by: Sean Paul +Link: http://patchwork.freedesktop.org/patch/msgid/20170601115430.4113-1-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_drv.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -379,7 +379,12 @@ EXPORT_SYMBOL(drm_put_dev); + void drm_unplug_dev(struct drm_device *dev) + { + /* for a USB device */ +- drm_dev_unregister(dev); ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_modeset_unregister_all(dev); ++ ++ drm_minor_unregister(dev, DRM_MINOR_PRIMARY); ++ drm_minor_unregister(dev, DRM_MINOR_RENDER); ++ drm_minor_unregister(dev, DRM_MINOR_CONTROL); + + mutex_lock(&drm_global_mutex); + diff --git a/queue-4.9/drm-msm-expose-our-reservation-object-when-exporting-a-dmabuf.patch b/queue-4.9/drm-msm-expose-our-reservation-object-when-exporting-a-dmabuf.patch new file mode 100644 index 00000000000..b33507e4901 --- /dev/null +++ b/queue-4.9/drm-msm-expose-our-reservation-object-when-exporting-a-dmabuf.patch @@ -0,0 +1,61 @@ +From 43523eba79bda8f5b4c27f8ffe20ea078d20113a Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 12 Apr 2017 12:11:58 -0700 +Subject: drm/msm: Expose our reservation object when exporting a dmabuf. + +From: Eric Anholt + +commit 43523eba79bda8f5b4c27f8ffe20ea078d20113a upstream. + +Without this, polling on the dma-buf (and presumably other devices +synchronizing against our rendering) would return immediately, even +while the BO was busy. + +Signed-off-by: Eric Anholt +Reviewed-by: Daniel Vetter +Cc: Rob Clark +Cc: linux-arm-msm@vger.kernel.org +Cc: freedreno@lists.freedesktop.org +Reviewed-by: Rob Clark +Signed-off-by: Rob Clark +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/msm/msm_drv.c | 1 + + drivers/gpu/drm/msm/msm_drv.h | 1 + + drivers/gpu/drm/msm/msm_gem_prime.c | 7 +++++++ + 3 files changed, 9 insertions(+) + +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -801,6 +801,7 @@ static struct drm_driver msm_driver = { + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_export = drm_gem_prime_export, + .gem_prime_import = drm_gem_prime_import, ++ .gem_prime_res_obj = msm_gem_prime_res_obj, + .gem_prime_pin = msm_gem_prime_pin, + .gem_prime_unpin = msm_gem_prime_unpin, + .gem_prime_get_sg_table = msm_gem_prime_get_sg_table, +--- a/drivers/gpu/drm/msm/msm_drv.h ++++ b/drivers/gpu/drm/msm/msm_drv.h +@@ -203,6 +203,7 @@ struct sg_table *msm_gem_prime_get_sg_ta + void *msm_gem_prime_vmap(struct drm_gem_object *obj); + void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); + int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); ++struct reservation_object *msm_gem_prime_res_obj(struct drm_gem_object *obj); + struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev, + struct dma_buf_attachment *attach, struct sg_table *sg); + int msm_gem_prime_pin(struct drm_gem_object *obj); +--- a/drivers/gpu/drm/msm/msm_gem_prime.c ++++ b/drivers/gpu/drm/msm/msm_gem_prime.c +@@ -70,3 +70,10 @@ void msm_gem_prime_unpin(struct drm_gem_ + if (!obj->import_attach) + msm_gem_put_pages(obj); + } ++ ++struct reservation_object *msm_gem_prime_res_obj(struct drm_gem_object *obj) ++{ ++ struct msm_gem_object *msm_obj = to_msm_bo(obj); ++ ++ return msm_obj->resv; ++} diff --git a/queue-4.9/ext4-fix-data-corruption-with-ext4_get_blocks_zero.patch b/queue-4.9/ext4-fix-data-corruption-with-ext4_get_blocks_zero.patch new file mode 100644 index 00000000000..4618f33aeeb --- /dev/null +++ b/queue-4.9/ext4-fix-data-corruption-with-ext4_get_blocks_zero.patch @@ -0,0 +1,188 @@ +From 4f8caa60a5a13a78f26198618f21774bd6aa6498 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 26 May 2017 17:40:52 -0400 +Subject: ext4: fix data corruption with EXT4_GET_BLOCKS_ZERO + +From: Jan Kara + +commit 4f8caa60a5a13a78f26198618f21774bd6aa6498 upstream. + +When ext4_map_blocks() is called with EXT4_GET_BLOCKS_ZERO to zero-out +allocated blocks and these blocks are actually converted from unwritten +extent the following race can happen: + +CPU0 CPU1 + +page fault page fault +... ... +ext4_map_blocks() + ext4_ext_map_blocks() + ext4_ext_handle_unwritten_extents() + ext4_ext_convert_to_initialized() + - zero out converted extent + ext4_zeroout_es() + - inserts extent as initialized in status tree + + ext4_map_blocks() + ext4_es_lookup_extent() + - finds initialized extent + write data + ext4_issue_zeroout() + - zeroes out new extent overwriting data + +This problem can be reproduced by generic/340 for the fallocated case +for the last block in the file. + +Fix the problem by avoiding zeroing out the area we are mapping with +ext4_map_blocks() in ext4_ext_convert_to_initialized(). It is pointless +to zero out this area in the first place as the caller asked us to +convert the area to initialized because he is just going to write data +there before the transaction finishes. To achieve this we delete the +special case of zeroing out full extent as that will be handled by the +cases below zeroing only the part of the extent that needs it. We also +instruct ext4_split_extent() that the middle of extent being split +contains data so that ext4_split_extent_at() cannot zero out full extent +in case of ENOSPC. + +Fixes: 12735f881952c32b31bc4e433768f18489f79ec9 +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/extents.c | 80 ++++++++++++++++++++++++------------------------------ + 1 file changed, 37 insertions(+), 43 deletions(-) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3413,13 +3413,13 @@ static int ext4_ext_convert_to_initializ + struct ext4_sb_info *sbi; + struct ext4_extent_header *eh; + struct ext4_map_blocks split_map; +- struct ext4_extent zero_ex; ++ struct ext4_extent zero_ex1, zero_ex2; + struct ext4_extent *ex, *abut_ex; + ext4_lblk_t ee_block, eof_block; + unsigned int ee_len, depth, map_len = map->m_len; + int allocated = 0, max_zeroout = 0; + int err = 0; +- int split_flag = 0; ++ int split_flag = EXT4_EXT_DATA_VALID2; + + ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical" + "block %llu, max_blocks %u\n", inode->i_ino, +@@ -3436,7 +3436,8 @@ static int ext4_ext_convert_to_initializ + ex = path[depth].p_ext; + ee_block = le32_to_cpu(ex->ee_block); + ee_len = ext4_ext_get_actual_len(ex); +- zero_ex.ee_len = 0; ++ zero_ex1.ee_len = 0; ++ zero_ex2.ee_len = 0; + + trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); + +@@ -3576,62 +3577,52 @@ static int ext4_ext_convert_to_initializ + if (ext4_encrypted_inode(inode)) + max_zeroout = 0; + +- /* If extent is less than s_max_zeroout_kb, zeroout directly */ +- if (max_zeroout && (ee_len <= max_zeroout)) { +- err = ext4_ext_zeroout(inode, ex); +- if (err) +- goto out; +- zero_ex.ee_block = ex->ee_block; +- zero_ex.ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)); +- ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); +- +- err = ext4_ext_get_access(handle, inode, path + depth); +- if (err) +- goto out; +- ext4_ext_mark_initialized(ex); +- ext4_ext_try_to_merge(handle, inode, path, ex); +- err = ext4_ext_dirty(handle, inode, path + path->p_depth); +- goto out; +- } +- + /* +- * four cases: ++ * five cases: + * 1. split the extent into three extents. +- * 2. split the extent into two extents, zeroout the first half. +- * 3. split the extent into two extents, zeroout the second half. ++ * 2. split the extent into two extents, zeroout the head of the first ++ * extent. ++ * 3. split the extent into two extents, zeroout the tail of the second ++ * extent. + * 4. split the extent into two extents with out zeroout. ++ * 5. no splitting needed, just possibly zeroout the head and / or the ++ * tail of the extent. + */ + split_map.m_lblk = map->m_lblk; + split_map.m_len = map->m_len; + +- if (max_zeroout && (allocated > map->m_len)) { ++ if (max_zeroout && (allocated > split_map.m_len)) { + if (allocated <= max_zeroout) { +- /* case 3 */ +- zero_ex.ee_block = +- cpu_to_le32(map->m_lblk); +- zero_ex.ee_len = cpu_to_le16(allocated); +- ext4_ext_store_pblock(&zero_ex, +- ext4_ext_pblock(ex) + map->m_lblk - ee_block); +- err = ext4_ext_zeroout(inode, &zero_ex); ++ /* case 3 or 5 */ ++ zero_ex1.ee_block = ++ cpu_to_le32(split_map.m_lblk + ++ split_map.m_len); ++ zero_ex1.ee_len = ++ cpu_to_le16(allocated - split_map.m_len); ++ ext4_ext_store_pblock(&zero_ex1, ++ ext4_ext_pblock(ex) + split_map.m_lblk + ++ split_map.m_len - ee_block); ++ err = ext4_ext_zeroout(inode, &zero_ex1); + if (err) + goto out; +- split_map.m_lblk = map->m_lblk; + split_map.m_len = allocated; +- } else if (map->m_lblk - ee_block + map->m_len < max_zeroout) { +- /* case 2 */ +- if (map->m_lblk != ee_block) { +- zero_ex.ee_block = ex->ee_block; +- zero_ex.ee_len = cpu_to_le16(map->m_lblk - ++ } ++ if (split_map.m_lblk - ee_block + split_map.m_len < ++ max_zeroout) { ++ /* case 2 or 5 */ ++ if (split_map.m_lblk != ee_block) { ++ zero_ex2.ee_block = ex->ee_block; ++ zero_ex2.ee_len = cpu_to_le16(split_map.m_lblk - + ee_block); +- ext4_ext_store_pblock(&zero_ex, ++ ext4_ext_store_pblock(&zero_ex2, + ext4_ext_pblock(ex)); +- err = ext4_ext_zeroout(inode, &zero_ex); ++ err = ext4_ext_zeroout(inode, &zero_ex2); + if (err) + goto out; + } + ++ split_map.m_len += split_map.m_lblk - ee_block; + split_map.m_lblk = ee_block; +- split_map.m_len = map->m_lblk - ee_block + map->m_len; + allocated = map->m_len; + } + } +@@ -3642,8 +3633,11 @@ static int ext4_ext_convert_to_initializ + err = 0; + out: + /* If we have gotten a failure, don't zero out status tree */ +- if (!err) +- err = ext4_zeroout_es(inode, &zero_ex); ++ if (!err) { ++ err = ext4_zeroout_es(inode, &zero_ex1); ++ if (!err) ++ err = ext4_zeroout_es(inode, &zero_ex2); ++ } + return err ? err : allocated; + } + diff --git a/queue-4.9/ext4-fix-fdatasync-2-after-extent-manipulation-operations.patch b/queue-4.9/ext4-fix-fdatasync-2-after-extent-manipulation-operations.patch new file mode 100644 index 00000000000..3fe598d3c9a --- /dev/null +++ b/queue-4.9/ext4-fix-fdatasync-2-after-extent-manipulation-operations.patch @@ -0,0 +1,68 @@ +From 67a7d5f561f469ad2fa5154d2888258ab8e6df7c Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 29 May 2017 13:24:55 -0400 +Subject: ext4: fix fdatasync(2) after extent manipulation operations + +From: Jan Kara + +commit 67a7d5f561f469ad2fa5154d2888258ab8e6df7c upstream. + +Currently, extent manipulation operations such as hole punch, range +zeroing, or extent shifting do not record the fact that file data has +changed and thus fdatasync(2) has a work to do. As a result if we crash +e.g. after a punch hole and fdatasync, user can still possibly see the +punched out data after journal replay. Test generic/392 fails due to +these problems. + +Fix the problem by properly marking that file data has changed in these +operations. + +Fixes: a4bb6b64e39abc0e41ca077725f2a72c868e7622 +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/extents.c | 5 +++++ + fs/ext4/inode.c | 2 ++ + 2 files changed, 7 insertions(+) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4887,6 +4887,8 @@ static long ext4_zero_range(struct file + + /* Zero out partial block at the edges of the range */ + ret = ext4_zero_partial_blocks(handle, inode, offset, len); ++ if (ret >= 0) ++ ext4_update_inode_fsync_trans(handle, inode, 1); + + if (file->f_flags & O_SYNC) + ext4_handle_sync(handle); +@@ -5573,6 +5575,7 @@ int ext4_collapse_range(struct inode *in + ext4_handle_sync(handle); + inode->i_mtime = inode->i_ctime = ext4_current_time(inode); + ext4_mark_inode_dirty(handle, inode); ++ ext4_update_inode_fsync_trans(handle, inode, 1); + + out_stop: + ext4_journal_stop(handle); +@@ -5746,6 +5749,8 @@ int ext4_insert_range(struct inode *inod + up_write(&EXT4_I(inode)->i_data_sem); + if (IS_SYNC(inode)) + ext4_handle_sync(handle); ++ if (ret >= 0) ++ ext4_update_inode_fsync_trans(handle, inode, 1); + + out_stop: + ext4_journal_stop(handle); +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4044,6 +4044,8 @@ int ext4_punch_hole(struct inode *inode, + + inode->i_mtime = inode->i_ctime = ext4_current_time(inode); + ext4_mark_inode_dirty(handle, inode); ++ if (ret >= 0) ++ ext4_update_inode_fsync_trans(handle, inode, 1); + out_stop: + ext4_journal_stop(handle); + out_dio: diff --git a/queue-4.9/ext4-fix-seek_hole.patch b/queue-4.9/ext4-fix-seek_hole.patch new file mode 100644 index 00000000000..32c2951bcae --- /dev/null +++ b/queue-4.9/ext4-fix-seek_hole.patch @@ -0,0 +1,143 @@ +From 7d95eddf313c88b24f99d4ca9c2411a4b82fef33 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Sun, 21 May 2017 22:33:23 -0400 +Subject: ext4: fix SEEK_HOLE + +From: Jan Kara + +commit 7d95eddf313c88b24f99d4ca9c2411a4b82fef33 upstream. + +Currently, SEEK_HOLE implementation in ext4 may both return that there's +a hole at some offset although that offset already has data and skip +some holes during a search for the next hole. The first problem is +demostrated by: + +xfs_io -c "falloc 0 256k" -c "pwrite 0 56k" -c "seek -h 0" file +wrote 57344/57344 bytes at offset 0 +56 KiB, 14 ops; 0.0000 sec (2.054 GiB/sec and 538461.5385 ops/sec) +Whence Result +HOLE 0 + +Where we can see that SEEK_HOLE wrongly returned offset 0 as containing +a hole although we have written data there. The second problem can be +demonstrated by: + +xfs_io -c "falloc 0 256k" -c "pwrite 0 56k" -c "pwrite 128k 8k" + -c "seek -h 0" file + +wrote 57344/57344 bytes at offset 0 +56 KiB, 14 ops; 0.0000 sec (1.978 GiB/sec and 518518.5185 ops/sec) +wrote 8192/8192 bytes at offset 131072 +8 KiB, 2 ops; 0.0000 sec (2 GiB/sec and 500000.0000 ops/sec) +Whence Result +HOLE 139264 + +Where we can see that hole at offsets 56k..128k has been ignored by the +SEEK_HOLE call. + +The underlying problem is in the ext4_find_unwritten_pgoff() which is +just buggy. In some cases it fails to update returned offset when it +finds a hole (when no pages are found or when the first found page has +higher index than expected), in some cases conditions for detecting hole +are just missing (we fail to detect a situation where indices of +returned pages are not contiguous). + +Fix ext4_find_unwritten_pgoff() to properly detect non-contiguous page +indices and also handle all cases where we got less pages then expected +in one place and handle it properly there. + +Fixes: c8c0df241cc2719b1262e627f999638411934f60 +CC: Zheng Liu +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/file.c | 50 ++++++++++++++------------------------------------ + 1 file changed, 14 insertions(+), 36 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -432,47 +432,27 @@ static int ext4_find_unwritten_pgoff(str + num = min_t(pgoff_t, end - index, PAGEVEC_SIZE); + nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index, + (pgoff_t)num); +- if (nr_pages == 0) { +- if (whence == SEEK_DATA) +- break; +- +- BUG_ON(whence != SEEK_HOLE); +- /* +- * If this is the first time to go into the loop and +- * offset is not beyond the end offset, it will be a +- * hole at this offset +- */ +- if (lastoff == startoff || lastoff < endoff) +- found = 1; ++ if (nr_pages == 0) + break; +- } +- +- /* +- * If this is the first time to go into the loop and +- * offset is smaller than the first page offset, it will be a +- * hole at this offset. +- */ +- if (lastoff == startoff && whence == SEEK_HOLE && +- lastoff < page_offset(pvec.pages[0])) { +- found = 1; +- break; +- } + + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + struct buffer_head *bh, *head; + + /* +- * If the current offset is not beyond the end of given +- * range, it will be a hole. ++ * If current offset is smaller than the page offset, ++ * there is a hole at this offset. + */ +- if (lastoff < endoff && whence == SEEK_HOLE && +- page->index > end) { ++ if (whence == SEEK_HOLE && lastoff < endoff && ++ lastoff < page_offset(pvec.pages[i])) { + found = 1; + *offset = lastoff; + goto out; + } + ++ if (page->index > end) ++ goto out; ++ + lock_page(page); + + if (unlikely(page->mapping != inode->i_mapping)) { +@@ -512,20 +492,18 @@ static int ext4_find_unwritten_pgoff(str + unlock_page(page); + } + +- /* +- * The no. of pages is less than our desired, that would be a +- * hole in there. +- */ +- if (nr_pages < num && whence == SEEK_HOLE) { +- found = 1; +- *offset = lastoff; ++ /* The no. of pages is less than our desired, we are done. */ ++ if (nr_pages < num) + break; +- } + + index = pvec.pages[i - 1]->index + 1; + pagevec_release(&pvec); + } while (index <= end); + ++ if (whence == SEEK_HOLE && lastoff < endoff) { ++ found = 1; ++ *offset = lastoff; ++ } + out: + pagevec_release(&pvec); + return found; diff --git a/queue-4.9/ext4-keep-existing-extra-fields-when-inode-expands.patch b/queue-4.9/ext4-keep-existing-extra-fields-when-inode-expands.patch new file mode 100644 index 00000000000..12e768a45b1 --- /dev/null +++ b/queue-4.9/ext4-keep-existing-extra-fields-when-inode-expands.patch @@ -0,0 +1,35 @@ +From 887a9730614727c4fff7cb756711b190593fc1df Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Sun, 21 May 2017 22:36:23 -0400 +Subject: ext4: keep existing extra fields when inode expands + +From: Konstantin Khlebnikov + +commit 887a9730614727c4fff7cb756711b190593fc1df upstream. + +ext4_expand_extra_isize() should clear only space between old and new +size. + +Fixes: 6dd4ee7cab7e # v2.6.23 +Signed-off-by: Konstantin Khlebnikov +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5441,8 +5441,9 @@ static int ext4_expand_extra_isize(struc + /* No extended attributes present */ + if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) || + header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) { +- memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0, +- new_extra_isize); ++ memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + ++ EXT4_I(inode)->i_extra_isize, 0, ++ new_extra_isize - EXT4_I(inode)->i_extra_isize); + EXT4_I(inode)->i_extra_isize = new_extra_isize; + return 0; + } diff --git a/queue-4.9/iio-adc-bcm_iproc_adc-swap-primary-and-secondary-isr-handler-s.patch b/queue-4.9/iio-adc-bcm_iproc_adc-swap-primary-and-secondary-isr-handler-s.patch new file mode 100644 index 00000000000..ca5db80456a --- /dev/null +++ b/queue-4.9/iio-adc-bcm_iproc_adc-swap-primary-and-secondary-isr-handler-s.patch @@ -0,0 +1,70 @@ +From f7d86ecf83cb66d3c4c6ac4edb1dd50c0919aa2b Mon Sep 17 00:00:00 2001 +From: Raveendra Padasalagi +Date: Tue, 16 May 2017 12:22:42 +0530 +Subject: iio: adc: bcm_iproc_adc: swap primary and secondary isr handler's + +From: Raveendra Padasalagi + +commit f7d86ecf83cb66d3c4c6ac4edb1dd50c0919aa2b upstream. + +The third argument of devm_request_threaded_irq() is the primary +handler. It is called in hardirq context and checks whether the +interrupt is relevant to the device. If the primary handler returns +IRQ_WAKE_THREAD, the secondary handler (a.k.a. handler thread) is +scheduled to run in process context. + +bcm_iproc_adc.c uses the secondary handler as the primary one +and the other way around. So this patch fixes the same, along with +re-naming the secondary handler and primary handler names properly. + +Tested on the BCM9583XX iProc SoC based boards. + +Fixes: 4324c97ecedc ("iio: Add driver for Broadcom iproc-static-adc") +Reported-by: Pavel Roskin +Signed-off-by: Raveendra Padasalagi +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/adc/bcm_iproc_adc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/iio/adc/bcm_iproc_adc.c ++++ b/drivers/iio/adc/bcm_iproc_adc.c +@@ -143,7 +143,7 @@ static void iproc_adc_reg_dump(struct ii + iproc_adc_dbg_reg(dev, adc_priv, IPROC_SOFT_BYPASS_DATA); + } + +-static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) ++static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) + { + u32 channel_intr_status; + u32 intr_status; +@@ -167,7 +167,7 @@ static irqreturn_t iproc_adc_interrupt_h + return IRQ_NONE; + } + +-static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data) ++static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data) + { + irqreturn_t retval = IRQ_NONE; + struct iproc_adc_priv *adc_priv; +@@ -181,7 +181,7 @@ static irqreturn_t iproc_adc_interrupt_t + adc_priv = iio_priv(indio_dev); + + regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status); +- dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_thread(),INTRPT_STS:%x\n", ++ dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_handler(),INTRPT_STS:%x\n", + intr_status); + + intr_channels = (intr_status & IPROC_ADC_INTR_MASK) >> IPROC_ADC_INTR; +@@ -566,8 +566,8 @@ static int iproc_adc_probe(struct platfo + } + + ret = devm_request_threaded_irq(&pdev->dev, adc_priv->irqno, +- iproc_adc_interrupt_thread, + iproc_adc_interrupt_handler, ++ iproc_adc_interrupt_thread, + IRQF_SHARED, "iproc-adc", indio_dev); + if (ret) { + dev_err(&pdev->dev, "request_irq error %d\n", ret); diff --git a/queue-4.9/iio-light-ltr501-fix-interchanged-als-ps-register-field.patch b/queue-4.9/iio-light-ltr501-fix-interchanged-als-ps-register-field.patch new file mode 100644 index 00000000000..017091aa15f --- /dev/null +++ b/queue-4.9/iio-light-ltr501-fix-interchanged-als-ps-register-field.patch @@ -0,0 +1,42 @@ +From 7cc3bff4efe6164a0c8163331c8aa55454799f42 Mon Sep 17 00:00:00 2001 +From: Franziska Naepelt +Date: Wed, 17 May 2017 12:41:19 +0200 +Subject: iio: light: ltr501 Fix interchanged als/ps register field + +From: Franziska Naepelt + +commit 7cc3bff4efe6164a0c8163331c8aa55454799f42 upstream. + +The register mapping for the IIO driver for the Liteon Light and Proximity +sensor LTR501 interrupt mode is interchanged (ALS/PS). +There is a register called INTERRUPT register (address 0x8F) +Bit 0 represents PS measurement trigger. +Bit 1 represents ALS measurement trigger. +This two bit fields are interchanged within the driver. +see datasheet page 24: +http://optoelectronics.liteon.com/upload/download/DS86-2012-0006/S_110_LTR-501ALS-01_PrelimDS_ver1%5B1%5D.pdf + +Signed-off-by: Franziska Naepelt +Fixes: 7ac702b3144b6 ("iio: ltr501: Add interrupt support") +Acked-by: Peter Meerwald-Stadler +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/light/ltr501.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iio/light/ltr501.c ++++ b/drivers/iio/light/ltr501.c +@@ -74,9 +74,9 @@ static const int int_time_mapping[] = {1 + static const struct reg_field reg_field_it = + REG_FIELD(LTR501_ALS_MEAS_RATE, 3, 4); + static const struct reg_field reg_field_als_intr = +- REG_FIELD(LTR501_INTR, 0, 0); +-static const struct reg_field reg_field_ps_intr = + REG_FIELD(LTR501_INTR, 1, 1); ++static const struct reg_field reg_field_ps_intr = ++ REG_FIELD(LTR501_INTR, 0, 0); + static const struct reg_field reg_field_als_rate = + REG_FIELD(LTR501_ALS_MEAS_RATE, 0, 2); + static const struct reg_field reg_field_ps_rate = diff --git a/queue-4.9/iio-proximity-as3935-fix-as3935_int-mask.patch b/queue-4.9/iio-proximity-as3935-fix-as3935_int-mask.patch new file mode 100644 index 00000000000..aba5c11a6c0 --- /dev/null +++ b/queue-4.9/iio-proximity-as3935-fix-as3935_int-mask.patch @@ -0,0 +1,36 @@ +From 275292d3a3d62670b1b13484707b74e5239b4bb0 Mon Sep 17 00:00:00 2001 +From: Matt Ranostay +Date: Thu, 27 Apr 2017 00:52:32 -0700 +Subject: iio: proximity: as3935: fix AS3935_INT mask + +From: Matt Ranostay + +commit 275292d3a3d62670b1b13484707b74e5239b4bb0 upstream. + +AS3935 interrupt mask has been incorrect so valid lightning events +would never trigger an buffer event. Also noise interrupt should be +BIT(0). + +Fixes: 24ddb0e4bba4 ("iio: Add AS3935 lightning sensor support") +Signed-off-by: Matt Ranostay +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/proximity/as3935.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iio/proximity/as3935.c ++++ b/drivers/iio/proximity/as3935.c +@@ -40,9 +40,9 @@ + #define AS3935_AFE_PWR_BIT BIT(0) + + #define AS3935_INT 0x03 +-#define AS3935_INT_MASK 0x07 ++#define AS3935_INT_MASK 0x0f + #define AS3935_EVENT_INT BIT(3) +-#define AS3935_NOISE_INT BIT(1) ++#define AS3935_NOISE_INT BIT(0) + + #define AS3935_DATA 0x07 + #define AS3935_DATA_MASK 0x3F diff --git a/queue-4.9/iio-proximity-as3935-fix-iio_trigger_poll-issue.patch b/queue-4.9/iio-proximity-as3935-fix-iio_trigger_poll-issue.patch new file mode 100644 index 00000000000..9ad9f5f3b6a --- /dev/null +++ b/queue-4.9/iio-proximity-as3935-fix-iio_trigger_poll-issue.patch @@ -0,0 +1,44 @@ +From 9122b54f266ddee09654fe3fbc503c1a60f4a01c Mon Sep 17 00:00:00 2001 +From: Matt Ranostay +Date: Thu, 4 May 2017 17:32:19 -0700 +Subject: iio: proximity: as3935: fix iio_trigger_poll issue + +From: Matt Ranostay + +commit 9122b54f266ddee09654fe3fbc503c1a60f4a01c upstream. + +Using iio_trigger_poll() can oops when multiple interrupts +happen before the first is handled. + +Use iio_trigger_poll_chained() instead and use the timestamp +when processed, since it will be in theory be 2 ms max latency. + +Fixes: 24ddb0e4bba4 ("iio: Add AS3935 lightning sensor support") +Signed-off-by: Matt Ranostay +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/proximity/as3935.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iio/proximity/as3935.c ++++ b/drivers/iio/proximity/as3935.c +@@ -215,7 +215,7 @@ static irqreturn_t as3935_trigger_handle + + st->buffer[0] = val & AS3935_DATA_MASK; + iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, +- pf->timestamp); ++ iio_get_time_ns(indio_dev)); + err_read: + iio_trigger_notify_done(indio_dev->trig); + +@@ -244,7 +244,7 @@ static void as3935_event_work(struct wor + + switch (val) { + case AS3935_EVENT_INT: +- iio_trigger_poll(st->trig); ++ iio_trigger_poll_chained(st->trig); + break; + case AS3935_NOISE_INT: + dev_warn(&st->spi->dev, "noise level is too high\n"); diff --git a/queue-4.9/input-elantech-add-fujitsu-lifebook-e546-e557-to-force-crc_enabled.patch b/queue-4.9/input-elantech-add-fujitsu-lifebook-e546-e557-to-force-crc_enabled.patch new file mode 100644 index 00000000000..a2bf1f13004 --- /dev/null +++ b/queue-4.9/input-elantech-add-fujitsu-lifebook-e546-e557-to-force-crc_enabled.patch @@ -0,0 +1,66 @@ +From 47eb0c8b4d9eb6368941c6a9bb443f00847a46d7 Mon Sep 17 00:00:00 2001 +From: Ulrik De Bie +Date: Wed, 7 Jun 2017 10:30:57 -0700 +Subject: Input: elantech - add Fujitsu Lifebook E546/E557 to force crc_enabled + +From: Ulrik De Bie + +commit 47eb0c8b4d9eb6368941c6a9bb443f00847a46d7 upstream. + +The Lifebook E546 and E557 touchpad were also not functioning and +worked after running: + + echo "1" > /sys/devices/platform/i8042/serio2/crc_enabled + +Add them to the list of machines that need this workaround. + +Signed-off-by: Ulrik De Bie +Reviewed-by: Arjan Opmeer +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elantech.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1118,8 +1118,10 @@ static int elantech_get_resolution_v4(st + * Asus UX32VD 0x361f02 00, 15, 0e clickpad + * Avatar AVIU-145A2 0x361f00 ? clickpad + * Fujitsu LIFEBOOK E544 0x470f00 d0, 12, 09 2 hw buttons ++ * Fujitsu LIFEBOOK E546 0x470f00 50, 12, 09 2 hw buttons + * Fujitsu LIFEBOOK E547 0x470f00 50, 12, 09 2 hw buttons + * Fujitsu LIFEBOOK E554 0x570f01 40, 14, 0c 2 hw buttons ++ * Fujitsu LIFEBOOK E557 0x570f01 40, 14, 0c 2 hw buttons + * Fujitsu T725 0x470f01 05, 12, 09 2 hw buttons + * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) + * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons +@@ -1525,6 +1527,13 @@ static const struct dmi_system_id elante + }, + }, + { ++ /* Fujitsu LIFEBOOK E546 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E546"), ++ }, ++ }, ++ { + /* Fujitsu LIFEBOOK E547 does not work with crc_enabled == 0 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +@@ -1546,6 +1555,13 @@ static const struct dmi_system_id elante + }, + }, + { ++ /* Fujitsu LIFEBOOK E557 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E557"), ++ }, ++ }, ++ { + /* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), diff --git a/queue-4.9/kvm-arm-arm64-vgic-v2-do-not-use-active-pending-state-for-a-hw-interrupt.patch b/queue-4.9/kvm-arm-arm64-vgic-v2-do-not-use-active-pending-state-for-a-hw-interrupt.patch new file mode 100644 index 00000000000..e4c50cd5793 --- /dev/null +++ b/queue-4.9/kvm-arm-arm64-vgic-v2-do-not-use-active-pending-state-for-a-hw-interrupt.patch @@ -0,0 +1,42 @@ +From ddf42d068f8802de122bb7efdfcb3179336053f1 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Tue, 2 May 2017 14:30:39 +0100 +Subject: KVM: arm/arm64: vgic-v2: Do not use Active+Pending state for a HW interrupt + +From: Marc Zyngier + +commit ddf42d068f8802de122bb7efdfcb3179336053f1 upstream. + +When an interrupt is injected with the HW bit set (indicating that +deactivation should be propagated to the physical distributor), +special care must be taken so that we never mark the corresponding +LR with the Active+Pending state (as the pending state is kept in +the physycal distributor). + +Cc: stable@vger.kernel.org +Fixes: 140b086dd197 ("KVM: arm/arm64: vgic-new: Add GICv2 world switch backend") +Signed-off-by: Marc Zyngier +Reviewed-by: Christoffer Dall +Signed-off-by: Christoffer Dall +Signed-off-by: Greg Kroah-Hartman + +--- + virt/kvm/arm/vgic/vgic-v2.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/virt/kvm/arm/vgic/vgic-v2.c ++++ b/virt/kvm/arm/vgic/vgic-v2.c +@@ -168,6 +168,13 @@ void vgic_v2_populate_lr(struct kvm_vcpu + if (irq->hw) { + val |= GICH_LR_HW; + val |= irq->hwintid << GICH_LR_PHYSID_CPUID_SHIFT; ++ /* ++ * Never set pending+active on a HW interrupt, as the ++ * pending state is kept at the physical distributor ++ * level. ++ */ ++ if (irq->active && irq->pending) ++ val &= ~GICH_LR_PENDING_BIT; + } else { + if (irq->config == VGIC_CONFIG_LEVEL) + val |= GICH_LR_EOI; diff --git a/queue-4.9/kvm-arm-arm64-vgic-v3-do-not-use-active-pending-state-for-a-hw-interrupt.patch b/queue-4.9/kvm-arm-arm64-vgic-v3-do-not-use-active-pending-state-for-a-hw-interrupt.patch new file mode 100644 index 00000000000..c5bc331b4a1 --- /dev/null +++ b/queue-4.9/kvm-arm-arm64-vgic-v3-do-not-use-active-pending-state-for-a-hw-interrupt.patch @@ -0,0 +1,42 @@ +From 3d6e77ad1489650afa20da92bb589c8778baa8da Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Tue, 2 May 2017 14:30:40 +0100 +Subject: KVM: arm/arm64: vgic-v3: Do not use Active+Pending state for a HW interrupt + +From: Marc Zyngier + +commit 3d6e77ad1489650afa20da92bb589c8778baa8da upstream. + +When an interrupt is injected with the HW bit set (indicating that +deactivation should be propagated to the physical distributor), +special care must be taken so that we never mark the corresponding +LR with the Active+Pending state (as the pending state is kept in +the physycal distributor). + +Fixes: 59529f69f504 ("KVM: arm/arm64: vgic-new: Add GICv3 world switch backend") +Signed-off-by: Marc Zyngier +Reviewed-by: Christoffer Dall +Signed-off-by: Christoffer Dall +Signed-off-by: Greg Kroah-Hartman + + +--- + virt/kvm/arm/vgic/vgic-v3.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/virt/kvm/arm/vgic/vgic-v3.c ++++ b/virt/kvm/arm/vgic/vgic-v3.c +@@ -151,6 +151,13 @@ void vgic_v3_populate_lr(struct kvm_vcpu + if (irq->hw) { + val |= ICH_LR_HW; + val |= ((u64)irq->hwintid) << ICH_LR_PHYS_ID_SHIFT; ++ /* ++ * Never set pending+active on a HW interrupt, as the ++ * pending state is kept at the physical distributor ++ * level. ++ */ ++ if (irq->active && irq->pending) ++ val &= ~ICH_LR_PENDING_BIT; + } else { + if (irq->config == VGIC_CONFIG_LEVEL) + val |= ICH_LR_EOI; diff --git a/queue-4.9/mei-make-sysfs-modalias-format-similar-as-uevent-modalias.patch b/queue-4.9/mei-make-sysfs-modalias-format-similar-as-uevent-modalias.patch new file mode 100644 index 00000000000..fa555409da9 --- /dev/null +++ b/queue-4.9/mei-make-sysfs-modalias-format-similar-as-uevent-modalias.patch @@ -0,0 +1,52 @@ +From 6f9193ec044a8f72d8b6ae94a5c4ab6e8b0f00ca Mon Sep 17 00:00:00 2001 +From: Pratyush Anand +Date: Mon, 29 May 2017 22:08:24 +0300 +Subject: mei: make sysfs modalias format similar as uevent modalias + +From: Pratyush Anand + +commit 6f9193ec044a8f72d8b6ae94a5c4ab6e8b0f00ca upstream. + +modprobe is not able to resolve sysfs modalias for mei devices. + + # cat +/sys/class/watchdog/watchdog0/device/watchdog/watchdog0/device/modalias +mei::05b79a6f-4628-4d7f-899d-a91514cb32ab: + # modprobe --set-version 4.9.6-200.fc25.x86_64 -R +mei::05b79a6f-4628-4d7f-899d-a91514cb32ab: +modprobe: FATAL: Module mei::05b79a6f-4628-4d7f-899d-a91514cb32ab: not +found in directory /lib/modules/4.9.6-200.fc25.x86_64 + # cat /lib/modules/4.9.6-200.fc25.x86_64/modules.alias | grep +05b79a6f-4628-4d7f-899d-a91514cb32ab +alias mei:*:05b79a6f-4628-4d7f-899d-a91514cb32ab:*:* mei_wdt + +commit b26864cad1c9 ("mei: bus: add client protocol +version to the device alias"), however sysfs modalias +is still in formmat mei:S:uuid:*. + +This patch equates format of uevent and sysfs modalias so that modprobe +is able to resolve the aliases. + +Fixes: commit b26864cad1c9 ("mei: bus: add client protocol version to the device alias") +Signed-off-by: Pratyush Anand +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/bus.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/misc/mei/bus.c ++++ b/drivers/misc/mei/bus.c +@@ -678,8 +678,10 @@ static ssize_t modalias_show(struct devi + { + struct mei_cl_device *cldev = to_mei_cl_device(dev); + const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl); ++ u8 version = mei_me_cl_ver(cldev->me_cl); + +- return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid); ++ return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:%02X:", ++ cldev->name, uuid, version); + } + static DEVICE_ATTR_RO(modalias); + diff --git a/queue-4.9/series b/queue-4.9/series index f60c0318d0b..6aa1dd5e299 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -38,3 +38,37 @@ arm64-kvm-preserve-res1-bits-in-sctlr_el2.patch arm64-kvm-allow-unaligned-accesses-at-el2.patch arm-kvm-allow-unaligned-accesses-at-hyp.patch kvm-async_pf-avoid-async-pf-injection-when-in-guest-mode.patch +kvm-arm-arm64-vgic-v3-do-not-use-active-pending-state-for-a-hw-interrupt.patch +kvm-arm-arm64-vgic-v2-do-not-use-active-pending-state-for-a-hw-interrupt.patch +dmaengine-usb-dmac-fix-dmaor-ae-bit-definition.patch +dmaengine-ep93xx-always-start-from-base0.patch +dmaengine-ep93xx-don-t-drain-the-transfers-in-terminate_all.patch +dmaengine-mv_xor_v2-handle-mv_xor_v2_prep_sw_desc-error-properly.patch +dmaengine-mv_xor_v2-properly-handle-wrapping-in-the-array-of-hw-descriptors.patch +dmaengine-mv_xor_v2-do-not-use-descriptors-not-acked-by-async_tx.patch +dmaengine-mv_xor_v2-enable-xor-engine-after-its-configuration.patch +dmaengine-mv_xor_v2-fix-tx_submit-implementation.patch +dmaengine-mv_xor_v2-remove-interrupt-coalescing.patch +dmaengine-mv_xor_v2-set-dma-mask-to-40-bits.patch +cfq-iosched-fix-the-delay-of-cfq_group-s-vdisktime-under-iops-mode.patch +xen-privcmd-support-correctly-64kb-page-granularity-when-mapping-memory.patch +ext4-fix-seek_hole.patch +ext4-keep-existing-extra-fields-when-inode-expands.patch +ext4-fix-data-corruption-with-ext4_get_blocks_zero.patch +ext4-fix-fdatasync-2-after-extent-manipulation-operations.patch +drm-fix-oops-xserver-hang-when-unplugging-usb-drm-devices.patch +usb-gadget-f_mass_storage-serialize-wake-and-sleep-execution.patch +usb-chipidea-udc-fix-null-pointer-dereference-if-udc_start-failed.patch +usb-chipidea-debug-check-before-accessing-ci_role.patch +staging-lustre-lov-remove-set_fs-call-from-lov_getstripe.patch +iio-adc-bcm_iproc_adc-swap-primary-and-secondary-isr-handler-s.patch +iio-light-ltr501-fix-interchanged-als-ps-register-field.patch +iio-proximity-as3935-fix-as3935_int-mask.patch +iio-proximity-as3935-fix-iio_trigger_poll-issue.patch +mei-make-sysfs-modalias-format-similar-as-uevent-modalias.patch +cpufreq-cpufreq_register_driver-should-return-enodev-if-init-fails.patch +target-re-add-check-to-reject-control-writes-with-overflow-data.patch +drm-msm-expose-our-reservation-object-when-exporting-a-dmabuf.patch +ahci-acer-sa5-271-ssd-not-detected-fix.patch +cgroup-prevent-kill_css-from-being-called-more-than-once.patch +input-elantech-add-fujitsu-lifebook-e546-e557-to-force-crc_enabled.patch diff --git a/queue-4.9/staging-lustre-lov-remove-set_fs-call-from-lov_getstripe.patch b/queue-4.9/staging-lustre-lov-remove-set_fs-call-from-lov_getstripe.patch new file mode 100644 index 00000000000..f8f0b7041ad --- /dev/null +++ b/queue-4.9/staging-lustre-lov-remove-set_fs-call-from-lov_getstripe.patch @@ -0,0 +1,58 @@ +From 0a33252e060e97ed3fbdcec9517672f1e91aaef3 Mon Sep 17 00:00:00 2001 +From: Oleg Drokin +Date: Fri, 26 May 2017 23:40:33 -0400 +Subject: staging/lustre/lov: remove set_fs() call from lov_getstripe() + +From: Oleg Drokin + +commit 0a33252e060e97ed3fbdcec9517672f1e91aaef3 upstream. + +lov_getstripe() calls set_fs(KERNEL_DS) so that it can handle a struct +lov_user_md pointer from user- or kernel-space. This changes the +behavior of copy_from_user() on SPARC and may result in a misaligned +access exception which in turn oopses the kernel. In fact the +relevant argument to lov_getstripe() is never called with a +kernel-space pointer and so changing the address limits is unnecessary +and so we remove the calls to save, set, and restore the address +limits. + +Signed-off-by: John L. Hammond +Reviewed-on: http://review.whamcloud.com/6150 +Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3221 +Reviewed-by: Andreas Dilger +Reviewed-by: Li Wei +Signed-off-by: Oleg Drokin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/lustre/lustre/lov/lov_pack.c | 9 --------- + 1 file changed, 9 deletions(-) + +--- a/drivers/staging/lustre/lustre/lov/lov_pack.c ++++ b/drivers/staging/lustre/lustre/lov/lov_pack.c +@@ -387,18 +387,10 @@ int lov_getstripe(struct lov_object *obj + struct lov_mds_md *lmmk = NULL; + int rc, lmmk_size, lmm_size; + int lum_size; +- mm_segment_t seg; + + if (!lsm) + return -ENODATA; + +- /* +- * "Switch to kernel segment" to allow copying from kernel space by +- * copy_{to,from}_user(). +- */ +- seg = get_fs(); +- set_fs(KERNEL_DS); +- + /* we only need the header part from user space to get lmm_magic and + * lmm_stripe_count, (the header part is common to v1 and v3) + */ +@@ -478,6 +470,5 @@ int lov_getstripe(struct lov_object *obj + out_free: + kfree(lmmk); + out: +- set_fs(seg); + return rc; + } diff --git a/queue-4.9/target-re-add-check-to-reject-control-writes-with-overflow-data.patch b/queue-4.9/target-re-add-check-to-reject-control-writes-with-overflow-data.patch new file mode 100644 index 00000000000..549ac5e5598 --- /dev/null +++ b/queue-4.9/target-re-add-check-to-reject-control-writes-with-overflow-data.patch @@ -0,0 +1,73 @@ +From 4ff83daa0200affe1894bd33d17bac404e3d78d4 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 11 May 2017 01:07:24 -0700 +Subject: target: Re-add check to reject control WRITEs with overflow data + +From: Nicholas Bellinger + +commit 4ff83daa0200affe1894bd33d17bac404e3d78d4 upstream. + +During v4.3 when the overflow/underflow check was relaxed by +commit c72c525022: + + commit c72c5250224d475614a00c1d7e54a67f77cd3410 + Author: Roland Dreier + Date: Wed Jul 22 15:08:18 2015 -0700 + + target: allow underflow/overflow for PR OUT etc. commands + +to allow underflow/overflow for Windows compliance + FCP, a +consequence was to allow control CDBs to process overflow +data for iscsi-target with immediate data as well. + +As per Roland's original change, continue to allow underflow +cases for control CDBs to make Windows compliance + FCP happy, +but until overflow for control CDBs is supported tree-wide, +explicitly reject all control WRITEs with overflow following +pre v4.3.y logic. + +Reported-by: Bart Van Assche +Cc: Roland Dreier +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -1182,15 +1182,28 @@ target_cmd_size_check(struct se_cmd *cmd + if (cmd->unknown_data_length) { + cmd->data_length = size; + } else if (size != cmd->data_length) { +- pr_warn("TARGET_CORE[%s]: Expected Transfer Length:" ++ pr_warn_ratelimited("TARGET_CORE[%s]: Expected Transfer Length:" + " %u does not match SCSI CDB Length: %u for SAM Opcode:" + " 0x%02x\n", cmd->se_tfo->get_fabric_name(), + cmd->data_length, size, cmd->t_task_cdb[0]); + +- if (cmd->data_direction == DMA_TO_DEVICE && +- cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { +- pr_err("Rejecting underflow/overflow WRITE data\n"); +- return TCM_INVALID_CDB_FIELD; ++ if (cmd->data_direction == DMA_TO_DEVICE) { ++ if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { ++ pr_err_ratelimited("Rejecting underflow/overflow" ++ " for WRITE data CDB\n"); ++ return TCM_INVALID_CDB_FIELD; ++ } ++ /* ++ * Some fabric drivers like iscsi-target still expect to ++ * always reject overflow writes. Reject this case until ++ * full fabric driver level support for overflow writes ++ * is introduced tree-wide. ++ */ ++ if (size > cmd->data_length) { ++ pr_err_ratelimited("Rejecting overflow for" ++ " WRITE control CDB\n"); ++ return TCM_INVALID_CDB_FIELD; ++ } + } + /* + * Reject READ_* or WRITE_* with overflow/underflow for diff --git a/queue-4.9/usb-chipidea-debug-check-before-accessing-ci_role.patch b/queue-4.9/usb-chipidea-debug-check-before-accessing-ci_role.patch new file mode 100644 index 00000000000..0b5de4fd477 --- /dev/null +++ b/queue-4.9/usb-chipidea-debug-check-before-accessing-ci_role.patch @@ -0,0 +1,31 @@ +From 0340ff83cd4475261e7474033a381bc125b45244 Mon Sep 17 00:00:00 2001 +From: Michael Thalmeier +Date: Thu, 18 May 2017 16:14:14 +0200 +Subject: usb: chipidea: debug: check before accessing ci_role + +From: Michael Thalmeier + +commit 0340ff83cd4475261e7474033a381bc125b45244 upstream. + +ci_role BUGs when the role is >= CI_ROLE_END. + +Signed-off-by: Michael Thalmeier +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/debug.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/chipidea/debug.c ++++ b/drivers/usb/chipidea/debug.c +@@ -294,7 +294,8 @@ static int ci_role_show(struct seq_file + { + struct ci_hdrc *ci = s->private; + +- seq_printf(s, "%s\n", ci_role(ci)->name); ++ if (ci->role != CI_ROLE_END) ++ seq_printf(s, "%s\n", ci_role(ci)->name); + + return 0; + } diff --git a/queue-4.9/usb-chipidea-udc-fix-null-pointer-dereference-if-udc_start-failed.patch b/queue-4.9/usb-chipidea-udc-fix-null-pointer-dereference-if-udc_start-failed.patch new file mode 100644 index 00000000000..12bcddc13b6 --- /dev/null +++ b/queue-4.9/usb-chipidea-udc-fix-null-pointer-dereference-if-udc_start-failed.patch @@ -0,0 +1,83 @@ +From aa1f058d7d9244423b8c5a75b9484b1115df7f02 Mon Sep 17 00:00:00 2001 +From: Jisheng Zhang +Date: Mon, 24 Apr 2017 12:35:51 +0000 +Subject: usb: chipidea: udc: fix NULL pointer dereference if udc_start failed + +From: Jisheng Zhang + +commit aa1f058d7d9244423b8c5a75b9484b1115df7f02 upstream. + +Fix below NULL pointer dereference. we set ci->roles[CI_ROLE_GADGET] +too early in ci_hdrc_gadget_init(), if udc_start() fails due to some +reason, the ci->roles[CI_ROLE_GADGET] check in ci_hdrc_gadget_destroy +can't protect us. + +We fix this issue by only setting ci->roles[CI_ROLE_GADGET] if +udc_start() succeed. + +[ 1.398550] Unable to handle kernel NULL pointer dereference at +virtual address 00000000 +... +[ 1.448600] PC is at dma_pool_free+0xb8/0xf0 +[ 1.453012] LR is at dma_pool_free+0x28/0xf0 +[ 2.113369] [] dma_pool_free+0xb8/0xf0 +[ 2.118857] [] destroy_eps+0x4c/0x68 +[ 2.124165] [] ci_hdrc_gadget_destroy+0x28/0x50 +[ 2.130461] [] ci_hdrc_probe+0x588/0x7e8 +[ 2.136129] [] platform_drv_probe+0x50/0xb8 +[ 2.142066] [] driver_probe_device+0x1fc/0x2a8 +[ 2.148270] [] __device_attach_driver+0x9c/0xf8 +[ 2.154563] [] bus_for_each_drv+0x58/0x98 +[ 2.160317] [] __device_attach+0xc4/0x138 +[ 2.166072] [] device_initial_probe+0x10/0x18 +[ 2.172185] [] bus_probe_device+0x94/0xa0 +[ 2.177940] [] device_add+0x3f0/0x560 +[ 2.183337] [] platform_device_add+0x180/0x240 +[ 2.189541] [] ci_hdrc_add_device+0x440/0x4f8 +[ 2.195654] [] ci_hdrc_usb2_probe+0x13c/0x2d8 +[ 2.201769] [] platform_drv_probe+0x50/0xb8 +[ 2.207705] [] driver_probe_device+0x1fc/0x2a8 +[ 2.213910] [] __driver_attach+0xac/0xb0 +[ 2.219575] [] bus_for_each_dev+0x60/0xa0 +[ 2.225329] [] driver_attach+0x20/0x28 +[ 2.230816] [] bus_add_driver+0x1d0/0x238 +[ 2.236571] [] driver_register+0x60/0xf8 +[ 2.242237] [] __platform_driver_register+0x44/0x50 +[ 2.248891] [] ci_hdrc_usb2_driver_init+0x18/0x20 +[ 2.255365] [] do_one_initcall+0x38/0x128 +[ 2.261121] [] kernel_init_freeable+0x1ac/0x250 +[ 2.267414] [] kernel_init+0x10/0x100 +[ 2.272810] [] ret_from_fork+0x10/0x50 + +Fixes: 3f124d233e97 ("usb: chipidea: add role init and destroy APIs") +Signed-off-by: Jisheng Zhang +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/udc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -1987,6 +1987,7 @@ static void udc_id_switch_for_host(struc + int ci_hdrc_gadget_init(struct ci_hdrc *ci) + { + struct ci_role_driver *rdrv; ++ int ret; + + if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC)) + return -ENXIO; +@@ -1999,7 +2000,10 @@ int ci_hdrc_gadget_init(struct ci_hdrc * + rdrv->stop = udc_id_switch_for_host; + rdrv->irq = udc_irq; + rdrv->name = "gadget"; +- ci->roles[CI_ROLE_GADGET] = rdrv; + +- return udc_start(ci); ++ ret = udc_start(ci); ++ if (!ret) ++ ci->roles[CI_ROLE_GADGET] = rdrv; ++ ++ return ret; + } diff --git a/queue-4.9/usb-gadget-f_mass_storage-serialize-wake-and-sleep-execution.patch b/queue-4.9/usb-gadget-f_mass_storage-serialize-wake-and-sleep-execution.patch new file mode 100644 index 00000000000..758844dd2dd --- /dev/null +++ b/queue-4.9/usb-gadget-f_mass_storage-serialize-wake-and-sleep-execution.patch @@ -0,0 +1,98 @@ +From dc9217b69dd6089dcfeb86ed4b3c671504326087 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 11 May 2017 17:26:48 -0700 +Subject: usb: gadget: f_mass_storage: Serialize wake and sleep execution + +From: Thinh Nguyen + +commit dc9217b69dd6089dcfeb86ed4b3c671504326087 upstream. + +f_mass_storage has a memorry barrier issue with the sleep and wake +functions that can cause a deadlock. This results in intermittent hangs +during MSC file transfer. The host will reset the device after receiving +no response to resume the transfer. This issue is seen when dwc3 is +processing 2 transfer-in-progress events at the same time, invoking +completion handlers for CSW and CBW. Also this issue occurs depending on +the system timing and latency. + +To increase the chance to hit this issue, you can force dwc3 driver to +wait and process those 2 events at once by adding a small delay (~100us) +in dwc3_check_event_buf() whenever the request is for CSW and read the +event count again. Avoid debugging with printk and ftrace as extra +delays and memory barrier will mask this issue. + +Scenario which can lead to failure: +----------------------------------- +1) The main thread sleeps and waits for the next command in + get_next_command(). +2) bulk_in_complete() wakes up main thread for CSW. +3) bulk_out_complete() tries to wake up the running main thread for CBW. +4) thread_wakeup_needed is not loaded with correct value in + sleep_thread(). +5) Main thread goes to sleep again. + +The pattern is shown below. Note the 2 critical variables. + * common->thread_wakeup_needed + * bh->state + + CPU 0 (sleep_thread) CPU 1 (wakeup_thread) + ============================== =============================== + + bh->state = BH_STATE_FULL; + smp_wmb(); + thread_wakeup_needed = 0; thread_wakeup_needed = 1; + smp_rmb(); + if (bh->state != BH_STATE_FULL) + sleep again ... + +As pointed out by Alan Stern, this is an R-pattern issue. The issue can +be seen when there are two wakeups in quick succession. The +thread_wakeup_needed can be overwritten in sleep_thread, and the read of +the bh->state maybe reordered before the write to thread_wakeup_needed. + +This patch applies full memory barrier smp_mb() in both sleep_thread() +and wakeup_thread() to ensure the order which the thread_wakeup_needed +and bh->state are written and loaded. + +However, a better solution in the future would be to use wait_queue +method that takes care of managing memory barrier between waker and +waiter. + +Acked-by: Alan Stern +Signed-off-by: Thinh Nguyen +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_mass_storage.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/function/f_mass_storage.c ++++ b/drivers/usb/gadget/function/f_mass_storage.c +@@ -395,7 +395,11 @@ static int fsg_set_halt(struct fsg_dev * + /* Caller must hold fsg->lock */ + static void wakeup_thread(struct fsg_common *common) + { +- smp_wmb(); /* ensure the write of bh->state is complete */ ++ /* ++ * Ensure the reading of thread_wakeup_needed ++ * and the writing of bh->state are completed ++ */ ++ smp_mb(); + /* Tell the main thread that something has happened */ + common->thread_wakeup_needed = 1; + if (common->thread_task) +@@ -626,7 +630,12 @@ static int sleep_thread(struct fsg_commo + } + __set_current_state(TASK_RUNNING); + common->thread_wakeup_needed = 0; +- smp_rmb(); /* ensure the latest bh->state is visible */ ++ ++ /* ++ * Ensure the writing of thread_wakeup_needed ++ * and the reading of bh->state are completed ++ */ ++ smp_mb(); + return rc; + } + diff --git a/queue-4.9/xen-privcmd-support-correctly-64kb-page-granularity-when-mapping-memory.patch b/queue-4.9/xen-privcmd-support-correctly-64kb-page-granularity-when-mapping-memory.patch new file mode 100644 index 00000000000..faa3f632a3a --- /dev/null +++ b/queue-4.9/xen-privcmd-support-correctly-64kb-page-granularity-when-mapping-memory.patch @@ -0,0 +1,43 @@ +From 753c09b5652bb4fe53e2db648002ec64b32b8827 Mon Sep 17 00:00:00 2001 +From: Julien Grall +Date: Wed, 31 May 2017 14:03:57 +0100 +Subject: xen/privcmd: Support correctly 64KB page granularity when mapping memory + +From: Julien Grall + +commit 753c09b5652bb4fe53e2db648002ec64b32b8827 upstream. + +Commit 5995a68 "xen/privcmd: Add support for Linux 64KB page granularity" did +not go far enough to support 64KB in mmap_batch_fn. + +The variable 'nr' is the number of 4KB chunk to map. However, when Linux +is using 64KB page granularity the array of pages (vma->vm_private_data) +contain one page per 64KB. Fix it by incrementing st->index correctly. + +Furthermore, st->va is not correctly incremented as PAGE_SIZE != +XEN_PAGE_SIZE. + +Fixes: 5995a68 ("xen/privcmd: Add support for Linux 64KB page granularity") +Reported-by: Feng Kan +Signed-off-by: Julien Grall +Reviewed-by: Boris Ostrovsky +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/privcmd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/xen/privcmd.c ++++ b/drivers/xen/privcmd.c +@@ -335,8 +335,8 @@ static int mmap_batch_fn(void *data, int + st->global_error = 1; + } + } +- st->va += PAGE_SIZE * nr; +- st->index += nr; ++ st->va += XEN_PAGE_SIZE * nr; ++ st->index += nr / XEN_PFN_PER_PAGE; + + return 0; + }