]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Mar 2013 00:55:47 +0000 (16:55 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Mar 2013 00:55:47 +0000 (16:55 -0800)
added patches:
block-fix-synchronization-and-limit-check-in-blk_alloc_devt.patch
ext4-fix-possible-use-after-free-with-aio.patch
firewire-add-minor-number-range-check-to-fw_device_init.patch
fs-fix-possible-use-after-free-with-aio.patch
idr-fix-a-subtle-bug-in-idr_get_next.patch
media-cx18-ivtv-fix-regression-remove-__init-from-a-non-init-function.patch
media-omap_vout-find_vma-needs-mmap_sem-held.patch
media-rc-unlock-on-error-in-show_protocols.patch
media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch
nbd-fsync-and-kill-block-device-on-shutdown.patch
sysctl-fix-null-checking-in-bin_dn_node_address.patch
xen-blkback-do-not-leak-mode-property.patch
xen-blkback-don-t-trust-the-handle-from-the-frontend.patch
xen-blkback-use-balloon-pages-for-persistent-grants.patch
xen-blkfront-drop-the-use-of-llist_for_each_entry_safe.patch

16 files changed:
queue-3.8/block-fix-synchronization-and-limit-check-in-blk_alloc_devt.patch [new file with mode: 0644]
queue-3.8/ext4-fix-possible-use-after-free-with-aio.patch [new file with mode: 0644]
queue-3.8/firewire-add-minor-number-range-check-to-fw_device_init.patch [new file with mode: 0644]
queue-3.8/fs-fix-possible-use-after-free-with-aio.patch [new file with mode: 0644]
queue-3.8/idr-fix-a-subtle-bug-in-idr_get_next.patch [new file with mode: 0644]
queue-3.8/media-cx18-ivtv-fix-regression-remove-__init-from-a-non-init-function.patch [new file with mode: 0644]
queue-3.8/media-omap_vout-find_vma-needs-mmap_sem-held.patch [new file with mode: 0644]
queue-3.8/media-rc-unlock-on-error-in-show_protocols.patch [new file with mode: 0644]
queue-3.8/media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch [new file with mode: 0644]
queue-3.8/nbd-fsync-and-kill-block-device-on-shutdown.patch [new file with mode: 0644]
queue-3.8/series
queue-3.8/sysctl-fix-null-checking-in-bin_dn_node_address.patch [new file with mode: 0644]
queue-3.8/xen-blkback-do-not-leak-mode-property.patch [new file with mode: 0644]
queue-3.8/xen-blkback-don-t-trust-the-handle-from-the-frontend.patch [new file with mode: 0644]
queue-3.8/xen-blkback-use-balloon-pages-for-persistent-grants.patch [new file with mode: 0644]
queue-3.8/xen-blkfront-drop-the-use-of-llist_for_each_entry_safe.patch [new file with mode: 0644]

diff --git a/queue-3.8/block-fix-synchronization-and-limit-check-in-blk_alloc_devt.patch b/queue-3.8/block-fix-synchronization-and-limit-check-in-blk_alloc_devt.patch
new file mode 100644 (file)
index 0000000..1e64dd2
--- /dev/null
@@ -0,0 +1,61 @@
+From ce23bba842aee98092225d9576dba47c82352521 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 27 Feb 2013 17:03:56 -0800
+Subject: block: fix synchronization and limit check in blk_alloc_devt()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit ce23bba842aee98092225d9576dba47c82352521 upstream.
+
+idr allocation in blk_alloc_devt() wasn't synchronized against lookup
+and removal, and its limit check was off by one - 1 << MINORBITS is
+the number of minors allowed, not the maximum allowed minor.
+
+Add locking and rename MAX_EXT_DEVT to NR_EXT_DEVT and fix limit
+checking.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Acked-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/genhd.c |   13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -25,7 +25,7 @@ static DEFINE_MUTEX(block_class_lock);
+ struct kobject *block_depr;
+ /* for extended dynamic devt allocation, currently only one major is used */
+-#define MAX_EXT_DEVT          (1 << MINORBITS)
++#define NR_EXT_DEVT           (1 << MINORBITS)
+ /* For extended devt allocation.  ext_devt_mutex prevents look up
+  * results from going away underneath its user.
+@@ -424,19 +424,16 @@ int blk_alloc_devt(struct hd_struct *par
+                       return -ENOMEM;
+               mutex_lock(&ext_devt_mutex);
+               rc = idr_get_new(&ext_devt_idr, part, &idx);
++              if (!rc && idx >= NR_EXT_DEVT) {
++                      idr_remove(&ext_devt_idr, idx);
++                      rc = -EBUSY;
++              }
+               mutex_unlock(&ext_devt_mutex);
+       } while (rc == -EAGAIN);
+       if (rc)
+               return rc;
+-      if (idx > MAX_EXT_DEVT) {
+-              mutex_lock(&ext_devt_mutex);
+-              idr_remove(&ext_devt_idr, idx);
+-              mutex_unlock(&ext_devt_mutex);
+-              return -EBUSY;
+-      }
+-
+       *devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
+       return 0;
+ }
diff --git a/queue-3.8/ext4-fix-possible-use-after-free-with-aio.patch b/queue-3.8/ext4-fix-possible-use-after-free-with-aio.patch
new file mode 100644 (file)
index 0000000..83922d2
--- /dev/null
@@ -0,0 +1,59 @@
+From 091e26dfc156aeb3b73bc5c5f277e433ad39331c Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 29 Jan 2013 22:48:17 -0500
+Subject: ext4: fix possible use-after-free with AIO
+
+From: Jan Kara <jack@suse.cz>
+
+commit 091e26dfc156aeb3b73bc5c5f277e433ad39331c upstream.
+
+Running AIO is pinning inode in memory using file reference. Once AIO
+is completed using aio_complete(), file reference is put and inode can
+be freed from memory. So we have to be sure that calling aio_complete()
+is the last thing we do with the inode.
+
+Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
+Acked-by: Jeff Moyer <jmoyer@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c   |    2 +-
+ fs/ext4/page-io.c |    9 ++++-----
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -2977,9 +2977,9 @@ static void ext4_end_io_dio(struct kiocb
+       if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
+               ext4_free_io_end(io_end);
+ out:
++              inode_dio_done(inode);
+               if (is_async)
+                       aio_complete(iocb, ret, 0);
+-              inode_dio_done(inode);
+               return;
+       }
+--- a/fs/ext4/page-io.c
++++ b/fs/ext4/page-io.c
+@@ -103,14 +103,13 @@ static int ext4_end_io(ext4_io_end_t *io
+                        "(inode %lu, offset %llu, size %zd, error %d)",
+                        inode->i_ino, offset, size, ret);
+       }
+-      if (io->iocb)
+-              aio_complete(io->iocb, io->result, 0);
+-
+-      if (io->flag & EXT4_IO_END_DIRECT)
+-              inode_dio_done(inode);
+       /* Wake up anyone waiting on unwritten extent conversion */
+       if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
+               wake_up_all(ext4_ioend_wq(inode));
++      if (io->flag & EXT4_IO_END_DIRECT)
++              inode_dio_done(inode);
++      if (io->iocb)
++              aio_complete(io->iocb, io->result, 0);
+       return ret;
+ }
diff --git a/queue-3.8/firewire-add-minor-number-range-check-to-fw_device_init.patch b/queue-3.8/firewire-add-minor-number-range-check-to-fw_device_init.patch
new file mode 100644 (file)
index 0000000..60a522f
--- /dev/null
@@ -0,0 +1,36 @@
+From 3bec60d511179853138836ae6e1b61fe34d9235f Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 27 Feb 2013 17:04:04 -0800
+Subject: firewire: add minor number range check to fw_device_init()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 3bec60d511179853138836ae6e1b61fe34d9235f upstream.
+
+fw_device_init() didn't check whether the allocated minor number isn't
+too large.  Fail if it goes overflows MINORBITS.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Suggested-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Acked-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firewire/core-device.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/firewire/core-device.c
++++ b/drivers/firewire/core-device.c
+@@ -1020,6 +1020,10 @@ static void fw_device_init(struct work_s
+       ret = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
+             idr_get_new(&fw_device_idr, device, &minor) :
+             -ENOMEM;
++      if (minor >= 1 << MINORBITS) {
++              idr_remove(&fw_device_idr, minor);
++              minor = -ENOSPC;
++      }
+       up_write(&fw_device_rwsem);
+       if (ret < 0)
diff --git a/queue-3.8/fs-fix-possible-use-after-free-with-aio.patch b/queue-3.8/fs-fix-possible-use-after-free-with-aio.patch
new file mode 100644 (file)
index 0000000..3e6e08c
--- /dev/null
@@ -0,0 +1,39 @@
+From 54c807e71d5ac59dee56c685f2b66e27cd54c475 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 30 Jan 2013 00:28:01 +0100
+Subject: fs: Fix possible use-after-free with AIO
+
+From: Jan Kara <jack@suse.cz>
+
+commit 54c807e71d5ac59dee56c685f2b66e27cd54c475 upstream.
+
+Running AIO is pinning inode in memory using file reference. Once AIO
+is completed using aio_complete(), file reference is put and inode can
+be freed from memory. So we have to be sure that calling aio_complete()
+is the last thing we do with the inode.
+
+Acked-by: Jeff Moyer <jmoyer@redhat.com>
+CC: Christoph Hellwig <hch@infradead.org>
+CC: Jens Axboe <axboe@kernel.dk>
+CC: Jeff Moyer <jmoyer@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/direct-io.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/direct-io.c
++++ b/fs/direct-io.c
+@@ -261,9 +261,9 @@ static ssize_t dio_complete(struct dio *
+               dio->end_io(dio->iocb, offset, transferred,
+                           dio->private, ret, is_async);
+       } else {
++              inode_dio_done(dio->inode);
+               if (is_async)
+                       aio_complete(dio->iocb, ret, 0);
+-              inode_dio_done(dio->inode);
+       }
+       return ret;
diff --git a/queue-3.8/idr-fix-a-subtle-bug-in-idr_get_next.patch b/queue-3.8/idr-fix-a-subtle-bug-in-idr_get_next.patch
new file mode 100644 (file)
index 0000000..0e0f053
--- /dev/null
@@ -0,0 +1,73 @@
+From 6cdae7416a1c45c2ce105a78187d9b7e8feb9e24 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 27 Feb 2013 17:03:34 -0800
+Subject: idr: fix a subtle bug in idr_get_next()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 6cdae7416a1c45c2ce105a78187d9b7e8feb9e24 upstream.
+
+The iteration logic of idr_get_next() is borrowed mostly verbatim from
+idr_for_each().  It walks down the tree looking for the slot matching
+the current ID.  If the matching slot is not found, the ID is
+incremented by the distance of single slot at the given level and
+repeats.
+
+The implementation assumes that during the whole iteration id is aligned
+to the layer boundaries of the level closest to the leaf, which is true
+for all iterations starting from zero or an existing element and thus is
+fine for idr_for_each().
+
+However, idr_get_next() may be given any point and if the starting id
+hits in the middle of a non-existent layer, increment to the next layer
+will end up skipping the same offset into it.  For example, an IDR with
+IDs filled between [64, 127] would look like the following.
+
+          [  0  64 ... ]
+       /----/   |
+       |        |
+      NULL    [ 64 ... 127 ]
+
+If idr_get_next() is called with 63 as the starting point, it will try
+to follow down the pointer from 0.  As it is NULL, it will then try to
+proceed to the next slot in the same level by adding the slot distance
+at that level which is 64 - making the next try 127.  It goes around the
+loop and finds and returns 127 skipping [64, 126].
+
+Note that this bug also triggers in idr_for_each_entry() loop which
+deletes during iteration as deletions can make layers go away leaving
+the iteration with unaligned ID into missing layers.
+
+Fix it by ensuring proceeding to the next slot doesn't carry over the
+unaligned offset - ie.  use round_up(id + 1, slot_distance) instead of
+id += slot_distance.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: David Teigland <teigland@redhat.com>
+Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/idr.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -625,7 +625,14 @@ void *idr_get_next(struct idr *idp, int
+                       return p;
+               }
+-              id += 1 << n;
++              /*
++               * Proceed to the next layer at the current level.  Unlike
++               * idr_for_each(), @id isn't guaranteed to be aligned to
++               * layer boundary at this point and adding 1 << n may
++               * incorrectly skip IDs.  Make sure we jump to the
++               * beginning of the next layer using round_up().
++               */
++              id = round_up(id + 1, 1 << n);
+               while (n < fls(id)) {
+                       n += IDR_BITS;
+                       p = *--paa;
diff --git a/queue-3.8/media-cx18-ivtv-fix-regression-remove-__init-from-a-non-init-function.patch b/queue-3.8/media-cx18-ivtv-fix-regression-remove-__init-from-a-non-init-function.patch
new file mode 100644 (file)
index 0000000..28c5548
--- /dev/null
@@ -0,0 +1,68 @@
+From cfb046cb800ba306b211fbbe4ac633486e11055f Mon Sep 17 00:00:00 2001
+From: Hans Verkuil <hans.verkuil@cisco.com>
+Date: Sat, 9 Feb 2013 05:40:10 -0300
+Subject: media: cx18/ivtv: fix regression: remove __init from a non-init function
+
+From: Hans Verkuil <hans.verkuil@cisco.com>
+
+commit cfb046cb800ba306b211fbbe4ac633486e11055f upstream.
+
+Commits 5e6e81b2890db3969527772a8350825a85c22d5c (cx18) and
+2aebbf6737212265b917ed27c875c59d3037110a (ivtv) added an __init
+annotation to the cx18-alsa-load and ivtv-alsa-load functions. However,
+these functions are called *after* initialization by the main cx18/ivtv
+driver. By that time the memory containing those functions is already
+freed and your machine goes BOOM.
+
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/pci/cx18/cx18-alsa-main.c |    2 +-
+ drivers/media/pci/cx18/cx18-alsa-pcm.h  |    2 +-
+ drivers/media/pci/ivtv/ivtv-alsa-main.c |    2 +-
+ drivers/media/pci/ivtv/ivtv-alsa-pcm.h  |    2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/media/pci/cx18/cx18-alsa-main.c
++++ b/drivers/media/pci/cx18/cx18-alsa-main.c
+@@ -197,7 +197,7 @@ err_exit:
+       return ret;
+ }
+-static int __init cx18_alsa_load(struct cx18 *cx)
++static int cx18_alsa_load(struct cx18 *cx)
+ {
+       struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
+       struct cx18_stream *s;
+--- a/drivers/media/pci/cx18/cx18-alsa-pcm.h
++++ b/drivers/media/pci/cx18/cx18-alsa-pcm.h
+@@ -20,7 +20,7 @@
+  *  02111-1307  USA
+  */
+-int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
++int snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
+ /* Used by cx18-mailbox to announce the PCM data to the module */
+ void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
+--- a/drivers/media/pci/ivtv/ivtv-alsa-main.c
++++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c
+@@ -205,7 +205,7 @@ err_exit:
+       return ret;
+ }
+-static int __init ivtv_alsa_load(struct ivtv *itv)
++static int ivtv_alsa_load(struct ivtv *itv)
+ {
+       struct v4l2_device *v4l2_dev = &itv->v4l2_dev;
+       struct ivtv_stream *s;
+--- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
++++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
+@@ -20,4 +20,4 @@
+  *  02111-1307  USA
+  */
+-int __init snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
++int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
diff --git a/queue-3.8/media-omap_vout-find_vma-needs-mmap_sem-held.patch b/queue-3.8/media-omap_vout-find_vma-needs-mmap_sem-held.patch
new file mode 100644 (file)
index 0000000..0e94b51
--- /dev/null
@@ -0,0 +1,63 @@
+From 55ee64b30a38d688232e5eb2860467dddc493573 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@ZenIV.linux.org.uk>
+Date: Sun, 16 Dec 2012 16:04:46 -0300
+Subject: media: omap_vout: find_vma() needs ->mmap_sem held
+
+From: Al Viro <viro@ZenIV.linux.org.uk>
+
+commit 55ee64b30a38d688232e5eb2860467dddc493573 upstream.
+
+Walking rbtree while it's modified is a Bad Idea(tm); besides,
+the result of find_vma() can be freed just as it's getting returned
+to caller.  Fortunately, it's easy to fix - just take ->mmap_sem a bit
+earlier (and don't bother with find_vma() at all if virtp >= PAGE_OFFSET -
+in that case we don't even look at its result).
+
+While we are at it, what prevents VIDIOC_PREPARE_BUF calling
+v4l_prepare_buf() -> (e.g) vb2_ioctl_prepare_buf() -> vb2_prepare_buf() ->
+__buf_prepare() -> __qbuf_userptr() -> vb2_vmalloc_get_userptr() -> find_vma(),
+AFAICS without having taken ->mmap_sem anywhere in process?  The code flow
+is bloody convoluted and depends on a bunch of things done by initialization,
+so I certainly might've missed something...
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Sakari Ailus <sakari.ailus@iki.fi>
+Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Cc: Archit Taneja <archit@ti.com>
+Cc: Prabhakar Lad <prabhakar.lad@ti.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/platform/omap/omap_vout.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/media/platform/omap/omap_vout.c
++++ b/drivers/media/platform/omap/omap_vout.c
+@@ -205,19 +205,21 @@ static u32 omap_vout_uservirt_to_phys(u3
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = current->mm;
+-      vma = find_vma(mm, virtp);
+       /* For kernel direct-mapped memory, take the easy way */
+-      if (virtp >= PAGE_OFFSET) {
+-              physp = virt_to_phys((void *) virtp);
+-      } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
++      if (virtp >= PAGE_OFFSET)
++              return virt_to_phys((void *) virtp);
++
++      down_read(&current->mm->mmap_sem);
++      vma = find_vma(mm, virtp);
++      if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
+               /* this will catch, kernel-allocated, mmaped-to-usermode
+                  addresses */
+               physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
++              up_read(&current->mm->mmap_sem);
+       } else {
+               /* otherwise, use get_user_pages() for general userland pages */
+               int res, nr_pages = 1;
+               struct page *pages;
+-              down_read(&current->mm->mmap_sem);
+               res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
+                               0, &pages, NULL);
diff --git a/queue-3.8/media-rc-unlock-on-error-in-show_protocols.patch b/queue-3.8/media-rc-unlock-on-error-in-show_protocols.patch
new file mode 100644 (file)
index 0000000..b2adb96
--- /dev/null
@@ -0,0 +1,37 @@
+From 30ebc5e44d057a1619ad63fe32c8c1670c37c4b8 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Tue, 27 Nov 2012 13:35:09 -0300
+Subject: media: rc: unlock on error in show_protocols()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 30ebc5e44d057a1619ad63fe32c8c1670c37c4b8 upstream.
+
+We recently introduced a new return -ENODEV in this function but we need
+to unlock before returning.
+
+[mchehab@redhat.com: found two patches with the same fix. Merged SOB's/acks into one patch]
+Acked-by: Herton R. Krzesinski <herton.krzesinski@canonical.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Douglas Bagnall <douglas@paradise.net.nz>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/rc/rc-main.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/rc/rc-main.c
++++ b/drivers/media/rc/rc-main.c
+@@ -789,8 +789,10 @@ static ssize_t show_protocols(struct dev
+       } else if (dev->raw) {
+               enabled = dev->raw->enabled_protocols;
+               allowed = ir_raw_get_allowed_protocols();
+-      } else
++      } else {
++              mutex_unlock(&dev->lock);
+               return -ENODEV;
++      }
+       IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
+                  (long long)allowed,
diff --git a/queue-3.8/media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch b/queue-3.8/media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch
new file mode 100644 (file)
index 0000000..ce38de9
--- /dev/null
@@ -0,0 +1,80 @@
+From 317efce991620adc589b3005b9baed433dcb2a56 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 24 Nov 2012 21:35:48 -0300
+Subject: media: v4l: Reset subdev v4l2_dev field to NULL if registration fails
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit 317efce991620adc589b3005b9baed433dcb2a56 upstream.
+
+When subdev registration fails the subdev v4l2_dev field is left to a
+non-NULL value. Later calls to v4l2_device_unregister_subdev() will
+consider the subdev as registered and will module_put() the subdev
+module without any matching module_get().
+Fix this by setting the subdev v4l2_dev field to NULL in
+v4l2_device_register_subdev() when the function fails.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/v4l2-core/v4l2-device.c |   30 ++++++++++++++----------------
+ 1 file changed, 14 insertions(+), 16 deletions(-)
+
+--- a/drivers/media/v4l2-core/v4l2-device.c
++++ b/drivers/media/v4l2-core/v4l2-device.c
+@@ -159,31 +159,21 @@ int v4l2_device_register_subdev(struct v
+       sd->v4l2_dev = v4l2_dev;
+       if (sd->internal_ops && sd->internal_ops->registered) {
+               err = sd->internal_ops->registered(sd);
+-              if (err) {
+-                      module_put(sd->owner);
+-                      return err;
+-              }
++              if (err)
++                      goto error_module;
+       }
+       /* This just returns 0 if either of the two args is NULL */
+       err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL);
+-      if (err) {
+-              if (sd->internal_ops && sd->internal_ops->unregistered)
+-                      sd->internal_ops->unregistered(sd);
+-              module_put(sd->owner);
+-              return err;
+-      }
++      if (err)
++              goto error_unregister;
+ #if defined(CONFIG_MEDIA_CONTROLLER)
+       /* Register the entity. */
+       if (v4l2_dev->mdev) {
+               err = media_device_register_entity(v4l2_dev->mdev, entity);
+-              if (err < 0) {
+-                      if (sd->internal_ops && sd->internal_ops->unregistered)
+-                              sd->internal_ops->unregistered(sd);
+-                      module_put(sd->owner);
+-                      return err;
+-              }
++              if (err < 0)
++                      goto error_unregister;
+       }
+ #endif
+@@ -192,6 +182,14 @@ int v4l2_device_register_subdev(struct v
+       spin_unlock(&v4l2_dev->lock);
+       return 0;
++
++error_unregister:
++      if (sd->internal_ops && sd->internal_ops->unregistered)
++              sd->internal_ops->unregistered(sd);
++error_module:
++      module_put(sd->owner);
++      sd->v4l2_dev = NULL;
++      return err;
+ }
+ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
diff --git a/queue-3.8/nbd-fsync-and-kill-block-device-on-shutdown.patch b/queue-3.8/nbd-fsync-and-kill-block-device-on-shutdown.patch
new file mode 100644 (file)
index 0000000..039cf16
--- /dev/null
@@ -0,0 +1,91 @@
+From 3a2d63f87989e01437ba994df5f297528c353d7d Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Wed, 27 Feb 2013 17:05:25 -0800
+Subject: nbd: fsync and kill block device on shutdown
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+commit 3a2d63f87989e01437ba994df5f297528c353d7d upstream.
+
+There are two problems with shutdown in the NBD driver.
+
+1: Receiving the NBD_DISCONNECT ioctl does not sync the filesystem.
+
+   This patch adds the sync operation into __nbd_ioctl()'s
+   NBD_DISCONNECT handler.  This is useful because BLKFLSBUF is restricted
+   to processes that have CAP_SYS_ADMIN, and the NBD client may not
+   possess it (fsync of the block device does not sync the filesystem,
+   either).
+
+2: Once we clear the socket we have no guarantee that later reads will
+   come from the same backing storage.
+
+   The patch adds calls to kill_bdev() in __nbd_ioctl()'s socket
+   clearing code so the page cache is cleaned, lest reads that hit on the
+   page cache will return stale data from the previously-accessible disk.
+
+Example:
+
+    # qemu-nbd -r -c/dev/nbd0 /dev/sr0
+    # file -s /dev/nbd0
+    /dev/stdin: # UDF filesystem data (version 1.5) etc.
+    # qemu-nbd -d /dev/nbd0
+    # qemu-nbd -r -c/dev/nbd0 /dev/sda
+    # file -s /dev/nbd0
+    /dev/stdin: # UDF filesystem data (version 1.5) etc.
+
+While /dev/sda has:
+
+    # file -s /dev/sda
+    /dev/sda: x86 boot sector; etc.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Acked-by: Paul Clements <Paul.Clements@steeleye.com>
+Cc: Alex Bligh <alex@alex.org.uk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/nbd.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -595,12 +595,20 @@ static int __nbd_ioctl(struct block_devi
+               struct request sreq;
+               dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
++              if (!nbd->sock)
++                      return -EINVAL;
++              mutex_unlock(&nbd->tx_lock);
++              fsync_bdev(bdev);
++              mutex_lock(&nbd->tx_lock);
+               blk_rq_init(NULL, &sreq);
+               sreq.cmd_type = REQ_TYPE_SPECIAL;
+               nbd_cmd(&sreq) = NBD_CMD_DISC;
++
++              /* Check again after getting mutex back.  */
+               if (!nbd->sock)
+                       return -EINVAL;
++
+               nbd_send_req(nbd, &sreq);
+                 return 0;
+       }
+@@ -614,6 +622,7 @@ static int __nbd_ioctl(struct block_devi
+               nbd_clear_que(nbd);
+               BUG_ON(!list_empty(&nbd->queue_head));
+               BUG_ON(!list_empty(&nbd->waiting_queue));
++              kill_bdev(bdev);
+               if (file)
+                       fput(file);
+               return 0;
+@@ -702,6 +711,7 @@ static int __nbd_ioctl(struct block_devi
+               nbd->file = NULL;
+               nbd_clear_que(nbd);
+               dev_warn(disk_to_dev(nbd->disk), "queue cleared\n");
++              kill_bdev(bdev);
+               queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
+               if (file)
+                       fput(file);
index fc1e7472a195197515e9e3bcdf8ca3f6bff94a3d..b1dbfec70c823a4894d1567a8967812730012bcf 100644 (file)
@@ -30,3 +30,18 @@ ocfs2-fix-possible-use-after-free-with-aio.patch
 ocfs2-fix-ocfs2_init_security_and_acl-to-initialize-acl-correctly.patch
 ocfs2-ac-ac_allow_chain_relink-0-won-t-disable-group-relink.patch
 block-fix-ext_devt_idr-handling.patch
+xen-blkback-do-not-leak-mode-property.patch
+xen-blkback-don-t-trust-the-handle-from-the-frontend.patch
+xen-blkfront-drop-the-use-of-llist_for_each_entry_safe.patch
+xen-blkback-use-balloon-pages-for-persistent-grants.patch
+idr-fix-a-subtle-bug-in-idr_get_next.patch
+block-fix-synchronization-and-limit-check-in-blk_alloc_devt.patch
+firewire-add-minor-number-range-check-to-fw_device_init.patch
+sysctl-fix-null-checking-in-bin_dn_node_address.patch
+nbd-fsync-and-kill-block-device-on-shutdown.patch
+fs-fix-possible-use-after-free-with-aio.patch
+ext4-fix-possible-use-after-free-with-aio.patch
+media-cx18-ivtv-fix-regression-remove-__init-from-a-non-init-function.patch
+media-v4l-reset-subdev-v4l2_dev-field-to-null-if-registration-fails.patch
+media-omap_vout-find_vma-needs-mmap_sem-held.patch
+media-rc-unlock-on-error-in-show_protocols.patch
diff --git a/queue-3.8/sysctl-fix-null-checking-in-bin_dn_node_address.patch b/queue-3.8/sysctl-fix-null-checking-in-bin_dn_node_address.patch
new file mode 100644 (file)
index 0000000..d1a58a9
--- /dev/null
@@ -0,0 +1,36 @@
+From df1778be1a33edffa51d094eeda87c858ded6560 Mon Sep 17 00:00:00 2001
+From: Xi Wang <xi.wang@gmail.com>
+Date: Wed, 27 Feb 2013 17:05:21 -0800
+Subject: sysctl: fix null checking in bin_dn_node_address()
+
+From: Xi Wang <xi.wang@gmail.com>
+
+commit df1778be1a33edffa51d094eeda87c858ded6560 upstream.
+
+The null check of `strchr() + 1' is broken, which is always non-null,
+leading to OOB read.  Instead, check the result of strchr().
+
+Signed-off-by: Xi Wang <xi.wang@gmail.com>
+Cc: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sysctl_binary.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kernel/sysctl_binary.c
++++ b/kernel/sysctl_binary.c
+@@ -1194,9 +1194,10 @@ static ssize_t bin_dn_node_address(struc
+               /* Convert the decnet address to binary */
+               result = -EIO;
+-              nodep = strchr(buf, '.') + 1;
++              nodep = strchr(buf, '.');
+               if (!nodep)
+                       goto out;
++              ++nodep;
+               area = simple_strtoul(buf, NULL, 10);
+               node = simple_strtoul(nodep, NULL, 10);
diff --git a/queue-3.8/xen-blkback-do-not-leak-mode-property.patch b/queue-3.8/xen-blkback-do-not-leak-mode-property.patch
new file mode 100644 (file)
index 0000000..bbbe677
--- /dev/null
@@ -0,0 +1,113 @@
+From 9d092603cc306ee6edfe917bf9ab8beb5f32d7bc Mon Sep 17 00:00:00 2001
+From: Jan Beulich <JBeulich@suse.com>
+Date: Thu, 20 Dec 2012 10:31:11 +0000
+Subject: xen-blkback: do not leak mode property
+
+From: Jan Beulich <JBeulich@suse.com>
+
+commit 9d092603cc306ee6edfe917bf9ab8beb5f32d7bc upstream.
+
+"be->mode" is obtained from xenbus_read(), which does a kmalloc() for
+the message body. The short string is never released, so do it along
+with freeing "be" itself, and make sure the string isn't kept when
+backend_changed() doesn't complete successfully (which made it
+desirable to slightly re-structure that function, so that the error
+cleanup can be done in one place).
+
+Reported-by: Olaf Hering <olaf@aepfle.de>
+Signed-off-by: Jan Beulich <jbeulich@suse.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 |   49 ++++++++++++++++++-------------------
+ 1 file changed, 24 insertions(+), 25 deletions(-)
+
+--- a/drivers/block/xen-blkback/xenbus.c
++++ b/drivers/block/xen-blkback/xenbus.c
+@@ -367,6 +367,7 @@ static int xen_blkbk_remove(struct xenbu
+               be->blkif = NULL;
+       }
++      kfree(be->mode);
+       kfree(be);
+       dev_set_drvdata(&dev->dev, NULL);
+       return 0;
+@@ -502,6 +503,7 @@ static void backend_changed(struct xenbu
+               = container_of(watch, struct backend_info, backend_watch);
+       struct xenbus_device *dev = be->dev;
+       int cdrom = 0;
++      unsigned long handle;
+       char *device_type;
+       DPRINTK("");
+@@ -521,10 +523,10 @@ static void backend_changed(struct xenbu
+               return;
+       }
+-      if ((be->major || be->minor) &&
+-          ((be->major != major) || (be->minor != minor))) {
+-              pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
+-                      be->major, be->minor, major, minor);
++      if (be->major | be->minor) {
++              if (be->major != major || be->minor != minor)
++                      pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
++                              be->major, be->minor, major, minor);
+               return;
+       }
+@@ -542,36 +544,33 @@ static void backend_changed(struct xenbu
+               kfree(device_type);
+       }
+-      if (be->major == 0 && be->minor == 0) {
+-              /* Front end dir is a number, which is used as the handle. */
++      /* Front end dir is a number, which is used as the handle. */
++      err = strict_strtoul(strrchr(dev->otherend, '/') + 1, 0, &handle);
++      if (err)
++              return;
+-              char *p = strrchr(dev->otherend, '/') + 1;
+-              long handle;
+-              err = strict_strtoul(p, 0, &handle);
+-              if (err)
+-                      return;
++      be->major = major;
++      be->minor = minor;
+-              be->major = major;
+-              be->minor = minor;
+-
+-              err = xen_vbd_create(be->blkif, handle, major, minor,
+-                               (NULL == strchr(be->mode, 'w')), cdrom);
+-              if (err) {
+-                      be->major = 0;
+-                      be->minor = 0;
+-                      xenbus_dev_fatal(dev, err, "creating vbd structure");
+-                      return;
+-              }
++      err = xen_vbd_create(be->blkif, handle, major, minor,
++                           !strchr(be->mode, 'w'), cdrom);
++      if (err)
++              xenbus_dev_fatal(dev, err, "creating vbd structure");
++      else {
+               err = xenvbd_sysfs_addif(dev);
+               if (err) {
+                       xen_vbd_free(&be->blkif->vbd);
+-                      be->major = 0;
+-                      be->minor = 0;
+                       xenbus_dev_fatal(dev, err, "creating sysfs entries");
+-                      return;
+               }
++      }
++      if (err) {
++              kfree(be->mode);
++              be->mode = NULL;
++              be->major = 0;
++              be->minor = 0;
++      } else {
+               /* We're potentially connected now */
+               xen_update_blkif_status(be->blkif);
+       }
diff --git a/queue-3.8/xen-blkback-don-t-trust-the-handle-from-the-frontend.patch b/queue-3.8/xen-blkback-don-t-trust-the-handle-from-the-frontend.patch
new file mode 100644 (file)
index 0000000..6bf3b5d
--- /dev/null
@@ -0,0 +1,38 @@
+From 01c681d4c70d64cb72142a2823f27c4146a02e63 Mon Sep 17 00:00:00 2001
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Wed, 16 Jan 2013 11:36:23 -0500
+Subject: xen/blkback: Don't trust the handle from the frontend.
+
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+
+commit 01c681d4c70d64cb72142a2823f27c4146a02e63 upstream.
+
+The 'handle' is the device that the request is from. For the life-time
+of the ring we copy it from a request to a response so that the frontend
+is not surprised by it. But we do not need it - when we start processing
+I/Os we have our own 'struct phys_req' which has only most essential
+information about the request. In fact the 'vbd_translate' ends up
+over-writing the preq.dev with a value from the backend.
+
+This assignment of preq.dev with the 'handle' value is superfluous
+so lets not do it.
+
+Acked-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.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 deletion(-)
+
+--- a/drivers/block/xen-blkback/blkback.c
++++ b/drivers/block/xen-blkback/blkback.c
+@@ -879,7 +879,6 @@ static int dispatch_rw_block_io(struct x
+               goto fail_response;
+       }
+-      preq.dev           = req->u.rw.handle;
+       preq.sector_number = req->u.rw.sector_number;
+       preq.nr_sects      = 0;
diff --git a/queue-3.8/xen-blkback-use-balloon-pages-for-persistent-grants.patch b/queue-3.8/xen-blkback-use-balloon-pages-for-persistent-grants.patch
new file mode 100644 (file)
index 0000000..5afbe96
--- /dev/null
@@ -0,0 +1,53 @@
+From 087ffecdaa1875cc683a7a5bc0695b3ebfce3bad Mon Sep 17 00:00:00 2001
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Thu, 14 Feb 2013 11:12:09 +0100
+Subject: xen-blkback: use balloon pages for persistent grants
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit 087ffecdaa1875cc683a7a5bc0695b3ebfce3bad upstream.
+
+With current persistent grants implementation we are not freeing the
+persistent grants after we disconnect the device. Since grant map
+operations change the mfn of the allocated page, and we can no longer
+pass it to __free_page without setting the mfn to a sane value, use
+balloon grant pages instead, as the gntdev device does.
+
+Signed-off-by: Roger Pau MonnĂ© <roger.pau@citrix.com>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.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 |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/block/xen-blkback/blkback.c
++++ b/drivers/block/xen-blkback/blkback.c
+@@ -46,6 +46,7 @@
+ #include <xen/xen.h>
+ #include <asm/xen/hypervisor.h>
+ #include <asm/xen/hypercall.h>
++#include <xen/balloon.h>
+ #include "common.h"
+ /*
+@@ -239,6 +240,7 @@ static void free_persistent_gnts(struct
+                       ret = gnttab_unmap_refs(unmap, NULL, pages,
+                               segs_to_unmap);
+                       BUG_ON(ret);
++                      free_xenballooned_pages(segs_to_unmap, pages);
+                       segs_to_unmap = 0;
+               }
+@@ -527,8 +529,8 @@ static int xen_blkbk_map(struct blkif_re
+                               GFP_KERNEL);
+                       if (!persistent_gnt)
+                               return -ENOMEM;
+-                      persistent_gnt->page = alloc_page(GFP_KERNEL);
+-                      if (!persistent_gnt->page) {
++                      if (alloc_xenballooned_pages(1, &persistent_gnt->page,
++                          false)) {
+                               kfree(persistent_gnt);
+                               return -ENOMEM;
+                       }
diff --git a/queue-3.8/xen-blkfront-drop-the-use-of-llist_for_each_entry_safe.patch b/queue-3.8/xen-blkfront-drop-the-use-of-llist_for_each_entry_safe.patch
new file mode 100644 (file)
index 0000000..aa3fdb3
--- /dev/null
@@ -0,0 +1,141 @@
+From f84adf4921ae3115502f44ff467b04bf2f88cf04 Mon Sep 17 00:00:00 2001
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Wed, 13 Feb 2013 13:01:55 -0500
+Subject: xen-blkfront: drop the use of llist_for_each_entry_safe
+
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+
+commit f84adf4921ae3115502f44ff467b04bf2f88cf04 upstream.
+
+Replace llist_for_each_entry_safe with a while loop.
+
+llist_for_each_entry_safe can trigger a bug in GCC 4.1, so it's best
+to remove it and use a while loop and do the deletion manually.
+
+Specifically this bug can be triggered by hot-unplugging a disk, either
+by doing xm block-detach or by save/restore cycle.
+
+BUG: unable to handle kernel paging request at fffffffffffffff0
+IP: [<ffffffffa0047223>] blkif_free+0x63/0x130 [xen_blkfront]
+The crash call trace is:
+       ...
+bad_area_nosemaphore+0x13/0x20
+do_page_fault+0x25e/0x4b0
+page_fault+0x25/0x30
+? blkif_free+0x63/0x130 [xen_blkfront]
+blkfront_resume+0x46/0xa0 [xen_blkfront]
+xenbus_dev_resume+0x6c/0x140
+pm_op+0x192/0x1b0
+device_resume+0x82/0x1e0
+dpm_resume+0xc9/0x1a0
+dpm_resume_end+0x15/0x30
+do_suspend+0x117/0x1e0
+
+When drilling down to the assembler code, on newer GCC it does
+.L29:
+        cmpq    $-16, %r12      #, persistent_gnt check
+        je      .L30           #, out of the loop
+.L25:
+       ... code in the loop
+        testq   %r13, %r13      # n
+        je      .L29           #, back to the top of the loop
+        cmpq    $-16, %r12      #, persistent_gnt check
+        movq    16(%r12), %r13  # <variable>.node.next, n
+        jne     .L25           #,      back to the top of the loop
+.L30:
+
+While on GCC 4.1, it is:
+L78:
+       ... code in the loop
+       testq   %r13, %r13      # n
+        je      .L78    #,     back to the top of the loop
+        movq    16(%rbx), %r13  # <variable>.node.next, n
+        jmp     .L78    #,     back to the top of the loop
+
+Which basically means that the exit loop condition instead of
+being:
+
+       &(pos)->member != NULL;
+
+is:
+       ;
+
+which makes the loop unbound.
+
+Since xen-blkfront is the only user of the llist_for_each_entry_safe
+macro remove it from llist.h.
+
+Orabug: 16263164
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/xen-blkfront.c |   13 ++++++++++---
+ include/linux/llist.h        |   25 -------------------------
+ 2 files changed, 10 insertions(+), 28 deletions(-)
+
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -791,7 +791,7 @@ static void blkif_restart_queue(struct w
+ static void blkif_free(struct blkfront_info *info, int suspend)
+ {
+       struct llist_node *all_gnts;
+-      struct grant *persistent_gnt;
++      struct grant *persistent_gnt, *tmp;
+       struct llist_node *n;
+       /* Prevent new requests being issued until we fix things up. */
+@@ -805,10 +805,17 @@ static void blkif_free(struct blkfront_i
+       /* Remove all persistent grants */
+       if (info->persistent_gnts_c) {
+               all_gnts = llist_del_all(&info->persistent_gnts);
+-              llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) {
++              persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node);
++              while (persistent_gnt) {
+                       gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
+                       __free_page(pfn_to_page(persistent_gnt->pfn));
+-                      kfree(persistent_gnt);
++                      tmp = persistent_gnt;
++                      n = persistent_gnt->node.next;
++                      if (n)
++                              persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node);
++                      else
++                              persistent_gnt = NULL;
++                      kfree(tmp);
+               }
+               info->persistent_gnts_c = 0;
+       }
+--- a/include/linux/llist.h
++++ b/include/linux/llist.h
+@@ -125,31 +125,6 @@ static inline void init_llist_head(struc
+            (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))
+ /**
+- * llist_for_each_entry_safe - iterate safely against remove over some entries
+- * of lock-less list of given type.
+- * @pos:      the type * to use as a loop cursor.
+- * @n:                another type * to use as a temporary storage.
+- * @node:     the fist entry of deleted list entries.
+- * @member:   the name of the llist_node with the struct.
+- *
+- * In general, some entries of the lock-less list can be traversed
+- * safely only after being removed from list, so start with an entry
+- * instead of list head. This variant allows removal of entries
+- * as we iterate.
+- *
+- * If being used on entries deleted from lock-less list directly, the
+- * traverse order is from the newest to the oldest added entry.  If
+- * you want to traverse from the oldest to the newest, you must
+- * reverse the order by yourself before traversing.
+- */
+-#define llist_for_each_entry_safe(pos, n, node, member)               \
+-      for ((pos) = llist_entry((node), typeof(*(pos)), member),       \
+-           (n) = (pos)->member.next;                                  \
+-           &(pos)->member != NULL;                                    \
+-           (pos) = llist_entry(n, typeof(*(pos)), member),            \
+-           (n) = (&(pos)->member != NULL) ? (pos)->member.next : NULL)
+-
+-/**
+  * llist_empty - tests whether a lock-less list is empty
+  * @head:     the list to test
+  *