--- /dev/null
+From abab13b5c4fd1fec4f9a61622548012d93dc2831 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@fb.com>
+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 <axboe@fb.com>
+
+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 <bvanassche@acm.org>
+Fixes: 4bb659b156996
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From b8839b8c55f3fdd60dc36abcda7e0266aff7985c Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+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 <snitzer@redhat.com>
+
+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 <snitzer@redhat.com>
+Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)
--- /dev/null
+From eb76faf53b1ff7a77ce3f78cc98ad392ac70c2a0 Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Tue, 30 Sep 2014 09:32:46 +0100
+Subject: dm bufio: update last_accessed when relinking a buffer
+
+From: Joe Thornber <ejt@redhat.com>
+
+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 <ejt@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
+ /*----------------------------------------------------------------
--- /dev/null
+From 0e825862f3c04cee40e25f55680333728a4ffa9b Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 1 Oct 2014 13:29:48 -0400
+Subject: dm bufio: when done scanning return from __scan immediately
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+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 <thornber@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From 56ec16cb1e1ce46354de8511eef962a417c32c92 Mon Sep 17 00:00:00 2001
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+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 <khoroshilov@ispras.ru>
+
+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 <khoroshilov@ispras.ru>
+Reviewed-by: Jonathan Brassow <jbrassow@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From 82cfb90bc99d7b7e0ec62d0505b9d4f06805d5db Mon Sep 17 00:00:00 2001
+From: Lai Jiangshan <laijs@cn.fujitsu.com>
+Date: Thu, 18 Sep 2014 16:49:41 +0200
+Subject: drbd: compute the end before rb_insert_augmented()
+
+From: Lai Jiangshan <laijs@cn.fujitsu.com>
+
+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 <walken@google.com>
+Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
+Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
+Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 1e99cfa8de0f0879091e33cd65fd60418d006ad9 Mon Sep 17 00:00:00 2001
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Tue, 7 Oct 2014 19:04:58 +1100
+Subject: drm/ast: Fix HW cursor image
+
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+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 <benh@kernel.crashing.org>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From c0c3e735fa7bae29c6623511127fd021b2d6d849 Mon Sep 17 00:00:00 2001
+From: Olaf Hering <olaf@aepfle.de>
+Date: Fri, 11 Apr 2014 08:56:23 +0200
+Subject: drm/cirrus: bind also to qemu-xen-traditional
+
+From: Olaf Hering <olaf@aepfle.de>
+
+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 <olaf@aepfle.de>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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,}
+ };
+
--- /dev/null
+From d889c52427d48c05f163f2f39b2cfc12e17e5266 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Mon, 15 Sep 2014 21:11:51 +1000
+Subject: drm/gt214-/kms: fix hda eld regression
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit d889c52427d48c05f163f2f39b2cfc12e17e5266 upstream.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
--- /dev/null
+From c479f4383ea8940dd6f88da61798ad31feb33e51 Mon Sep 17 00:00:00 2001
+From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Date: Fri, 26 Sep 2014 15:05:22 +0100
+Subject: drm/i915: Do not leak pages when freeing userptr objects
+
+From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+
+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 <tvrtko.ursulin@intel.com>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: "Barbalho, Rafael" <rafael.barbalho@intel.com>
+Tested-by: Rafael Barbalho <rafael.barbalho@intel.com>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+[danvet: Remove unused local variable sg.]
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From e9681366ea9e76ab8f75e84351f2f3ca63ee542c Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+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 <chris@chris-wilson.co.uk>
+
+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: [<ffffffff8114af33>] 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:[<ffffffff8114af33>] [<ffffffff8114af33>] 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] [<ffffffff814a75f2>] __i915_mm_struct_free__worker+0x42/0x80
+[ 73.429116] [<ffffffff8106321a>] process_one_work+0x1ba/0x610
+[ 73.429632] [<ffffffff810631af>] ? process_one_work+0x14f/0x610
+[ 73.430153] [<ffffffff810636db>] worker_thread+0x6b/0x4a0
+[ 73.430671] [<ffffffff8108d67d>] ? trace_hardirqs_on+0xd/0x10
+[ 73.431501] [<ffffffff81063670>] ? process_one_work+0x610/0x610
+[ 73.432030] [<ffffffff8106a206>] kthread+0xf6/0x110
+[ 73.432561] [<ffffffff8106a110>] ? __kthread_parkme+0x80/0x80
+[ 73.433100] [<ffffffff8169c22c>] ret_from_fork+0x7c/0xb0
+[ 73.433644] [<ffffffff8106a110>] ? __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 [<ffffffff8114af33>] mmu_notifier_unregister+0x23/0x130
+[ 73.437017] RSP <ffff88008816bd50>
+[ 73.437704] CR2: 000000000000004c
+
+Fixes regression from commit ad46cb533d586fdb256855437af876617c6cf609
+Author: Chris Wilson <chris@chris-wilson.co.uk>
+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 <chris@chris-wilson.co.uk>
+Cc: Jacek Danecki <jacek.danecki@intel.com>
+Cc: "Gong, Zhipeng" <zhipeng.gong@intel.com>
+Cc: Jacek Danecki <jacek.danecki@intel.com>
+Cc: "Ursulin, Tvrtko" <tvrtko.ursulin@intel.com>
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
--- /dev/null
+From 595d373f1e9c9ce0fc946457fdb488e8a58972cd Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Mon, 8 Sep 2014 10:33:32 +1000
+Subject: drm/nouveau/bios: memset dcb struct to zero before parsing
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 595d373f1e9c9ce0fc946457fdb488e8a58972cd upstream.
+
+Fixes type/mask calculation being based on uninitialised data for VGA
+outputs.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From b485a7005faba38286bc02ab1d80e2cbf61c1002 Mon Sep 17 00:00:00 2001
+From: Emil Velikov <emil.l.velikov@gmail.com>
+Date: Mon, 8 Sep 2014 20:27:57 +0100
+Subject: drm/nouveau/gpio: rename g92 class to g94
+
+From: Emil Velikov <emil.l.velikov@gmail.com>
+
+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 <bskeggs@redhat.com>
+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 <emil.l.velikov@gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From b478e336b3e75505707a11e78ef8b964ef0a03af Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Date: Tue, 2 Sep 2014 09:51:15 -0300
+Subject: drm/tilcdc: Fix the error path in tilcdc_load()
+
+From: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+
+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 <detheridge@ti.com>
+Tested-by: Johannes Pointner <johannes.pointner@br-automation.com>
+Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Fixes: 3a49012224ca ("drm/tilcdc: panel: fix leak when unloading the module")
+Signed-off-by: Matwey V. Kornilov <matwey.kornilov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From e351943b081f4d9e6f692ce1a6117e8d2e71f478 Mon Sep 17 00:00:00 2001
+From: Josh Boyer <jwboyer@fedoraproject.org>
+Date: Fri, 5 Sep 2014 13:19:59 -0400
+Subject: drm/vmwgfx: Fix drm.h include
+
+From: Josh Boyer <jwboyer@fedoraproject.org>
+
+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 <drm/drm.h>, 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 <jbastian@redhat.com>
+Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <drm.h>
++#include <drm/drm.h>
+ #endif
+
+ #define DRM_VMW_MAX_SURFACE_FACES 6
--- /dev/null
+From f74a289b9480648a654e5afd8458c2263c03a1e1 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Tue, 16 Sep 2014 12:40:26 -0400
+Subject: framebuffer: fix border color
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+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 <mpatocka@redhat.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) {
--- /dev/null
+From 5b789da8a7fc357661fc61faaf853e9161cc9700 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Tue, 16 Sep 2014 12:38:53 -0400
+Subject: framebuffer: fix screen corruption when copying
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+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 <mpatocka@redhat.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 5989a55a4c9aafba8b152c6bf52244510c2b88b9 Mon Sep 17 00:00:00 2001
+From: Jason Gerecke <killertofu@gmail.com>
+Date: Tue, 23 Sep 2014 11:09:28 -0700
+Subject: HID: input: Fix TransducerSerialNumber implementation
+
+From: Jason Gerecke <killertofu@gmail.com>
+
+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 <jason.gerecke@wacom.com>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Reviewed-by: Ping Cheng <pingc@wacom.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From b0cfb794a3dd1d699f3e453f9180bd06508fb8f0 Mon Sep 17 00:00:00 2001
+From: Andreas Bosch <linux@progandy.de>
+Date: Wed, 15 Oct 2014 10:44:50 -0700
+Subject: Input: alps - fix v4 button press recognition
+
+From: Andreas Bosch <linux@progandy.de>
+
+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 <linux@progandy.de>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 9ff84a17302aeb8913ff244ecc0d8f9d219fecb5 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sat, 11 Oct 2014 11:27:37 -0700
+Subject: Input: i8042 - add noloop quirk for Asus X750LN
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+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 <hdegoede@redhat.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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"),
--- /dev/null
+From 993b3a3f80a7842a48cd46c2b41e1b3ef6302468 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Fri, 24 Oct 2014 14:55:24 -0700
+Subject: Input: i8042 - quirks for Fujitsu Lifebook A544 and Lifebook AH544
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+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 <hdegoede@redhat.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 = {
--- /dev/null
+From aa972409951e0675e07918620427517cad5090e0 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Tue, 2 Sep 2014 09:49:18 -0700
+Subject: Input: synaptics - gate forcepad support by DMI check
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+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 <nicole.faerber@kernelconcepts.de>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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))
--- /dev/null
+From 25b11ce2a3607d7c39a2ca121eea0c67c722b34e Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Fri, 19 Sep 2014 10:03:13 -0600
+Subject: iommu/amd: Split init_iommu_group() from iommu_init_device()
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+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 <alex.williamson@redhat.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
--- /dev/null
+From f096c061f5525d1b35a65b793057b52061dcb486 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Fri, 19 Sep 2014 10:03:06 -0600
+Subject: iommu: Rework iommu_group_get_for_pci_dev()
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+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 <alex.williamson@redhat.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/notifier.h>
+ #include <linux/err.h>
+ #include <linux/pci.h>
++#include <linux/bitops.h>
+ #include <trace/events/iommu.h>
+
+ 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();
--- /dev/null
+From 5152970538a5e16c03bbcb9f1c780489a795ed40 Mon Sep 17 00:00:00 2001
+From: Chris Ball <chris@printf.net>
+Date: Thu, 4 Sep 2014 17:11:53 +0100
+Subject: mfd: rtsx_pcr: Fix MSI enable error handling
+
+From: Chris Ball <chris@printf.net>
+
+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 <Jared_Dominguez@Dell.com>
+Tested-by: D. Jared Dominguez <Jared_Dominguez@Dell.com>
+Signed-off-by: Chris Ball <chris@printf.net>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From 6ac734d2242949f41eb1346ca0fd4ed010c937aa Mon Sep 17 00:00:00 2001
+From: Vignesh R <vigneshr@ti.com>
+Date: Mon, 1 Sep 2014 12:01:06 +0530
+Subject: mfd: ti_am335x_tscadc: Fix TSC operation after ADC continouous mode
+
+From: Vignesh R <vigneshr@ti.com>
+
+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 <vigneshr@ti.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 6a71f38dd87f255a0586104ce2a14d5a3ddf3401 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Mon, 8 Sep 2014 15:28:42 +0200
+Subject: mfd: ti_am335x_tscadc: Fix TSC resume
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+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 <bigeasy@linutronix.de>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+ }
--- /dev/null
+From 0d0826019e529f21c84687521d03f60cd241ca7d Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+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" <ebiederm@xmission.com>
+
+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 <luto@amacapital.net>
+Reviewed-by: Andy Lutomirski <luto@amacapital.net>
+Link: http://lkml.kernel.org/r/87bnpmihks.fsf@x220.int.ebiederm.org
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Andy Lutomirski <luto@amacapital.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From d3051b489aa81ca9ba62af366149ef42b8dae97c Mon Sep 17 00:00:00 2001
+From: Prarit Bhargava <prarit@redhat.com>
+Date: Tue, 14 Oct 2014 02:51:39 +1030
+Subject: modules, lock around setting of MODULE_STATE_UNFORMED
+
+From: Prarit Bhargava <prarit@redhat.com>
+
+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:[<ffffffff810d64c5>] [<ffffffff810d64c5>] 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:
+ [<ffffffff810d666c>] m_show+0x19c/0x1e0
+ [<ffffffff811e4d7e>] seq_read+0x16e/0x3b0
+ [<ffffffff812281ed>] proc_reg_read+0x3d/0x80
+ [<ffffffff811c0f2c>] vfs_read+0x9c/0x170
+ [<ffffffff811c1a58>] SyS_read+0x58/0xb0
+ [<ffffffff81605829>] 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 [<ffffffff810d64c5>] module_flags+0xb5/0xc0
+ RSP <ffff88080fa7fe18>
+
+ 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 <prarit@redhat.com>
+Reviewed-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 661a88860274e059fdb744dfaa98c045db7b5d1d Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+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 <k.kozlowski@samsung.com>
+
+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 : [<c01f4220>] lr : [<c030fe38>] 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] [<c01f4220>] (strcmp) from [<c030fe38>] (power_supply_match_device_by_name+0x10/0x1c)
+[ 2.695303] [<c030fe38>] (power_supply_match_device_by_name) from [<c026b1c8>] (class_find_device+0x54/0xac)
+[ 2.705106] [<c026b1c8>] (class_find_device) from [<c030fee0>] (power_supply_get_by_name+0x1c/0x30)
+[ 2.714137] [<c030fee0>] (power_supply_get_by_name) from [<c03138fc>] (charger_manager_probe+0x3d8/0xe58)
+[ 2.723683] [<c03138fc>] (charger_manager_probe) from [<c026b71c>] (platform_drv_probe+0x2c/0x5c)
+[ 2.732532] [<c026b71c>] (platform_drv_probe) from [<c026a330>] (driver_probe_device+0x10c/0x224)
+[ 2.741384] [<c026a330>] (driver_probe_device) from [<c026a4dc>] (__driver_attach+0x94/0x98)
+[ 2.749813] [<c026a4dc>] (__driver_attach) from [<c0268b5c>] (bus_for_each_dev+0x54/0x88)
+[ 2.757969] [<c0268b5c>] (bus_for_each_dev) from [<c0269b18>] (bus_add_driver+0xd4/0x1d0)
+[ 2.766123] [<c0269b18>] (bus_add_driver) from [<c026aaf0>] (driver_register+0x78/0xf4)
+[ 2.774110] [<c026aaf0>] (driver_register) from [<c00088a4>] (do_one_initcall+0x80/0x1bc)
+[ 2.782276] [<c00088a4>] (do_one_initcall) from [<c0603cc4>] (kernel_init_freeable+0x100/0x1cc)
+[ 2.790952] [<c0603cc4>] (kernel_init_freeable) from [<c0453950>] (kernel_init+0x8/0xec)
+[ 2.799029] [<c0453950>] (kernel_init) from [<c000e728>] (ret_from_fork+0x14/0x2c)
+[ 2.806572] Code: e12fff1e e1a03000 eafffff7 e4d03001 (e4d12001)
+[ 2.812832] ---[ end trace 7f12556111b9e7ef ]---
+
+Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Fixes: 856ee6115e2d ("charger-manager: Support deivce tree in charger manager driver")
+Signed-off-by: Sebastian Reichel <sre@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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++;
--- /dev/null
+From d4bf205da618bbd0b038e404d646f14e76915718 Mon Sep 17 00:00:00 2001
+From: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
+Date: Sun, 12 Oct 2014 23:09:08 -0400
+Subject: pstore: Fix duplicate {console,ftrace}-efi entries
+
+From: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
+
+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 <valdis.kletnieks@vt.edu>
+Acked-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From e999dbc254044e8d2a5818d92d205f65bae28f37 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Sun, 19 Oct 2014 17:13:57 +0200
+Subject: Revert "block: all blk-mq requests are tagged"
+
+From: Christoph Hellwig <hch@lst.de>
+
+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 <hch@lst.de>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Jens Axboe <axboe@kernel.dk>
+Reported-by: Meelis Roos <mroos@linux.ee>
+Tested-by: Meelis Roos <mroos@linux.ee>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 *);
--- /dev/null
+From 48e9a6c1f54695609b709bf674aac133794ada00 Mon Sep 17 00:00:00 2001
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 24 Sep 2014 16:37:20 +0200
+Subject: s390/topology: call set_sched_topology early
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+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 <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 923190d32de4428afbea5e5773be86bea60a9925 Mon Sep 17 00:00:00 2001
+From: Stephen Smalley <sds@tycho.nsa.gov>
+Date: Mon, 6 Oct 2014 16:32:52 -0400
+Subject: selinux: fix inode security list corruption
+
+From: Stephen Smalley <sds@tycho.nsa.gov>
+
+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 <shivnandan.k@samsung.com>
+Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
+Signed-off-by: Paul Moore <pmoore@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
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
--- /dev/null
+From 1bf1890e86869032099b539bc83b098be12fc5a7 Mon Sep 17 00:00:00 2001
+From: Richard Genoud <richard.genoud@gmail.com>
+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 <richard.genoud@gmail.com>
+
+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
+[<c000d298>] (unwind_backtrace) from [<c000baa8>] (show_stack+0x10/0x14)
+[<c000baa8>] (show_stack) from [<c01b7a68>] (destroy_ai+0x230/0x244)
+[<c01b7a68>] (destroy_ai) from [<c01b8fd4>] (ubi_attach+0x98/0x1ec)
+[<c01b8fd4>] (ubi_attach) from [<c01ade90>] (ubi_attach_mtd_dev+0x2b8/0x868)
+[<c01ade90>] (ubi_attach_mtd_dev) from [<c038b510>] (ubi_init+0x1dc/0x2ac)
+[<c038b510>] (ubi_init) from [<c0008860>] (do_one_initcall+0x94/0x140)
+[<c0008860>] (do_one_initcall) from [<c037aadc>] (kernel_init_freeable+0xe8/0x1b0)
+[<c037aadc>] (kernel_init_freeable) from [<c02730ac>] (kernel_init+0x8/0xe4)
+[<c02730ac>] (kernel_init) from [<c00093f0>] (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 <richard.genoud@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From 06d9c2905f745c8b1920a335cbb366ba6b0fc754 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Fri, 29 Aug 2014 18:42:29 -0300
+Subject: UBI: block: Add support for the UBI_VOLUME_UPDATED notification
+
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+
+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 <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From 978d6496758d19de2431ebf163337fc7b92f8c45 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Fri, 29 Aug 2014 18:42:28 -0300
+Subject: UBI: block: Fix block device size setting
+
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+
+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 <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From fda322a1b3b9e8ee231913c500f73c6988b1aff5 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Fri, 29 Aug 2014 18:42:30 -0300
+Subject: UBI: Dispatch update notification if the volume is updated
+
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+
+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 <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From 6fbc198cf623944ab60a1db6d306a4d55cdd820d Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Tue, 14 Oct 2014 10:40:29 +1030
+Subject: virtio_pci: fix virtio spec compliance on restore
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+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 <amit.shah@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From 61cecca865280bef4f8a9748d0a9afa5df351ac2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <roger.pau@citrix.com>
+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?= <roger.pau@citrix.com>
+
+commit 61cecca865280bef4f8a9748d0a9afa5df351ac2 upstream.
+
+Fix leaking a page when a grant mapping has failed.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reported-and-Tested-by: Tao Chen <boby.chen@huawei.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 12ea729645ace01e08f9654df155622898d3aae6 Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Mon, 8 Sep 2014 15:21:33 +0200
+Subject: xen/blkback: unmap all persistent grants when frontend gets disconnected
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+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] [<ffffffff814111ef>] ? unregister_xenbus_watch+0x16f/0x1e0
+[ 343.243825] [<ffffffffa0016fbf>] blkfront_remove+0x3f/0x140 [xen_blkfront]
+...
+[ 343.243825] RIP [<ffffffffa0016aae>] blkif_free+0x34e/0x360 [xen_blkfront]
+[ 343.243825] RSP <ffff88001eb8fdc0>
+
+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 <vkuznets@redhat.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);