]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Dec 2017 14:02:15 +0000 (15:02 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Dec 2017 14:02:15 +0000 (15:02 +0100)
added patches:
drm-i915-don-t-try-indexed-reads-to-alternate-slave-addresses.patch
drm-i915-prevent-zero-length-index-write.patch
nfsd-fix-another-open-stateid-race.patch
nfsd-fix-stateid-races-between-open-and-close.patch
nfsd-make-init_open_stateid-a-bit-more-whole.patch

queue-4.4/drm-i915-don-t-try-indexed-reads-to-alternate-slave-addresses.patch [new file with mode: 0644]
queue-4.4/drm-i915-prevent-zero-length-index-write.patch [new file with mode: 0644]
queue-4.4/nfsd-fix-another-open-stateid-race.patch [new file with mode: 0644]
queue-4.4/nfsd-fix-stateid-races-between-open-and-close.patch [new file with mode: 0644]
queue-4.4/nfsd-make-init_open_stateid-a-bit-more-whole.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/drm-i915-don-t-try-indexed-reads-to-alternate-slave-addresses.patch b/queue-4.4/drm-i915-don-t-try-indexed-reads-to-alternate-slave-addresses.patch
new file mode 100644 (file)
index 0000000..8f91104
--- /dev/null
@@ -0,0 +1,42 @@
+From ae5c631e605a452a5a0e73205a92810c01ed954b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 23 Nov 2017 21:41:56 +0200
+Subject: drm/i915: Don't try indexed reads to alternate slave addresses
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit ae5c631e605a452a5a0e73205a92810c01ed954b upstream.
+
+We can only specify the one slave address to indexed reads/writes.
+Make sure the messages we check are destined to the same slave
+address before deciding to do an indexed transfer.
+
+Cc: Daniel Kurtz <djkurtz@chromium.org>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Sean Paul <seanpaul@chromium.org>
+Fixes: 56f9eac05489 ("drm/i915/intel_i2c: use INDEX cycles for i2c read transactions")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20171123194157.25367-2-ville.syrjala@linux.intel.com
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+(cherry picked from commit c4deb62d7821672265b87952bcd1c808f3bf3e8f)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_i2c.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/i915/intel_i2c.c
++++ b/drivers/gpu/drm/i915/intel_i2c.c
+@@ -440,6 +440,7 @@ static bool
+ gmbus_is_index_read(struct i2c_msg *msgs, int i, int num)
+ {
+       return (i + 1 < num &&
++              msgs[i].addr == msgs[i + 1].addr &&
+               !(msgs[i].flags & I2C_M_RD) && msgs[i].len <= 2 &&
+               (msgs[i + 1].flags & I2C_M_RD));
+ }
diff --git a/queue-4.4/drm-i915-prevent-zero-length-index-write.patch b/queue-4.4/drm-i915-prevent-zero-length-index-write.patch
new file mode 100644 (file)
index 0000000..8917e61
--- /dev/null
@@ -0,0 +1,44 @@
+From 56350fb8978bbf4aafe08f21234e161dd128b417 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 23 Nov 2017 21:41:57 +0200
+Subject: drm/i915: Prevent zero length "index" write
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 56350fb8978bbf4aafe08f21234e161dd128b417 upstream.
+
+The hardware always writes one or two bytes in the index portion of
+an indexed transfer. Make sure the message we send as the index
+doesn't have a zero length.
+
+Cc: Daniel Kurtz <djkurtz@chromium.org>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Sean Paul <seanpaul@chromium.org>
+Fixes: 56f9eac05489 ("drm/i915/intel_i2c: use INDEX cycles for i2c read transactions")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20171123194157.25367-3-ville.syrjala@linux.intel.com
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+(cherry picked from commit bb9e0d4bca50f429152e74a459160b41f3d60fb2)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_i2c.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/intel_i2c.c
++++ b/drivers/gpu/drm/i915/intel_i2c.c
+@@ -441,7 +441,8 @@ gmbus_is_index_read(struct i2c_msg *msgs
+ {
+       return (i + 1 < num &&
+               msgs[i].addr == msgs[i + 1].addr &&
+-              !(msgs[i].flags & I2C_M_RD) && msgs[i].len <= 2 &&
++              !(msgs[i].flags & I2C_M_RD) &&
++              (msgs[i].len == 1 || msgs[i].len == 2) &&
+               (msgs[i + 1].flags & I2C_M_RD));
+ }
diff --git a/queue-4.4/nfsd-fix-another-open-stateid-race.patch b/queue-4.4/nfsd-fix-another-open-stateid-race.patch
new file mode 100644 (file)
index 0000000..97d4ab4
--- /dev/null
@@ -0,0 +1,91 @@
+From d8a1a000555ecd1b824ac1ed6df8fe364dfbbbb0 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Fri, 3 Nov 2017 08:00:11 -0400
+Subject: nfsd: Fix another OPEN stateid race
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit d8a1a000555ecd1b824ac1ed6df8fe364dfbbbb0 upstream.
+
+If nfsd4_process_open2() is initialising a new stateid, and yet the
+call to nfs4_get_vfs_file() fails for some reason, then we must
+declare the stateid closed, and unhash it before dropping the mutex.
+
+Right now, we unhash the stateid after dropping the mutex, and without
+changing the stateid type, meaning that another OPEN could theoretically
+look it up and attempt to use it.
+
+Reported-by: Andrew W Elble <aweits@rit.edu>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4state.c |   28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -4319,6 +4319,7 @@ nfsd4_process_open2(struct svc_rqst *rqs
+       struct nfs4_ol_stateid *stp = NULL;
+       struct nfs4_delegation *dp = NULL;
+       __be32 status;
++      bool new_stp = false;
+       /*
+        * Lookup file; if found, lookup stateid and check open request,
+@@ -4338,11 +4339,19 @@ nfsd4_process_open2(struct svc_rqst *rqs
+                       goto out;
+       }
++      if (!stp) {
++              stp = init_open_stateid(fp, open);
++              if (!open->op_stp)
++                      new_stp = true;
++      }
++
+       /*
+        * OPEN the file, or upgrade an existing OPEN.
+        * If truncate fails, the OPEN fails.
++       *
++       * stp is already locked.
+        */
+-      if (stp) {
++      if (!new_stp) {
+               /* Stateid was found, this is an OPEN upgrade */
+               status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
+               if (status) {
+@@ -4350,22 +4359,11 @@ nfsd4_process_open2(struct svc_rqst *rqs
+                       goto out;
+               }
+       } else {
+-              /* stp is returned locked. */
+-              stp = init_open_stateid(fp, open);
+-              /* See if we lost the race to some other thread */
+-              if (stp->st_access_bmap != 0) {
+-                      status = nfs4_upgrade_open(rqstp, fp, current_fh,
+-                                              stp, open);
+-                      if (status) {
+-                              mutex_unlock(&stp->st_mutex);
+-                              goto out;
+-                      }
+-                      goto upgrade_out;
+-              }
+               status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
+               if (status) {
+-                      mutex_unlock(&stp->st_mutex);
++                      stp->st_stid.sc_type = NFS4_CLOSED_STID;
+                       release_open_stateid(stp);
++                      mutex_unlock(&stp->st_mutex);
+                       goto out;
+               }
+@@ -4374,7 +4372,7 @@ nfsd4_process_open2(struct svc_rqst *rqs
+               if (stp->st_clnt_odstate == open->op_odstate)
+                       open->op_odstate = NULL;
+       }
+-upgrade_out:
++
+       nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
+       mutex_unlock(&stp->st_mutex);
diff --git a/queue-4.4/nfsd-fix-stateid-races-between-open-and-close.patch b/queue-4.4/nfsd-fix-stateid-races-between-open-and-close.patch
new file mode 100644 (file)
index 0000000..fd7174c
--- /dev/null
@@ -0,0 +1,153 @@
+From 15ca08d3299682dc49bad73251677b2c5017ef08 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Fri, 3 Nov 2017 08:00:10 -0400
+Subject: nfsd: Fix stateid races between OPEN and CLOSE
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 15ca08d3299682dc49bad73251677b2c5017ef08 upstream.
+
+Open file stateids can linger on the nfs4_file list of stateids even
+after they have been closed. In order to avoid reusing such a
+stateid, and confusing the client, we need to recheck the
+nfs4_stid's type after taking the mutex.
+Otherwise, we risk reusing an old stateid that was already closed,
+which will confuse clients that expect new stateids to conform to
+RFC7530 Sections 9.1.4.2 and 16.2.5 or RFC5661 Sections 8.2.2 and 18.2.4.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4state.c |   67 +++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 59 insertions(+), 8 deletions(-)
+
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -3379,7 +3379,9 @@ nfsd4_find_existing_open(struct nfs4_fil
+               /* ignore lock owners */
+               if (local->st_stateowner->so_is_open_owner == 0)
+                       continue;
+-              if (local->st_stateowner == &oo->oo_owner) {
++              if (local->st_stateowner != &oo->oo_owner)
++                      continue;
++              if (local->st_stid.sc_type == NFS4_OPEN_STID) {
+                       ret = local;
+                       atomic_inc(&ret->st_stid.sc_count);
+                       break;
+@@ -3388,6 +3390,52 @@ nfsd4_find_existing_open(struct nfs4_fil
+       return ret;
+ }
++static __be32
++nfsd4_verify_open_stid(struct nfs4_stid *s)
++{
++      __be32 ret = nfs_ok;
++
++      switch (s->sc_type) {
++      default:
++              break;
++      case NFS4_CLOSED_STID:
++      case NFS4_CLOSED_DELEG_STID:
++              ret = nfserr_bad_stateid;
++              break;
++      case NFS4_REVOKED_DELEG_STID:
++              ret = nfserr_deleg_revoked;
++      }
++      return ret;
++}
++
++/* Lock the stateid st_mutex, and deal with races with CLOSE */
++static __be32
++nfsd4_lock_ol_stateid(struct nfs4_ol_stateid *stp)
++{
++      __be32 ret;
++
++      mutex_lock(&stp->st_mutex);
++      ret = nfsd4_verify_open_stid(&stp->st_stid);
++      if (ret != nfs_ok)
++              mutex_unlock(&stp->st_mutex);
++      return ret;
++}
++
++static struct nfs4_ol_stateid *
++nfsd4_find_and_lock_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
++{
++      struct nfs4_ol_stateid *stp;
++      for (;;) {
++              spin_lock(&fp->fi_lock);
++              stp = nfsd4_find_existing_open(fp, open);
++              spin_unlock(&fp->fi_lock);
++              if (!stp || nfsd4_lock_ol_stateid(stp) == nfs_ok)
++                      break;
++              nfs4_put_stid(&stp->st_stid);
++      }
++      return stp;
++}
++
+ static struct nfs4_openowner *
+ alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
+                          struct nfsd4_compound_state *cstate)
+@@ -3432,6 +3480,7 @@ init_open_stateid(struct nfs4_file *fp,
+       mutex_init(&stp->st_mutex);
+       mutex_lock(&stp->st_mutex);
++retry:
+       spin_lock(&oo->oo_owner.so_client->cl_lock);
+       spin_lock(&fp->fi_lock);
+@@ -3456,7 +3505,11 @@ out_unlock:
+       spin_unlock(&fp->fi_lock);
+       spin_unlock(&oo->oo_owner.so_client->cl_lock);
+       if (retstp) {
+-              mutex_lock(&retstp->st_mutex);
++              /* Handle races with CLOSE */
++              if (nfsd4_lock_ol_stateid(retstp) != nfs_ok) {
++                      nfs4_put_stid(&retstp->st_stid);
++                      goto retry;
++              }
+               /* To keep mutex tracking happy */
+               mutex_unlock(&stp->st_mutex);
+               stp = retstp;
+@@ -4277,9 +4330,7 @@ nfsd4_process_open2(struct svc_rqst *rqs
+               status = nfs4_check_deleg(cl, open, &dp);
+               if (status)
+                       goto out;
+-              spin_lock(&fp->fi_lock);
+-              stp = nfsd4_find_existing_open(fp, open);
+-              spin_unlock(&fp->fi_lock);
++              stp = nfsd4_find_and_lock_existing_open(fp, open);
+       } else {
+               open->op_file = NULL;
+               status = nfserr_bad_stateid;
+@@ -4293,7 +4344,6 @@ nfsd4_process_open2(struct svc_rqst *rqs
+        */
+       if (stp) {
+               /* Stateid was found, this is an OPEN upgrade */
+-              mutex_lock(&stp->st_mutex);
+               status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
+               if (status) {
+                       mutex_unlock(&stp->st_mutex);
+@@ -5150,7 +5200,6 @@ static void nfsd4_close_open_stateid(str
+       bool unhashed;
+       LIST_HEAD(reaplist);
+-      s->st_stid.sc_type = NFS4_CLOSED_STID;
+       spin_lock(&clp->cl_lock);
+       unhashed = unhash_open_stateid(s, &reaplist);
+@@ -5189,10 +5238,12 @@ nfsd4_close(struct svc_rqst *rqstp, stru
+       nfsd4_bump_seqid(cstate, status);
+       if (status)
+               goto out; 
++
++      stp->st_stid.sc_type = NFS4_CLOSED_STID;
+       nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
+-      mutex_unlock(&stp->st_mutex);
+       nfsd4_close_open_stateid(stp);
++      mutex_unlock(&stp->st_mutex);
+       /* put reference from nfs4_preprocess_seqid_op */
+       nfs4_put_stid(&stp->st_stid);
diff --git a/queue-4.4/nfsd-make-init_open_stateid-a-bit-more-whole.patch b/queue-4.4/nfsd-make-init_open_stateid-a-bit-more-whole.patch
new file mode 100644 (file)
index 0000000..18047b9
--- /dev/null
@@ -0,0 +1,92 @@
+From 8c7245abda877d4689b3371db8ae2a4400d7d9ce Mon Sep 17 00:00:00 2001
+From: Oleg Drokin <green@linuxhacker.ru>
+Date: Tue, 14 Jun 2016 23:28:06 -0400
+Subject: nfsd: Make init_open_stateid() a bit more whole
+
+From: Oleg Drokin <green@linuxhacker.ru>
+
+commit 8c7245abda877d4689b3371db8ae2a4400d7d9ce upstream.
+
+Move the state selection logic inside from the caller,
+always making it return correct stp to use.
+
+Signed-off-by: J . Bruce Fields <bfields@fieldses.org>
+Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4state.c |   27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -3420,13 +3420,14 @@ alloc_init_open_stateowner(unsigned int
+ }
+ static struct nfs4_ol_stateid *
+-init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
+-              struct nfsd4_open *open)
++init_open_stateid(struct nfs4_file *fp, struct nfsd4_open *open)
+ {
+       struct nfs4_openowner *oo = open->op_openowner;
+       struct nfs4_ol_stateid *retstp = NULL;
++      struct nfs4_ol_stateid *stp;
++      stp = open->op_stp;
+       /* We are moving these outside of the spinlocks to avoid the warnings */
+       mutex_init(&stp->st_mutex);
+       mutex_lock(&stp->st_mutex);
+@@ -3437,6 +3438,8 @@ init_open_stateid(struct nfs4_ol_stateid
+       retstp = nfsd4_find_existing_open(fp, open);
+       if (retstp)
+               goto out_unlock;
++
++      open->op_stp = NULL;
+       atomic_inc(&stp->st_stid.sc_count);
+       stp->st_stid.sc_type = NFS4_OPEN_STID;
+       INIT_LIST_HEAD(&stp->st_locks);
+@@ -3454,10 +3457,11 @@ out_unlock:
+       spin_unlock(&oo->oo_owner.so_client->cl_lock);
+       if (retstp) {
+               mutex_lock(&retstp->st_mutex);
+-              /* Not that we need to, just for neatness */
++              /* To keep mutex tracking happy */
+               mutex_unlock(&stp->st_mutex);
++              stp = retstp;
+       }
+-      return retstp;
++      return stp;
+ }
+ /*
+@@ -4260,7 +4264,6 @@ nfsd4_process_open2(struct svc_rqst *rqs
+       struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
+       struct nfs4_file *fp = NULL;
+       struct nfs4_ol_stateid *stp = NULL;
+-      struct nfs4_ol_stateid *swapstp = NULL;
+       struct nfs4_delegation *dp = NULL;
+       __be32 status;
+@@ -4297,16 +4300,10 @@ nfsd4_process_open2(struct svc_rqst *rqs
+                       goto out;
+               }
+       } else {
+-              stp = open->op_stp;
+-              open->op_stp = NULL;
+-              /*
+-               * init_open_stateid() either returns a locked stateid
+-               * it found, or initializes and locks the new one we passed in
+-               */
+-              swapstp = init_open_stateid(stp, fp, open);
+-              if (swapstp) {
+-                      nfs4_put_stid(&stp->st_stid);
+-                      stp = swapstp;
++              /* stp is returned locked. */
++              stp = init_open_stateid(fp, open);
++              /* See if we lost the race to some other thread */
++              if (stp->st_access_bmap != 0) {
+                       status = nfs4_upgrade_open(rqstp, fp, current_fh,
+                                               stp, open);
+                       if (status) {
index be27457e1da4cade2127c24c050382ac14221b49..e4924214f13428ef6b19a8c42f3b386036475c14 100644 (file)
@@ -20,3 +20,8 @@ drm-radeon-fix-atombios-on-big-endian.patch
 drm-panel-simple-add-missing-panel_simple_unprepare-calls.patch
 mtd-nand-fix-writing-mtdoops-to-nand-flash.patch
 nfs-revalidate-.-etc-correctly-on-open.patch
+drm-i915-don-t-try-indexed-reads-to-alternate-slave-addresses.patch
+drm-i915-prevent-zero-length-index-write.patch
+nfsd-make-init_open_stateid-a-bit-more-whole.patch
+nfsd-fix-stateid-races-between-open-and-close.patch
+nfsd-fix-another-open-stateid-race.patch