]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.13-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Feb 2014 16:37:05 +0000 (08:37 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Feb 2014 16:37:05 +0000 (08:37 -0800)
added patches:
cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch
cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch
nfs-do-not-set-nfs_ino_invalid_label-unless-server-supports-labeled-nfs.patch
nfs-fix-error-return-in-nfs4_select_rw_stateid.patch
rtl8187-fix-regression-on-mips-without-coherent-dma.patch
rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch
rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch

queue-3.13/cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch [new file with mode: 0644]
queue-3.13/cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch [new file with mode: 0644]
queue-3.13/nfs-do-not-set-nfs_ino_invalid_label-unless-server-supports-labeled-nfs.patch [new file with mode: 0644]
queue-3.13/nfs-fix-error-return-in-nfs4_select_rw_stateid.patch [new file with mode: 0644]
queue-3.13/rtl8187-fix-regression-on-mips-without-coherent-dma.patch [new file with mode: 0644]
queue-3.13/rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch [new file with mode: 0644]
queue-3.13/rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch [new file with mode: 0644]
queue-3.13/series

diff --git a/queue-3.13/cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch b/queue-3.13/cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch
new file mode 100644 (file)
index 0000000..40408c0
--- /dev/null
@@ -0,0 +1,98 @@
+From 5d81de8e8667da7135d3a32a964087c0faf5483f Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Fri, 14 Feb 2014 07:20:35 -0500
+Subject: cifs: ensure that uncached writes handle unmapped areas correctly
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 5d81de8e8667da7135d3a32a964087c0faf5483f upstream.
+
+It's possible for userland to pass down an iovec via writev() that has a
+bogus user pointer in it. If that happens and we're doing an uncached
+write, then we can end up getting less bytes than we expect from the
+call to iov_iter_copy_from_user. This is CVE-2014-0069
+
+cifs_iovec_write isn't set up to handle that situation however. It'll
+blindly keep chugging through the page array and not filling those pages
+with anything useful. Worse yet, we'll later end up with a negative
+number in wdata->tailsz, which will confuse the sending routines and
+cause an oops at the very least.
+
+Fix this by having the copy phase of cifs_iovec_write stop copying data
+in this situation and send the last write as a short one. At the same
+time, we want to avoid sending a zero-length write to the server, so
+break out of the loop and set rc to -EFAULT if that happens. This also
+allows us to handle the case where no address in the iovec is valid.
+
+[Note: Marking this for stable on v3.4+ kernels, but kernels as old as
+       v2.6.38 may have a similar problem and may need similar fix]
+
+Reviewed-by: Pavel Shilovsky <piastry@etersoft.ru>
+Reported-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/file.c |   37 ++++++++++++++++++++++++++++++++++---
+ 1 file changed, 34 insertions(+), 3 deletions(-)
+
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -2381,7 +2381,7 @@ cifs_iovec_write(struct file *file, cons
+                unsigned long nr_segs, loff_t *poffset)
+ {
+       unsigned long nr_pages, i;
+-      size_t copied, len, cur_len;
++      size_t bytes, copied, len, cur_len;
+       ssize_t total_written = 0;
+       loff_t offset;
+       struct iov_iter it;
+@@ -2436,14 +2436,45 @@ cifs_iovec_write(struct file *file, cons
+               save_len = cur_len;
+               for (i = 0; i < nr_pages; i++) {
+-                      copied = min_t(const size_t, cur_len, PAGE_SIZE);
++                      bytes = min_t(const size_t, cur_len, PAGE_SIZE);
+                       copied = iov_iter_copy_from_user(wdata->pages[i], &it,
+-                                                       0, copied);
++                                                       0, bytes);
+                       cur_len -= copied;
+                       iov_iter_advance(&it, copied);
++                      /*
++                       * If we didn't copy as much as we expected, then that
++                       * may mean we trod into an unmapped area. Stop copying
++                       * at that point. On the next pass through the big
++                       * loop, we'll likely end up getting a zero-length
++                       * write and bailing out of it.
++                       */
++                      if (copied < bytes)
++                              break;
+               }
+               cur_len = save_len - cur_len;
++              /*
++               * If we have no data to send, then that probably means that
++               * the copy above failed altogether. That's most likely because
++               * the address in the iovec was bogus. Set the rc to -EFAULT,
++               * free anything we allocated and bail out.
++               */
++              if (!cur_len) {
++                      for (i = 0; i < nr_pages; i++)
++                              put_page(wdata->pages[i]);
++                      kfree(wdata);
++                      rc = -EFAULT;
++                      break;
++              }
++
++              /*
++               * i + 1 now represents the number of pages we actually used in
++               * the copy phase above. Bring nr_pages down to that, and free
++               * any pages that we didn't use.
++               */
++              for ( ; nr_pages > i + 1; nr_pages--)
++                      put_page(wdata->pages[nr_pages - 1]);
++
+               wdata->sync_mode = WB_SYNC_ALL;
+               wdata->nr_pages = nr_pages;
+               wdata->offset = (__u64)offset;
diff --git a/queue-3.13/cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch b/queue-3.13/cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch
new file mode 100644 (file)
index 0000000..d91ea8f
--- /dev/null
@@ -0,0 +1,79 @@
+From 2365c4eaf077c48574ab6f143960048fc0f31518 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <piastry@etersoft.ru>
+Date: Fri, 14 Feb 2014 13:31:02 +0400
+Subject: CIFS: Fix too big maxBuf size for SMB3 mounts
+
+From: Pavel Shilovsky <piastry@etersoft.ru>
+
+commit 2365c4eaf077c48574ab6f143960048fc0f31518 upstream.
+
+SMB3 servers can respond with MaxTransactSize of more than 4M
+that can cause a memory allocation error returned from kmalloc
+in a lock codepath. Also the client doesn't support multicredit
+requests now and allows buffer sizes of 65536 bytes only. Set
+MaxTransactSize to this maximum supported value.
+
+Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
+Acked-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2glob.h |    3 +++
+ fs/cifs/smb2ops.c  |   14 ++++----------
+ fs/cifs/smb2pdu.c  |    4 +++-
+ 3 files changed, 10 insertions(+), 11 deletions(-)
+
+--- a/fs/cifs/smb2glob.h
++++ b/fs/cifs/smb2glob.h
+@@ -57,4 +57,7 @@
+ #define SMB2_CMACAES_SIZE (16)
+ #define SMB3_SIGNKEY_SIZE (16)
++/* Maximum buffer size value we can send with 1 credit */
++#define SMB2_MAX_BUFFER_SIZE 65536
++
+ #endif        /* _SMB2_GLOB_H */
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -182,11 +182,8 @@ smb2_negotiate_wsize(struct cifs_tcon *t
+       /* start with specified wsize, or default */
+       wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
+       wsize = min_t(unsigned int, wsize, server->max_write);
+-      /*
+-       * limit write size to 2 ** 16, because we don't support multicredit
+-       * requests now.
+-       */
+-      wsize = min_t(unsigned int, wsize, 2 << 15);
++      /* set it to the maximum buffer size value we can send with 1 credit */
++      wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
+       return wsize;
+ }
+@@ -200,11 +197,8 @@ smb2_negotiate_rsize(struct cifs_tcon *t
+       /* start with specified rsize, or default */
+       rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
+       rsize = min_t(unsigned int, rsize, server->max_read);
+-      /*
+-       * limit write size to 2 ** 16, because we don't support multicredit
+-       * requests now.
+-       */
+-      rsize = min_t(unsigned int, rsize, 2 << 15);
++      /* set it to the maximum buffer size value we can send with 1 credit */
++      rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE);
+       return rsize;
+ }
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -413,7 +413,9 @@ SMB2_negotiate(const unsigned int xid, s
+       /* SMB2 only has an extended negflavor */
+       server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
+-      server->maxBuf = le32_to_cpu(rsp->MaxTransactSize);
++      /* set it to the maximum buffer size value we can send with 1 credit */
++      server->maxBuf = min_t(unsigned int, le32_to_cpu(rsp->MaxTransactSize),
++                             SMB2_MAX_BUFFER_SIZE);
+       server->max_read = le32_to_cpu(rsp->MaxReadSize);
+       server->max_write = le32_to_cpu(rsp->MaxWriteSize);
+       /* BB Do we need to validate the SecurityMode? */
diff --git a/queue-3.13/nfs-do-not-set-nfs_ino_invalid_label-unless-server-supports-labeled-nfs.patch b/queue-3.13/nfs-do-not-set-nfs_ino_invalid_label-unless-server-supports-labeled-nfs.patch
new file mode 100644 (file)
index 0000000..91e0562
--- /dev/null
@@ -0,0 +1,114 @@
+From fd1defc257e2b12ab69bc0b379105c00eca4e112 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Thu, 6 Feb 2014 14:38:53 -0500
+Subject: NFS: Do not set NFS_INO_INVALID_LABEL unless server supports labeled NFS
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit fd1defc257e2b12ab69bc0b379105c00eca4e112 upstream.
+
+Commit aa9c2669626c (NFS: Client implementation of Labeled-NFS) introduces
+a performance regression. When nfs_zap_caches_locked is called, it sets
+the NFS_INO_INVALID_LABEL flag irrespectively of whether or not the
+NFS server supports security labels. Since that flag is never cleared,
+it means that all calls to nfs_revalidate_inode() will now trigger
+an on-the-wire GETATTR call.
+
+This patch ensures that we never set the NFS_INO_INVALID_LABEL unless the
+server advertises support for labeled NFS.
+It also causes nfs_setsecurity() to clear NFS_INO_INVALID_LABEL when it
+has successfully set the security label for the inode.
+Finally it gets rid of the NFS_INO_INVALID_LABEL cruft from nfs_update_inode,
+which has nothing to do with labeled NFS.
+
+Reported-by: Neil Brown <neilb@suse.de>
+Tested-by: Neil Brown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/inode.c    |   14 ++++++++++----
+ fs/nfs/internal.h |    9 +++++++++
+ 2 files changed, 19 insertions(+), 4 deletions(-)
+
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -164,17 +164,16 @@ static void nfs_zap_caches_locked(struct
+       if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
+               nfs_fscache_invalidate(inode);
+               nfsi->cache_validity |= NFS_INO_INVALID_ATTR
+-                                      | NFS_INO_INVALID_LABEL
+                                       | NFS_INO_INVALID_DATA
+                                       | NFS_INO_INVALID_ACCESS
+                                       | NFS_INO_INVALID_ACL
+                                       | NFS_INO_REVAL_PAGECACHE;
+       } else
+               nfsi->cache_validity |= NFS_INO_INVALID_ATTR
+-                                      | NFS_INO_INVALID_LABEL
+                                       | NFS_INO_INVALID_ACCESS
+                                       | NFS_INO_INVALID_ACL
+                                       | NFS_INO_REVAL_PAGECACHE;
++      nfs_zap_label_cache_locked(nfsi);
+ }
+ void nfs_zap_caches(struct inode *inode)
+@@ -266,6 +265,13 @@ nfs_init_locked(struct inode *inode, voi
+ }
+ #ifdef CONFIG_NFS_V4_SECURITY_LABEL
++static void nfs_clear_label_invalid(struct inode *inode)
++{
++      spin_lock(&inode->i_lock);
++      NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_LABEL;
++      spin_unlock(&inode->i_lock);
++}
++
+ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
+                                       struct nfs4_label *label)
+ {
+@@ -283,6 +289,7 @@ void nfs_setsecurity(struct inode *inode
+                                       __func__,
+                                       (char *)label->label,
+                                       label->len, error);
++              nfs_clear_label_invalid(inode);
+       }
+ }
+@@ -1597,7 +1604,7 @@ static int nfs_update_inode(struct inode
+               inode->i_blocks = fattr->du.nfs2.blocks;
+       /* Update attrtimeo value if we're out of the unstable period */
+-      if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) {
++      if (invalid & NFS_INO_INVALID_ATTR) {
+               nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
+               nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
+               nfsi->attrtimeo_timestamp = now;
+@@ -1610,7 +1617,6 @@ static int nfs_update_inode(struct inode
+               }
+       }
+       invalid &= ~NFS_INO_INVALID_ATTR;
+-      invalid &= ~NFS_INO_INVALID_LABEL;
+       /* Don't invalidate the data if we were to blame */
+       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
+                               || S_ISLNK(inode->i_mode)))
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -279,9 +279,18 @@ static inline void nfs4_label_free(struc
+       }
+       return;
+ }
++
++static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
++{
++      if (nfs_server_capable(&nfsi->vfs_inode, NFS_CAP_SECURITY_LABEL))
++              nfsi->cache_validity |= NFS_INO_INVALID_LABEL;
++}
+ #else
+ static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
+ static inline void nfs4_label_free(void *label) {}
++static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
++{
++}
+ #endif /* CONFIG_NFS_V4_SECURITY_LABEL */
+ /* proc.c */
diff --git a/queue-3.13/nfs-fix-error-return-in-nfs4_select_rw_stateid.patch b/queue-3.13/nfs-fix-error-return-in-nfs4_select_rw_stateid.patch
new file mode 100644 (file)
index 0000000..c7cd7a3
--- /dev/null
@@ -0,0 +1,37 @@
+From 146d70caaa1b87f64597743429d7da4b8073d0c9 Mon Sep 17 00:00:00 2001
+From: Andy Adamson <andros@netapp.com>
+Date: Tue, 18 Feb 2014 10:36:05 -0500
+Subject: NFS fix error return in nfs4_select_rw_stateid
+
+From: Andy Adamson <andros@netapp.com>
+
+commit 146d70caaa1b87f64597743429d7da4b8073d0c9 upstream.
+
+Do not return an error when nfs4_copy_delegation_stateid succeeds.
+
+Signed-off-by: Andy Adamson <andros@netapp.com>
+Link: http://lkml.kernel.org/r/1392737765-41942-1-git-send-email-andros@netapp.com
+Fixes: ef1820f9be27b (NFSv4: Don't try to recover NFSv4 locks when...)
+Cc: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4state.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1015,8 +1015,11 @@ int nfs4_select_rw_stateid(nfs4_stateid
+       if (ret == -EIO)
+               /* A lost lock - don't even consider delegations */
+               goto out;
+-      if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
++      /* returns true if delegation stateid found and copied */
++      if (nfs4_copy_delegation_stateid(dst, state->inode, fmode)) {
++              ret = 0;
+               goto out;
++      }
+       if (ret != -ENOENT)
+               /* nfs4_copy_delegation_stateid() didn't over-write
+                * dst, so it still has the lock stateid which we now
diff --git a/queue-3.13/rtl8187-fix-regression-on-mips-without-coherent-dma.patch b/queue-3.13/rtl8187-fix-regression-on-mips-without-coherent-dma.patch
new file mode 100644 (file)
index 0000000..b5744a2
--- /dev/null
@@ -0,0 +1,83 @@
+From b6213e413a4e0c66548153516b074df14f9d08e0 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <stf_xl@wp.pl>
+Date: Mon, 10 Feb 2014 22:38:28 +0100
+Subject: rtl8187: fix regression on MIPS without coherent DMA
+
+From: Stanislaw Gruszka <stf_xl@wp.pl>
+
+commit b6213e413a4e0c66548153516b074df14f9d08e0 upstream.
+
+This patch fixes regression caused by commit a16dad77634 "MIPS: Fix
+potencial corruption". That commit fixes one corruption scenario in
+cost of adding another one, which actually start to cause crashes
+on Yeeloong laptop when rtl8187 driver is used.
+
+For correct DMA read operation on machines without DMA coherence, kernel
+have to invalidate cache, such it will refill later with new data that
+device wrote to memory, when that data is needed to process. We can only
+invalidate full cache line. Hence when cache line includes both dma
+buffer and some other data (written in cache, but not yet in main
+memory), the other data can not hit memory due to invalidation. That
+happen on rtl8187 where struct rtl8187_priv fields are located just
+before and after small buffers that are passed to USB layer and DMA
+is performed on them.
+
+To fix the problem we align buffers and reserve space after them to make
+them match cache line.
+
+This patch does not resolve all possible MIPS problems entirely, for
+that we have to assure that we always map cache aligned buffers for DMA,
+what can be complex or even not possible. But patch fixes visible and
+reproducible regression and seems other possible corruptions do not
+happen in practice, since Yeeloong laptop works stable without rtl8187
+driver.
+
+Bug report:
+https://bugzilla.kernel.org/show_bug.cgi?id=54391
+
+Reported-by: Petr Pisar <petr.pisar@atlas.cz>
+Bisected-by: Tom Li <biergaizi2009@gmail.com>
+Reported-and-tested-by: Tom Li <biergaizi2009@gmail.com>
+Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Acked-by: Larry Finger <Larry.Finger@lwfinger.next>
+Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtl818x/rtl8187/rtl8187.h |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
++++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
+@@ -15,6 +15,8 @@
+ #ifndef RTL8187_H
+ #define RTL8187_H
++#include <linux/cache.h>
++
+ #include "rtl818x.h"
+ #include "leds.h"
+@@ -139,7 +141,10 @@ struct rtl8187_priv {
+       u8 aifsn[4];
+       u8 rfkill_mask;
+       struct {
+-              __le64 buf;
++              union {
++                      __le64 buf;
++                      u8 dummy1[L1_CACHE_BYTES];
++              } ____cacheline_aligned;
+               struct sk_buff_head queue;
+       } b_tx_status; /* This queue is used by both -b and non-b devices */
+       struct mutex io_mutex;
+@@ -147,7 +152,8 @@ struct rtl8187_priv {
+               u8 bits8;
+               __le16 bits16;
+               __le32 bits32;
+-      } *io_dmabuf;
++              u8 dummy2[L1_CACHE_BYTES];
++      } *io_dmabuf ____cacheline_aligned;
+       bool rfkill_off;
+       u16 seqno;
+ };
diff --git a/queue-3.13/rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch b/queue-3.13/rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch
new file mode 100644 (file)
index 0000000..30c345c
--- /dev/null
@@ -0,0 +1,35 @@
+From 2e8c5e56b307271c2dab6f8bfd1d8a3822ca2390 Mon Sep 17 00:00:00 2001
+From: Olivier Langlois <olivier@trillion01.com>
+Date: Sat, 1 Feb 2014 01:11:10 -0500
+Subject: rtlwifi: Fix incorrect return from rtl_ps_enable_nic()
+
+From: Olivier Langlois <olivier@trillion01.com>
+
+commit 2e8c5e56b307271c2dab6f8bfd1d8a3822ca2390 upstream.
+
+rtl_ps_enable_nic() is called from loops that will loop until this function returns true or a
+maximum number of retries is performed.
+
+hw_init() returns non-zero on error. In that situation return false to
+restore the original design intent to retry hw init when it fails.
+
+Signed-off-by: Olivier Langlois <olivier@trillion01.com>
+Acked-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/ps.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rtlwifi/ps.c
++++ b/drivers/net/wireless/rtlwifi/ps.c
+@@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_
+       /*<2> Enable Adapter */
+       if (rtlpriv->cfg->ops->hw_init(hw))
+-              return 1;
++              return false;
+       RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+       /*<3> Enable Interrupt */
diff --git a/queue-3.13/rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch b/queue-3.13/rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch
new file mode 100644 (file)
index 0000000..21d0d90
--- /dev/null
@@ -0,0 +1,118 @@
+From f78bccd79ba3cd9d9664981b501d57bdb81ab8a4 Mon Sep 17 00:00:00 2001
+From: Olivier Langlois <olivier@trillion01.com>
+Date: Sat, 1 Feb 2014 01:11:09 -0500
+Subject: rtlwifi: rtl8192ce: Fix too long disable of IRQs
+
+From: Olivier Langlois <olivier@trillion01.com>
+
+commit f78bccd79ba3cd9d9664981b501d57bdb81ab8a4 upstream.
+
+rtl8192ce is disabling for too long the local interrupts during hw initiatialisation when performing scans
+
+The observable symptoms in dmesg can be:
+
+- underruns from ALSA playback
+- clock freezes (tstamps do not change for several dmesg entries until irqs are finaly reenabled):
+
+[  250.817669] rtlwifi:rtl_op_config():<0-0-0> 0x100
+[  250.817685] rtl8192ce:_rtl92ce_phy_set_rf_power_state():<0-1-0> IPS Set eRf nic enable
+[  250.817732] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.817796] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.817910] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818024] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818139] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818253] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818367] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11
+[  250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:98053f15:10
+[  250.818472] rtl8192ce:rtl92ce_sw_led_on():<0-1-0> LedAddr:4E ledpin=1
+[  250.818472] rtl8192c_common:rtl92c_download_fw():<0-1-0> Firmware Version(49), Signature(0x88c1),Size(32)
+[  250.818472] rtl8192ce:rtl92ce_enable_hw_security_config():<0-1-0> PairwiseEncAlgorithm = 0 GroupEncAlgorithm = 0
+[  250.818472] rtl8192ce:rtl92ce_enable_hw_security_config():<0-1-0> The SECR-value cc
+[  250.818472] rtl8192c_common:rtl92c_dm_check_txpower_tracking_thermal_meter():<0-1-0> Schedule TxPowerTracking direct call!!
+[  250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> rtl92c_dm_txpower_tracking_callback_thermalmeter
+[  250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Readback Thermal Meter = 0xe pre thermal meter 0xf eeprom_thermalmeter 0xf
+[  250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Initial pathA ele_d reg0xc80 = 0x40000000, ofdm_index=0xc
+[  250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Initial reg0xa24 = 0x90e1317, cck_index=0xc, ch14 0
+[  250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Readback Thermal Meter = 0xe pre thermal meter 0xf eeprom_thermalmeter 0xf delta 0x1 delta_lck 0x0 delta_iqk 0x0
+[  250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> <===
+[  250.818472] rtl8192c_common:rtl92c_dm_initialize_txpower_tracking_thermalmeter():<0-1-0> pMgntInfo->txpower_tracking = 1
+[  250.818472] rtl8192ce:rtl92ce_led_control():<0-1-0> ledaction 3
+[  250.818472] rtl8192ce:rtl92ce_sw_led_on():<0-1-0> LedAddr:4E ledpin=1
+[  250.818472] rtlwifi:rtl_ips_nic_on():<0-1-0> before spin_unlock_irqrestore
+[  251.154656] PCM: Lost interrupts? [Q]-0 (stream=0, delta=15903, new_hw_ptr=293408, old_hw_ptr=277505)
+
+The exact code flow that causes that is:
+
+1. wpa_supplicant send a start_scan request to the nl80211 driver
+2. mac80211 module call rtl_op_config with IEEE80211_CONF_CHANGE_IDLE
+3.   rtl_ips_nic_on is called which disable local irqs
+4.     rtl92c_phy_set_rf_power_state() is called
+5.       rtl_ps_enable_nic() is called and hw_init()is executed and then the interrupts on the device are enabled
+
+A good solution could be to refactor the code to avoid calling rtl92ce_hw_init() with the irqs disabled
+but a quick and dirty solution that has proven to work is
+to reenable the irqs during the function rtl92ce_hw_init().
+
+I think that it is safe doing so since the device interrupt will only be enabled after the init function succeed.
+
+Signed-off-by: Olivier Langlois <olivier@trillion01.com>
+Acked-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/rtl8192ce/hw.c |   18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+@@ -937,14 +937,26 @@ int rtl92ce_hw_init(struct ieee80211_hw
+       bool is92c;
+       int err;
+       u8 tmp_u1b;
++      unsigned long flags;
+       rtlpci->being_init_adapter = true;
++
++      /* Since this function can take a very long time (up to 350 ms)
++       * and can be called with irqs disabled, reenable the irqs
++       * to let the other devices continue being serviced.
++       *
++       * It is safe doing so since our own interrupts will only be enabled
++       * in a subsequent step.
++       */
++      local_save_flags(flags);
++      local_irq_enable();
++
+       rtlpriv->intf_ops->disable_aspm(hw);
+       rtstatus = _rtl92ce_init_mac(hw);
+       if (!rtstatus) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
+               err = 1;
+-              return err;
++              goto exit;
+       }
+       err = rtl92c_download_fw(hw);
+@@ -952,7 +964,7 @@ int rtl92ce_hw_init(struct ieee80211_hw
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                        "Failed to download FW. Init HW without FW now..\n");
+               err = 1;
+-              return err;
++              goto exit;
+       }
+       rtlhal->last_hmeboxnum = 0;
+@@ -1032,6 +1044,8 @@ int rtl92ce_hw_init(struct ieee80211_hw
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
+       }
+       rtl92c_dm_init(hw);
++exit:
++      local_irq_restore(flags);
+       rtlpci->being_init_adapter = false;
+       return err;
+ }
index bca72000158a5731efbcc7ba9e798b18e9c4ba63..04ddf68ecf44623e25cd6063763f1ddb9df0599d 100644 (file)
@@ -26,3 +26,10 @@ powerpc-powernv-rework-eeh-reset.patch
 jbd2-fix-use-after-free-in-jbd2_journal_start_reserved.patch
 avr32-fix-missing-module.h-causing-build-failure-in-mimc200-fram.c.patch
 avr32-makefile-add-d__linux__-flag-for-gcc-4.4.7-use.patch
+cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch
+cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch
+rtl8187-fix-regression-on-mips-without-coherent-dma.patch
+rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch
+rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch
+nfs-do-not-set-nfs_ino_invalid_label-unless-server-supports-labeled-nfs.patch
+nfs-fix-error-return-in-nfs4_select_rw_stateid.patch