]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Mar 2013 04:25:48 +0000 (12:25 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Mar 2013 04:25:48 +0000 (12:25 +0800)
added patches:
btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch
cifs-ensure-that-cifs_get_root-only-traverses-directories.patch
nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch
scsi-dc395x-uninitialized-variable-in-device_alloc.patch
scsi-storvsc-initialize-the-sglist.patch
sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch
target-pscsi-fix-page-increment.patch
xen-pci-we-don-t-do-multiple-msi-s.patch

queue-3.4/btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch [new file with mode: 0644]
queue-3.4/cifs-ensure-that-cifs_get_root-only-traverses-directories.patch [new file with mode: 0644]
queue-3.4/nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch [new file with mode: 0644]
queue-3.4/scsi-dc395x-uninitialized-variable-in-device_alloc.patch [new file with mode: 0644]
queue-3.4/scsi-storvsc-initialize-the-sglist.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch [new file with mode: 0644]
queue-3.4/target-pscsi-fix-page-increment.patch [new file with mode: 0644]
queue-3.4/xen-pci-we-don-t-do-multiple-msi-s.patch [new file with mode: 0644]

diff --git a/queue-3.4/btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch b/queue-3.4/btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch
new file mode 100644 (file)
index 0000000..31156a8
--- /dev/null
@@ -0,0 +1,37 @@
+From 1cba0cdf5e4dbcd9e5fa5b54d7a028e55e2ca057 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Wed, 20 Feb 2013 14:06:20 -0500
+Subject: btrfs: Init io_lock after cloning btrfs device struct
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 1cba0cdf5e4dbcd9e5fa5b54d7a028e55e2ca057 upstream.
+
+__btrfs_close_devices() clones btrfs device structs with
+memcpy(). Some of the fields in the clone are reinitialized, but it's
+missing to init io_lock. In mainline this goes unnoticed, but on RT it
+leaves the plist pointing to the original about to be freed lock
+struct.
+
+Initialize io_lock after cloning, so no references to the original
+struct are left.
+
+Reported-and-tested-by: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Chris Mason <chris.mason@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/volumes.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -557,6 +557,7 @@ static int __btrfs_close_devices(struct
+               new_device->writeable = 0;
+               new_device->in_fs_metadata = 0;
+               new_device->can_discard = 0;
++              spin_lock_init(&new_device->io_lock);
+               list_replace_rcu(&device->dev_list, &new_device->dev_list);
+               call_rcu(&device->rcu, free_device);
diff --git a/queue-3.4/cifs-ensure-that-cifs_get_root-only-traverses-directories.patch b/queue-3.4/cifs-ensure-that-cifs_get_root-only-traverses-directories.patch
new file mode 100644 (file)
index 0000000..001196f
--- /dev/null
@@ -0,0 +1,92 @@
+From ce2ac52105aa663056dfc17966ebed1bf93e6e64 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Fri, 1 Feb 2013 15:11:01 -0500
+Subject: cifs: ensure that cifs_get_root() only traverses directories
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit ce2ac52105aa663056dfc17966ebed1bf93e6e64 upstream.
+
+Kjell Braden reported this oops:
+
+[  833.211970] BUG: unable to handle kernel NULL pointer dereference at           (null)
+[  833.212816] IP: [<          (null)>]           (null)
+[  833.213280] PGD 1b9b2067 PUD e9f7067 PMD 0
+[  833.213874] Oops: 0010 [#1] SMP
+[  833.214344] CPU 0
+[  833.214458] Modules linked in: des_generic md4 nls_utf8 cifs vboxvideo drm snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq bnep rfcomm snd_timer bluetooth snd_seq_device ppdev snd vboxguest parport_pc joydev mac_hid soundcore snd_page_alloc psmouse i2c_piix4 serio_raw lp parport usbhid hid e1000
+[  833.215629]
+[  833.215629] Pid: 1752, comm: mount.cifs Not tainted 3.0.0-rc7-bisectcifs-fec11dd9a0+ #18 innotek GmbH VirtualBox/VirtualBox
+[  833.215629] RIP: 0010:[<0000000000000000>]  [<          (null)>]           (null)
+[  833.215629] RSP: 0018:ffff8800119c9c50  EFLAGS: 00010282
+[  833.215629] RAX: ffffffffa02186c0 RBX: ffff88000c427780 RCX: 0000000000000000
+[  833.215629] RDX: 0000000000000000 RSI: ffff88000c427780 RDI: ffff88000c4362e8
+[  833.215629] RBP: ffff8800119c9c88 R08: ffff88001fc15e30 R09: 00000000d69515c7
+[  833.215629] R10: ffffffffa0201972 R11: ffff88000e8f6a28 R12: ffff88000c4362e8
+[  833.215629] R13: 0000000000000000 R14: 0000000000000000 R15: ffff88001181aaa6
+[  833.215629] FS:  00007f2986171700(0000) GS:ffff88001fc00000(0000) knlGS:0000000000000000
+[  833.215629] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
+[  833.215629] CR2: 0000000000000000 CR3: 000000001b982000 CR4: 00000000000006f0
+[  833.215629] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[  833.215629] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+[  833.215629] Process mount.cifs (pid: 1752, threadinfo ffff8800119c8000, task ffff88001c1c16f0)
+[  833.215629] Stack:
+[  833.215629]  ffffffff8116a9b5 ffff8800119c9c88 ffffffff81178075 0000000000000286
+[  833.215629]  0000000000000000 ffff88000c4276c0 ffff8800119c9ce8 ffff8800119c9cc8
+[  833.215629]  ffffffff8116b06e ffff88001bc6fc00 ffff88000c4276c0 ffff88000c4276c0
+[  833.215629] Call Trace:
+[  833.215629]  [<ffffffff8116a9b5>] ? d_alloc_and_lookup+0x45/0x90
+[  833.215629]  [<ffffffff81178075>] ? d_lookup+0x35/0x60
+[  833.215629]  [<ffffffff8116b06e>] __lookup_hash.part.14+0x9e/0xc0
+[  833.215629]  [<ffffffff8116b1d6>] lookup_one_len+0x146/0x1e0
+[  833.215629]  [<ffffffff815e4f7e>] ? _raw_spin_lock+0xe/0x20
+[  833.215629]  [<ffffffffa01eef0d>] cifs_do_mount+0x26d/0x500 [cifs]
+[  833.215629]  [<ffffffff81163bd3>] mount_fs+0x43/0x1b0
+[  833.215629]  [<ffffffff8117d41a>] vfs_kern_mount+0x6a/0xd0
+[  833.215629]  [<ffffffff8117e584>] do_kern_mount+0x54/0x110
+[  833.215629]  [<ffffffff8117fdc2>] do_mount+0x262/0x840
+[  833.215629]  [<ffffffff81108a0e>] ? __get_free_pages+0xe/0x50
+[  833.215629]  [<ffffffff8117f9ca>] ? copy_mount_options+0x3a/0x180
+[  833.215629]  [<ffffffff8118075d>] sys_mount+0x8d/0xe0
+[  833.215629]  [<ffffffff815ece82>] system_call_fastpath+0x16/0x1b
+[  833.215629] Code:  Bad RIP value.
+[  833.215629] RIP  [<          (null)>]           (null)
+[  833.215629]  RSP <ffff8800119c9c50>
+[  833.215629] CR2: 0000000000000000
+[  833.238525] ---[ end trace ec00758b8d44f529 ]---
+
+When walking down the path on the server, it's possible to hit a
+symlink. The path walking code assumes that the caller will handle that
+situation properly, but cifs_get_root() isn't set up for it. This patch
+prevents the oops by simply returning an error.
+
+A better solution would be to try and chase the symlinks here, but that's
+fairly complicated to handle.
+
+Fixes:
+
+    https://bugzilla.kernel.org/show_bug.cgi?id=53221
+
+Reported-and-tested-by: Kjell Braden <afflux@pentabarf.de>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsfs.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -557,6 +557,11 @@ cifs_get_root(struct smb_vol *vol, struc
+                       dentry = ERR_PTR(-ENOENT);
+                       break;
+               }
++              if (!S_ISDIR(dir->i_mode)) {
++                      dput(dentry);
++                      dentry = ERR_PTR(-ENOTDIR);
++                      break;
++              }
+               /* skip separators */
+               while (*s == sep)
diff --git a/queue-3.4/nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch b/queue-3.4/nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch
new file mode 100644 (file)
index 0000000..1776071
--- /dev/null
@@ -0,0 +1,90 @@
+From 5a7a613a47a715711b3f2d3322a0eac21d459166 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 22 Feb 2013 12:53:43 -0500
+Subject: NFS: Don't allow NFS silly-renamed files to be deleted, no signal
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 5a7a613a47a715711b3f2d3322a0eac21d459166 upstream.
+
+Commit 73ca100 broke the code that prevents the client from deleting
+a silly renamed dentry.  This affected "delete on last close"
+semantics as after that commit, nothing prevented removal of
+silly-renamed files.  As a result, a process holding a file open
+could easily get an ESTALE on the file in a directory where some
+other process issued 'rm -rf some_dir_containing_the_file' twice.
+Before the commit, any attempt at unlinking silly renamed files would
+fail inside may_delete() with -EBUSY because of the
+DCACHE_NFSFS_RENAMED flag.  The following testcase demonstrates
+the problem:
+  tail -f /nfsmnt/dir/file &
+  rm -rf /nfsmnt/dir
+  rm -rf /nfsmnt/dir
+  # second removal does not fail, 'tail' process receives ESTALE
+
+The problem with the above commit is that it unhashes the old and
+new dentries from the lookup path, even in the normal case when
+a signal is not encountered and it would have been safe to call
+d_move.  Unfortunately the old dentry has the special
+DCACHE_NFSFS_RENAMED flag set on it.  Unhashing has the
+side-effect that future lookups call d_alloc(), allocating a new
+dentry without the special flag for any silly-renamed files.  As a
+result, subsequent calls to unlink silly renamed files do not fail
+but allow the removal to go through.  This will result in ESTALE
+errors for any other process doing operations on the file.
+
+To fix this, go back to using d_move on success.
+For the signal case, it's unclear what we may safely do beyond d_drop.
+
+Reported-by: Dave Wysochanski <dwysocha@redhat.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Acked-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/unlink.c |   20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+--- a/fs/nfs/unlink.c
++++ b/fs/nfs/unlink.c
+@@ -336,20 +336,14 @@ static void nfs_async_rename_done(struct
+       struct inode *old_dir = data->old_dir;
+       struct inode *new_dir = data->new_dir;
+       struct dentry *old_dentry = data->old_dentry;
+-      struct dentry *new_dentry = data->new_dentry;
+       if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
+               rpc_restart_call_prepare(task);
+               return;
+       }
+-      if (task->tk_status != 0) {
++      if (task->tk_status != 0)
+               nfs_cancel_async_unlink(old_dentry);
+-              return;
+-      }
+-
+-      d_drop(old_dentry);
+-      d_drop(new_dentry);
+ }
+ /**
+@@ -550,6 +544,18 @@ nfs_sillyrename(struct inode *dir, struc
+       error = rpc_wait_for_completion_task(task);
+       if (error == 0)
+               error = task->tk_status;
++      switch (error) {
++      case 0:
++              /* The rename succeeded */
++              nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
++              d_move(dentry, sdentry);
++              break;
++      case -ERESTARTSYS:
++              /* The result of the rename is unknown. Play it safe by
++               * forcing a new lookup */
++              d_drop(dentry);
++              d_drop(sdentry);
++      }
+       rpc_put_task(task);
+ out_dput:
+       dput(sdentry);
diff --git a/queue-3.4/scsi-dc395x-uninitialized-variable-in-device_alloc.patch b/queue-3.4/scsi-dc395x-uninitialized-variable-in-device_alloc.patch
new file mode 100644 (file)
index 0000000..9bed4a2
--- /dev/null
@@ -0,0 +1,38 @@
+From 208afec4f3be8c51ad6eebe6611dd6d2ad2fa298 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 11 Feb 2013 22:03:18 +0300
+Subject: SCSI: dc395x: uninitialized variable in device_alloc()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 208afec4f3be8c51ad6eebe6611dd6d2ad2fa298 upstream.
+
+This bug was introduced back in bitkeeper days in 2003.  We use
+"dcb->dev_mode" before it has been initialized.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Oliver Neukum <oliver@neukum.org>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/dc395x.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/dc395x.c
++++ b/drivers/scsi/dc395x.c
+@@ -3747,13 +3747,13 @@ static struct DeviceCtlBlk *device_alloc
+       dcb->max_command = 1;
+       dcb->target_id = target;
+       dcb->target_lun = lun;
++      dcb->dev_mode = eeprom->target[target].cfg0;
+ #ifndef DC395x_NO_DISCONNECT
+       dcb->identify_msg =
+           IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun);
+ #else
+       dcb->identify_msg = IDENTIFY(0, lun);
+ #endif
+-      dcb->dev_mode = eeprom->target[target].cfg0;
+       dcb->inquiry7 = 0;
+       dcb->sync_mode = 0;
+       dcb->min_nego_period = clock_period[period_index];
diff --git a/queue-3.4/scsi-storvsc-initialize-the-sglist.patch b/queue-3.4/scsi-storvsc-initialize-the-sglist.patch
new file mode 100644 (file)
index 0000000..bcc97c6
--- /dev/null
@@ -0,0 +1,29 @@
+From 9d2696e658ef4f209955ddaa987d43f1a1bd81a1 Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Wed, 6 Feb 2013 05:15:28 -0800
+Subject: SCSI: storvsc: Initialize the sglist
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit 9d2696e658ef4f209955ddaa987d43f1a1bd81a1 upstream.
+
+Properly initialize scatterlist before using it.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/storvsc_drv.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -467,6 +467,7 @@ static struct scatterlist *create_bounce
+       if (!bounce_sgl)
+               return NULL;
++      sg_init_table(bounce_sgl, num_pages);
+       for (i = 0; i < num_pages; i++) {
+               page_buf = alloc_page(GFP_ATOMIC);
+               if (!page_buf)
index c1c383c8e7c92d3f5684176412631e34b05d7908..c55b44b5641343726eea342e61a369714b2a0362 100644 (file)
@@ -1,2 +1,10 @@
 arm-vfp-fix-emulation-of-second-vfp-instruction.patch
 arm-fix-scheduling-while-atomic-warning-in-alignment-handling-code.patch
+xen-pci-we-don-t-do-multiple-msi-s.patch
+scsi-dc395x-uninitialized-variable-in-device_alloc.patch
+scsi-storvsc-initialize-the-sglist.patch
+target-pscsi-fix-page-increment.patch
+btrfs-init-io_lock-after-cloning-btrfs-device-struct.patch
+cifs-ensure-that-cifs_get_root-only-traverses-directories.patch
+nfs-don-t-allow-nfs-silly-renamed-files-to-be-deleted-no-signal.patch
+sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch
diff --git a/queue-3.4/sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch b/queue-3.4/sunrpc-don-t-start-the-retransmission-timer-when-out-of-socket-space.patch
new file mode 100644 (file)
index 0000000..9f31e79
--- /dev/null
@@ -0,0 +1,45 @@
+From a9a6b52ee1baa865283a91eb8d443ee91adfca56 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 22 Feb 2013 14:57:57 -0500
+Subject: SUNRPC: Don't start the retransmission timer when out of socket space
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit a9a6b52ee1baa865283a91eb8d443ee91adfca56 upstream.
+
+If the socket is full, we're better off just waiting until it empties,
+or until the connection is broken. The reason why we generally don't
+want to time out is that the call to xprt->ops->release_xprt() will
+trigger a connection reset, which isn't helpful...
+
+Let's make an exception for soft RPC calls, since they have to provide
+timeout guarantees.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/xprt.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -485,13 +485,17 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_task
+  * xprt_wait_for_buffer_space - wait for transport output buffer to clear
+  * @task: task to be put to sleep
+  * @action: function pointer to be executed after wait
++ *
++ * Note that we only set the timer for the case of RPC_IS_SOFT(), since
++ * we don't in general want to force a socket disconnection due to
++ * an incomplete RPC call transmission.
+  */
+ void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
+ {
+       struct rpc_rqst *req = task->tk_rqstp;
+       struct rpc_xprt *xprt = req->rq_xprt;
+-      task->tk_timeout = req->rq_timeout;
++      task->tk_timeout = RPC_IS_SOFT(task) ? req->rq_timeout : 0;
+       rpc_sleep_on(&xprt->pending, task, action);
+ }
+ EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
diff --git a/queue-3.4/target-pscsi-fix-page-increment.patch b/queue-3.4/target-pscsi-fix-page-increment.patch
new file mode 100644 (file)
index 0000000..1a1a89a
--- /dev/null
@@ -0,0 +1,31 @@
+From 472b72f2db7831d7dbe22ffdff4adee3bd49b05d Mon Sep 17 00:00:00 2001
+From: Asias He <asias@redhat.com>
+Date: Wed, 27 Feb 2013 13:29:29 +0800
+Subject: target/pscsi: Fix page increment
+
+From: Asias He <asias@redhat.com>
+
+commit 472b72f2db7831d7dbe22ffdff4adee3bd49b05d upstream.
+
+The page++ is wrong. It makes bio_add_pc_page() pointing to a wrong page
+address if the 'while (len > 0 && data_len > 0) { ... }' loop is
+executed more than one once.
+
+Signed-off-by: Asias He <asias@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_pscsi.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/target/target_core_pscsi.c
++++ b/drivers/target/target_core_pscsi.c
+@@ -1042,7 +1042,6 @@ static int pscsi_map_sg(struct se_task *
+                               bio = NULL;
+                       }
+-                      page++;
+                       len -= bytes;
+                       data_len -= bytes;
+                       off = 0;
diff --git a/queue-3.4/xen-pci-we-don-t-do-multiple-msi-s.patch b/queue-3.4/xen-pci-we-don-t-do-multiple-msi-s.patch
new file mode 100644 (file)
index 0000000..c49e888
--- /dev/null
@@ -0,0 +1,74 @@
+From 884ac2978a295b7df3c4a686d3bff6932bbbb460 Mon Sep 17 00:00:00 2001
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Thu, 28 Feb 2013 09:05:41 -0500
+Subject: xen/pci: We don't do multiple MSI's.
+
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+
+commit 884ac2978a295b7df3c4a686d3bff6932bbbb460 upstream.
+
+There is no hypercall to setup multiple MSI per PCI device.
+As such with these two new commits:
+-  08261d87f7d1b6253ab3223756625a5c74532293
+   PCI/MSI: Enable multiple MSIs with pci_enable_msi_block_auto()
+- 5ca72c4f7c412c2002363218901eba5516c476b1
+   AHCI: Support multiple MSIs
+
+we would call the PHYSDEVOP_map_pirq 'nvec' times with the same
+contents of the PCI device. Sander discovered that we would get
+the same PIRQ value 'nvec' times and return said values to the
+caller. That of course meant that the device was configured only
+with one MSI and AHCI would fail with:
+
+ahci 0000:00:11.0: version 3.0
+xen: registering gsi 19 triggering 0 polarity 1
+xen: --> pirq=19 -> irq=19 (gsi=19)
+(XEN) [2013-02-27 19:43:07] IOAPIC[0]: Set PCI routing entry (6-19 -> 0x99 -> IRQ 19 Mode:1 Active:1)
+ahci 0000:00:11.0: AHCI 0001.0200 32 slots 4 ports 6 Gbps 0xf impl SATA mode
+ahci 0000:00:11.0: flags: 64bit ncq sntf ilck pm led clo pmp pio slum part
+ahci: probe of 0000:00:11.0 failed with error -22
+
+That is b/c in ahci_host_activate the second call to
+devm_request_threaded_irq  would return -EINVAL as we passed in
+(on the second run) an IRQ that was never initialized.
+
+Reported-and-Tested-by: Sander Eikelenboom <linux@eikelenboom.it>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/pci/xen.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/x86/pci/xen.c
++++ b/arch/x86/pci/xen.c
+@@ -162,6 +162,9 @@ static int xen_setup_msi_irqs(struct pci
+       struct msi_desc *msidesc;
+       int *v;
++      if (type == PCI_CAP_ID_MSI && nvec > 1)
++              return 1;
++
+       v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL);
+       if (!v)
+               return -ENOMEM;
+@@ -220,6 +223,9 @@ static int xen_hvm_setup_msi_irqs(struct
+       struct msi_desc *msidesc;
+       struct msi_msg msg;
++      if (type == PCI_CAP_ID_MSI && nvec > 1)
++              return 1;
++
+       list_for_each_entry(msidesc, &dev->msi_list, list) {
+               __read_msi_msg(msidesc, &msg);
+               pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
+@@ -263,6 +269,9 @@ static int xen_initdom_setup_msi_irqs(st
+       int ret = 0;
+       struct msi_desc *msidesc;
++      if (type == PCI_CAP_ID_MSI && nvec > 1)
++              return 1;
++
+       list_for_each_entry(msidesc, &dev->msi_list, list) {
+               struct physdev_map_pirq map_irq;
+               domid_t domid;