From: Greg Kroah-Hartman Date: Mon, 10 Nov 2014 02:14:46 +0000 (+0900) Subject: 3.17-stable patches X-Git-Tag: v3.10.60~61 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d2926f94dc354a13a12cbfda351b1ed3e86e1eef;p=thirdparty%2Fkernel%2Fstable-queue.git 3.17-stable patches added patches: blk-mq-fix-potential-hang-if-rolling-wakeup-depth-is-too-high.patch block-fix-alignment_offset-math-that-assumes-io_min-is-a-power-of-2.patch dm-bufio-update-last_accessed-when-relinking-a-buffer.patch dm-bufio-when-done-scanning-return-from-__scan-immediately.patch dm-log-userspace-fix-memory-leak-in-dm_ulog_tfr_init-failure-path.patch drbd-compute-the-end-before-rb_insert_augmented.patch drm-ast-fix-hw-cursor-image.patch drm-cirrus-bind-also-to-qemu-xen-traditional.patch drm-gt214-kms-fix-hda-eld-regression.patch drm-i915-do-not-leak-pages-when-freeing-userptr-objects.patch drm-i915-do-not-store-the-error-pointer-for-a-failed-userptr-registration.patch drm-nouveau-bios-memset-dcb-struct-to-zero-before-parsing.patch drm-nouveau-gpio-rename-g92-class-to-g94.patch drm-tilcdc-fix-the-error-path-in-tilcdc_load.patch drm-vmwgfx-fix-drm.h-include.patch framebuffer-fix-border-color.patch framebuffer-fix-screen-corruption-when-copying.patch hid-input-fix-transducerserialnumber-implementation.patch input-alps-fix-v4-button-press-recognition.patch input-i8042-add-noloop-quirk-for-asus-x750ln.patch input-i8042-quirks-for-fujitsu-lifebook-a544-and-lifebook-ah544.patch input-synaptics-gate-forcepad-support-by-dmi-check.patch iommu-amd-split-init_iommu_group-from-iommu_init_device.patch iommu-rework-iommu_group_get_for_pci_dev.patch mfd-rtsx_pcr-fix-msi-enable-error-handling.patch mfd-ti_am335x_tscadc-fix-tsc-operation-after-adc-continouous-mode.patch mfd-ti_am335x_tscadc-fix-tsc-resume.patch mnt-prevent-pivot_root-from-creating-a-loop-in-the-mount-tree.patch modules-lock-around-setting-of-module_state_unformed.patch power-charger-manager-fix-null-pointer-exception-with-missing-cm-fuel-gauge.patch pstore-fix-duplicate-console-ftrace-efi-entries.patch revert-block-all-blk-mq-requests-are-tagged.patch s390-topology-call-set_sched_topology-early.patch selinux-fix-inode-security-list-corruption.patch ubi-add-missing-kmem_cache_free-in-process_pool_aeb-error-path.patch ubi-block-add-support-for-the-ubi_volume_updated-notification.patch ubi-block-fix-block-device-size-setting.patch ubi-dispatch-update-notification-if-the-volume-is-updated.patch virtio_pci-fix-virtio-spec-compliance-on-restore.patch xen-blkback-fix-leak-on-grant-map-error-path.patch xen-blkback-unmap-all-persistent-grants-when-frontend-gets-disconnected.patch --- diff --git a/queue-3.17/blk-mq-fix-potential-hang-if-rolling-wakeup-depth-is-too-high.patch b/queue-3.17/blk-mq-fix-potential-hang-if-rolling-wakeup-depth-is-too-high.patch new file mode 100644 index 00000000000..ec2bbc11405 --- /dev/null +++ b/queue-3.17/blk-mq-fix-potential-hang-if-rolling-wakeup-depth-is-too-high.patch @@ -0,0 +1,38 @@ +From abab13b5c4fd1fec4f9a61622548012d93dc2831 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Tue, 7 Oct 2014 08:39:20 -0600 +Subject: blk-mq: fix potential hang if rolling wakeup depth is too high + +From: Jens Axboe + +commit abab13b5c4fd1fec4f9a61622548012d93dc2831 upstream. + +We currently divide the queue depth by 4 as our batch wakeup +count, but we split the wakeups over BT_WAIT_QUEUES number of +wait queues. This defaults to 8. If the product of the resulting +batch wake count and BT_WAIT_QUEUES is higher than the device +queue depth, we can get into a situation where a task goes to +sleep waiting for a request, but never gets woken up. + +Reported-by: Bart Van Assche +Fixes: 4bb659b156996 +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-mq-tag.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/block/blk-mq-tag.c ++++ b/block/blk-mq-tag.c +@@ -463,8 +463,8 @@ static void bt_update_count(struct blk_m + } + + bt->wake_cnt = BT_WAIT_BATCH; +- if (bt->wake_cnt > depth / 4) +- bt->wake_cnt = max(1U, depth / 4); ++ if (bt->wake_cnt > depth / BT_WAIT_QUEUES) ++ bt->wake_cnt = max(1U, depth / BT_WAIT_QUEUES); + + bt->depth = depth; + } diff --git a/queue-3.17/block-fix-alignment_offset-math-that-assumes-io_min-is-a-power-of-2.patch b/queue-3.17/block-fix-alignment_offset-math-that-assumes-io_min-is-a-power-of-2.patch new file mode 100644 index 00000000000..bbeec6392a1 --- /dev/null +++ b/queue-3.17/block-fix-alignment_offset-math-that-assumes-io_min-is-a-power-of-2.patch @@ -0,0 +1,64 @@ +From b8839b8c55f3fdd60dc36abcda7e0266aff7985c Mon Sep 17 00:00:00 2001 +From: Mike Snitzer +Date: Wed, 8 Oct 2014 18:26:13 -0400 +Subject: block: fix alignment_offset math that assumes io_min is a power-of-2 + +From: Mike Snitzer + +commit b8839b8c55f3fdd60dc36abcda7e0266aff7985c upstream. + +The math in both blk_stack_limits() and queue_limit_alignment_offset() +assume that a block device's io_min (aka minimum_io_size) is always a +power-of-2. Fix the math such that it works for non-power-of-2 io_min. + +This issue (of alignment_offset != 0) became apparent when testing +dm-thinp with a thinp blocksize that matches a RAID6 stripesize of +1280K. Commit fdfb4c8c1 ("dm thin: set minimum_io_size to pool's data +block size") unlocked the potential for alignment_offset != 0 due to +the dm-thin-pool's io_min possibly being a non-power-of-2. + +Signed-off-by: Mike Snitzer +Acked-by: Martin K. Petersen +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-settings.c | 4 ++-- + include/linux/blkdev.h | 5 ++--- + 2 files changed, 4 insertions(+), 5 deletions(-) + +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -574,7 +574,7 @@ int blk_stack_limits(struct queue_limits + bottom = max(b->physical_block_size, b->io_min) + alignment; + + /* Verify that top and bottom intervals line up */ +- if (max(top, bottom) & (min(top, bottom) - 1)) { ++ if (max(top, bottom) % min(top, bottom)) { + t->misaligned = 1; + ret = -1; + } +@@ -619,7 +619,7 @@ int blk_stack_limits(struct queue_limits + + /* Find lowest common alignment_offset */ + t->alignment_offset = lcm(t->alignment_offset, alignment) +- & (max(t->physical_block_size, t->io_min) - 1); ++ % max(t->physical_block_size, t->io_min); + + /* Verify that new alignment_offset is on a logical block boundary */ + if (t->alignment_offset & (t->logical_block_size - 1)) { +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -1285,10 +1285,9 @@ static inline int queue_alignment_offset + static inline int queue_limit_alignment_offset(struct queue_limits *lim, sector_t sector) + { + unsigned int granularity = max(lim->physical_block_size, lim->io_min); +- unsigned int alignment = (sector << 9) & (granularity - 1); ++ unsigned int alignment = sector_div(sector, granularity >> 9) << 9; + +- return (granularity + lim->alignment_offset - alignment) +- & (granularity - 1); ++ return (granularity + lim->alignment_offset - alignment) % granularity; + } + + static inline int bdev_alignment_offset(struct block_device *bdev) diff --git a/queue-3.17/dm-bufio-update-last_accessed-when-relinking-a-buffer.patch b/queue-3.17/dm-bufio-update-last_accessed-when-relinking-a-buffer.patch new file mode 100644 index 00000000000..a6e602ca2ae --- /dev/null +++ b/queue-3.17/dm-bufio-update-last_accessed-when-relinking-a-buffer.patch @@ -0,0 +1,39 @@ +From eb76faf53b1ff7a77ce3f78cc98ad392ac70c2a0 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Tue, 30 Sep 2014 09:32:46 +0100 +Subject: dm bufio: update last_accessed when relinking a buffer + +From: Joe Thornber + +commit eb76faf53b1ff7a77ce3f78cc98ad392ac70c2a0 upstream. + +The 'last_accessed' member of the dm_buffer structure was only set when +the the buffer was created. This led to each buffer being discarded +after dm_bufio_max_age time even if it was used recently. In practice +this resulted in all thinp metadata being evicted soon after being read +-- this is particularly problematic for metadata intensive workloads +like multithreaded small random IO. + +'last_accessed' is now updated each time the buffer is moved to the head +of the LRU list, so the buffer is now properly discarded if it was not +used in dm_bufio_max_age time. + +Signed-off-by: Joe Thornber +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-bufio.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -465,6 +465,7 @@ static void __relink_lru(struct dm_buffe + c->n_buffers[dirty]++; + b->list_mode = dirty; + list_move(&b->lru_list, &c->lru[dirty]); ++ b->last_accessed = jiffies; + } + + /*---------------------------------------------------------------- diff --git a/queue-3.17/dm-bufio-when-done-scanning-return-from-__scan-immediately.patch b/queue-3.17/dm-bufio-when-done-scanning-return-from-__scan-immediately.patch new file mode 100644 index 00000000000..2ce0a96b446 --- /dev/null +++ b/queue-3.17/dm-bufio-when-done-scanning-return-from-__scan-immediately.patch @@ -0,0 +1,43 @@ +From 0e825862f3c04cee40e25f55680333728a4ffa9b Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 1 Oct 2014 13:29:48 -0400 +Subject: dm bufio: when done scanning return from __scan immediately + +From: Mikulas Patocka + +commit 0e825862f3c04cee40e25f55680333728a4ffa9b upstream. + +When __scan frees the required number of buffer entries that the +shrinker requested (nr_to_scan becomes zero) it must return. Before +this fix the __scan code exited only the inner loop and continued in the +outer loop -- which could result in reduced performance due to extra +buffers being freed (e.g. unnecessarily evicted thinp metadata needing +to be synchronously re-read into bufio's cache). + +Also, move dm_bufio_cond_resched to __scan's inner loop, so that +iterating the bufio client's lru lists doesn't result in scheduling +latency. + +Reported-by: Joe Thornber +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-bufio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1473,9 +1473,9 @@ static long __scan(struct dm_bufio_clien + list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) { + freed += __cleanup_old_buffer(b, gfp_mask, 0); + if (!--nr_to_scan) +- break; ++ return freed; ++ dm_bufio_cond_resched(); + } +- dm_bufio_cond_resched(); + } + return freed; + } diff --git a/queue-3.17/dm-log-userspace-fix-memory-leak-in-dm_ulog_tfr_init-failure-path.patch b/queue-3.17/dm-log-userspace-fix-memory-leak-in-dm_ulog_tfr_init-failure-path.patch new file mode 100644 index 00000000000..d83ddc64039 --- /dev/null +++ b/queue-3.17/dm-log-userspace-fix-memory-leak-in-dm_ulog_tfr_init-failure-path.patch @@ -0,0 +1,34 @@ +From 56ec16cb1e1ce46354de8511eef962a417c32c92 Mon Sep 17 00:00:00 2001 +From: Alexey Khoroshilov +Date: Wed, 1 Oct 2014 22:58:35 +0200 +Subject: dm log userspace: fix memory leak in dm_ulog_tfr_init failure path + +From: Alexey Khoroshilov + +commit 56ec16cb1e1ce46354de8511eef962a417c32c92 upstream. + +If cn_add_callback() fails in dm_ulog_tfr_init(), it does not +deallocate prealloced memory but calls cn_del_callback(). + +Found by Linux Driver Verification project (linuxtesting.org). + +Signed-off-by: Alexey Khoroshilov +Reviewed-by: Jonathan Brassow +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-log-userspace-transfer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/dm-log-userspace-transfer.c ++++ b/drivers/md/dm-log-userspace-transfer.c +@@ -272,7 +272,7 @@ int dm_ulog_tfr_init(void) + + r = cn_add_callback(&ulog_cn_id, "dmlogusr", cn_ulog_callback); + if (r) { +- cn_del_callback(&ulog_cn_id); ++ kfree(prealloced_cn_msg); + return r; + } + diff --git a/queue-3.17/drbd-compute-the-end-before-rb_insert_augmented.patch b/queue-3.17/drbd-compute-the-end-before-rb_insert_augmented.patch new file mode 100644 index 00000000000..179d63b92c2 --- /dev/null +++ b/queue-3.17/drbd-compute-the-end-before-rb_insert_augmented.patch @@ -0,0 +1,60 @@ +From 82cfb90bc99d7b7e0ec62d0505b9d4f06805d5db Mon Sep 17 00:00:00 2001 +From: Lai Jiangshan +Date: Thu, 18 Sep 2014 16:49:41 +0200 +Subject: drbd: compute the end before rb_insert_augmented() + +From: Lai Jiangshan + +commit 82cfb90bc99d7b7e0ec62d0505b9d4f06805d5db upstream. + +Commit 98683650 "Merge branch 'drbd-8.4_ed6' into +for-3.8-drivers-drbd-8.4_ed6" switches to the new augment API, but the +new API requires that the tree is augmented before rb_insert_augmented() +is called, which is missing. + +So we add the augment-code to drbd_insert_interval() when it travels the +tree up to down before rb_insert_augmented(). See the example in +include/linux/interval_tree_generic.h or Documentation/rbtree.txt. + +drbd_insert_interval() may cancel the insertion when traveling, in this +case, the just added augment-code does nothing before cancel since the +@this node is already in the subtrees in this case. + +CC: Michel Lespinasse +Signed-off-by: Lai Jiangshan +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Philipp Reisner +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/drbd/drbd_interval.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/block/drbd/drbd_interval.c ++++ b/drivers/block/drbd/drbd_interval.c +@@ -79,6 +79,7 @@ bool + drbd_insert_interval(struct rb_root *root, struct drbd_interval *this) + { + struct rb_node **new = &root->rb_node, *parent = NULL; ++ sector_t this_end = this->sector + (this->size >> 9); + + BUG_ON(!IS_ALIGNED(this->size, 512)); + +@@ -87,6 +88,8 @@ drbd_insert_interval(struct rb_root *roo + rb_entry(*new, struct drbd_interval, rb); + + parent = *new; ++ if (here->end < this_end) ++ here->end = this_end; + if (this->sector < here->sector) + new = &(*new)->rb_left; + else if (this->sector > here->sector) +@@ -99,6 +102,7 @@ drbd_insert_interval(struct rb_root *roo + return false; + } + ++ this->end = this_end; + rb_link_node(&this->rb, parent, new); + rb_insert_augmented(&this->rb, root, &augment_callbacks); + return true; diff --git a/queue-3.17/drm-ast-fix-hw-cursor-image.patch b/queue-3.17/drm-ast-fix-hw-cursor-image.patch new file mode 100644 index 00000000000..84abf006567 --- /dev/null +++ b/queue-3.17/drm-ast-fix-hw-cursor-image.patch @@ -0,0 +1,34 @@ +From 1e99cfa8de0f0879091e33cd65fd60418d006ad9 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Tue, 7 Oct 2014 19:04:58 +1100 +Subject: drm/ast: Fix HW cursor image + +From: Benjamin Herrenschmidt + +commit 1e99cfa8de0f0879091e33cd65fd60418d006ad9 upstream. + +The translation from the X driver to the KMS one typo'ed a couple +of array indices, causing the HW cursor to look weird (blocky with +leaking edge colors). This fixes it. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/ast/ast_mode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/ast/ast_mode.c ++++ b/drivers/gpu/drm/ast/ast_mode.c +@@ -1080,8 +1080,8 @@ static u32 copy_cursor_image(u8 *src, u8 + srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; + data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); + data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); +- data32.b[2] = srcdata32[0].b[1] | (srcdata32[1].b[0] >> 4); +- data32.b[3] = srcdata32[0].b[3] | (srcdata32[1].b[2] >> 4); ++ data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4); ++ data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4); + + writel(data32.ul, dstxor); + csum += data32.ul; diff --git a/queue-3.17/drm-cirrus-bind-also-to-qemu-xen-traditional.patch b/queue-3.17/drm-cirrus-bind-also-to-qemu-xen-traditional.patch new file mode 100644 index 00000000000..870ab4379fa --- /dev/null +++ b/queue-3.17/drm-cirrus-bind-also-to-qemu-xen-traditional.patch @@ -0,0 +1,31 @@ +From c0c3e735fa7bae29c6623511127fd021b2d6d849 Mon Sep 17 00:00:00 2001 +From: Olaf Hering +Date: Fri, 11 Apr 2014 08:56:23 +0200 +Subject: drm/cirrus: bind also to qemu-xen-traditional + +From: Olaf Hering + +commit c0c3e735fa7bae29c6623511127fd021b2d6d849 upstream. + +qemu as used by xend/xm toolstack uses a different subvendor id. +Bind the drm driver also to this emulated card. + +Signed-off-by: Olaf Hering +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/cirrus/cirrus_drv.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/cirrus/cirrus_drv.c ++++ b/drivers/gpu/drm/cirrus/cirrus_drv.c +@@ -32,6 +32,8 @@ static struct drm_driver driver; + static const struct pci_device_id pciidlist[] = { + { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0, + 0, 0 }, ++ { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, PCI_VENDOR_ID_XEN, ++ 0x0001, 0, 0, 0 }, + {0,} + }; + diff --git a/queue-3.17/drm-gt214-kms-fix-hda-eld-regression.patch b/queue-3.17/drm-gt214-kms-fix-hda-eld-regression.patch new file mode 100644 index 00000000000..7064dd74435 --- /dev/null +++ b/queue-3.17/drm-gt214-kms-fix-hda-eld-regression.patch @@ -0,0 +1,52 @@ +From d889c52427d48c05f163f2f39b2cfc12e17e5266 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 15 Sep 2014 21:11:51 +1000 +Subject: drm/gt214-/kms: fix hda eld regression + +From: Ben Skeggs + +commit d889c52427d48c05f163f2f39b2cfc12e17e5266 upstream. + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nv50_display.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nv50_display.c ++++ b/drivers/gpu/drm/nouveau/nv50_display.c +@@ -1653,15 +1653,17 @@ nv50_audio_mode_set(struct drm_encoder * + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nouveau_connector *nv_connector; + struct nv50_disp *disp = nv50_disp(encoder->dev); +- struct { +- struct nv50_disp_mthd_v1 base; +- struct nv50_disp_sor_hda_eld_v0 eld; ++ struct __packed { ++ struct { ++ struct nv50_disp_mthd_v1 mthd; ++ struct nv50_disp_sor_hda_eld_v0 eld; ++ } base; + u8 data[sizeof(nv_connector->base.eld)]; + } args = { +- .base.version = 1, +- .base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, +- .base.hasht = nv_encoder->dcb->hasht, +- .base.hashm = nv_encoder->dcb->hashm, ++ .base.mthd.version = 1, ++ .base.mthd.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, ++ .base.mthd.hasht = nv_encoder->dcb->hasht, ++ .base.mthd.hashm = nv_encoder->dcb->hashm, + }; + + nv_connector = nouveau_encoder_connector_get(nv_encoder); +@@ -1671,7 +1673,7 @@ nv50_audio_mode_set(struct drm_encoder * + drm_edid_to_eld(&nv_connector->base, nv_connector->edid); + memcpy(args.data, nv_connector->base.eld, sizeof(args.data)); + +- nvif_mthd(disp->disp, 0, &args, sizeof(args)); ++ nvif_mthd(disp->disp, 0, &args, sizeof(args.base) + args.data[2] * 4); + } + + static void diff --git a/queue-3.17/drm-i915-do-not-leak-pages-when-freeing-userptr-objects.patch b/queue-3.17/drm-i915-do-not-leak-pages-when-freeing-userptr-objects.patch new file mode 100644 index 00000000000..422778f239d --- /dev/null +++ b/queue-3.17/drm-i915-do-not-leak-pages-when-freeing-userptr-objects.patch @@ -0,0 +1,48 @@ +From c479f4383ea8940dd6f88da61798ad31feb33e51 Mon Sep 17 00:00:00 2001 +From: Tvrtko Ursulin +Date: Fri, 26 Sep 2014 15:05:22 +0100 +Subject: drm/i915: Do not leak pages when freeing userptr objects + +From: Tvrtko Ursulin + +commit c479f4383ea8940dd6f88da61798ad31feb33e51 upstream. + +sg_alloc_table_from_pages() can build us a table with coalesced ranges which +means we need to iterate over pages and not sg table entries when releasing +page references. + +Signed-off-by: Tvrtko Ursulin +Cc: Chris Wilson +Cc: "Barbalho, Rafael" +Tested-by: Rafael Barbalho +Reviewed-by: Chris Wilson +[danvet: Remove unused local variable sg.] +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem_userptr.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_gem_userptr.c ++++ b/drivers/gpu/drm/i915/i915_gem_userptr.c +@@ -689,16 +689,15 @@ i915_gem_userptr_get_pages(struct drm_i9 + static void + i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) + { +- struct scatterlist *sg; +- int i; ++ struct sg_page_iter sg_iter; + + BUG_ON(obj->userptr.work != NULL); + + if (obj->madv != I915_MADV_WILLNEED) + obj->dirty = 0; + +- for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) { +- struct page *page = sg_page(sg); ++ for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { ++ struct page *page = sg_page_iter_page(&sg_iter); + + if (obj->dirty) + set_page_dirty(page); diff --git a/queue-3.17/drm-i915-do-not-store-the-error-pointer-for-a-failed-userptr-registration.patch b/queue-3.17/drm-i915-do-not-store-the-error-pointer-for-a-failed-userptr-registration.patch new file mode 100644 index 00000000000..aecc0f353f6 --- /dev/null +++ b/queue-3.17/drm-i915-do-not-store-the-error-pointer-for-a-failed-userptr-registration.patch @@ -0,0 +1,109 @@ +From e9681366ea9e76ab8f75e84351f2f3ca63ee542c Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 26 Sep 2014 10:31:02 +0100 +Subject: drm/i915: Do not store the error pointer for a failed userptr registration + +From: Chris Wilson + +commit e9681366ea9e76ab8f75e84351f2f3ca63ee542c upstream. + +If we fail to create our mmu notification, we report the error back and +currently store the error inside the i915_mm_struct. This not only causes +subsequent registerations of the same mm to fail (an issue if the first +was interrupted by a signal and needed to be restarted) but also causes +us to eventually try and free the error pointer. + +[ 73.419599] BUG: unable to handle kernel NULL pointer dereference at 000000000000004c +[ 73.419831] IP: [] mmu_notifier_unregister+0x23/0x130 +[ 73.420065] PGD 8650c067 PUD 870bb067 PMD 0 +[ 73.420319] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC +[ 73.420580] CPU: 0 PID: 42 Comm: kworker/0:1 Tainted: G W 3.17.0-rc6+ #1561 +[ 73.420837] Hardware name: Intel Corporation SandyBridge Platform/LosLunas CRB, BIOS ASNBCPT1.86C.0075.P00.1106281639 06/28/2011 +[ 73.421405] Workqueue: events __i915_mm_struct_free__worker +[ 73.421724] task: ffff880088a81220 ti: ffff880088168000 task.ti: ffff880088168000 +[ 73.422051] RIP: 0010:[] [] mmu_notifier_unregister+0x23/0x130 +[ 73.422410] RSP: 0018:ffff88008816bd50 EFLAGS: 00010286 +[ 73.422765] RAX: 0000000000000003 RBX: ffff880086485400 RCX: 0000000000000000 +[ 73.423137] RDX: ffff88016d80ee90 RSI: ffff880086485400 RDI: 0000000000000044 +[ 73.423513] RBP: ffff88008816bd70 R08: 0000000000000001 R09: 0000000000000000 +[ 73.423895] R10: 0000000000000320 R11: 0000000000000001 R12: 0000000000000044 +[ 73.424282] R13: ffff880166e5f008 R14: ffff88016d815200 R15: ffff880166e5f040 +[ 73.424682] FS: 0000000000000000(0000) GS:ffff88016d800000(0000) knlGS:0000000000000000 +[ 73.425099] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 73.425537] CR2: 000000000000004c CR3: 0000000087f5f000 CR4: 00000000000407f0 +[ 73.426157] Stack: +[ 73.426597] ffff880088a81248 ffff880166e5f038 fffffffffffffffc ffff880166e5f008 +[ 73.427096] ffff88008816bd98 ffffffff814a75f2 ffff880166e5f038 ffff8800880f8a28 +[ 73.427603] ffff88016d812ac0 ffff88008816be00 ffffffff8106321a ffffffff810631af +[ 73.428119] Call Trace: +[ 73.428606] [] __i915_mm_struct_free__worker+0x42/0x80 +[ 73.429116] [] process_one_work+0x1ba/0x610 +[ 73.429632] [] ? process_one_work+0x14f/0x610 +[ 73.430153] [] worker_thread+0x6b/0x4a0 +[ 73.430671] [] ? trace_hardirqs_on+0xd/0x10 +[ 73.431501] [] ? process_one_work+0x610/0x610 +[ 73.432030] [] kthread+0xf6/0x110 +[ 73.432561] [] ? __kthread_parkme+0x80/0x80 +[ 73.433100] [] ret_from_fork+0x7c/0xb0 +[ 73.433644] [] ? __kthread_parkme+0x80/0x80 +[ 73.434194] Code: 0f 1f 84 00 00 00 00 00 66 66 66 66 90 8b 46 4c 85 c0 0f 8e 10 01 00 00 55 48 89 e5 41 55 41 54 53 48 89 f3 49 89 fc 48 83 ec 08 <48> 83 7f 08 00 0f 84 b1 00 00 00 48 c7 c7 40 e6 ac 82 e8 26 65 +[ 73.435942] RIP [] mmu_notifier_unregister+0x23/0x130 +[ 73.437017] RSP +[ 73.437704] CR2: 000000000000004c + +Fixes regression from commit ad46cb533d586fdb256855437af876617c6cf609 +Author: Chris Wilson +Date: Thu Aug 7 14:20:40 2014 +0100 + + drm/i915: Prevent recursive deadlock on releasing a busy userptr + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84207 +Testcase: igt/gem_render_copy_redux +Testcase: igt/gem_userptr_blits/create-destroy-sync +Signed-off-by: Chris Wilson +Cc: Jacek Danecki +Cc: "Gong, Zhipeng" +Cc: Jacek Danecki +Cc: "Ursulin, Tvrtko" +Reviewed-by: Tvrtko Ursulin +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem_userptr.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_gem_userptr.c ++++ b/drivers/gpu/drm/i915/i915_gem_userptr.c +@@ -293,15 +293,23 @@ i915_gem_userptr_release__mmu_notifier(s + static struct i915_mmu_notifier * + i915_mmu_notifier_find(struct i915_mm_struct *mm) + { +- if (mm->mn == NULL) { +- down_write(&mm->mm->mmap_sem); +- mutex_lock(&to_i915(mm->dev)->mm_lock); +- if (mm->mn == NULL) +- mm->mn = i915_mmu_notifier_create(mm->mm); +- mutex_unlock(&to_i915(mm->dev)->mm_lock); +- up_write(&mm->mm->mmap_sem); ++ struct i915_mmu_notifier *mn = mm->mn; ++ ++ mn = mm->mn; ++ if (mn) ++ return mn; ++ ++ down_write(&mm->mm->mmap_sem); ++ mutex_lock(&to_i915(mm->dev)->mm_lock); ++ if ((mn = mm->mn) == NULL) { ++ mn = i915_mmu_notifier_create(mm->mm); ++ if (!IS_ERR(mn)) ++ mm->mn = mn; + } +- return mm->mn; ++ mutex_unlock(&to_i915(mm->dev)->mm_lock); ++ up_write(&mm->mm->mmap_sem); ++ ++ return mn; + } + + static int diff --git a/queue-3.17/drm-nouveau-bios-memset-dcb-struct-to-zero-before-parsing.patch b/queue-3.17/drm-nouveau-bios-memset-dcb-struct-to-zero-before-parsing.patch new file mode 100644 index 00000000000..004fd479a80 --- /dev/null +++ b/queue-3.17/drm-nouveau-bios-memset-dcb-struct-to-zero-before-parsing.patch @@ -0,0 +1,29 @@ +From 595d373f1e9c9ce0fc946457fdb488e8a58972cd Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 8 Sep 2014 10:33:32 +1000 +Subject: drm/nouveau/bios: memset dcb struct to zero before parsing + +From: Ben Skeggs + +commit 595d373f1e9c9ce0fc946457fdb488e8a58972cd upstream. + +Fixes type/mask calculation being based on uninitialised data for VGA +outputs. + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c ++++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +@@ -124,6 +124,7 @@ dcb_outp_parse(struct nouveau_bios *bios + struct dcb_output *outp) + { + u16 dcb = dcb_outp(bios, idx, ver, len); ++ memset(outp, 0x00, sizeof(*outp)); + if (dcb) { + if (*ver >= 0x20) { + u32 conn = nv_ro32(bios, dcb + 0x00); diff --git a/queue-3.17/drm-nouveau-gpio-rename-g92-class-to-g94.patch b/queue-3.17/drm-nouveau-gpio-rename-g92-class-to-g94.patch new file mode 100644 index 00000000000..397d1afd3e5 --- /dev/null +++ b/queue-3.17/drm-nouveau-gpio-rename-g92-class-to-g94.patch @@ -0,0 +1,403 @@ +From b485a7005faba38286bc02ab1d80e2cbf61c1002 Mon Sep 17 00:00:00 2001 +From: Emil Velikov +Date: Mon, 8 Sep 2014 20:27:57 +0100 +Subject: drm/nouveau/gpio: rename g92 class to g94 + +From: Emil Velikov + +commit b485a7005faba38286bc02ab1d80e2cbf61c1002 upstream. + +nv92 hardware has only 16 interrupt lines, while nv94 and later +has 32. Accessing 0xe0c{0,4} registers on nv92 can lead to incorrect +PDISP setup. This is a regression introduced with + +commit 9d0f5ec9ee0fd5dc5fc1cc2cf559286431e406e3 +Author: Ben Skeggs +Date: Mon May 12 15:22:42 2014 +1000 + + gpio: split g92 class from nv50 + +Reported-by: estece on #nouveau +Signed-off-by: Emil Velikov +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/Makefile | 2 + drivers/gpu/drm/nouveau/core/engine/device/nv50.c | 22 +++--- + drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | 14 +-- + drivers/gpu/drm/nouveau/core/include/subdev/gpio.h | 2 + drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c | 74 --------------------- + drivers/gpu/drm/nouveau/core/subdev/gpio/nv94.c | 74 +++++++++++++++++++++ + drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c | 4 - + drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h | 4 - + 8 files changed, 98 insertions(+), 98 deletions(-) + +--- a/drivers/gpu/drm/nouveau/Makefile ++++ b/drivers/gpu/drm/nouveau/Makefile +@@ -129,7 +129,7 @@ nouveau-y += core/subdev/fb/gddr5.o + nouveau-y += core/subdev/gpio/base.o + nouveau-y += core/subdev/gpio/nv10.o + nouveau-y += core/subdev/gpio/nv50.o +-nouveau-y += core/subdev/gpio/nv92.o ++nouveau-y += core/subdev/gpio/nv94.o + nouveau-y += core/subdev/gpio/nvd0.o + nouveau-y += core/subdev/gpio/nve0.o + nouveau-y += core/subdev/i2c/base.o +--- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c ++++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c +@@ -141,7 +141,7 @@ nv50_identify(struct nouveau_device *dev + case 0x92: + device->cname = "G92"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; +@@ -169,7 +169,7 @@ nv50_identify(struct nouveau_device *dev + case 0x94: + device->cname = "G94"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; +@@ -197,7 +197,7 @@ nv50_identify(struct nouveau_device *dev + case 0x96: + device->cname = "G96"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; +@@ -225,7 +225,7 @@ nv50_identify(struct nouveau_device *dev + case 0x98: + device->cname = "G98"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; +@@ -253,7 +253,7 @@ nv50_identify(struct nouveau_device *dev + case 0xa0: + device->cname = "G200"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; +@@ -281,7 +281,7 @@ nv50_identify(struct nouveau_device *dev + case 0xaa: + device->cname = "MCP77/MCP78"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; +@@ -309,7 +309,7 @@ nv50_identify(struct nouveau_device *dev + case 0xac: + device->cname = "MCP79/MCP7A"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; +@@ -337,7 +337,7 @@ nv50_identify(struct nouveau_device *dev + case 0xa3: + device->cname = "GT215"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -367,7 +367,7 @@ nv50_identify(struct nouveau_device *dev + case 0xa5: + device->cname = "GT216"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -396,7 +396,7 @@ nv50_identify(struct nouveau_device *dev + case 0xa8: + device->cname = "GT218"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -425,7 +425,7 @@ nv50_identify(struct nouveau_device *dev + case 0xaf: + device->cname = "MCP89"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +--- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c ++++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +@@ -60,7 +60,7 @@ nvc0_identify(struct nouveau_device *dev + case 0xc0: + device->cname = "GF100"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -92,7 +92,7 @@ nvc0_identify(struct nouveau_device *dev + case 0xc4: + device->cname = "GF104"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -124,7 +124,7 @@ nvc0_identify(struct nouveau_device *dev + case 0xc3: + device->cname = "GF106"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -155,7 +155,7 @@ nvc0_identify(struct nouveau_device *dev + case 0xce: + device->cname = "GF114"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -187,7 +187,7 @@ nvc0_identify(struct nouveau_device *dev + case 0xcf: + device->cname = "GF116"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -219,7 +219,7 @@ nvc0_identify(struct nouveau_device *dev + case 0xc1: + device->cname = "GF108"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +@@ -250,7 +250,7 @@ nvc0_identify(struct nouveau_device *dev + case 0xc8: + device->cname = "GF110"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; +- device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; ++ device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; +--- a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h ++++ b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h +@@ -40,7 +40,7 @@ nouveau_gpio(void *obj) + + extern struct nouveau_oclass *nv10_gpio_oclass; + extern struct nouveau_oclass *nv50_gpio_oclass; +-extern struct nouveau_oclass *nv92_gpio_oclass; ++extern struct nouveau_oclass *nv94_gpio_oclass; + extern struct nouveau_oclass *nvd0_gpio_oclass; + extern struct nouveau_oclass *nve0_gpio_oclass; + +--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c ++++ /dev/null +@@ -1,74 +0,0 @@ +-/* +- * Copyright 2012 Red Hat Inc. +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sublicense, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice shall be included in +- * all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. +- * +- * Authors: Ben Skeggs +- */ +- +-#include "priv.h" +- +-void +-nv92_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) +-{ +- u32 intr0 = nv_rd32(gpio, 0x00e054); +- u32 intr1 = nv_rd32(gpio, 0x00e074); +- u32 stat0 = nv_rd32(gpio, 0x00e050) & intr0; +- u32 stat1 = nv_rd32(gpio, 0x00e070) & intr1; +- *lo = (stat1 & 0xffff0000) | (stat0 >> 16); +- *hi = (stat1 << 16) | (stat0 & 0x0000ffff); +- nv_wr32(gpio, 0x00e054, intr0); +- nv_wr32(gpio, 0x00e074, intr1); +-} +- +-void +-nv92_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) +-{ +- u32 inte0 = nv_rd32(gpio, 0x00e050); +- u32 inte1 = nv_rd32(gpio, 0x00e070); +- if (type & NVKM_GPIO_LO) +- inte0 = (inte0 & ~(mask << 16)) | (data << 16); +- if (type & NVKM_GPIO_HI) +- inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); +- mask >>= 16; +- data >>= 16; +- if (type & NVKM_GPIO_LO) +- inte1 = (inte1 & ~(mask << 16)) | (data << 16); +- if (type & NVKM_GPIO_HI) +- inte1 = (inte1 & ~mask) | data; +- nv_wr32(gpio, 0x00e050, inte0); +- nv_wr32(gpio, 0x00e070, inte1); +-} +- +-struct nouveau_oclass * +-nv92_gpio_oclass = &(struct nouveau_gpio_impl) { +- .base.handle = NV_SUBDEV(GPIO, 0x92), +- .base.ofuncs = &(struct nouveau_ofuncs) { +- .ctor = _nouveau_gpio_ctor, +- .dtor = _nouveau_gpio_dtor, +- .init = _nouveau_gpio_init, +- .fini = _nouveau_gpio_fini, +- }, +- .lines = 32, +- .intr_stat = nv92_gpio_intr_stat, +- .intr_mask = nv92_gpio_intr_mask, +- .drive = nv50_gpio_drive, +- .sense = nv50_gpio_sense, +- .reset = nv50_gpio_reset, +-}.base; +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv94.c +@@ -0,0 +1,74 @@ ++/* ++ * Copyright 2012 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "priv.h" ++ ++void ++nv94_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) ++{ ++ u32 intr0 = nv_rd32(gpio, 0x00e054); ++ u32 intr1 = nv_rd32(gpio, 0x00e074); ++ u32 stat0 = nv_rd32(gpio, 0x00e050) & intr0; ++ u32 stat1 = nv_rd32(gpio, 0x00e070) & intr1; ++ *lo = (stat1 & 0xffff0000) | (stat0 >> 16); ++ *hi = (stat1 << 16) | (stat0 & 0x0000ffff); ++ nv_wr32(gpio, 0x00e054, intr0); ++ nv_wr32(gpio, 0x00e074, intr1); ++} ++ ++void ++nv94_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) ++{ ++ u32 inte0 = nv_rd32(gpio, 0x00e050); ++ u32 inte1 = nv_rd32(gpio, 0x00e070); ++ if (type & NVKM_GPIO_LO) ++ inte0 = (inte0 & ~(mask << 16)) | (data << 16); ++ if (type & NVKM_GPIO_HI) ++ inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); ++ mask >>= 16; ++ data >>= 16; ++ if (type & NVKM_GPIO_LO) ++ inte1 = (inte1 & ~(mask << 16)) | (data << 16); ++ if (type & NVKM_GPIO_HI) ++ inte1 = (inte1 & ~mask) | data; ++ nv_wr32(gpio, 0x00e050, inte0); ++ nv_wr32(gpio, 0x00e070, inte1); ++} ++ ++struct nouveau_oclass * ++nv94_gpio_oclass = &(struct nouveau_gpio_impl) { ++ .base.handle = NV_SUBDEV(GPIO, 0x94), ++ .base.ofuncs = &(struct nouveau_ofuncs) { ++ .ctor = _nouveau_gpio_ctor, ++ .dtor = _nouveau_gpio_dtor, ++ .init = _nouveau_gpio_init, ++ .fini = _nouveau_gpio_fini, ++ }, ++ .lines = 32, ++ .intr_stat = nv94_gpio_intr_stat, ++ .intr_mask = nv94_gpio_intr_mask, ++ .drive = nv50_gpio_drive, ++ .sense = nv50_gpio_sense, ++ .reset = nv50_gpio_reset, ++}.base; +--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c ++++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c +@@ -77,8 +77,8 @@ nvd0_gpio_oclass = &(struct nouveau_gpio + .fini = _nouveau_gpio_fini, + }, + .lines = 32, +- .intr_stat = nv92_gpio_intr_stat, +- .intr_mask = nv92_gpio_intr_mask, ++ .intr_stat = nv94_gpio_intr_stat, ++ .intr_mask = nv94_gpio_intr_mask, + .drive = nvd0_gpio_drive, + .sense = nvd0_gpio_sense, + .reset = nvd0_gpio_reset, +--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h ++++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h +@@ -56,8 +56,8 @@ void nv50_gpio_reset(struct nouveau_gpio + int nv50_gpio_drive(struct nouveau_gpio *, int, int, int); + int nv50_gpio_sense(struct nouveau_gpio *, int); + +-void nv92_gpio_intr_stat(struct nouveau_gpio *, u32 *, u32 *); +-void nv92_gpio_intr_mask(struct nouveau_gpio *, u32, u32, u32); ++void nv94_gpio_intr_stat(struct nouveau_gpio *, u32 *, u32 *); ++void nv94_gpio_intr_mask(struct nouveau_gpio *, u32, u32, u32); + + void nvd0_gpio_reset(struct nouveau_gpio *, u8); + int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int); diff --git a/queue-3.17/drm-tilcdc-fix-the-error-path-in-tilcdc_load.patch b/queue-3.17/drm-tilcdc-fix-the-error-path-in-tilcdc_load.patch new file mode 100644 index 00000000000..0228fb4a962 --- /dev/null +++ b/queue-3.17/drm-tilcdc-fix-the-error-path-in-tilcdc_load.patch @@ -0,0 +1,165 @@ +From b478e336b3e75505707a11e78ef8b964ef0a03af Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Tue, 2 Sep 2014 09:51:15 -0300 +Subject: drm/tilcdc: Fix the error path in tilcdc_load() + +From: Ezequiel Garcia + +commit b478e336b3e75505707a11e78ef8b964ef0a03af upstream. + +The current error path calls tilcdc_unload() in case of an error to release +the resources. However, this is wrong because not all resources have been +allocated by the time an error occurs in tilcdc_load(). + +To fix it, this commit adds proper labels to bail out at the different +stages in the load function, and release only the resources actually allocated. + +Tested-by: Darren Etheridge +Tested-by: Johannes Pointner +Signed-off-by: Ezequiel Garcia +Signed-off-by: Dave Airlie +Fixes: 3a49012224ca ("drm/tilcdc: panel: fix leak when unloading the module") +Signed-off-by: Matwey V. Kornilov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 60 ++++++++++++++++++++++++++++++------ + 1 file changed, 50 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c ++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +@@ -84,6 +84,7 @@ static int modeset_init(struct drm_devic + if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) { + /* oh nos! */ + dev_err(dev->dev, "no encoders/connectors found\n"); ++ drm_mode_config_cleanup(dev); + return -ENXIO; + } + +@@ -172,33 +173,37 @@ static int tilcdc_load(struct drm_device + dev->dev_private = priv; + + priv->wq = alloc_ordered_workqueue("tilcdc", 0); ++ if (!priv->wq) { ++ ret = -ENOMEM; ++ goto fail_free_priv; ++ } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev->dev, "failed to get memory resource\n"); + ret = -EINVAL; +- goto fail; ++ goto fail_free_wq; + } + + priv->mmio = ioremap_nocache(res->start, resource_size(res)); + if (!priv->mmio) { + dev_err(dev->dev, "failed to ioremap\n"); + ret = -ENOMEM; +- goto fail; ++ goto fail_free_wq; + } + + priv->clk = clk_get(dev->dev, "fck"); + if (IS_ERR(priv->clk)) { + dev_err(dev->dev, "failed to get functional clock\n"); + ret = -ENODEV; +- goto fail; ++ goto fail_iounmap; + } + + priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck"); + if (IS_ERR(priv->clk)) { + dev_err(dev->dev, "failed to get display clock\n"); + ret = -ENODEV; +- goto fail; ++ goto fail_put_clk; + } + + #ifdef CONFIG_CPU_FREQ +@@ -208,7 +213,7 @@ static int tilcdc_load(struct drm_device + CPUFREQ_TRANSITION_NOTIFIER); + if (ret) { + dev_err(dev->dev, "failed to register cpufreq notifier\n"); +- goto fail; ++ goto fail_put_disp_clk; + } + #endif + +@@ -253,13 +258,13 @@ static int tilcdc_load(struct drm_device + ret = modeset_init(dev); + if (ret < 0) { + dev_err(dev->dev, "failed to initialize mode setting\n"); +- goto fail; ++ goto fail_cpufreq_unregister; + } + + ret = drm_vblank_init(dev, 1); + if (ret < 0) { + dev_err(dev->dev, "failed to initialize vblank\n"); +- goto fail; ++ goto fail_mode_config_cleanup; + } + + pm_runtime_get_sync(dev->dev); +@@ -267,7 +272,7 @@ static int tilcdc_load(struct drm_device + pm_runtime_put_sync(dev->dev); + if (ret < 0) { + dev_err(dev->dev, "failed to install IRQ handler\n"); +- goto fail; ++ goto fail_vblank_cleanup; + } + + platform_set_drvdata(pdev, dev); +@@ -283,13 +288,48 @@ static int tilcdc_load(struct drm_device + priv->fbdev = drm_fbdev_cma_init(dev, bpp, + dev->mode_config.num_crtc, + dev->mode_config.num_connector); ++ if (IS_ERR(priv->fbdev)) { ++ ret = PTR_ERR(priv->fbdev); ++ goto fail_irq_uninstall; ++ } + + drm_kms_helper_poll_init(dev); + + return 0; + +-fail: +- tilcdc_unload(dev); ++fail_irq_uninstall: ++ pm_runtime_get_sync(dev->dev); ++ drm_irq_uninstall(dev); ++ pm_runtime_put_sync(dev->dev); ++ ++fail_vblank_cleanup: ++ drm_vblank_cleanup(dev); ++ ++fail_mode_config_cleanup: ++ drm_mode_config_cleanup(dev); ++ ++fail_cpufreq_unregister: ++ pm_runtime_disable(dev->dev); ++#ifdef CONFIG_CPU_FREQ ++ cpufreq_unregister_notifier(&priv->freq_transition, ++ CPUFREQ_TRANSITION_NOTIFIER); ++fail_put_disp_clk: ++ clk_put(priv->disp_clk); ++#endif ++ ++fail_put_clk: ++ clk_put(priv->clk); ++ ++fail_iounmap: ++ iounmap(priv->mmio); ++ ++fail_free_wq: ++ flush_workqueue(priv->wq); ++ destroy_workqueue(priv->wq); ++ ++fail_free_priv: ++ dev->dev_private = NULL; ++ kfree(priv); + return ret; + } + diff --git a/queue-3.17/drm-vmwgfx-fix-drm.h-include.patch b/queue-3.17/drm-vmwgfx-fix-drm.h-include.patch new file mode 100644 index 00000000000..bb67c7fb644 --- /dev/null +++ b/queue-3.17/drm-vmwgfx-fix-drm.h-include.patch @@ -0,0 +1,37 @@ +From e351943b081f4d9e6f692ce1a6117e8d2e71f478 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Fri, 5 Sep 2014 13:19:59 -0400 +Subject: drm/vmwgfx: Fix drm.h include + +From: Josh Boyer + +commit e351943b081f4d9e6f692ce1a6117e8d2e71f478 upstream. + +The userspace drm.h include doesn't prefix the drm directory. This can lead +to compile failures as /usr/include/drm/ isn't in the standard gcc include +paths. Fix it to be , which matches the rest of the driver drm +header files that get installed into /usr/include/drm. + +Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1138759 + +Fixes: 1d7a5cbf8f74e +Reported-by: Jeffrey Bastian +Signed-off-by: Josh Boyer +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + include/uapi/drm/vmwgfx_drm.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/uapi/drm/vmwgfx_drm.h ++++ b/include/uapi/drm/vmwgfx_drm.h +@@ -29,7 +29,7 @@ + #define __VMWGFX_DRM_H__ + + #ifndef __KERNEL__ +-#include ++#include + #endif + + #define DRM_VMW_MAX_SURFACE_FACES 6 diff --git a/queue-3.17/framebuffer-fix-border-color.patch b/queue-3.17/framebuffer-fix-border-color.patch new file mode 100644 index 00000000000..a02eae8af71 --- /dev/null +++ b/queue-3.17/framebuffer-fix-border-color.patch @@ -0,0 +1,100 @@ +From f74a289b9480648a654e5afd8458c2263c03a1e1 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 16 Sep 2014 12:40:26 -0400 +Subject: framebuffer: fix border color + +From: Mikulas Patocka + +commit f74a289b9480648a654e5afd8458c2263c03a1e1 upstream. + +The framebuffer code uses the current background color to fill the border +when switching consoles, however, this results in inconsistent behavior. +For example: +- start Midnigh Commander +- the border is black +- switch to another console and switch back +- the border is cyan +- type something into the command line in mc +- the border is cyan +- switch to another console and switch back +- the border is black +- press F9 to go to menu +- the border is black +- switch to another console and switch back +- the border is dark blue + +When switching to a console with Midnight Commander, the border is random +color that was left selected by the slang subsystem. + +This patch fixes this inconsistency by always using black as the +background color when switching consoles. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Tomi Valkeinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/console/bitblit.c | 3 +-- + drivers/video/console/fbcon_ccw.c | 3 +-- + drivers/video/console/fbcon_cw.c | 3 +-- + drivers/video/console/fbcon_ud.c | 3 +-- + 4 files changed, 4 insertions(+), 8 deletions(-) + +--- a/drivers/video/console/bitblit.c ++++ b/drivers/video/console/bitblit.c +@@ -205,7 +205,6 @@ static void bit_putcs(struct vc_data *vc + static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only) + { +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + unsigned int cw = vc->vc_font.width; + unsigned int ch = vc->vc_font.height; + unsigned int rw = info->var.xres - (vc->vc_cols*cw); +@@ -214,7 +213,7 @@ static void bit_clear_margins(struct vc_ + unsigned int bs = info->var.yres - bh; + struct fb_fillrect region; + +- region.color = attr_bgcol_ec(bgshift, vc, info); ++ region.color = 0; + region.rop = ROP_COPY; + + if (rw && !bottom_only) { +--- a/drivers/video/console/fbcon_ccw.c ++++ b/drivers/video/console/fbcon_ccw.c +@@ -197,9 +197,8 @@ static void ccw_clear_margins(struct vc_ + unsigned int bh = info->var.xres - (vc->vc_rows*ch); + unsigned int bs = vc->vc_rows*ch; + struct fb_fillrect region; +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + +- region.color = attr_bgcol_ec(bgshift,vc,info); ++ region.color = 0; + region.rop = ROP_COPY; + + if (rw && !bottom_only) { +--- a/drivers/video/console/fbcon_cw.c ++++ b/drivers/video/console/fbcon_cw.c +@@ -180,9 +180,8 @@ static void cw_clear_margins(struct vc_d + unsigned int bh = info->var.xres - (vc->vc_rows*ch); + unsigned int rs = info->var.yres - rw; + struct fb_fillrect region; +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + +- region.color = attr_bgcol_ec(bgshift,vc,info); ++ region.color = 0; + region.rop = ROP_COPY; + + if (rw && !bottom_only) { +--- a/drivers/video/console/fbcon_ud.c ++++ b/drivers/video/console/fbcon_ud.c +@@ -227,9 +227,8 @@ static void ud_clear_margins(struct vc_d + unsigned int rw = info->var.xres - (vc->vc_cols*cw); + unsigned int bh = info->var.yres - (vc->vc_rows*ch); + struct fb_fillrect region; +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + +- region.color = attr_bgcol_ec(bgshift,vc,info); ++ region.color = 0; + region.rop = ROP_COPY; + + if (rw && !bottom_only) { diff --git a/queue-3.17/framebuffer-fix-screen-corruption-when-copying.patch b/queue-3.17/framebuffer-fix-screen-corruption-when-copying.patch new file mode 100644 index 00000000000..506dca9178f --- /dev/null +++ b/queue-3.17/framebuffer-fix-screen-corruption-when-copying.patch @@ -0,0 +1,71 @@ +From 5b789da8a7fc357661fc61faaf853e9161cc9700 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 16 Sep 2014 12:38:53 -0400 +Subject: framebuffer: fix screen corruption when copying + +From: Mikulas Patocka + +commit 5b789da8a7fc357661fc61faaf853e9161cc9700 upstream. + +The function bitcpy_rev has a bug that may result in screen corruption. +The bug happens under these conditions: +* the end of the destination area of a copy operation is aligned on a long + word boundary +* the end of the source area is not aligned on a long word boundary +* we are copying more than one long word + +In this case, the variable shift is non-zero and the variable first is +zero. The statements FB_WRITEL(comp(d0, FB_READL(dst), first), dst) reads +the last long word of the destination and writes it back unchanged +(because first is zero). Correctly, we should write the variable d0 to the +last word of the destination in this case. + +This patch fixes the bug by introducing and extra test if first is zero. + +The patch also removes the references to fb_memmove in the code that is +commented out because fb_memmove was removed from framebuffer subsystem. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Tomi Valkeinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/fbdev/core/cfbcopyarea.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/video/fbdev/core/cfbcopyarea.c ++++ b/drivers/video/fbdev/core/cfbcopyarea.c +@@ -55,8 +55,8 @@ bitcpy(struct fb_info *p, unsigned long + * If you suspect bug in this function, compare it with this simple + * memmove implementation. + */ +- fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, +- (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); ++ memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, ++ (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); + return; + #endif + +@@ -221,8 +221,8 @@ bitcpy_rev(struct fb_info *p, unsigned l + * If you suspect bug in this function, compare it with this simple + * memmove implementation. + */ +- fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, +- (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); ++ memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, ++ (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); + return; + #endif + +@@ -324,7 +324,10 @@ bitcpy_rev(struct fb_info *p, unsigned l + d0 = d0 << left | d1 >> right; + } + d0 = fb_rev_pixels_in_long(d0, bswapmask); +- FB_WRITEL(comp(d0, FB_READL(dst), first), dst); ++ if (!first) ++ FB_WRITEL(d0, dst); ++ else ++ FB_WRITEL(comp(d0, FB_READL(dst), first), dst); + d0 = d1; + dst--; + n -= dst_idx+1; diff --git a/queue-3.17/hid-input-fix-transducerserialnumber-implementation.patch b/queue-3.17/hid-input-fix-transducerserialnumber-implementation.patch new file mode 100644 index 00000000000..4149e4d1051 --- /dev/null +++ b/queue-3.17/hid-input-fix-transducerserialnumber-implementation.patch @@ -0,0 +1,40 @@ +From 5989a55a4c9aafba8b152c6bf52244510c2b88b9 Mon Sep 17 00:00:00 2001 +From: Jason Gerecke +Date: Tue, 23 Sep 2014 11:09:28 -0700 +Subject: HID: input: Fix TransducerSerialNumber implementation + +From: Jason Gerecke + +commit 5989a55a4c9aafba8b152c6bf52244510c2b88b9 upstream. + +The commit which introduced TransducerSerialNumber (368c966) is missing +two crucial implementation details. Firstly, the commit does not set the +type/code/bit/max fields as expected later down the code which can cause +the driver to crash when a tablet with this usage is connected. Secondly, +the call to 'set_bit' causes MSC_PULSELED to be sent instead of the +expected MSC_SERIAL. This commit addreses both issues. + +Signed-off-by: Jason Gerecke +Reviewed-by: Benjamin Tissoires +Reviewed-by: Ping Cheng +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-input.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -689,7 +689,10 @@ static void hidinput_configure_usage(str + break; + + case 0x5b: /* TransducerSerialNumber */ +- set_bit(MSC_SERIAL, input->mscbit); ++ usage->type = EV_MSC; ++ usage->code = MSC_SERIAL; ++ bit = input->mscbit; ++ max = MSC_MAX; + break; + + default: goto unknown; diff --git a/queue-3.17/input-alps-fix-v4-button-press-recognition.patch b/queue-3.17/input-alps-fix-v4-button-press-recognition.patch new file mode 100644 index 00000000000..a0918378630 --- /dev/null +++ b/queue-3.17/input-alps-fix-v4-button-press-recognition.patch @@ -0,0 +1,36 @@ +From b0cfb794a3dd1d699f3e453f9180bd06508fb8f0 Mon Sep 17 00:00:00 2001 +From: Andreas Bosch +Date: Wed, 15 Oct 2014 10:44:50 -0700 +Subject: Input: alps - fix v4 button press recognition + +From: Andreas Bosch + +commit b0cfb794a3dd1d699f3e453f9180bd06508fb8f0 upstream. + +Since the change to struct input_mt_pos some variables are now bitfields +instead of integers. Automatic conversion from integer to bitfield entry +destroys information, therefore enforce boolean interpretation instead. + +Link: https://bugzilla.redhat.com/show_bug.cgi?id=1114768 +Fixes: 02d04254a5df ("Input: alps - use struct input_mt_pos to track coordinates") +Signed-off-by: Andreas Bosch +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/alps.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/input/mouse/alps.c ++++ b/drivers/input/mouse/alps.c +@@ -835,8 +835,8 @@ static void alps_process_packet_v4(struc + f->fingers = alps_process_bitmap(priv, f); + } + +- f->left = packet[4] & 0x01; +- f->right = packet[4] & 0x02; ++ f->left = !!(packet[4] & 0x01); ++ f->right = !!(packet[4] & 0x02); + + f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) | + ((packet[0] & 0x30) >> 4); diff --git a/queue-3.17/input-i8042-add-noloop-quirk-for-asus-x750ln.patch b/queue-3.17/input-i8042-add-noloop-quirk-for-asus-x750ln.patch new file mode 100644 index 00000000000..b5465893ae3 --- /dev/null +++ b/queue-3.17/input-i8042-add-noloop-quirk-for-asus-x750ln.patch @@ -0,0 +1,37 @@ +From 9ff84a17302aeb8913ff244ecc0d8f9d219fecb5 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sat, 11 Oct 2014 11:27:37 -0700 +Subject: Input: i8042 - add noloop quirk for Asus X750LN + +From: Hans de Goede + +commit 9ff84a17302aeb8913ff244ecc0d8f9d219fecb5 upstream. + +Without this the aux port does not get detected, and consequently the +touchpad will not work. + +https://bugzilla.redhat.com/show_bug.cgi?id=1110011 + +Signed-off-by: Hans de Goede +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/serio/i8042-x86ia64io.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -101,6 +101,12 @@ static const struct dmi_system_id __init + }, + { + .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"), ++ }, ++ }, ++ { ++ .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), + DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), + DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), diff --git a/queue-3.17/input-i8042-quirks-for-fujitsu-lifebook-a544-and-lifebook-ah544.patch b/queue-3.17/input-i8042-quirks-for-fujitsu-lifebook-a544-and-lifebook-ah544.patch new file mode 100644 index 00000000000..f578dd9e0e0 --- /dev/null +++ b/queue-3.17/input-i8042-quirks-for-fujitsu-lifebook-a544-and-lifebook-ah544.patch @@ -0,0 +1,46 @@ +From 993b3a3f80a7842a48cd46c2b41e1b3ef6302468 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 24 Oct 2014 14:55:24 -0700 +Subject: Input: i8042 - quirks for Fujitsu Lifebook A544 and Lifebook AH544 + +From: Hans de Goede + +commit 993b3a3f80a7842a48cd46c2b41e1b3ef6302468 upstream. + +These models need i8042.notimeout, otherwise the touchpad will not work. + +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=69731 +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1111138 +Signed-off-by: Hans de Goede +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/serio/i8042-x86ia64io.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -629,6 +629,22 @@ static const struct dmi_system_id __init + }, + }, + { ++ /* Fujitsu A544 laptop */ ++ /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), ++ }, ++ }, ++ { ++ /* Fujitsu AH544 laptop */ ++ /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), ++ }, ++ }, ++ { + /* Fujitsu U574 laptop */ + /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ + .matches = { diff --git a/queue-3.17/input-synaptics-gate-forcepad-support-by-dmi-check.patch b/queue-3.17/input-synaptics-gate-forcepad-support-by-dmi-check.patch new file mode 100644 index 00000000000..ab8ad215572 --- /dev/null +++ b/queue-3.17/input-synaptics-gate-forcepad-support-by-dmi-check.patch @@ -0,0 +1,96 @@ +From aa972409951e0675e07918620427517cad5090e0 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Tue, 2 Sep 2014 09:49:18 -0700 +Subject: Input: synaptics - gate forcepad support by DMI check + +From: Dmitry Torokhov + +commit aa972409951e0675e07918620427517cad5090e0 upstream. + +Unfortunately, ForcePad capability is not actually exported over PS/2, so +we have to resort to DMI checks. + +Reported-by: Nicole Faerber +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/synaptics.c | 22 +++++++++++++++++++++- + drivers/input/mouse/synaptics.h | 8 ++------ + 2 files changed, 23 insertions(+), 7 deletions(-) + +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -618,6 +618,8 @@ static void synaptics_parse_agm(const un + priv->agm_pending = true; + } + ++static bool is_forcepad; ++ + static int synaptics_parse_hw_state(const unsigned char buf[], + struct synaptics_data *priv, + struct synaptics_hw_state *hw) +@@ -647,7 +649,7 @@ static int synaptics_parse_hw_state(cons + hw->left = (buf[0] & 0x01) ? 1 : 0; + hw->right = (buf[0] & 0x02) ? 1 : 0; + +- if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) { ++ if (is_forcepad) { + /* + * ForcePads, like Clickpads, use middle button + * bits to report primary button clicks. +@@ -1678,11 +1680,29 @@ static const struct dmi_system_id __init + { } + }; + ++static const struct dmi_system_id forcepad_dmi_table[] __initconst = { ++#if defined(CONFIG_DMI) && defined(CONFIG_X86) ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook Folio 1040 G1"), ++ }, ++ }, ++#endif ++ { } ++}; ++ + void __init synaptics_module_init(void) + { + impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); + broken_olpc_ec = dmi_check_system(olpc_dmi_table); + cr48_profile_sensor = dmi_check_system(cr48_dmi_table); ++ ++ /* ++ * Unfortunately ForcePad capability is not exported over PS/2, ++ * so we have to resort to checking DMI. ++ */ ++ is_forcepad = dmi_check_system(forcepad_dmi_table); + } + + static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) +--- a/drivers/input/mouse/synaptics.h ++++ b/drivers/input/mouse/synaptics.h +@@ -77,12 +77,9 @@ + * for noise. + * 2 0x08 image sensor image sensor tracks 5 fingers, but only + * reports 2. ++ * 2 0x01 uniform clickpad whole clickpad moves instead of being ++ * hinged at the top. + * 2 0x20 report min query 0x0f gives min coord reported +- * 2 0x80 forcepad forcepad is a variant of clickpad that +- * does not have physical buttons but rather +- * uses pressure above certain threshold to +- * report primary clicks. Forcepads also have +- * clickpad bit set. + */ + #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ + #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ +@@ -91,7 +88,6 @@ + #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) + #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) + #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) +-#define SYN_CAP_FORCEPAD(ex0c) ((ex0c) & 0x008000) + + /* synaptics modes query bits */ + #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) diff --git a/queue-3.17/iommu-amd-split-init_iommu_group-from-iommu_init_device.patch b/queue-3.17/iommu-amd-split-init_iommu_group-from-iommu_init_device.patch new file mode 100644 index 00000000000..76d53773017 --- /dev/null +++ b/queue-3.17/iommu-amd-split-init_iommu_group-from-iommu_init_device.patch @@ -0,0 +1,90 @@ +From 25b11ce2a3607d7c39a2ca121eea0c67c722b34e Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Fri, 19 Sep 2014 10:03:13 -0600 +Subject: iommu/amd: Split init_iommu_group() from iommu_init_device() + +From: Alex Williamson + +commit 25b11ce2a3607d7c39a2ca121eea0c67c722b34e upstream. + +For a PCI device, aliases from the IVRS table won't be populated +into dma_alias_devfn until after iommu_init_device() is called on +each device. We therefore want to split init_iommu_group() to +be called from a separate loop immediately following. + +Signed-off-by: Alex Williamson +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu.c | 27 +++++++++++++-------------- + 1 file changed, 13 insertions(+), 14 deletions(-) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -260,17 +260,13 @@ static bool check_device(struct device * + return true; + } + +-static int init_iommu_group(struct device *dev) ++static void init_iommu_group(struct device *dev) + { + struct iommu_group *group; + + group = iommu_group_get_for_dev(dev); +- +- if (IS_ERR(group)) +- return PTR_ERR(group); +- +- iommu_group_put(group); +- return 0; ++ if (!IS_ERR(group)) ++ iommu_group_put(group); + } + + static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) +@@ -340,7 +336,6 @@ static int iommu_init_device(struct devi + struct pci_dev *pdev = to_pci_dev(dev); + struct iommu_dev_data *dev_data; + u16 alias; +- int ret; + + if (dev->archdata.iommu) + return 0; +@@ -364,12 +359,6 @@ static int iommu_init_device(struct devi + dev_data->alias_data = alias_data; + } + +- ret = init_iommu_group(dev); +- if (ret) { +- free_dev_data(dev_data); +- return ret; +- } +- + if (pci_iommuv2_capable(pdev)) { + struct amd_iommu *iommu; + +@@ -455,6 +444,15 @@ int __init amd_iommu_init_devices(void) + goto out_free; + } + ++ /* ++ * Initialize IOMMU groups only after iommu_init_device() has ++ * had a chance to populate any IVRS defined aliases. ++ */ ++ for_each_pci_dev(pdev) { ++ if (check_device(&pdev->dev)) ++ init_iommu_group(&pdev->dev); ++ } ++ + return 0; + + out_free: +@@ -2415,6 +2413,7 @@ static int device_change_notifier(struct + case BUS_NOTIFY_ADD_DEVICE: + + iommu_init_device(dev); ++ init_iommu_group(dev); + + /* + * dev_data is still NULL and diff --git a/queue-3.17/iommu-rework-iommu_group_get_for_pci_dev.patch b/queue-3.17/iommu-rework-iommu_group_get_for_pci_dev.patch new file mode 100644 index 00000000000..a8d6dc5a213 --- /dev/null +++ b/queue-3.17/iommu-rework-iommu_group_get_for_pci_dev.patch @@ -0,0 +1,243 @@ +From f096c061f5525d1b35a65b793057b52061dcb486 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Fri, 19 Sep 2014 10:03:06 -0600 +Subject: iommu: Rework iommu_group_get_for_pci_dev() + +From: Alex Williamson + +commit f096c061f5525d1b35a65b793057b52061dcb486 upstream. + +It turns out that our assumption that aliases are always to the same +slot isn't true. One particular platform reports an IVRS alias of the +SATA controller (00:11.0) for the legacy IDE controller (00:14.1). +When we hit this, we attempt to use a single IOMMU group for +everything on the same bus, which in this case is the root complex. +We already have multiple groups defined for the root complex by this +point, resulting in multiple WARN_ON hits. + +This patch makes these sorts of aliases work again with IOMMU groups +by reworking how we search through the PCI address space to find +existing groups. This should also now handle looped dependencies and +all sorts of crazy inter-dependencies that we'll likely never see. + +The recursion used here should never be very deep. It's unlikely to +have individual aliases and only theoretical that we'd ever see a +chain where one alias causes us to search through to yet another +alias. We're also only dealing with PCIe device on a single bus, +which means we'll typically only see multiple slots in use on the root +complex. Loops are also a theoretically possibility, which I've +tested using fake DMA alias quirks and prevent from causing problems +using a bitmap of the devfn space that's been visited. + +Signed-off-by: Alex Williamson +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/iommu.c | 163 +++++++++++++++++++++++++++++--------------------- + 1 file changed, 96 insertions(+), 67 deletions(-) + +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + + static struct kset *iommu_group_kset; +@@ -519,6 +520,9 @@ int iommu_group_id(struct iommu_group *g + } + EXPORT_SYMBOL_GPL(iommu_group_id); + ++static struct iommu_group *get_pci_alias_group(struct pci_dev *pdev, ++ unsigned long *devfns); ++ + /* + * To consider a PCI device isolated, we require ACS to support Source + * Validation, Request Redirection, Completer Redirection, and Upstream +@@ -529,6 +533,86 @@ EXPORT_SYMBOL_GPL(iommu_group_id); + */ + #define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) + ++/* ++ * For multifunction devices which are not isolated from each other, find ++ * all the other non-isolated functions and look for existing groups. For ++ * each function, we also need to look for aliases to or from other devices ++ * that may already have a group. ++ */ ++static struct iommu_group *get_pci_function_alias_group(struct pci_dev *pdev, ++ unsigned long *devfns) ++{ ++ struct pci_dev *tmp = NULL; ++ struct iommu_group *group; ++ ++ if (!pdev->multifunction || pci_acs_enabled(pdev, REQ_ACS_FLAGS)) ++ return NULL; ++ ++ for_each_pci_dev(tmp) { ++ if (tmp == pdev || tmp->bus != pdev->bus || ++ PCI_SLOT(tmp->devfn) != PCI_SLOT(pdev->devfn) || ++ pci_acs_enabled(tmp, REQ_ACS_FLAGS)) ++ continue; ++ ++ group = get_pci_alias_group(tmp, devfns); ++ if (group) { ++ pci_dev_put(tmp); ++ return group; ++ } ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Look for aliases to or from the given device for exisiting groups. The ++ * dma_alias_devfn only supports aliases on the same bus, therefore the search ++ * space is quite small (especially since we're really only looking at pcie ++ * device, and therefore only expect multiple slots on the root complex or ++ * downstream switch ports). It's conceivable though that a pair of ++ * multifunction devices could have aliases between them that would cause a ++ * loop. To prevent this, we use a bitmap to track where we've been. ++ */ ++static struct iommu_group *get_pci_alias_group(struct pci_dev *pdev, ++ unsigned long *devfns) ++{ ++ struct pci_dev *tmp = NULL; ++ struct iommu_group *group; ++ ++ if (test_and_set_bit(pdev->devfn & 0xff, devfns)) ++ return NULL; ++ ++ group = iommu_group_get(&pdev->dev); ++ if (group) ++ return group; ++ ++ for_each_pci_dev(tmp) { ++ if (tmp == pdev || tmp->bus != pdev->bus) ++ continue; ++ ++ /* We alias them or they alias us */ ++ if (((pdev->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) && ++ pdev->dma_alias_devfn == tmp->devfn) || ++ ((tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) && ++ tmp->dma_alias_devfn == pdev->devfn)) { ++ ++ group = get_pci_alias_group(tmp, devfns); ++ if (group) { ++ pci_dev_put(tmp); ++ return group; ++ } ++ ++ group = get_pci_function_alias_group(tmp, devfns); ++ if (group) { ++ pci_dev_put(tmp); ++ return group; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ + struct group_for_pci_data { + struct pci_dev *pdev; + struct iommu_group *group; +@@ -557,7 +641,7 @@ static struct iommu_group *iommu_group_g + struct group_for_pci_data data; + struct pci_bus *bus; + struct iommu_group *group = NULL; +- struct pci_dev *tmp; ++ u64 devfns[4] = { 0 }; + + /* + * Find the upstream DMA alias for the device. A device must not +@@ -591,76 +675,21 @@ static struct iommu_group *iommu_group_g + } + + /* +- * Next we need to consider DMA alias quirks. If one device aliases +- * to another, they should be grouped together. It's theoretically +- * possible that aliases could create chains of devices where each +- * device aliases another device. If we then factor in multifunction +- * ACS grouping requirements, each alias could incorporate a new slot +- * with multiple functions, each with aliases. This is all extremely +- * unlikely as DMA alias quirks are typically only used for PCIe +- * devices where we usually have a single slot per bus. Furthermore, +- * the alias quirk is usually to another function within the slot +- * (and ACS multifunction is not supported) or to a different slot +- * that doesn't physically exist. The likely scenario is therefore +- * that everything on the bus gets grouped together. To reduce the +- * problem space, share the IOMMU group for all devices on the bus +- * if a DMA alias quirk is present on the bus. +- */ +- tmp = NULL; +- for_each_pci_dev(tmp) { +- if (tmp->bus != pdev->bus || +- !(tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN)) +- continue; +- +- pci_dev_put(tmp); +- tmp = NULL; +- +- /* We have an alias quirk, search for an existing group */ +- for_each_pci_dev(tmp) { +- struct iommu_group *group_tmp; +- +- if (tmp->bus != pdev->bus) +- continue; +- +- group_tmp = iommu_group_get(&tmp->dev); +- if (!group) { +- group = group_tmp; +- continue; +- } +- +- if (group_tmp) { +- WARN_ON(group != group_tmp); +- iommu_group_put(group_tmp); +- } +- } +- +- return group ? group : iommu_group_alloc(); +- } +- +- /* +- * Non-multifunction devices or multifunction devices supporting +- * ACS get their own group. ++ * Look for existing groups on device aliases. If we alias another ++ * device or another device aliases us, use the same group. + */ +- if (!pdev->multifunction || pci_acs_enabled(pdev, REQ_ACS_FLAGS)) +- return iommu_group_alloc(); ++ group = get_pci_alias_group(pdev, (unsigned long *)devfns); ++ if (group) ++ return group; + + /* +- * Multifunction devices not supporting ACS share a group with other +- * similar devices in the same slot. ++ * Look for existing groups on non-isolated functions on the same ++ * slot and aliases of those funcions, if any. No need to clear ++ * the search bitmap, the tested devfns are still valid. + */ +- tmp = NULL; +- for_each_pci_dev(tmp) { +- if (tmp == pdev || tmp->bus != pdev->bus || +- PCI_SLOT(tmp->devfn) != PCI_SLOT(pdev->devfn) || +- pci_acs_enabled(tmp, REQ_ACS_FLAGS)) +- continue; +- +- group = iommu_group_get(&tmp->dev); +- if (group) { +- pci_dev_put(tmp); +- return group; +- } +- } ++ group = get_pci_function_alias_group(pdev, (unsigned long *)devfns); ++ if (group) ++ return group; + + /* No shared group found, allocate new */ + return iommu_group_alloc(); diff --git a/queue-3.17/mfd-rtsx_pcr-fix-msi-enable-error-handling.patch b/queue-3.17/mfd-rtsx_pcr-fix-msi-enable-error-handling.patch new file mode 100644 index 00000000000..e735225a0ff --- /dev/null +++ b/queue-3.17/mfd-rtsx_pcr-fix-msi-enable-error-handling.patch @@ -0,0 +1,37 @@ +From 5152970538a5e16c03bbcb9f1c780489a795ed40 Mon Sep 17 00:00:00 2001 +From: Chris Ball +Date: Thu, 4 Sep 2014 17:11:53 +0100 +Subject: mfd: rtsx_pcr: Fix MSI enable error handling + +From: Chris Ball + +commit 5152970538a5e16c03bbcb9f1c780489a795ed40 upstream. + +pci_enable_msi() can return failure with both positive and negative +integers -- it returns 0 for success -- but is only tested here for +"if (ret < 0)". This causes us to try to use MSI on the RTS5249 SD +reader in the Dell XPS 11 when enabling MSI failed, causing: + +[ 1.737110] rtsx_pci: probe of 0000:05:00.0 failed with error -110 + +Reported-by: D. Jared Dominguez +Tested-by: D. Jared Dominguez +Signed-off-by: Chris Ball +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/rtsx_pcr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mfd/rtsx_pcr.c ++++ b/drivers/mfd/rtsx_pcr.c +@@ -1197,7 +1197,7 @@ static int rtsx_pci_probe(struct pci_dev + pcr->msi_en = msi_en; + if (pcr->msi_en) { + ret = pci_enable_msi(pcidev); +- if (ret < 0) ++ if (ret) + pcr->msi_en = false; + } + diff --git a/queue-3.17/mfd-ti_am335x_tscadc-fix-tsc-operation-after-adc-continouous-mode.patch b/queue-3.17/mfd-ti_am335x_tscadc-fix-tsc-operation-after-adc-continouous-mode.patch new file mode 100644 index 00000000000..89ef728a423 --- /dev/null +++ b/queue-3.17/mfd-ti_am335x_tscadc-fix-tsc-operation-after-adc-continouous-mode.patch @@ -0,0 +1,46 @@ +From 6ac734d2242949f41eb1346ca0fd4ed010c937aa Mon Sep 17 00:00:00 2001 +From: Vignesh R +Date: Mon, 1 Sep 2014 12:01:06 +0530 +Subject: mfd: ti_am335x_tscadc: Fix TSC operation after ADC continouous mode + +From: Vignesh R + +commit 6ac734d2242949f41eb1346ca0fd4ed010c937aa upstream. + +After enabling and disabling ADC continuous mode via sysfs, ts_print_raw +fails to return any data. This is because when ADC is configured for +continuous mode, it disables touch screen steps.These steps are not +re-enabled when ADC continuous mode is disabled. Therefore existing values +of REG_SE needs to be cached before enabling continuous mode and +disabling touch screen steps and enabling ADC steps. The cached value +are to be restored to REG_SE once ADC is disabled. + +Fixes: 7ca6740cd1cd ("mfd: input: iio: ti_amm335x: Rework TSC/ADC synchronization") + +Signed-off-by: Vignesh R +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/ti_am335x_tscadc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mfd/ti_am335x_tscadc.c ++++ b/drivers/mfd/ti_am335x_tscadc.c +@@ -53,7 +53,7 @@ void am335x_tsc_se_set_cache(struct ti_t + unsigned long flags; + + spin_lock_irqsave(&tsadc->reg_lock, flags); +- tsadc->reg_se_cache = val; ++ tsadc->reg_se_cache |= val; + if (tsadc->adc_waiting) + wake_up(&tsadc->reg_se_wait); + else if (!tsadc->adc_in_use) +@@ -96,6 +96,7 @@ static void am335x_tscadc_need_adc(struc + void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val) + { + spin_lock_irq(&tsadc->reg_lock); ++ tsadc->reg_se_cache |= val; + am335x_tscadc_need_adc(tsadc); + + tscadc_writel(tsadc, REG_SE, val); diff --git a/queue-3.17/mfd-ti_am335x_tscadc-fix-tsc-resume.patch b/queue-3.17/mfd-ti_am335x_tscadc-fix-tsc-resume.patch new file mode 100644 index 00000000000..c27bc44223a --- /dev/null +++ b/queue-3.17/mfd-ti_am335x_tscadc-fix-tsc-resume.patch @@ -0,0 +1,38 @@ +From 6a71f38dd87f255a0586104ce2a14d5a3ddf3401 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Mon, 8 Sep 2014 15:28:42 +0200 +Subject: mfd: ti_am335x_tscadc: Fix TSC resume + +From: Sebastian Andrzej Siewior + +commit 6a71f38dd87f255a0586104ce2a14d5a3ddf3401 upstream. + +In the resume path, the ADC invokes am335x_tsc_se_set_cache() with 0 as +the steps argument if continous mode is not in use. This in turn disables +all steps and so the TSC is not working until one ADC sampling is +performed. + +This patch fixes it by writing the current cached mask instead of the +passed steps. + +Fixes: 7ca6740cd1cd ("mfd: input: iio: ti_amm335x: Rework TSC/ADCA +synchronization") +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/ti_am335x_tscadc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mfd/ti_am335x_tscadc.c ++++ b/drivers/mfd/ti_am335x_tscadc.c +@@ -57,7 +57,7 @@ void am335x_tsc_se_set_cache(struct ti_t + if (tsadc->adc_waiting) + wake_up(&tsadc->reg_se_wait); + else if (!tsadc->adc_in_use) +- tscadc_writel(tsadc, REG_SE, val); ++ tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache); + + spin_unlock_irqrestore(&tsadc->reg_lock, flags); + } diff --git a/queue-3.17/mnt-prevent-pivot_root-from-creating-a-loop-in-the-mount-tree.patch b/queue-3.17/mnt-prevent-pivot_root-from-creating-a-loop-in-the-mount-tree.patch new file mode 100644 index 00000000000..c3935435fae --- /dev/null +++ b/queue-3.17/mnt-prevent-pivot_root-from-creating-a-loop-in-the-mount-tree.patch @@ -0,0 +1,47 @@ +From 0d0826019e529f21c84687521d03f60cd241ca7d Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Wed, 8 Oct 2014 10:42:27 -0700 +Subject: mnt: Prevent pivot_root from creating a loop in the mount tree + +From: "Eric W. Biederman" + +commit 0d0826019e529f21c84687521d03f60cd241ca7d upstream. + +Andy Lutomirski recently demonstrated that when chroot is used to set +the root path below the path for the new ``root'' passed to pivot_root +the pivot_root system call succeeds and leaks mounts. + +In examining the code I see that starting with a new root that is +below the current root in the mount tree will result in a loop in the +mount tree after the mounts are detached and then reattached to one +another. Resulting in all kinds of ugliness including a leak of that +mounts involved in the leak of the mount loop. + +Prevent this problem by ensuring that the new mount is reachable from +the current root of the mount tree. + +[Added stable cc. Fixes CVE-2014-7970. --Andy] + +Reported-by: Andy Lutomirski +Reviewed-by: Andy Lutomirski +Link: http://lkml.kernel.org/r/87bnpmihks.fsf@x220.int.ebiederm.org +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Andy Lutomirski +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -2822,6 +2822,9 @@ SYSCALL_DEFINE2(pivot_root, const char _ + /* make sure we can reach put_old from new_root */ + if (!is_path_reachable(old_mnt, old.dentry, &new)) + goto out4; ++ /* make certain new is below the root */ ++ if (!is_path_reachable(new_mnt, new.dentry, &root)) ++ goto out4; + root_mp->m_count++; /* pin it so it won't go away */ + lock_mount_hash(); + detach_mnt(new_mnt, &parent_path); diff --git a/queue-3.17/modules-lock-around-setting-of-module_state_unformed.patch b/queue-3.17/modules-lock-around-setting-of-module_state_unformed.patch new file mode 100644 index 00000000000..56600ac4bc3 --- /dev/null +++ b/queue-3.17/modules-lock-around-setting-of-module_state_unformed.patch @@ -0,0 +1,168 @@ +From d3051b489aa81ca9ba62af366149ef42b8dae97c Mon Sep 17 00:00:00 2001 +From: Prarit Bhargava +Date: Tue, 14 Oct 2014 02:51:39 +1030 +Subject: modules, lock around setting of MODULE_STATE_UNFORMED + +From: Prarit Bhargava + +commit d3051b489aa81ca9ba62af366149ef42b8dae97c upstream. + +A panic was seen in the following sitation. + +There are two threads running on the system. The first thread is a system +monitoring thread that is reading /proc/modules. The second thread is +loading and unloading a module (in this example I'm using my simple +dummy-module.ko). Note, in the "real world" this occurred with the qlogic +driver module. + +When doing this, the following panic occurred: + + ------------[ cut here ]------------ + kernel BUG at kernel/module.c:3739! + invalid opcode: 0000 [#1] SMP + Modules linked in: binfmt_misc sg nfsv3 rpcsec_gss_krb5 nfsv4 dns_resolver nfs fscache intel_powerclamp coretemp kvm_intel kvm crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel lrw igb gf128mul glue_helper iTCO_wdt iTCO_vendor_support ablk_helper ptp sb_edac cryptd pps_core edac_core shpchp i2c_i801 pcspkr wmi lpc_ich ioatdma mfd_core dca ipmi_si nfsd ipmi_msghandler auth_rpcgss nfs_acl lockd sunrpc xfs libcrc32c sr_mod cdrom sd_mod crc_t10dif crct10dif_common mgag200 syscopyarea sysfillrect sysimgblt i2c_algo_bit drm_kms_helper ttm isci drm libsas ahci libahci scsi_transport_sas libata i2c_core dm_mirror dm_region_hash dm_log dm_mod [last unloaded: dummy_module] + CPU: 37 PID: 186343 Comm: cat Tainted: GF O-------------- 3.10.0+ #7 + Hardware name: Intel Corporation S2600CP/S2600CP, BIOS RMLSDP.86I.00.29.D696.1311111329 11/11/2013 + task: ffff8807fd2d8000 ti: ffff88080fa7c000 task.ti: ffff88080fa7c000 + RIP: 0010:[] [] module_flags+0xb5/0xc0 + RSP: 0018:ffff88080fa7fe18 EFLAGS: 00010246 + RAX: 0000000000000003 RBX: ffffffffa03b5200 RCX: 0000000000000000 + RDX: 0000000000001000 RSI: ffff88080fa7fe38 RDI: ffffffffa03b5000 + RBP: ffff88080fa7fe28 R08: 0000000000000010 R09: 0000000000000000 + R10: 0000000000000000 R11: 000000000000000f R12: ffffffffa03b5000 + R13: ffffffffa03b5008 R14: ffffffffa03b5200 R15: ffffffffa03b5000 + FS: 00007f6ae57ef740(0000) GS:ffff88101e7a0000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000404f70 CR3: 0000000ffed48000 CR4: 00000000001407e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + Stack: + ffffffffa03b5200 ffff8810101e4800 ffff88080fa7fe70 ffffffff810d666c + ffff88081e807300 000000002e0f2fbf 0000000000000000 ffff88100f257b00 + ffffffffa03b5008 ffff88080fa7ff48 ffff8810101e4800 ffff88080fa7fee0 + Call Trace: + [] m_show+0x19c/0x1e0 + [] seq_read+0x16e/0x3b0 + [] proc_reg_read+0x3d/0x80 + [] vfs_read+0x9c/0x170 + [] SyS_read+0x58/0xb0 + [] system_call_fastpath+0x16/0x1b + Code: 48 63 c2 83 c2 01 c6 04 03 29 48 63 d2 eb d9 0f 1f 80 00 00 00 00 48 63 d2 c6 04 13 2d 41 8b 0c 24 8d 50 02 83 f9 01 75 b2 eb cb <0f> 0b 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 41 + RIP [] module_flags+0xb5/0xc0 + RSP + + Consider the two processes running on the system. + + CPU 0 (/proc/modules reader) + CPU 1 (loading/unloading module) + + CPU 0 opens /proc/modules, and starts displaying data for each module by + traversing the modules list via fs/seq_file.c:seq_open() and + fs/seq_file.c:seq_read(). For each module in the modules list, seq_read + does + + op->start() <-- this is a pointer to m_start() + op->show() <- this is a pointer to m_show() + op->stop() <-- this is a pointer to m_stop() + + The m_start(), m_show(), and m_stop() module functions are defined in + kernel/module.c. The m_start() and m_stop() functions acquire and release + the module_mutex respectively. + + ie) When reading /proc/modules, the module_mutex is acquired and released + for each module. + + m_show() is called with the module_mutex held. It accesses the module + struct data and attempts to write out module data. It is in this code + path that the above BUG_ON() warning is encountered, specifically m_show() + calls + + static char *module_flags(struct module *mod, char *buf) + { + int bx = 0; + + BUG_ON(mod->state == MODULE_STATE_UNFORMED); + ... + + The other thread, CPU 1, in unloading the module calls the syscall + delete_module() defined in kernel/module.c. The module_mutex is acquired + for a short time, and then released. free_module() is called without the + module_mutex. free_module() then sets mod->state = MODULE_STATE_UNFORMED, + also without the module_mutex. Some additional code is called and then the + module_mutex is reacquired to remove the module from the modules list: + + /* Now we can delete it from the lists */ + mutex_lock(&module_mutex); + stop_machine(__unlink_module, mod, NULL); + mutex_unlock(&module_mutex); + +This is the sequence of events that leads to the panic. + +CPU 1 is removing dummy_module via delete_module(). It acquires the +module_mutex, and then releases it. CPU 1 has NOT set dummy_module->state to +MODULE_STATE_UNFORMED yet. + +CPU 0, which is reading the /proc/modules, acquires the module_mutex and +acquires a pointer to the dummy_module which is still in the modules list. +CPU 0 calls m_show for dummy_module. The check in m_show() for +MODULE_STATE_UNFORMED passed for dummy_module even though it is being +torn down. + +Meanwhile CPU 1, which has been continuing to remove dummy_module without +holding the module_mutex, now calls free_module() and sets +dummy_module->state to MODULE_STATE_UNFORMED. + +CPU 0 now calls module_flags() with dummy_module and ... + +static char *module_flags(struct module *mod, char *buf) +{ + int bx = 0; + + BUG_ON(mod->state == MODULE_STATE_UNFORMED); + +and BOOM. + +Acquire and release the module_mutex lock around the setting of +MODULE_STATE_UNFORMED in the teardown path, which should resolve the +problem. + +Testing: In the unpatched kernel I can panic the system within 1 minute by +doing + +while (true) do insmod dummy_module.ko; rmmod dummy_module.ko; done + +and + +while (true) do cat /proc/modules; done + +in separate terminals. + +In the patched kernel I was able to run just over one hour without seeing +any issues. I also verified the output of panic via sysrq-c and the output +of /proc/modules looks correct for all three states for the dummy_module. + + dummy_module 12661 0 - Unloading 0xffffffffa03a5000 (OE-) + dummy_module 12661 0 - Live 0xffffffffa03bb000 (OE) + dummy_module 14015 1 - Loading 0xffffffffa03a5000 (OE+) + +Signed-off-by: Prarit Bhargava +Reviewed-by: Oleg Nesterov +Signed-off-by: Rusty Russell +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/module.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -1842,7 +1842,9 @@ static void free_module(struct module *m + + /* We leave it in list to prevent duplicate loads, but make sure + * that noone uses it while it's being deconstructed. */ ++ mutex_lock(&module_mutex); + mod->state = MODULE_STATE_UNFORMED; ++ mutex_unlock(&module_mutex); + + /* Remove dynamic debug info */ + ddebug_remove_module(mod->name); diff --git a/queue-3.17/power-charger-manager-fix-null-pointer-exception-with-missing-cm-fuel-gauge.patch b/queue-3.17/power-charger-manager-fix-null-pointer-exception-with-missing-cm-fuel-gauge.patch new file mode 100644 index 00000000000..1ddebfe6905 --- /dev/null +++ b/queue-3.17/power-charger-manager-fix-null-pointer-exception-with-missing-cm-fuel-gauge.patch @@ -0,0 +1,87 @@ +From 661a88860274e059fdb744dfaa98c045db7b5d1d Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 26 Sep 2014 13:27:03 +0200 +Subject: power: charger-manager: Fix NULL pointer exception with missing cm-fuel-gauge + +From: Krzysztof Kozlowski + +commit 661a88860274e059fdb744dfaa98c045db7b5d1d upstream. + +NULL pointer exception happens during charger-manager probe if +'cm-fuel-gauge' property is not present. + +[ 2.448536] Unable to handle kernel NULL pointer dereference at virtual address 00000000 +[ 2.456572] pgd = c0004000 +[ 2.459217] [00000000] *pgd=00000000 +[ 2.462759] Internal error: Oops: 5 [#1] PREEMPT SMP ARM +[ 2.468047] Modules linked in: +[ 2.471089] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.17.0-rc6-00251-ge44cf96cd525-dirty #969 +[ 2.479765] task: ea890000 ti: ea87a000 task.ti: ea87a000 +[ 2.485161] PC is at strcmp+0x4/0x30 +[ 2.488719] LR is at power_supply_match_device_by_name+0x10/0x1c +[ 2.494695] pc : [] lr : [] psr: a0000113 +[ 2.494695] sp : ea87bde0 ip : 00000000 fp : eaa97010 +[ 2.506150] r10: 00000004 r9 : ea97269c r8 : ea3bbfd0 +[ 2.511360] r7 : eaa97000 r6 : c030fe28 r5 : 00000000 r4 : ea3b0000 +[ 2.517869] r3 : 0000006d r2 : 00000000 r1 : 00000000 r0 : c057c195 +[ 2.524381] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel +[ 2.531671] Control: 10c5387d Table: 4000404a DAC: 00000015 +[ 2.537399] Process swapper/0 (pid: 1, stack limit = 0xea87a240) +[ 2.543388] Stack: (0xea87bde0 to 0xea87c000) +[ 2.547733] bde0: ea3b0210 c026b1c8 eaa97010 eaa97000 eaa97010 eabb60a8 ea3b0210 00000000 +[ 2.555891] be00: 00000008 ea2db210 ea1a3410 c030fee0 ea3bbf90 c03138fc c068969c c013526c +[ 2.564050] be20: eaa040c0 00000000 c068969c 00000000 eaa040c0 ea2da300 00000002 00000000 +[ 2.572208] be40: 00000001 ea2da3c0 00000000 00000001 00000000 eaa97010 c068969c 00000000 +[ 2.580367] be60: 00000000 c068969c 00000000 00000002 00000000 c026b71c c026b6f0 eaa97010 +[ 2.588527] be80: c0e82530 c026a330 00000000 eaa97010 c068969c eaa97044 00000000 c061df50 +[ 2.596686] bea0: ea87a000 c026a4dc 00000000 c068969c c026a448 c0268b5c ea8054a8 eaa8fd50 +[ 2.604845] bec0: c068969c ea2db180 c06801f8 c0269b18 c0590f68 c068969c c0656c98 c068969c +[ 2.613004] bee0: c0656c98 ea3bbe40 c06988c0 c026aaf0 00000000 c0656c98 c0656c98 c00088a4 +[ 2.621163] bf00: 00000000 c0055f48 00000000 00000004 00000000 ea890000 c05dbc54 c062c178 +[ 2.629323] bf20: c0603518 c005f674 00000001 ea87a000 eb7ff83b c0476440 00000091 c003d41c +[ 2.637482] bf40: c05db344 00000007 eb7ff858 00000007 c065a76c c0647d24 00000007 c062c170 +[ 2.645642] bf60: c06988c0 00000091 c062c178 c0603518 00000000 c0603cc4 00000007 00000007 +[ 2.653801] bf80: c0603518 c0c0c0c0 00000000 c0453948 00000000 00000000 00000000 00000000 +[ 2.661959] bfa0: 00000000 c0453950 00000000 c000e728 00000000 00000000 00000000 00000000 +[ 2.670118] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 2.678277] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 c0c0c0c0 c0c0c0c0 +[ 2.686454] [] (strcmp) from [] (power_supply_match_device_by_name+0x10/0x1c) +[ 2.695303] [] (power_supply_match_device_by_name) from [] (class_find_device+0x54/0xac) +[ 2.705106] [] (class_find_device) from [] (power_supply_get_by_name+0x1c/0x30) +[ 2.714137] [] (power_supply_get_by_name) from [] (charger_manager_probe+0x3d8/0xe58) +[ 2.723683] [] (charger_manager_probe) from [] (platform_drv_probe+0x2c/0x5c) +[ 2.732532] [] (platform_drv_probe) from [] (driver_probe_device+0x10c/0x224) +[ 2.741384] [] (driver_probe_device) from [] (__driver_attach+0x94/0x98) +[ 2.749813] [] (__driver_attach) from [] (bus_for_each_dev+0x54/0x88) +[ 2.757969] [] (bus_for_each_dev) from [] (bus_add_driver+0xd4/0x1d0) +[ 2.766123] [] (bus_add_driver) from [] (driver_register+0x78/0xf4) +[ 2.774110] [] (driver_register) from [] (do_one_initcall+0x80/0x1bc) +[ 2.782276] [] (do_one_initcall) from [] (kernel_init_freeable+0x100/0x1cc) +[ 2.790952] [] (kernel_init_freeable) from [] (kernel_init+0x8/0xec) +[ 2.799029] [] (kernel_init) from [] (ret_from_fork+0x14/0x2c) +[ 2.806572] Code: e12fff1e e1a03000 eafffff7 e4d03001 (e4d12001) +[ 2.812832] ---[ end trace 7f12556111b9e7ef ]--- + +Signed-off-by: Krzysztof Kozlowski +Fixes: 856ee6115e2d ("charger-manager: Support deivce tree in charger manager driver") +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/charger-manager.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/power/charger-manager.c ++++ b/drivers/power/charger-manager.c +@@ -1720,6 +1720,11 @@ static int charger_manager_probe(struct + return -EINVAL; + } + ++ if (!desc->psy_fuel_gauge) { ++ dev_err(&pdev->dev, "No fuel gauge power supply defined\n"); ++ return -EINVAL; ++ } ++ + /* Counting index only */ + while (desc->psy_charger_stat[i]) + i++; diff --git a/queue-3.17/pstore-fix-duplicate-console-ftrace-efi-entries.patch b/queue-3.17/pstore-fix-duplicate-console-ftrace-efi-entries.patch new file mode 100644 index 00000000000..a1ae7e2c33d --- /dev/null +++ b/queue-3.17/pstore-fix-duplicate-console-ftrace-efi-entries.patch @@ -0,0 +1,64 @@ +From d4bf205da618bbd0b038e404d646f14e76915718 Mon Sep 17 00:00:00 2001 +From: Valdis Kletnieks +Date: Sun, 12 Oct 2014 23:09:08 -0400 +Subject: pstore: Fix duplicate {console,ftrace}-efi entries + +From: Valdis Kletnieks + +commit d4bf205da618bbd0b038e404d646f14e76915718 upstream. + +The pstore filesystem still creates duplicate filename/inode pairs for +some pstore types. Add the id to the filename to prevent that. + +Before patch: + +[/sys/fs/pstore] ls -li +total 0 +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi +1250 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi + +After: + +[/sys/fs/pstore] ls -li +total 0 +1232 -r--r--r--. 1 root root 148 Sep 29 17:09 console-efi-141202499100000 +1231 -r--r--r--. 1 root root 67 Sep 29 17:09 console-efi-141202499200000 +1230 -r--r--r--. 1 root root 148 Sep 29 17:44 console-efi-141202705400000 +1229 -r--r--r--. 1 root root 67 Sep 29 17:44 console-efi-141202705500000 +1228 -r--r--r--. 1 root root 67 Sep 29 20:42 console-efi-141203772600000 +1227 -r--r--r--. 1 root root 148 Sep 29 23:42 console-efi-141204854900000 +1226 -r--r--r--. 1 root root 67 Sep 29 23:42 console-efi-141204855000000 +1225 -r--r--r--. 1 root root 148 Sep 29 23:59 console-efi-141204954200000 +1224 -r--r--r--. 1 root root 67 Sep 29 23:59 console-efi-141204954400000 + +Signed-off-by: Valdis Kletnieks +Acked-by: Kees Cook +Signed-off-by: Tony Luck +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/inode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/pstore/inode.c ++++ b/fs/pstore/inode.c +@@ -320,10 +320,10 @@ int pstore_mkfile(enum pstore_type_id ty + compressed ? ".enc.z" : ""); + break; + case PSTORE_TYPE_CONSOLE: +- sprintf(name, "console-%s", psname); ++ sprintf(name, "console-%s-%lld", psname, id); + break; + case PSTORE_TYPE_FTRACE: +- sprintf(name, "ftrace-%s", psname); ++ sprintf(name, "ftrace-%s-%lld", psname, id); + break; + case PSTORE_TYPE_MCE: + sprintf(name, "mce-%s-%lld", psname, id); diff --git a/queue-3.17/revert-block-all-blk-mq-requests-are-tagged.patch b/queue-3.17/revert-block-all-blk-mq-requests-are-tagged.patch new file mode 100644 index 00000000000..1e441bfd7e8 --- /dev/null +++ b/queue-3.17/revert-block-all-blk-mq-requests-are-tagged.patch @@ -0,0 +1,38 @@ +From e999dbc254044e8d2a5818d92d205f65bae28f37 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Sun, 19 Oct 2014 17:13:57 +0200 +Subject: Revert "block: all blk-mq requests are tagged" + +From: Christoph Hellwig + +commit e999dbc254044e8d2a5818d92d205f65bae28f37 upstream. + +This reverts commit fb3ccb5da71273e7f0d50b50bc879e50cedd60e7. + +SCSI-2/SPI actually needs the tagged/untagged flag in the request to +work properly. Revert this patch and add a follow on to set it in +the right place. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Martin K. Petersen +Acked-by: Jens Axboe +Reported-by: Meelis Roos +Tested-by: Meelis Roos +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/blkdev.h | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -1142,8 +1142,7 @@ static inline bool blk_needs_flush_plug( + /* + * tag stuff + */ +-#define blk_rq_tagged(rq) \ +- ((rq)->mq_ctx || ((rq)->cmd_flags & REQ_QUEUED)) ++#define blk_rq_tagged(rq) ((rq)->cmd_flags & REQ_QUEUED) + extern int blk_queue_start_tag(struct request_queue *, struct request *); + extern struct request *blk_queue_find_tag(struct request_queue *, int); + extern void blk_queue_end_tag(struct request_queue *, struct request *); diff --git a/queue-3.17/s390-topology-call-set_sched_topology-early.patch b/queue-3.17/s390-topology-call-set_sched_topology-early.patch new file mode 100644 index 00000000000..e24e2ed5b87 --- /dev/null +++ b/queue-3.17/s390-topology-call-set_sched_topology-early.patch @@ -0,0 +1,49 @@ +From 48e9a6c1f54695609b709bf674aac133794ada00 Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Wed, 24 Sep 2014 16:37:20 +0200 +Subject: s390/topology: call set_sched_topology early + +From: Martin Schwidefsky + +commit 48e9a6c1f54695609b709bf674aac133794ada00 upstream. + +The call to topology_init is too late for the set_sched_topology call. +The initial scheduling domain structure has already been established +with default topology array. Use the smp_cpus_done() call to get the +s390 specific topology array registered early enough. + +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/kernel/topology.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/arch/s390/kernel/topology.c ++++ b/arch/s390/kernel/topology.c +@@ -464,15 +464,17 @@ static struct sched_domain_topology_leve + + static int __init topology_init(void) + { +- if (!MACHINE_HAS_TOPOLOGY) { ++ if (MACHINE_HAS_TOPOLOGY) ++ set_topology_timer(); ++ else + topology_update_polarization_simple(); +- goto out; +- } +- set_topology_timer(); +-out: +- +- set_sched_topology(s390_topology); +- + return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); + } + device_initcall(topology_init); ++ ++static int __init early_topology_init(void) ++{ ++ set_sched_topology(s390_topology); ++ return 0; ++} ++early_initcall(early_topology_init); diff --git a/queue-3.17/selinux-fix-inode-security-list-corruption.patch b/queue-3.17/selinux-fix-inode-security-list-corruption.patch new file mode 100644 index 00000000000..cba7bdf6df3 --- /dev/null +++ b/queue-3.17/selinux-fix-inode-security-list-corruption.patch @@ -0,0 +1,59 @@ +From 923190d32de4428afbea5e5773be86bea60a9925 Mon Sep 17 00:00:00 2001 +From: Stephen Smalley +Date: Mon, 6 Oct 2014 16:32:52 -0400 +Subject: selinux: fix inode security list corruption + +From: Stephen Smalley + +commit 923190d32de4428afbea5e5773be86bea60a9925 upstream. + +sb_finish_set_opts() can race with inode_free_security() +when initializing inode security structures for inodes +created prior to initial policy load or by the filesystem +during ->mount(). This appears to have always been +a possible race, but commit 3dc91d4 ("SELinux: Fix possible +NULL pointer dereference in selinux_inode_permission()") +made it more evident by immediately reusing the unioned +list/rcu element of the inode security structure for call_rcu() +upon an inode_free_security(). But the underlying issue +was already present before that commit as a possible use-after-free +of isec. + +Shivnandan Kumar reported the list corruption and proposed +a patch to split the list and rcu elements out of the union +as separate fields of the inode_security_struct so that setting +the rcu element would not affect the list element. However, +this would merely hide the issue and not truly fix the code. + +This patch instead moves up the deletion of the list entry +prior to dropping the sbsec->isec_lock initially. Then, +if the inode is dropped subsequently, there will be no further +references to the isec. + +Reported-by: Shivnandan Kumar +Signed-off-by: Stephen Smalley +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/hooks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -481,6 +481,7 @@ next_inode: + list_entry(sbsec->isec_head.next, + struct inode_security_struct, list); + struct inode *inode = isec->inode; ++ list_del_init(&isec->list); + spin_unlock(&sbsec->isec_lock); + inode = igrab(inode); + if (inode) { +@@ -489,7 +490,6 @@ next_inode: + iput(inode); + } + spin_lock(&sbsec->isec_lock); +- list_del_init(&isec->list); + goto next_inode; + } + spin_unlock(&sbsec->isec_lock); diff --git a/queue-3.17/series b/queue-3.17/series index d95cc7bdcec..626d95cc3ca 100644 --- a/queue-3.17/series +++ b/queue-3.17/series @@ -68,3 +68,44 @@ libceph-ceph-msgr-workqueue-needs-a-resque-worker.patch sched-use-dl_bw_of-under-rcu-read-lock.patch um-ubd-fix-for-processes-stuck-in-d-state-forever.patch random-add-and-use-memzero_explicit-for-clearing-data.patch +s390-topology-call-set_sched_topology-early.patch +ubi-block-fix-block-device-size-setting.patch +ubi-block-add-support-for-the-ubi_volume_updated-notification.patch +ubi-dispatch-update-notification-if-the-volume-is-updated.patch +ubi-add-missing-kmem_cache_free-in-process_pool_aeb-error-path.patch +mnt-prevent-pivot_root-from-creating-a-loop-in-the-mount-tree.patch +mfd-ti_am335x_tscadc-fix-tsc-operation-after-adc-continouous-mode.patch +mfd-ti_am335x_tscadc-fix-tsc-resume.patch +mfd-rtsx_pcr-fix-msi-enable-error-handling.patch +iommu-rework-iommu_group_get_for_pci_dev.patch +iommu-amd-split-init_iommu_group-from-iommu_init_device.patch +pstore-fix-duplicate-console-ftrace-efi-entries.patch +selinux-fix-inode-security-list-corruption.patch +power-charger-manager-fix-null-pointer-exception-with-missing-cm-fuel-gauge.patch +virtio_pci-fix-virtio-spec-compliance-on-restore.patch +xen-blkback-unmap-all-persistent-grants-when-frontend-gets-disconnected.patch +xen-blkback-fix-leak-on-grant-map-error-path.patch +drm-cirrus-bind-also-to-qemu-xen-traditional.patch +blk-mq-fix-potential-hang-if-rolling-wakeup-depth-is-too-high.patch +dm-bufio-update-last_accessed-when-relinking-a-buffer.patch +dm-bufio-when-done-scanning-return-from-__scan-immediately.patch +drbd-compute-the-end-before-rb_insert_augmented.patch +block-fix-alignment_offset-math-that-assumes-io_min-is-a-power-of-2.patch +revert-block-all-blk-mq-requests-are-tagged.patch +dm-log-userspace-fix-memory-leak-in-dm_ulog_tfr_init-failure-path.patch +modules-lock-around-setting-of-module_state_unformed.patch +framebuffer-fix-screen-corruption-when-copying.patch +framebuffer-fix-border-color.patch +input-synaptics-gate-forcepad-support-by-dmi-check.patch +input-i8042-add-noloop-quirk-for-asus-x750ln.patch +input-alps-fix-v4-button-press-recognition.patch +input-i8042-quirks-for-fujitsu-lifebook-a544-and-lifebook-ah544.patch +hid-input-fix-transducerserialnumber-implementation.patch +drm-ast-fix-hw-cursor-image.patch +drm-nouveau-gpio-rename-g92-class-to-g94.patch +drm-i915-do-not-store-the-error-pointer-for-a-failed-userptr-registration.patch +drm-i915-do-not-leak-pages-when-freeing-userptr-objects.patch +drm-vmwgfx-fix-drm.h-include.patch +drm-tilcdc-fix-the-error-path-in-tilcdc_load.patch +drm-nouveau-bios-memset-dcb-struct-to-zero-before-parsing.patch +drm-gt214-kms-fix-hda-eld-regression.patch diff --git a/queue-3.17/ubi-add-missing-kmem_cache_free-in-process_pool_aeb-error-path.patch b/queue-3.17/ubi-add-missing-kmem_cache_free-in-process_pool_aeb-error-path.patch new file mode 100644 index 00000000000..ef6c1c7e133 --- /dev/null +++ b/queue-3.17/ubi-add-missing-kmem_cache_free-in-process_pool_aeb-error-path.patch @@ -0,0 +1,48 @@ +From 1bf1890e86869032099b539bc83b098be12fc5a7 Mon Sep 17 00:00:00 2001 +From: Richard Genoud +Date: Tue, 9 Sep 2014 14:25:01 +0200 +Subject: UBI: add missing kmem_cache_free() in process_pool_aeb error path + +From: Richard Genoud + +commit 1bf1890e86869032099b539bc83b098be12fc5a7 upstream. + +I ran into this error after a ubiupdatevol, because I forgot to backport +e9110361a9a4 UBI: fix the volumes tree sorting criteria. + +UBI error: process_pool_aeb: orphaned volume in fastmap pool +UBI error: ubi_scan_fastmap: Attach by fastmap failed, doing a full scan! +kmem_cache_destroy ubi_ainf_peb_slab: Slab cache still has objects +CPU: 0 PID: 1 Comm: swapper Not tainted 3.14.18-00053-gf05cac8dbf85 #1 +[] (unwind_backtrace) from [] (show_stack+0x10/0x14) +[] (show_stack) from [] (destroy_ai+0x230/0x244) +[] (destroy_ai) from [] (ubi_attach+0x98/0x1ec) +[] (ubi_attach) from [] (ubi_attach_mtd_dev+0x2b8/0x868) +[] (ubi_attach_mtd_dev) from [] (ubi_init+0x1dc/0x2ac) +[] (ubi_init) from [] (do_one_initcall+0x94/0x140) +[] (do_one_initcall) from [] (kernel_init_freeable+0xe8/0x1b0) +[] (kernel_init_freeable) from [] (kernel_init+0x8/0xe4) +[] (kernel_init) from [] (ret_from_fork+0x14/0x24) +UBI: scanning is finished + +Freeing the cache in the error path fixes the Slab error. + +Tested on at91sam9g35 (3.14.18+fastmap backports) + +Signed-off-by: Richard Genoud +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/fastmap.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mtd/ubi/fastmap.c ++++ b/drivers/mtd/ubi/fastmap.c +@@ -330,6 +330,7 @@ static int process_pool_aeb(struct ubi_d + av = tmp_av; + else { + ubi_err("orphaned volume in fastmap pool!"); ++ kmem_cache_free(ai->aeb_slab_cache, new_aeb); + return UBI_BAD_FASTMAP; + } + diff --git a/queue-3.17/ubi-block-add-support-for-the-ubi_volume_updated-notification.patch b/queue-3.17/ubi-block-add-support-for-the-ubi_volume_updated-notification.patch new file mode 100644 index 00000000000..f501d858d9d --- /dev/null +++ b/queue-3.17/ubi-block-add-support-for-the-ubi_volume_updated-notification.patch @@ -0,0 +1,53 @@ +From 06d9c2905f745c8b1920a335cbb366ba6b0fc754 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 29 Aug 2014 18:42:29 -0300 +Subject: UBI: block: Add support for the UBI_VOLUME_UPDATED notification + +From: Ezequiel Garcia + +commit 06d9c2905f745c8b1920a335cbb366ba6b0fc754 upstream. + +Static volumes can change its 'used_bytes' when they get updated, +and so the block interface must listen to the UBI_VOLUME_UPDATED +notification to resize the block device accordingly. + +Signed-off-by: Ezequiel Garcia +Signed-off-by: Artem Bityutskiy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/block.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -523,8 +523,12 @@ static int ubiblock_resize(struct ubi_vo + } + + mutex_lock(&dev->dev_mutex); +- set_capacity(dev->gd, disk_capacity); +- ubi_msg("%s resized to %lld bytes", dev->gd->disk_name, vi->used_bytes); ++ ++ if (get_capacity(dev->gd) != disk_capacity) { ++ set_capacity(dev->gd, disk_capacity); ++ ubi_msg("%s resized to %lld bytes", dev->gd->disk_name, ++ vi->used_bytes); ++ } + mutex_unlock(&dev->dev_mutex); + mutex_unlock(&devices_mutex); + return 0; +@@ -548,6 +552,14 @@ static int ubiblock_notify(struct notifi + case UBI_VOLUME_RESIZED: + ubiblock_resize(&nt->vi); + break; ++ case UBI_VOLUME_UPDATED: ++ /* ++ * If the volume is static, a content update might mean the ++ * size (i.e. used_bytes) was also changed. ++ */ ++ if (nt->vi.vol_type == UBI_STATIC_VOLUME) ++ ubiblock_resize(&nt->vi); ++ break; + default: + break; + } diff --git a/queue-3.17/ubi-block-fix-block-device-size-setting.patch b/queue-3.17/ubi-block-fix-block-device-size-setting.patch new file mode 100644 index 00000000000..d4c0af47681 --- /dev/null +++ b/queue-3.17/ubi-block-fix-block-device-size-setting.patch @@ -0,0 +1,87 @@ +From 978d6496758d19de2431ebf163337fc7b92f8c45 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 29 Aug 2014 18:42:28 -0300 +Subject: UBI: block: Fix block device size setting + +From: Ezequiel Garcia + +commit 978d6496758d19de2431ebf163337fc7b92f8c45 upstream. + +We are currently taking the block device size from the ubi_volume_info.size +field. However, this is not the amount of data in the volume, but the +number of reserved physical eraseblocks, and hence leads to an incorrect +representation of the volume. + +In particular, this produces I/O errors on static volumes as the block +interface may attempt to read unmapped PEBs: + +$ cat /dev/ubiblock0_0 > /dev/null +UBI error: ubiblock_read_to_buf: ubiblock0_0 ubi_read error -22 +end_request: I/O error, dev ubiblock0_0, sector 9536 +Buffer I/O error on device ubiblock0_0, logical block 2384 +[snip] + +Fix this by using the ubi_volume_info.used_bytes field which is set to the +actual number of data bytes for both static and dynamic volumes. + +While here, improve the error message to be less stupid and more useful: +UBI error: ubiblock_read_to_buf: ubiblock0_1 ubi_read error -9 on LEB=0, off=15872, len=512 + +It's worth noticing that the 512-byte sector representation of the volume +is only correct if the volume size is multiple of 512-bytes. This is true for +virtually any NAND device, given eraseblocks and pages are 512-byte multiple +and hence so is the LEB size. + +Artem: tweak the error message and make it look more like other UBI error +messages. + +Fixes: 9d54c8a33eec ("UBI: R/O block driver on top of UBI volumes") +Signed-off-by: Ezequiel Garcia +Signed-off-by: Artem Bityutskiy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/block.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -188,8 +188,9 @@ static int ubiblock_read_to_buf(struct u + + ret = ubi_read(dev->desc, leb, buffer, offset, len); + if (ret) { +- ubi_err("%s ubi_read error %d", +- dev->gd->disk_name, ret); ++ ubi_err("%s: error %d while reading from LEB %d (offset %d, " ++ "length %d)", dev->gd->disk_name, ret, leb, offset, ++ len); + return ret; + } + return 0; +@@ -378,7 +379,7 @@ int ubiblock_create(struct ubi_volume_in + { + struct ubiblock *dev; + struct gendisk *gd; +- u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; ++ u64 disk_capacity = vi->used_bytes >> 9; + int ret; + + if ((sector_t)disk_capacity != disk_capacity) +@@ -502,7 +503,7 @@ int ubiblock_remove(struct ubi_volume_in + static int ubiblock_resize(struct ubi_volume_info *vi) + { + struct ubiblock *dev; +- u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; ++ u64 disk_capacity = vi->used_bytes >> 9; + + if ((sector_t)disk_capacity != disk_capacity) { + ubi_warn("%s: the volume is too big, cannot resize (%d LEBs)", +@@ -523,7 +524,7 @@ static int ubiblock_resize(struct ubi_vo + + mutex_lock(&dev->dev_mutex); + set_capacity(dev->gd, disk_capacity); +- ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size); ++ ubi_msg("%s resized to %lld bytes", dev->gd->disk_name, vi->used_bytes); + mutex_unlock(&dev->dev_mutex); + mutex_unlock(&devices_mutex); + return 0; diff --git a/queue-3.17/ubi-dispatch-update-notification-if-the-volume-is-updated.patch b/queue-3.17/ubi-dispatch-update-notification-if-the-volume-is-updated.patch new file mode 100644 index 00000000000..2ba5d7790e3 --- /dev/null +++ b/queue-3.17/ubi-dispatch-update-notification-if-the-volume-is-updated.patch @@ -0,0 +1,39 @@ +From fda322a1b3b9e8ee231913c500f73c6988b1aff5 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 29 Aug 2014 18:42:30 -0300 +Subject: UBI: Dispatch update notification if the volume is updated + +From: Ezequiel Garcia + +commit fda322a1b3b9e8ee231913c500f73c6988b1aff5 upstream. + +The UBI_IOCVOLUP ioctl is used to start an update and also to +truncate a volume. In the first case, a "volume updated" notification +is dispatched when the update is done. + +This commit adds the "volume updated" notification to be also sent when +the volume is truncated. This is required for UBI block and gluebi to get +notified about the new volume size. + +Signed-off-by: Ezequiel Garcia +Signed-off-by: Artem Bityutskiy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/cdev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/ubi/cdev.c ++++ b/drivers/mtd/ubi/cdev.c +@@ -425,8 +425,10 @@ static long vol_cdev_ioctl(struct file * + break; + + err = ubi_start_update(ubi, vol, bytes); +- if (bytes == 0) ++ if (bytes == 0) { ++ ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED); + revoke_exclusive(desc, UBI_READWRITE); ++ } + break; + } + diff --git a/queue-3.17/virtio_pci-fix-virtio-spec-compliance-on-restore.patch b/queue-3.17/virtio_pci-fix-virtio-spec-compliance-on-restore.patch new file mode 100644 index 00000000000..a0c323ad3b0 --- /dev/null +++ b/queue-3.17/virtio_pci-fix-virtio-spec-compliance-on-restore.patch @@ -0,0 +1,88 @@ +From 6fbc198cf623944ab60a1db6d306a4d55cdd820d Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Tue, 14 Oct 2014 10:40:29 +1030 +Subject: virtio_pci: fix virtio spec compliance on restore + +From: "Michael S. Tsirkin" + +commit 6fbc198cf623944ab60a1db6d306a4d55cdd820d upstream. + +On restore, virtio pci does the following: ++ set features ++ init vqs etc - device can be used at this point! ++ set ACKNOWLEDGE,DRIVER and DRIVER_OK status bits + +This is in violation of the virtio spec, which +requires the following order: +- ACKNOWLEDGE +- DRIVER +- init vqs +- DRIVER_OK + +This behaviour will break with hypervisors that assume spec compliant +behaviour. It seems like a good idea to have this patch applied to +stable branches to reduce the support butden for the hypervisors. + +Cc: Amit Shah +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Rusty Russell +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/virtio/virtio_pci.c | 33 ++++++++++++++++++++++++++++++--- + 1 file changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/virtio/virtio_pci.c ++++ b/drivers/virtio/virtio_pci.c +@@ -789,6 +789,7 @@ static int virtio_pci_restore(struct dev + struct pci_dev *pci_dev = to_pci_dev(dev); + struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); + struct virtio_driver *drv; ++ unsigned status = 0; + int ret; + + drv = container_of(vp_dev->vdev.dev.driver, +@@ -799,14 +800,40 @@ static int virtio_pci_restore(struct dev + return ret; + + pci_set_master(pci_dev); ++ /* We always start by resetting the device, in case a previous ++ * driver messed it up. */ ++ vp_reset(&vp_dev->vdev); ++ ++ /* Acknowledge that we've seen the device. */ ++ status |= VIRTIO_CONFIG_S_ACKNOWLEDGE; ++ vp_set_status(&vp_dev->vdev, status); ++ ++ /* Maybe driver failed before freeze. ++ * Restore the failed status, for debugging. */ ++ status |= vp_dev->saved_status & VIRTIO_CONFIG_S_FAILED; ++ vp_set_status(&vp_dev->vdev, status); ++ ++ if (!drv) ++ return 0; ++ ++ /* We have a driver! */ ++ status |= VIRTIO_CONFIG_S_DRIVER; ++ vp_set_status(&vp_dev->vdev, status); ++ + vp_finalize_features(&vp_dev->vdev); + +- if (drv && drv->restore) ++ if (drv->restore) { + ret = drv->restore(&vp_dev->vdev); ++ if (ret) { ++ status |= VIRTIO_CONFIG_S_FAILED; ++ vp_set_status(&vp_dev->vdev, status); ++ return ret; ++ } ++ } + + /* Finally, tell the device we're all set */ +- if (!ret) +- vp_set_status(&vp_dev->vdev, vp_dev->saved_status); ++ status |= VIRTIO_CONFIG_S_DRIVER_OK; ++ vp_set_status(&vp_dev->vdev, status); + + return ret; + } diff --git a/queue-3.17/xen-blkback-fix-leak-on-grant-map-error-path.patch b/queue-3.17/xen-blkback-fix-leak-on-grant-map-error-path.patch new file mode 100644 index 00000000000..46901ff76b9 --- /dev/null +++ b/queue-3.17/xen-blkback-fix-leak-on-grant-map-error-path.patch @@ -0,0 +1,33 @@ +From 61cecca865280bef4f8a9748d0a9afa5df351ac2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= +Date: Mon, 15 Sep 2014 11:55:27 +0200 +Subject: xen-blkback: fix leak on grant map error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= + +commit 61cecca865280bef4f8a9748d0a9afa5df351ac2 upstream. + +Fix leaking a page when a grant mapping has failed. + +Signed-off-by: Roger Pau Monné +Reported-and-Tested-by: Tao Chen +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/xen-blkback/blkback.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/block/xen-blkback/blkback.c ++++ b/drivers/block/xen-blkback/blkback.c +@@ -763,6 +763,7 @@ again: + BUG_ON(new_map_idx >= segs_to_map); + if (unlikely(map[new_map_idx].status != 0)) { + pr_debug(DRV_PFX "invalid buffer -- could not remap it\n"); ++ put_free_pages(blkif, &pages[seg_idx]->page, 1); + pages[seg_idx]->handle = BLKBACK_INVALID_HANDLE; + ret |= 1; + goto next; diff --git a/queue-3.17/xen-blkback-unmap-all-persistent-grants-when-frontend-gets-disconnected.patch b/queue-3.17/xen-blkback-unmap-all-persistent-grants-when-frontend-gets-disconnected.patch new file mode 100644 index 00000000000..efa7bbaa69f --- /dev/null +++ b/queue-3.17/xen-blkback-unmap-all-persistent-grants-when-frontend-gets-disconnected.patch @@ -0,0 +1,75 @@ +From 12ea729645ace01e08f9654df155622898d3aae6 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Mon, 8 Sep 2014 15:21:33 +0200 +Subject: xen/blkback: unmap all persistent grants when frontend gets disconnected + +From: Vitaly Kuznetsov + +commit 12ea729645ace01e08f9654df155622898d3aae6 upstream. + +blkback does not unmap persistent grants when frontend goes to Closed +state (e.g. when blkfront module is being removed). This leads to the +following in guest's dmesg: + +[ 343.243825] xen:grant_table: WARNING: g.e. 0x445 still in use! +[ 343.243825] xen:grant_table: WARNING: g.e. 0x42a still in use! +... + +When load module -> use device -> unload module sequence is performed multiple times +it is possible to hit BUG() condition in blkfront module: + +[ 343.243825] kernel BUG at drivers/block/xen-blkfront.c:954! +[ 343.243825] invalid opcode: 0000 [#1] SMP +[ 343.243825] Modules linked in: xen_blkfront(-) ata_generic pata_acpi [last unloaded: xen_blkfront] +... +[ 343.243825] Call Trace: +[ 343.243825] [] ? unregister_xenbus_watch+0x16f/0x1e0 +[ 343.243825] [] blkfront_remove+0x3f/0x140 [xen_blkfront] +... +[ 343.243825] RIP [] blkif_free+0x34e/0x360 [xen_blkfront] +[ 343.243825] RSP + +We don't need to keep these grants if we're disconnecting as frontend might already +forgot about them. Solve the issue by moving xen_blkbk_free_caches() call from +xen_blkif_free() to xen_blkif_disconnect(). + +Now we can see the following: +[ 928.590893] xen:grant_table: WARNING: g.e. 0x587 still in use! +[ 928.591861] xen:grant_table: WARNING: g.e. 0x372 still in use! +... +[ 929.592146] xen:grant_table: freeing g.e. 0x587 +[ 929.597174] xen:grant_table: freeing g.e. 0x372 +... + +Backend does not keep persistent grants any more, reconnect works fine. + +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/xen-blkback/xenbus.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -270,6 +270,9 @@ static int xen_blkif_disconnect(struct x + blkif->blk_rings.common.sring = NULL; + } + ++ /* Remove all persistent grants and the cache of ballooned pages. */ ++ xen_blkbk_free_caches(blkif); ++ + return 0; + } + +@@ -281,9 +284,6 @@ static void xen_blkif_free(struct xen_bl + xen_blkif_disconnect(blkif); + xen_vbd_free(&blkif->vbd); + +- /* Remove all persistent grants and the cache of ballooned pages. */ +- xen_blkbk_free_caches(blkif); +- + /* Make sure everything is drained before shutting down */ + BUG_ON(blkif->persistent_gnt_c != 0); + BUG_ON(atomic_read(&blkif->persistent_gnt_in_use) != 0);