commit:     8c5fb835790a108b9ab7d774b0bf85719dadc05f
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Sep 15 14:55:32 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Sep 15 14:55:32 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=8c5fb835

Linux patch 4.7.4

 0000_README            |    4 +
 1003_linux-4.7.4.patch | 2424 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2428 insertions(+)

diff --git a/0000_README b/0000_README
index f502025..2b11683 100644
--- a/0000_README
+++ b/0000_README
@@ -55,6 +55,10 @@ Patch:  1002_linux-4.7.3.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.7.3
 
+Patch:  1003_linux-4.7.4.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.7.4
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1003_linux-4.7.4.patch b/1003_linux-4.7.4.patch
new file mode 100644
index 0000000..5c75a93
--- /dev/null
+++ b/1003_linux-4.7.4.patch
@@ -0,0 +1,2424 @@
+diff --git a/Makefile b/Makefile
+index 4afff18fcb12..ec3bd119fbf8 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 7
+-SUBLEVEL = 3
++SUBLEVEL = 4
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index 60078a67d7e3..b15e1c158bda 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -1597,6 +1597,9 @@ void __init enable_IR_x2apic(void)
+       unsigned long flags;
+       int ret, ir_stat;
+ 
++      if (skip_ioapic_setup)
++              return;
++
+       ir_stat = irq_remapping_prepare();
+       if (ir_stat < 0 && !x2apic_supported())
+               return;
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 2475b1c72773..b993f88280a9 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -515,7 +515,9 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_end);
+ 
+ void blk_set_queue_dying(struct request_queue *q)
+ {
+-      queue_flag_set_unlocked(QUEUE_FLAG_DYING, q);
++      spin_lock_irq(q->queue_lock);
++      queue_flag_set(QUEUE_FLAG_DYING, q);
++      spin_unlock_irq(q->queue_lock);
+ 
+       if (q->mq_ops)
+               blk_mq_wake_waiters(q);
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index 261353166dcf..bea93441a9c6 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -94,9 +94,31 @@ static struct bio *blk_bio_segment_split(struct 
request_queue *q,
+       bool do_split = true;
+       struct bio *new = NULL;
+       const unsigned max_sectors = get_max_io_size(q, bio);
++      unsigned bvecs = 0;
+ 
+       bio_for_each_segment(bv, bio, iter) {
+               /*
++               * With arbitrary bio size, the incoming bio may be very
++               * big. We have to split the bio into small bios so that
++               * each holds at most BIO_MAX_PAGES bvecs because
++               * bio_clone() can fail to allocate big bvecs.
++               *
++               * It should have been better to apply the limit per
++               * request queue in which bio_clone() is involved,
++               * instead of globally. The biggest blocker is the
++               * bio_clone() in bio bounce.
++               *
++               * If bio is splitted by this reason, we should have
++               * allowed to continue bios merging, but don't do
++               * that now for making the change simple.
++               *
++               * TODO: deal with bio bounce's bio_clone() gracefully
++               * and convert the global limit into per-queue limit.
++               */
++              if (bvecs++ >= BIO_MAX_PAGES)
++                      goto split;
++
++              /*
+                * If the queue doesn't support SG gaps and adding this
+                * offset would create a gap, disallow it.
+                */
+diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
+index 84708a5f8c52..b206115d761c 100644
+--- a/drivers/block/floppy.c
++++ b/drivers/block/floppy.c
+@@ -3663,11 +3663,6 @@ static int floppy_open(struct block_device *bdev, 
fmode_t mode)
+ 
+       opened_bdev[drive] = bdev;
+ 
+-      if (!(mode & (FMODE_READ|FMODE_WRITE))) {
+-              res = -EINVAL;
+-              goto out;
+-      }
+-
+       res = -ENXIO;
+ 
+       if (!floppy_track_buffer) {
+@@ -3711,20 +3706,21 @@ static int floppy_open(struct block_device *bdev, 
fmode_t mode)
+       if (UFDCS->rawcmd == 1)
+               UFDCS->rawcmd = 2;
+ 
+-      UDRS->last_checked = 0;
+-      clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
+-      check_disk_change(bdev);
+-      if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
+-              goto out;
+-      if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags))
+-              goto out;
+-
+-      res = -EROFS;
+-
+-      if ((mode & FMODE_WRITE) &&
+-                      !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags))
+-              goto out;
+-
++      if (!(mode & FMODE_NDELAY)) {
++              if (mode & (FMODE_READ|FMODE_WRITE)) {
++                      UDRS->last_checked = 0;
++                      clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
++                      check_disk_change(bdev);
++                      if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
++                              goto out;
++                      if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags))
++                              goto out;
++              }
++              res = -EROFS;
++              if ((mode & FMODE_WRITE) &&
++                  !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags))
++                      goto out;
++      }
+       mutex_unlock(&open_lock);
+       mutex_unlock(&floppy_mutex);
+       return 0;
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c 
b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 0bb44d5b5df4..2ee40fd360ca 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -74,6 +74,8 @@ static const struct of_device_id machines[] __initconst = {
+       { .compatible = "ti,omap5", },
+ 
+       { .compatible = "xlnx,zynq-7000", },
++
++      { }
+ };
+ 
+ static int __init cpufreq_dt_platdev_init(void)
+diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
+index 6dc597126b79..b3044219772c 100644
+--- a/drivers/crypto/caam/caamalg.c
++++ b/drivers/crypto/caam/caamalg.c
+@@ -556,7 +556,10 @@ skip_enc:
+ 
+       /* Read and write assoclen bytes */
+       append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
+-      append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
++      if (alg->caam.geniv)
++              append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM, ivsize);
++      else
++              append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
+ 
+       /* Skip assoc data */
+       append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
+@@ -565,6 +568,14 @@ skip_enc:
+       append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
+                            KEY_VLF);
+ 
++      if (alg->caam.geniv) {
++              append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
++                              LDST_SRCDST_BYTE_CONTEXT |
++                              (ctx1_iv_off << LDST_OFFSET_SHIFT));
++              append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
++                          (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
++      }
++
+       /* Load Counter into CONTEXT1 reg */
+       if (is_rfc3686)
+               append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
+@@ -2150,7 +2161,7 @@ static void init_authenc_job(struct aead_request *req,
+ 
+       init_aead_job(req, edesc, all_contig, encrypt);
+ 
+-      if (ivsize && (is_rfc3686 || !(alg->caam.geniv && encrypt)))
++      if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
+               append_load_as_imm(desc, req->iv, ivsize,
+                                  LDST_CLASS_1_CCB |
+                                  LDST_SRCDST_BYTE_CONTEXT |
+@@ -2537,20 +2548,6 @@ static int aead_decrypt(struct aead_request *req)
+       return ret;
+ }
+ 
+-static int aead_givdecrypt(struct aead_request *req)
+-{
+-      struct crypto_aead *aead = crypto_aead_reqtfm(req);
+-      unsigned int ivsize = crypto_aead_ivsize(aead);
+-
+-      if (req->cryptlen < ivsize)
+-              return -EINVAL;
+-
+-      req->cryptlen -= ivsize;
+-      req->assoclen += ivsize;
+-
+-      return aead_decrypt(req);
+-}
+-
+ /*
+  * allocate and map the ablkcipher extended descriptor for ablkcipher
+  */
+@@ -3210,7 +3207,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = AES_BLOCK_SIZE,
+                       .maxauthsize = MD5_DIGEST_SIZE,
+               },
+@@ -3256,7 +3253,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = AES_BLOCK_SIZE,
+                       .maxauthsize = SHA1_DIGEST_SIZE,
+               },
+@@ -3302,7 +3299,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = AES_BLOCK_SIZE,
+                       .maxauthsize = SHA224_DIGEST_SIZE,
+               },
+@@ -3348,7 +3345,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = AES_BLOCK_SIZE,
+                       .maxauthsize = SHA256_DIGEST_SIZE,
+               },
+@@ -3394,7 +3391,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = AES_BLOCK_SIZE,
+                       .maxauthsize = SHA384_DIGEST_SIZE,
+               },
+@@ -3440,7 +3437,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = AES_BLOCK_SIZE,
+                       .maxauthsize = SHA512_DIGEST_SIZE,
+               },
+@@ -3486,7 +3483,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES3_EDE_BLOCK_SIZE,
+                       .maxauthsize = MD5_DIGEST_SIZE,
+               },
+@@ -3534,7 +3531,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES3_EDE_BLOCK_SIZE,
+                       .maxauthsize = SHA1_DIGEST_SIZE,
+               },
+@@ -3582,7 +3579,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES3_EDE_BLOCK_SIZE,
+                       .maxauthsize = SHA224_DIGEST_SIZE,
+               },
+@@ -3630,7 +3627,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES3_EDE_BLOCK_SIZE,
+                       .maxauthsize = SHA256_DIGEST_SIZE,
+               },
+@@ -3678,7 +3675,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES3_EDE_BLOCK_SIZE,
+                       .maxauthsize = SHA384_DIGEST_SIZE,
+               },
+@@ -3726,7 +3723,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES3_EDE_BLOCK_SIZE,
+                       .maxauthsize = SHA512_DIGEST_SIZE,
+               },
+@@ -3772,7 +3769,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES_BLOCK_SIZE,
+                       .maxauthsize = MD5_DIGEST_SIZE,
+               },
+@@ -3818,7 +3815,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES_BLOCK_SIZE,
+                       .maxauthsize = SHA1_DIGEST_SIZE,
+               },
+@@ -3864,7 +3861,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES_BLOCK_SIZE,
+                       .maxauthsize = SHA224_DIGEST_SIZE,
+               },
+@@ -3910,7 +3907,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES_BLOCK_SIZE,
+                       .maxauthsize = SHA256_DIGEST_SIZE,
+               },
+@@ -3956,7 +3953,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES_BLOCK_SIZE,
+                       .maxauthsize = SHA384_DIGEST_SIZE,
+               },
+@@ -4002,7 +3999,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = DES_BLOCK_SIZE,
+                       .maxauthsize = SHA512_DIGEST_SIZE,
+               },
+@@ -4051,7 +4048,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = CTR_RFC3686_IV_SIZE,
+                       .maxauthsize = MD5_DIGEST_SIZE,
+               },
+@@ -4102,7 +4099,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = CTR_RFC3686_IV_SIZE,
+                       .maxauthsize = SHA1_DIGEST_SIZE,
+               },
+@@ -4153,7 +4150,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = CTR_RFC3686_IV_SIZE,
+                       .maxauthsize = SHA224_DIGEST_SIZE,
+               },
+@@ -4204,7 +4201,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = CTR_RFC3686_IV_SIZE,
+                       .maxauthsize = SHA256_DIGEST_SIZE,
+               },
+@@ -4255,7 +4252,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = CTR_RFC3686_IV_SIZE,
+                       .maxauthsize = SHA384_DIGEST_SIZE,
+               },
+@@ -4306,7 +4303,7 @@ static struct caam_aead_alg driver_aeads[] = {
+                       .setkey = aead_setkey,
+                       .setauthsize = aead_setauthsize,
+                       .encrypt = aead_encrypt,
+-                      .decrypt = aead_givdecrypt,
++                      .decrypt = aead_decrypt,
+                       .ivsize = CTR_RFC3686_IV_SIZE,
+                       .maxauthsize = SHA512_DIGEST_SIZE,
+               },
+diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
+index 9bb99e274d23..79a05a3bc50b 100644
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -465,7 +465,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
+                                       val,
+                                       -1,
+                                       &replaced);
+-              state->color_mgmt_changed = replaced;
++              state->color_mgmt_changed |= replaced;
+               return ret;
+       } else if (property == config->ctm_property) {
+               ret = drm_atomic_replace_property_blob_from_id(crtc,
+@@ -473,7 +473,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
+                                       val,
+                                       sizeof(struct drm_color_ctm),
+                                       &replaced);
+-              state->color_mgmt_changed = replaced;
++              state->color_mgmt_changed |= replaced;
+               return ret;
+       } else if (property == config->gamma_lut_property) {
+               ret = drm_atomic_replace_property_blob_from_id(crtc,
+@@ -481,7 +481,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
+                                       val,
+                                       -1,
+                                       &replaced);
+-              state->color_mgmt_changed = replaced;
++              state->color_mgmt_changed |= replaced;
+               return ret;
+       } else if (crtc->funcs->atomic_set_property)
+               return crtc->funcs->atomic_set_property(crtc, state, property, 
val);
+diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
+index 0e3cc66aa8b7..a5cae1b6d57b 100644
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -5312,6 +5312,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
+       struct drm_pending_vblank_event *e = NULL;
+       int ret = -EINVAL;
+ 
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
+           page_flip->reserved != 0)
+               return -EINVAL;
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
+index eb4bb8b2f3a5..eb515f04eb9d 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -62,6 +62,14 @@ void msm_gem_submit_free(struct msm_gem_submit *submit)
+       kfree(submit);
+ }
+ 
++static inline unsigned long __must_check
++copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
++{
++      if (access_ok(VERIFY_READ, from, n))
++              return __copy_from_user_inatomic(to, from, n);
++      return -EFAULT;
++}
++
+ static int submit_lookup_objects(struct msm_gem_submit *submit,
+               struct drm_msm_gem_submit *args, struct drm_file *file)
+ {
+@@ -69,6 +77,7 @@ static int submit_lookup_objects(struct msm_gem_submit 
*submit,
+       int ret = 0;
+ 
+       spin_lock(&file->table_lock);
++      pagefault_disable();
+ 
+       for (i = 0; i < args->nr_bos; i++) {
+               struct drm_msm_gem_submit_bo submit_bo;
+@@ -82,10 +91,15 @@ static int submit_lookup_objects(struct msm_gem_submit 
*submit,
+                */
+               submit->bos[i].flags = 0;
+ 
+-              ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
+-              if (ret) {
+-                      ret = -EFAULT;
+-                      goto out_unlock;
++              ret = copy_from_user_inatomic(&submit_bo, userptr, 
sizeof(submit_bo));
++              if (unlikely(ret)) {
++                      pagefault_enable();
++                      spin_unlock(&file->table_lock);
++                      ret = copy_from_user(&submit_bo, userptr, 
sizeof(submit_bo));
++                      if (ret)
++                              goto out;
++                      spin_lock(&file->table_lock);
++                      pagefault_disable();
+               }
+ 
+               if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) {
+@@ -125,9 +139,12 @@ static int submit_lookup_objects(struct msm_gem_submit 
*submit,
+       }
+ 
+ out_unlock:
+-      submit->nr_bos = i;
++      pagefault_enable();
+       spin_unlock(&file->table_lock);
+ 
++out:
++      submit->nr_bos = i;
++
+       return ret;
+ }
+ 
+diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c 
b/drivers/gpu/drm/radeon/atombios_crtc.c
+index 259cd6e6d71c..17e34546ade2 100644
+--- a/drivers/gpu/drm/radeon/atombios_crtc.c
++++ b/drivers/gpu/drm/radeon/atombios_crtc.c
+@@ -627,7 +627,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
+                       if (radeon_crtc->ss.refdiv) {
+                               radeon_crtc->pll_flags |= 
RADEON_PLL_USE_REF_DIV;
+                               radeon_crtc->pll_reference_div = 
radeon_crtc->ss.refdiv;
+-                              if (rdev->family >= CHIP_RV770)
++                              if (ASIC_IS_AVIVO(rdev) &&
++                                  rdev->family != CHIP_RS780 &&
++                                  rdev->family != CHIP_RS880)
+                                       radeon_crtc->pll_flags |= 
RADEON_PLL_USE_FRAC_FB_DIV;
+                       }
+               }
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
+index 590b0377fbe2..0ab76dd13eb7 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -263,8 +263,8 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
+ 
+       rdev = radeon_get_rdev(bo->bdev);
+       ridx = radeon_copy_ring_index(rdev);
+-      old_start = old_mem->start << PAGE_SHIFT;
+-      new_start = new_mem->start << PAGE_SHIFT;
++      old_start = (u64)old_mem->start << PAGE_SHIFT;
++      new_start = (u64)new_mem->start << PAGE_SHIFT;
+ 
+       switch (old_mem->mem_type) {
+       case TTM_PL_VRAM:
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
+index 37cac59401d7..2e24616cd84a 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -321,6 +321,15 @@ vc4_first_render_job(struct vc4_dev *vc4)
+                               struct vc4_exec_info, head);
+ }
+ 
++static inline struct vc4_exec_info *
++vc4_last_render_job(struct vc4_dev *vc4)
++{
++      if (list_empty(&vc4->render_job_list))
++              return NULL;
++      return list_last_entry(&vc4->render_job_list,
++                             struct vc4_exec_info, head);
++}
++
+ /**
+  * struct vc4_texture_sample_info - saves the offsets into the UBO for texture
+  * setup parameters.
+diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
+index 46899d6de675..78ab08e8f87e 100644
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -574,8 +574,8 @@ vc4_cl_lookup_bos(struct drm_device *dev,
+       spin_unlock(&file_priv->table_lock);
+ 
+ fail:
+-      kfree(handles);
+-      return 0;
++      drm_free_large(handles);
++      return ret;
+ }
+ 
+ static int
+diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
+index b0104a346a74..094bc6a475c1 100644
+--- a/drivers/gpu/drm/vc4/vc4_irq.c
++++ b/drivers/gpu/drm/vc4/vc4_irq.c
+@@ -83,8 +83,10 @@ vc4_overflow_mem_work(struct work_struct *work)
+ 
+               spin_lock_irqsave(&vc4->job_lock, irqflags);
+               current_exec = vc4_first_bin_job(vc4);
++              if (!current_exec)
++                      current_exec = vc4_last_render_job(vc4);
+               if (current_exec) {
+-                      vc4->overflow_mem->seqno = vc4->finished_seqno + 1;
++                      vc4->overflow_mem->seqno = current_exec->seqno;
+                       list_add_tail(&vc4->overflow_mem->unref_head,
+                                     &current_exec->unref_list);
+                       vc4->overflow_mem = NULL;
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index 70ed1d0151b8..d3ef0fcaaddf 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -713,9 +713,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, 
unsigned int virq,
+       unsigned long flags;
+       int i;
+ 
+-      irq_set_chip_and_handler(virq, &gic_level_irq_controller,
+-                               handle_level_irq);
+-
+       spin_lock_irqsave(&gic_lock, flags);
+       gic_map_to_pin(intr, gic_cpu_pin);
+       gic_map_to_vpe(intr, mips_cm_vp_id(vpe));
+@@ -732,6 +729,10 @@ static int gic_irq_domain_map(struct irq_domain *d, 
unsigned int virq,
+ {
+       if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS)
+               return gic_local_irq_domain_map(d, virq, hw);
++
++      irq_set_chip_and_handler(virq, &gic_level_irq_controller,
++                               handle_level_irq);
++
+       return gic_shared_irq_domain_map(d, virq, hw, 0);
+ }
+ 
+@@ -771,11 +772,13 @@ static int gic_irq_domain_alloc(struct irq_domain *d, 
unsigned int virq,
+                       hwirq = GIC_SHARED_TO_HWIRQ(base_hwirq + i);
+ 
+                       ret = irq_domain_set_hwirq_and_chip(d, virq + i, hwirq,
+-                                                          
&gic_edge_irq_controller,
++                                                          
&gic_level_irq_controller,
+                                                           NULL);
+                       if (ret)
+                               goto error;
+ 
++                      irq_set_handler(virq + i, handle_level_irq);
++
+                       ret = gic_shared_irq_domain_map(d, virq + i, hwirq, 
cpu);
+                       if (ret)
+                               goto error;
+@@ -890,10 +893,17 @@ void gic_dev_domain_free(struct irq_domain *d, unsigned 
int virq,
+       return;
+ }
+ 
++static void gic_dev_domain_activate(struct irq_domain *domain,
++                                  struct irq_data *d)
++{
++      gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0);
++}
++
+ static struct irq_domain_ops gic_dev_domain_ops = {
+       .xlate = gic_dev_domain_xlate,
+       .alloc = gic_dev_domain_alloc,
+       .free = gic_dev_domain_free,
++      .activate = gic_dev_domain_activate,
+ };
+ 
+ static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node 
*ctrlr,
+diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
+index f5dbb4e884d8..5d3b2318cb3c 100644
+--- a/drivers/md/bcache/super.c
++++ b/drivers/md/bcache/super.c
+@@ -1818,7 +1818,7 @@ static int cache_alloc(struct cache_sb *sb, struct cache 
*ca)
+       free = roundup_pow_of_two(ca->sb.nbuckets) >> 10;
+ 
+       if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) ||
+-          !init_fifo(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) ||
++          !init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), 
GFP_KERNEL) ||
+           !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) ||
+           !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) ||
+           !init_fifo(&ca->free_inc,   free << 2, GFP_KERNEL) ||
+diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
+index e2fb44cc5c37..dc3a854e02d3 100644
+--- a/drivers/misc/mei/hw-me.c
++++ b/drivers/misc/mei/hw-me.c
+@@ -1263,8 +1263,14 @@ static bool mei_me_fw_type_nm(struct pci_dev *pdev)
+ static bool mei_me_fw_type_sps(struct pci_dev *pdev)
+ {
+       u32 reg;
+-      /* Read ME FW Status check for SPS Firmware */
+-      pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
++      unsigned int devfn;
++
++      /*
++       * Read ME FW Status register to check for SPS Firmware
++       * The SPS FW is only signaled in pci function 0
++       */
++      devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
++      pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_1, &reg);
+       trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_1", PCI_CFG_HFS_1, reg);
+       /* if bits [19:16] = 15, running SPS Firmware */
+       return (reg & 0xf0000) == 0xf0000;
+diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
+index 64e64da6da44..71cea9b296b2 100644
+--- a/drivers/misc/mei/pci-me.c
++++ b/drivers/misc/mei/pci-me.c
+@@ -85,8 +85,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
+ 
+       {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, mei_me_pch8_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, mei_me_pch8_cfg)},
+-      {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_cfg)},
+-      {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_cfg)},
++      {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_sps_cfg)},
++      {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_sps_cfg)},
+ 
+       {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)},
+diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
+index 83458f7a2824..6dc96c8dfe75 100644
+--- a/drivers/scsi/constants.c
++++ b/drivers/scsi/constants.c
+@@ -361,8 +361,9 @@ static const char * const snstext[] = {
+ 
+ /* Get sense key string or NULL if not available */
+ const char *
+-scsi_sense_key_string(unsigned char key) {
+-      if (key <= 0xE)
++scsi_sense_key_string(unsigned char key)
++{
++      if (key < ARRAY_SIZE(snstext))
+               return snstext[key];
+       return NULL;
+ }
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 0a4d54a87f7c..591e52009b58 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1196,6 +1196,8 @@ static int acm_probe(struct usb_interface *intf,
+       }
+ 
+       if (!buflen) {
++              if (!intf->cur_altsetting || !intf->cur_altsetting->endpoint)
++                      return -EINVAL;
+               if (intf->cur_altsetting->endpoint &&
+                               intf->cur_altsetting->endpoint->extralen &&
+                               intf->cur_altsetting->endpoint->extra) {
+@@ -1276,6 +1278,8 @@ next_desc:
+                               data_interface = usb_ifnum_to_if(usb_dev, 
(data_interface_num = call_interface_num));
+                       control_interface = intf;
+               } else {
++                      if (!intf->cur_altsetting)
++                              return -ENODEV;
+                       if (intf->cur_altsetting->desc.bNumEndpoints != 3) {
+                               dev_dbg(&intf->dev,"No union descriptor, giving 
up\n");
+                               return -ENODEV;
+@@ -1305,15 +1309,22 @@ next_desc:
+               combined_interfaces = 1;
+               /* a popular other OS doesn't use it */
+               quirks |= NO_CAP_LINE;
++              if (!data_interface->cur_altsetting)
++                      return -EINVAL;
+               if (data_interface->cur_altsetting->desc.bNumEndpoints != 3) {
+                       dev_err(&intf->dev, "This needs exactly 3 endpoints\n");
+                       return -EINVAL;
+               }
+ look_for_collapsed_interface:
++              if (!data_interface->cur_altsetting)
++                      return -EINVAL;
+               for (i = 0; i < 3; i++) {
+                       struct usb_endpoint_descriptor *ep;
+                       ep = &data_interface->cur_altsetting->endpoint[i].desc;
+ 
++                      if (!ep)
++                              return -ENODEV;
++
+                       if (usb_endpoint_is_int_in(ep))
+                               epctrl = ep;
+                       else if (usb_endpoint_is_bulk_out(ep))
+@@ -1332,8 +1343,12 @@ look_for_collapsed_interface:
+ skip_normal_probe:
+ 
+       /*workaround for switched interfaces */
++      if (!data_interface->cur_altsetting)
++              return -EINVAL;
+       if (data_interface->cur_altsetting->desc.bInterfaceClass
+                                               != CDC_DATA_INTERFACE_TYPE) {
++              if (!control_interface->cur_altsetting)
++                      return -EINVAL;
+               if (control_interface->cur_altsetting->desc.bInterfaceClass
+                                               == CDC_DATA_INTERFACE_TYPE) {
+                       dev_dbg(&intf->dev,
+@@ -1356,6 +1371,7 @@ skip_normal_probe:
+ 
+ 
+       if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 ||
++          !control_interface->cur_altsetting ||
+           control_interface->cur_altsetting->desc.bNumEndpoints == 0)
+               return -EINVAL;
+ 
+@@ -1363,6 +1379,8 @@ skip_normal_probe:
+       epread = &data_interface->cur_altsetting->endpoint[0].desc;
+       epwrite = &data_interface->cur_altsetting->endpoint[1].desc;
+ 
++      if (!epctrl || !epread || !epwrite)
++              return -ENODEV;
+ 
+       /* workaround for switched endpoints */
+       if (!usb_endpoint_dir_in(epread)) {
+diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
+index 9d6320e8ff3e..6e29d053843d 100644
+--- a/drivers/vhost/scsi.c
++++ b/drivers/vhost/scsi.c
+@@ -88,7 +88,7 @@ struct vhost_scsi_cmd {
+       struct scatterlist *tvc_prot_sgl;
+       struct page **tvc_upages;
+       /* Pointer to response header iovec */
+-      struct iovec *tvc_resp_iov;
++      struct iovec tvc_resp_iov;
+       /* Pointer to vhost_scsi for our device */
+       struct vhost_scsi *tvc_vhost;
+       /* Pointer to vhost_virtqueue for the cmd */
+@@ -547,7 +547,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work 
*work)
+               memcpy(v_rsp.sense, cmd->tvc_sense_buf,
+                      se_cmd->scsi_sense_length);
+ 
+-              iov_iter_init(&iov_iter, READ, cmd->tvc_resp_iov,
++              iov_iter_init(&iov_iter, READ, &cmd->tvc_resp_iov,
+                             cmd->tvc_in_iovs, sizeof(v_rsp));
+               ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter);
+               if (likely(ret == sizeof(v_rsp))) {
+@@ -1044,7 +1044,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
+               }
+               cmd->tvc_vhost = vs;
+               cmd->tvc_vq = vq;
+-              cmd->tvc_resp_iov = &vq->iov[out];
++              cmd->tvc_resp_iov = vq->iov[out];
+               cmd->tvc_in_iovs = in;
+ 
+               pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",
+diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c 
b/drivers/xen/xenbus/xenbus_dev_frontend.c
+index 7487971f9f78..c1010f018bd8 100644
+--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
++++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
+@@ -316,7 +316,7 @@ static int xenbus_write_transaction(unsigned msg_type,
+                       rc = -ENOMEM;
+                       goto out;
+               }
+-      } else {
++      } else if (msg_type == XS_TRANSACTION_END) {
+               list_for_each_entry(trans, &u->transactions, list)
+                       if (trans->handle.id == u->u.msg.tx_id)
+                               break;
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 71ccab1d22c6..b1495fa57d6d 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -659,7 +659,7 @@ static struct dentry *bd_mount(struct file_system_type 
*fs_type,
+ {
+       struct dentry *dent;
+       dent = mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC);
+-      if (dent)
++      if (!IS_ERR(dent))
+               dent->d_sb->s_iflags |= SB_I_CGROUPWB;
+       return dent;
+ }
+diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
+index 0f9961eede1e..f96547f83cab 100644
+--- a/fs/crypto/policy.c
++++ b/fs/crypto/policy.c
+@@ -95,10 +95,15 @@ static int create_encryption_context_from_policy(struct 
inode *inode,
+ int fscrypt_process_policy(struct inode *inode,
+                               const struct fscrypt_policy *policy)
+ {
++      if (!inode_owner_or_capable(inode))
++              return -EACCES;
++
+       if (policy->version != 0)
+               return -EINVAL;
+ 
+       if (!inode_has_encryption_context(inode)) {
++              if (!S_ISDIR(inode->i_mode))
++                      return -EINVAL;
+               if (!inode->i_sb->s_cop->empty_dir)
+                       return -EOPNOTSUPP;
+               if (!inode->i_sb->s_cop->empty_dir(inode))
+diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c
+index ad050698143f..8a9feb341f31 100644
+--- a/fs/ext4/crypto_policy.c
++++ b/fs/ext4/crypto_policy.c
+@@ -102,6 +102,9 @@ static int ext4_create_encryption_context_from_policy(
+ int ext4_process_policy(const struct ext4_encryption_policy *policy,
+                       struct inode *inode)
+ {
++      if (!inode_owner_or_capable(inode))
++              return -EACCES;
++
+       if (policy->version != 0)
+               return -EINVAL;
+ 
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index b747ec09c1ac..ea628af9d609 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -51,25 +51,31 @@ static __u32 ext4_inode_csum(struct inode *inode, struct 
ext4_inode *raw,
+                             struct ext4_inode_info *ei)
+ {
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+-      __u16 csum_lo;
+-      __u16 csum_hi = 0;
+       __u32 csum;
++      __u16 dummy_csum = 0;
++      int offset = offsetof(struct ext4_inode, i_checksum_lo);
++      unsigned int csum_size = sizeof(dummy_csum);
+ 
+-      csum_lo = le16_to_cpu(raw->i_checksum_lo);
+-      raw->i_checksum_lo = 0;
+-      if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
+-          EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) {
+-              csum_hi = le16_to_cpu(raw->i_checksum_hi);
+-              raw->i_checksum_hi = 0;
+-      }
++      csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, offset);
++      csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size);
++      offset += csum_size;
++      csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
++                         EXT4_GOOD_OLD_INODE_SIZE - offset);
+ 
+-      csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw,
+-                         EXT4_INODE_SIZE(inode->i_sb));
+-
+-      raw->i_checksum_lo = cpu_to_le16(csum_lo);
+-      if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
+-          EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi))
+-              raw->i_checksum_hi = cpu_to_le16(csum_hi);
++      if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
++              offset = offsetof(struct ext4_inode, i_checksum_hi);
++              csum = ext4_chksum(sbi, csum, (__u8 *)raw +
++                                 EXT4_GOOD_OLD_INODE_SIZE,
++                                 offset - EXT4_GOOD_OLD_INODE_SIZE);
++              if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) {
++                      csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum,
++                                         csum_size);
++                      offset += csum_size;
++                      csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
++                                         EXT4_INODE_SIZE(inode->i_sb) -
++                                         offset);
++              }
++      }
+ 
+       return csum;
+ }
+@@ -5460,8 +5466,6 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode 
*inode)
+                                                     sbi->s_want_extra_isize,
+                                                     iloc, handle);
+                       if (ret) {
+-                              ext4_set_inode_state(inode,
+-                                                   EXT4_STATE_NO_EXPAND);
+                               if (mnt_count !=
+                                       le16_to_cpu(sbi->s_es->s_mnt_count)) {
+                                       ext4_warning(inode->i_sb,
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index ec4c39952e84..5bb46b6ed456 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -420,15 +420,14 @@ static __le32 ext4_dx_csum(struct inode *inode, struct 
ext4_dir_entry *dirent,
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       __u32 csum;
+-      __le32 save_csum;
+       int size;
++      __u32 dummy_csum = 0;
++      int offset = offsetof(struct dx_tail, dt_checksum);
+ 
+       size = count_offset + (count * sizeof(struct dx_entry));
+-      save_csum = t->dt_checksum;
+-      t->dt_checksum = 0;
+       csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size);
+-      csum = ext4_chksum(sbi, csum, (__u8 *)t, sizeof(struct dx_tail));
+-      t->dt_checksum = save_csum;
++      csum = ext4_chksum(sbi, csum, (__u8 *)t, offset);
++      csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
+ 
+       return cpu_to_le32(csum);
+ }
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 639bd756a8d8..d4505f89fe76 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2068,23 +2068,25 @@ failed:
+ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
+                                  struct ext4_group_desc *gdp)
+ {
+-      int offset;
++      int offset = offsetof(struct ext4_group_desc, bg_checksum);
+       __u16 crc = 0;
+       __le32 le_group = cpu_to_le32(block_group);
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+ 
+       if (ext4_has_metadata_csum(sbi->s_sb)) {
+               /* Use new metadata_csum algorithm */
+-              __le16 save_csum;
+               __u32 csum32;
++              __u16 dummy_csum = 0;
+ 
+-              save_csum = gdp->bg_checksum;
+-              gdp->bg_checksum = 0;
+               csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group,
+                                    sizeof(le_group));
+-              csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp,
+-                                   sbi->s_desc_size);
+-              gdp->bg_checksum = save_csum;
++              csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, offset);
++              csum32 = ext4_chksum(sbi, csum32, (__u8 *)&dummy_csum,
++                                   sizeof(dummy_csum));
++              offset += sizeof(dummy_csum);
++              if (offset < sbi->s_desc_size)
++                      csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp + offset,
++                                           sbi->s_desc_size - offset);
+ 
+               crc = csum32 & 0xFFFF;
+               goto out;
+@@ -2094,8 +2096,6 @@ static __le16 ext4_group_desc_csum(struct super_block 
*sb, __u32 block_group,
+       if (!ext4_has_feature_gdt_csum(sb))
+               return 0;
+ 
+-      offset = offsetof(struct ext4_group_desc, bg_checksum);
+-
+       crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
+       crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
+       crc = crc16(crc, (__u8 *)gdp, offset);
+@@ -2131,6 +2131,7 @@ void ext4_group_desc_csum_set(struct super_block *sb, 
__u32 block_group,
+ 
+ /* Called at mount-time, super-block is locked */
+ static int ext4_check_descriptors(struct super_block *sb,
++                                ext4_fsblk_t sb_block,
+                                 ext4_group_t *first_not_zeroed)
+ {
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+@@ -2161,6 +2162,11 @@ static int ext4_check_descriptors(struct super_block 
*sb,
+                       grp = i;
+ 
+               block_bitmap = ext4_block_bitmap(sb, gdp);
++              if (block_bitmap == sb_block) {
++                      ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++                               "Block bitmap for group %u overlaps "
++                               "superblock", i);
++              }
+               if (block_bitmap < first_block || block_bitmap > last_block) {
+                       ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+                              "Block bitmap for group %u not in group "
+@@ -2168,6 +2174,11 @@ static int ext4_check_descriptors(struct super_block 
*sb,
+                       return 0;
+               }
+               inode_bitmap = ext4_inode_bitmap(sb, gdp);
++              if (inode_bitmap == sb_block) {
++                      ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++                               "Inode bitmap for group %u overlaps "
++                               "superblock", i);
++              }
+               if (inode_bitmap < first_block || inode_bitmap > last_block) {
+                       ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+                              "Inode bitmap for group %u not in group "
+@@ -2175,6 +2186,11 @@ static int ext4_check_descriptors(struct super_block 
*sb,
+                       return 0;
+               }
+               inode_table = ext4_inode_table(sb, gdp);
++              if (inode_table == sb_block) {
++                      ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++                               "Inode table for group %u overlaps "
++                               "superblock", i);
++              }
+               if (inode_table < first_block ||
+                   inode_table + sbi->s_itb_per_group - 1 > last_block) {
+                       ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+@@ -3677,7 +3693,7 @@ static int ext4_fill_super(struct super_block *sb, void 
*data, int silent)
+                       goto failed_mount2;
+               }
+       }
+-      if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
++      if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
+               ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
+               ret = -EFSCORRUPTED;
+               goto failed_mount2;
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index e79bd32b9b79..2eb935ca5d9e 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -121,17 +121,18 @@ static __le32 ext4_xattr_block_csum(struct inode *inode,
+ {
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+       __u32 csum;
+-      __le32 save_csum;
+       __le64 dsk_block_nr = cpu_to_le64(block_nr);
++      __u32 dummy_csum = 0;
++      int offset = offsetof(struct ext4_xattr_header, h_checksum);
+ 
+-      save_csum = hdr->h_checksum;
+-      hdr->h_checksum = 0;
+       csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr,
+                          sizeof(dsk_block_nr));
+-      csum = ext4_chksum(sbi, csum, (__u8 *)hdr,
+-                         EXT4_BLOCK_SIZE(inode->i_sb));
++      csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset);
++      csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
++      offset += sizeof(dummy_csum);
++      csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset,
++                         EXT4_BLOCK_SIZE(inode->i_sb) - offset);
+ 
+-      hdr->h_checksum = save_csum;
+       return cpu_to_le32(csum);
+ }
+ 
+@@ -1352,15 +1353,19 @@ int ext4_expand_extra_isize_ea(struct inode *inode, 
int new_extra_isize,
+       size_t min_offs, free;
+       int total_ino;
+       void *base, *start, *end;
+-      int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
++      int error = 0, tried_min_extra_isize = 0;
+       int s_min_extra_isize = 
le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
++      int isize_diff; /* How much do we need to grow i_extra_isize */
+ 
+       down_write(&EXT4_I(inode)->xattr_sem);
++      /*
++       * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty
++       */
++      ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
+ retry:
+-      if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
+-              up_write(&EXT4_I(inode)->xattr_sem);
+-              return 0;
+-      }
++      isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
++      if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
++              goto out;
+ 
+       header = IHDR(inode, raw_inode);
+       entry = IFIRST(header);
+@@ -1381,7 +1386,7 @@ retry:
+               goto cleanup;
+ 
+       free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
+-      if (free >= new_extra_isize) {
++      if (free >= isize_diff) {
+               entry = IFIRST(header);
+               ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize
+                               - new_extra_isize, (void *)raw_inode +
+@@ -1389,8 +1394,7 @@ retry:
+                               (void *)header, total_ino,
+                               inode->i_sb->s_blocksize);
+               EXT4_I(inode)->i_extra_isize = new_extra_isize;
+-              error = 0;
+-              goto cleanup;
++              goto out;
+       }
+ 
+       /*
+@@ -1413,7 +1417,7 @@ retry:
+               end = bh->b_data + bh->b_size;
+               min_offs = end - base;
+               free = ext4_xattr_free_space(first, &min_offs, base, NULL);
+-              if (free < new_extra_isize) {
++              if (free < isize_diff) {
+                       if (!tried_min_extra_isize && s_min_extra_isize) {
+                               tried_min_extra_isize++;
+                               new_extra_isize = s_min_extra_isize;
+@@ -1427,7 +1431,7 @@ retry:
+               free = inode->i_sb->s_blocksize;
+       }
+ 
+-      while (new_extra_isize > 0) {
++      while (isize_diff > 0) {
+               size_t offs, size, entry_size;
+               struct ext4_xattr_entry *small_entry = NULL;
+               struct ext4_xattr_info i = {
+@@ -1458,7 +1462,7 @@ retry:
+                       EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
+                                       EXT4_XATTR_LEN(last->e_name_len);
+                       if (total_size <= free && total_size < min_total_size) {
+-                              if (total_size < new_extra_isize) {
++                              if (total_size < isize_diff) {
+                                       small_entry = last;
+                               } else {
+                                       entry = last;
+@@ -1513,22 +1517,22 @@ retry:
+               error = ext4_xattr_ibody_set(handle, inode, &i, is);
+               if (error)
+                       goto cleanup;
++              total_ino -= entry_size;
+ 
+               entry = IFIRST(header);
+-              if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize)
+-                      shift_bytes = new_extra_isize;
++              if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
++                      shift_bytes = isize_diff;
+               else
+-                      shift_bytes = entry_size + size;
++                      shift_bytes = entry_size + EXT4_XATTR_SIZE(size);
+               /* Adjust the offsets and shift the remaining entries ahead */
+-              ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize -
+-                      shift_bytes, (void *)raw_inode +
+-                      EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes,
+-                      (void *)header, total_ino - entry_size,
+-                      inode->i_sb->s_blocksize);
++              ext4_xattr_shift_entries(entry, -shift_bytes,
++                      (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
++                      EXT4_I(inode)->i_extra_isize + shift_bytes,
++                      (void *)header, total_ino, inode->i_sb->s_blocksize);
+ 
+-              extra_isize += shift_bytes;
+-              new_extra_isize -= shift_bytes;
+-              EXT4_I(inode)->i_extra_isize = extra_isize;
++              isize_diff -= shift_bytes;
++              EXT4_I(inode)->i_extra_isize += shift_bytes;
++              header = IHDR(inode, raw_inode);
+ 
+               i.name = b_entry_name;
+               i.value = buffer;
+@@ -1550,6 +1554,8 @@ retry:
+               kfree(bs);
+       }
+       brelse(bh);
++out:
++      ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
+       up_write(&EXT4_I(inode)->xattr_sem);
+       return 0;
+ 
+@@ -1561,6 +1567,10 @@ cleanup:
+       kfree(is);
+       kfree(bs);
+       brelse(bh);
++      /*
++       * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
++       * size expansion failed.
++       */
+       up_write(&EXT4_I(inode)->xattr_sem);
+       return error;
+ }
+diff --git a/fs/namei.c b/fs/namei.c
+index 70580ab1445c..9281b2bf025a 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -901,6 +901,7 @@ static inline int may_follow_link(struct nameidata *nd)
+ {
+       const struct inode *inode;
+       const struct inode *parent;
++      kuid_t puid;
+ 
+       if (!sysctl_protected_symlinks)
+               return 0;
+@@ -916,7 +917,8 @@ static inline int may_follow_link(struct nameidata *nd)
+               return 0;
+ 
+       /* Allowed if parent directory and link owner match. */
+-      if (uid_eq(parent->i_uid, inode->i_uid))
++      puid = parent->i_uid;
++      if (uid_valid(puid) && uid_eq(puid, inode->i_uid))
+               return 0;
+ 
+       if (nd->flags & LOOKUP_RCU)
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index 80aa6f1eb336..4133aa7e7c09 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -80,6 +80,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
+       }
+ 
+       for (name = buf; name < (buf + list_size); name += strlen(name) + 1) {
++              if (ovl_is_private_xattr(name))
++                      continue;
+ retry:
+               size = vfs_getxattr(old, name, value, value_size);
+               if (size == -ERANGE)
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index d1cdc60dd68f..ac98a71e753a 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -231,7 +231,7 @@ static int ovl_readlink(struct dentry *dentry, char __user 
*buf, int bufsiz)
+ }
+ 
+ 
+-static bool ovl_is_private_xattr(const char *name)
++bool ovl_is_private_xattr(const char *name)
+ {
+       return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
+ }
+@@ -279,24 +279,27 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, 
size_t size)
+ {
+       struct dentry *realdentry = ovl_dentry_real(dentry);
+       ssize_t res;
+-      int off;
++      size_t len;
++      char *s;
+ 
+       res = vfs_listxattr(realdentry, list, size);
+       if (res <= 0 || size == 0)
+               return res;
+ 
+       /* filter out private xattrs */
+-      for (off = 0; off < res;) {
+-              char *s = list + off;
+-              size_t slen = strlen(s) + 1;
++      for (s = list, len = res; len;) {
++              size_t slen = strnlen(s, len) + 1;
+ 
+-              BUG_ON(off + slen > res);
++              /* underlying fs providing us with an broken xattr list? */
++              if (WARN_ON(slen > len))
++                      return -EIO;
+ 
++              len -= slen;
+               if (ovl_is_private_xattr(s)) {
+                       res -= slen;
+-                      memmove(s, s + slen, res - off);
++                      memmove(s, s + slen, len);
+               } else {
+-                      off += slen;
++                      s += slen;
+               }
+       }
+ 
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index cfbca53590d0..d8ddc31f591e 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -168,6 +168,8 @@ int ovl_check_empty_dir(struct dentry *dentry, struct 
list_head *list);
+ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list);
+ void ovl_cache_free(struct list_head *list);
+ int ovl_check_d_type_supported(struct path *realpath);
++void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
++                       struct dentry *dentry, int level);
+ 
+ /* inode.c */
+ int ovl_setattr(struct dentry *dentry, struct iattr *attr);
+@@ -180,6 +182,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode 
*inode,
+ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
+ int ovl_removexattr(struct dentry *dentry, const char *name);
+ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
++bool ovl_is_private_xattr(const char *name);
+ 
+ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
+                           struct ovl_entry *oe);
+diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
+index cf37fc76fc9f..f241b4ee3d8a 100644
+--- a/fs/overlayfs/readdir.c
++++ b/fs/overlayfs/readdir.c
+@@ -248,7 +248,7 @@ static inline int ovl_dir_read(struct path *realpath,
+                       err = rdd->err;
+       } while (!err && rdd->count);
+ 
+-      if (!err && rdd->first_maybe_whiteout)
++      if (!err && rdd->first_maybe_whiteout && rdd->dentry)
+               err = ovl_check_whiteouts(realpath->dentry, rdd);
+ 
+       fput(realfile);
+@@ -606,3 +606,64 @@ int ovl_check_d_type_supported(struct path *realpath)
+ 
+       return rdd.d_type_supported;
+ }
++
++static void ovl_workdir_cleanup_recurse(struct path *path, int level)
++{
++      int err;
++      struct inode *dir = path->dentry->d_inode;
++      LIST_HEAD(list);
++      struct ovl_cache_entry *p;
++      struct ovl_readdir_data rdd = {
++              .ctx.actor = ovl_fill_merge,
++              .dentry = NULL,
++              .list = &list,
++              .root = RB_ROOT,
++              .is_lowest = false,
++      };
++
++      err = ovl_dir_read(path, &rdd);
++      if (err)
++              goto out;
++
++      inode_lock_nested(dir, I_MUTEX_PARENT);
++      list_for_each_entry(p, &list, l_node) {
++              struct dentry *dentry;
++
++              if (p->name[0] == '.') {
++                      if (p->len == 1)
++                              continue;
++                      if (p->len == 2 && p->name[1] == '.')
++                              continue;
++              }
++              dentry = lookup_one_len(p->name, path->dentry, p->len);
++              if (IS_ERR(dentry))
++                      continue;
++              if (dentry->d_inode)
++                      ovl_workdir_cleanup(dir, path->mnt, dentry, level);
++              dput(dentry);
++      }
++      inode_unlock(dir);
++out:
++      ovl_cache_free(&list);
++}
++
++void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
++                       struct dentry *dentry, int level)
++{
++      int err;
++
++      if (!d_is_dir(dentry) || level > 1) {
++              ovl_cleanup(dir, dentry);
++              return;
++      }
++
++      err = ovl_do_rmdir(dir, dentry);
++      if (err) {
++              struct path path = { .mnt = mnt, .dentry = dentry };
++
++              inode_unlock(dir);
++              ovl_workdir_cleanup_recurse(&path, level + 1);
++              inode_lock_nested(dir, I_MUTEX_PARENT);
++              ovl_cleanup(dir, dentry);
++      }
++}
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index 6db75cbb668f..86f20256cda0 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -798,6 +798,10 @@ retry:
+               struct kstat stat = {
+                       .mode = S_IFDIR | 0,
+               };
++              struct iattr attr = {
++                      .ia_valid = ATTR_MODE,
++                      .ia_mode = stat.mode,
++              };
+ 
+               if (work->d_inode) {
+                       err = -EEXIST;
+@@ -805,7 +809,7 @@ retry:
+                               goto out_dput;
+ 
+                       retried = true;
+-                      ovl_cleanup(dir, work);
++                      ovl_workdir_cleanup(dir, mnt, work, 0);
+                       dput(work);
+                       goto retry;
+               }
+@@ -813,6 +817,21 @@ retry:
+               err = ovl_create_real(dir, work, &stat, NULL, NULL, true);
+               if (err)
+                       goto out_dput;
++
++              err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT);
++              if (err && err != -ENODATA && err != -EOPNOTSUPP)
++                      goto out_dput;
++
++              err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS);
++              if (err && err != -ENODATA && err != -EOPNOTSUPP)
++                      goto out_dput;
++
++              /* Clear any inherited mode bits */
++              inode_lock(work->d_inode);
++              err = notify_change(work, &attr, NULL);
++              inode_unlock(work->d_inode);
++              if (err)
++                      goto out_dput;
+       }
+ out_unlock:
+       inode_unlock(dir);
+diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
+index b45345d701e7..51157da3f76e 100644
+--- a/fs/ubifs/tnc_commit.c
++++ b/fs/ubifs/tnc_commit.c
+@@ -370,7 +370,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
+ 
+       p = c->gap_lebs;
+       do {
+-              ubifs_assert(p < c->gap_lebs + sizeof(int) * c->lst.idx_lebs);
++              ubifs_assert(p < c->gap_lebs + c->lst.idx_lebs);
+               written = layout_leb_in_gaps(c, p);
+               if (written < 0) {
+                       err = written;
+diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
+index b5fc27969e9d..c63710fbd95d 100644
+--- a/fs/ubifs/xattr.c
++++ b/fs/ubifs/xattr.c
+@@ -575,7 +575,8 @@ static int ubifs_xattr_get(const struct xattr_handler 
*handler,
+       dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
+               inode->i_ino, dentry, size);
+ 
+-      return  __ubifs_getxattr(inode, name, buffer, size);
++      name = xattr_full_name(handler, name);
++      return __ubifs_getxattr(inode, name, buffer, size);
+ }
+ 
+ static int ubifs_xattr_set(const struct xattr_handler *handler,
+@@ -586,6 +587,8 @@ static int ubifs_xattr_set(const struct xattr_handler 
*handler,
+       dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
+               name, inode->i_ino, dentry, size);
+ 
++      name = xattr_full_name(handler, name);
++
+       if (value)
+               return __ubifs_setxattr(inode, name, value, size, flags);
+       else
+diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
+index 12ca86778e02..85bdf3de2360 100644
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -581,7 +581,8 @@ xfs_sb_verify(
+        * Only check the in progress field for the primary superblock as
+        * mkfs.xfs doesn't clear it from secondary superblocks.
+        */
+-      return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
++      return xfs_mount_validate_sb(mp, &sb,
++                                   bp->b_maps[0].bm_bn == XFS_SB_DADDR,
+                                    check_version);
+ }
+ 
+diff --git a/include/linux/capability.h b/include/linux/capability.h
+index 00690ff92edf..5f3c63dde2d5 100644
+--- a/include/linux/capability.h
++++ b/include/linux/capability.h
+@@ -206,6 +206,7 @@ extern bool has_ns_capability_noaudit(struct task_struct 
*t,
+                                     struct user_namespace *ns, int cap);
+ extern bool capable(int cap);
+ extern bool ns_capable(struct user_namespace *ns, int cap);
++extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
+ #else
+ static inline bool has_capability(struct task_struct *t, int cap)
+ {
+@@ -233,6 +234,10 @@ static inline bool ns_capable(struct user_namespace *ns, 
int cap)
+ {
+       return true;
+ }
++static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
++{
++      return true;
++}
+ #endif /* CONFIG_MULTIUSER */
+ extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
+ extern bool file_ns_capable(const struct file *file, struct user_namespace 
*ns, int cap);
+diff --git a/kernel/capability.c b/kernel/capability.c
+index 45432b54d5c6..00411c82dac5 100644
+--- a/kernel/capability.c
++++ b/kernel/capability.c
+@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_struct *t, int 
cap)
+       return has_ns_capability_noaudit(t, &init_user_ns, cap);
+ }
+ 
++static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
++{
++      int capable;
++
++      if (unlikely(!cap_valid(cap))) {
++              pr_crit("capable() called with invalid cap=%u\n", cap);
++              BUG();
++      }
++
++      capable = audit ? security_capable(current_cred(), ns, cap) :
++                        security_capable_noaudit(current_cred(), ns, cap);
++      if (capable == 0) {
++              current->flags |= PF_SUPERPRIV;
++              return true;
++      }
++      return false;
++}
++
+ /**
+  * ns_capable - Determine if the current task has a superior capability in 
effect
+  * @ns:  The usernamespace we want the capability in
+@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_struct *t, int 
cap)
+  */
+ bool ns_capable(struct user_namespace *ns, int cap)
+ {
+-      if (unlikely(!cap_valid(cap))) {
+-              pr_crit("capable() called with invalid cap=%u\n", cap);
+-              BUG();
+-      }
+-
+-      if (security_capable(current_cred(), ns, cap) == 0) {
+-              current->flags |= PF_SUPERPRIV;
+-              return true;
+-      }
+-      return false;
++      return ns_capable_common(ns, cap, true);
+ }
+ EXPORT_SYMBOL(ns_capable);
+ 
++/**
++ * ns_capable_noaudit - Determine if the current task has a superior 
capability
++ * (unaudited) in effect
++ * @ns:  The usernamespace we want the capability in
++ * @cap: The capability to be tested for
++ *
++ * Return true if the current task has the given superior capability currently
++ * available for use, false if not.
++ *
++ * This sets PF_SUPERPRIV on the task if the capability is available on the
++ * assumption that it's about to be used.
++ */
++bool ns_capable_noaudit(struct user_namespace *ns, int cap)
++{
++      return ns_capable_common(ns, cap, false);
++}
++EXPORT_SYMBOL(ns_capable_noaudit);
+ 
+ /**
+  * capable - Determine if the current task has a superior capability in effect
+diff --git a/kernel/cred.c b/kernel/cred.c
+index 0c0cd8a62285..5f264fb5737d 100644
+--- a/kernel/cred.c
++++ b/kernel/cred.c
+@@ -689,6 +689,8 @@ EXPORT_SYMBOL(set_security_override_from_ctx);
+  */
+ int set_create_files_as(struct cred *new, struct inode *inode)
+ {
++      if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
++              return -EINVAL;
+       new->fsuid = inode->i_uid;
+       new->fsgid = inode->i_gid;
+       return security_kernel_create_files_as(new, inode);
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 4a7ec0c6c88c..aea4f4da3836 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -1406,7 +1406,6 @@ static struct task_struct *copy_process(unsigned long 
clone_flags,
+       p->real_start_time = ktime_get_boot_ns();
+       p->io_context = NULL;
+       p->audit_context = NULL;
+-      threadgroup_change_begin(current);
+       cgroup_fork(p);
+ #ifdef CONFIG_NUMA
+       p->mempolicy = mpol_dup(p->mempolicy);
+@@ -1558,6 +1557,7 @@ static struct task_struct *copy_process(unsigned long 
clone_flags,
+       INIT_LIST_HEAD(&p->thread_group);
+       p->task_works = NULL;
+ 
++      threadgroup_change_begin(current);
+       /*
+        * Ensure that the cgroup subsystem policies allow the new process to be
+        * forked. It should be noted the the new process's css_set can be 
changed
+@@ -1658,6 +1658,7 @@ static struct task_struct *copy_process(unsigned long 
clone_flags,
+ bad_fork_cancel_cgroup:
+       cgroup_cancel_fork(p);
+ bad_fork_free_pid:
++      threadgroup_change_end(current);
+       if (pid != &init_struct_pid)
+               free_pid(pid);
+ bad_fork_cleanup_thread:
+@@ -1690,7 +1691,6 @@ bad_fork_cleanup_policy:
+       mpol_put(p->mempolicy);
+ bad_fork_cleanup_threadgroup_lock:
+ #endif
+-      threadgroup_change_end(current);
+       delayacct_tsk_free(p);
+ bad_fork_cleanup_count:
+       atomic_dec(&p->cred->user->processes);
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 479d25cd3d4f..b6c394563178 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -401,7 +401,10 @@ static __always_inline u64 __ktime_get_fast_ns(struct 
tk_fast *tkf)
+       do {
+               seq = raw_read_seqcount_latch(&tkf->seq);
+               tkr = tkf->base + (seq & 0x01);
+-              now = ktime_to_ns(tkr->base) + timekeeping_get_ns(tkr);
++              now = ktime_to_ns(tkr->base);
++
++              now += clocksource_delta(tkr->read(tkr->clock),
++                                       tkr->cycle_last, tkr->mask);
+       } while (read_seqcount_retry(&tkf->seq, seq));
+ 
+       return now;
+diff --git a/kernel/time/timekeeping_debug.c b/kernel/time/timekeeping_debug.c
+index f6bd65236712..107310a6f36f 100644
+--- a/kernel/time/timekeeping_debug.c
++++ b/kernel/time/timekeeping_debug.c
+@@ -23,7 +23,9 @@
+ 
+ #include "timekeeping_internal.h"
+ 
+-static unsigned int sleep_time_bin[32] = {0};
++#define NUM_BINS 32
++
++static unsigned int sleep_time_bin[NUM_BINS] = {0};
+ 
+ static int tk_debug_show_sleep_time(struct seq_file *s, void *data)
+ {
+@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init);
+ 
+ void tk_debug_account_sleep_time(struct timespec64 *t)
+ {
+-      sleep_time_bin[fls(t->tv_sec)]++;
++      /* Cap bin index so we don't overflow the array */
++      int bin = min(fls(t->tv_sec), NUM_BINS-1);
++
++      sleep_time_bin[bin]++;
+ }
+ 
+diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
+index c0947544babe..f02ab80aa6ee 100644
+--- a/net/sunrpc/xprtrdma/frwr_ops.c
++++ b/net/sunrpc/xprtrdma/frwr_ops.c
+@@ -125,17 +125,16 @@ __frwr_reset_mr(struct rpcrdma_ia *ia, struct rpcrdma_mw 
*r)
+ }
+ 
+ static void
+-__frwr_reset_and_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mw *mw)
++__frwr_reset_and_unmap(struct rpcrdma_mw *mw)
+ {
++      struct rpcrdma_xprt *r_xprt = mw->mw_xprt;
+       struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+-      struct rpcrdma_frmr *f = &mw->frmr;
+       int rc;
+ 
+       rc = __frwr_reset_mr(ia, mw);
+-      ib_dma_unmap_sg(ia->ri_device, f->fr_sg, f->fr_nents, f->fr_dir);
++      ib_dma_unmap_sg(ia->ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir);
+       if (rc)
+               return;
+-
+       rpcrdma_put_mw(r_xprt, mw);
+ }
+ 
+@@ -152,8 +151,7 @@ __frwr_recovery_worker(struct work_struct *work)
+       struct rpcrdma_mw *r = container_of(work, struct rpcrdma_mw,
+                                           mw_work);
+ 
+-      __frwr_reset_and_unmap(r->mw_xprt, r);
+-      return;
++      __frwr_reset_and_unmap(r);
+ }
+ 
+ /* A broken MR was discovered in a context that can't sleep.
+@@ -167,8 +165,7 @@ __frwr_queue_recovery(struct rpcrdma_mw *r)
+ }
+ 
+ static int
+-__frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, struct ib_device *device,
+-          unsigned int depth)
++__frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, unsigned int depth)
+ {
+       struct rpcrdma_frmr *f = &r->frmr;
+       int rc;
+@@ -177,11 +174,11 @@ __frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, 
struct ib_device *device,
+       if (IS_ERR(f->fr_mr))
+               goto out_mr_err;
+ 
+-      f->fr_sg = kcalloc(depth, sizeof(*f->fr_sg), GFP_KERNEL);
+-      if (!f->fr_sg)
++      r->mw_sg = kcalloc(depth, sizeof(*r->mw_sg), GFP_KERNEL);
++      if (!r->mw_sg)
+               goto out_list_err;
+ 
+-      sg_init_table(f->fr_sg, depth);
++      sg_init_table(r->mw_sg, depth);
+ 
+       init_completion(&f->fr_linv_done);
+ 
+@@ -210,7 +207,7 @@ __frwr_release(struct rpcrdma_mw *r)
+       if (rc)
+               dprintk("RPC:       %s: ib_dereg_mr status %i\n",
+                       __func__, rc);
+-      kfree(r->frmr.fr_sg);
++      kfree(r->mw_sg);
+ }
+ 
+ static int
+@@ -350,7 +347,6 @@ static int
+ frwr_op_init(struct rpcrdma_xprt *r_xprt)
+ {
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+-      struct ib_device *device = r_xprt->rx_ia.ri_device;
+       unsigned int depth = r_xprt->rx_ia.ri_max_frmr_depth;
+       struct ib_pd *pd = r_xprt->rx_ia.ri_pd;
+       int i;
+@@ -372,7 +368,7 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt)
+               if (!r)
+                       return -ENOMEM;
+ 
+-              rc = __frwr_init(r, pd, device, depth);
++              rc = __frwr_init(r, pd, depth);
+               if (rc) {
+                       kfree(r);
+                       return rc;
+@@ -386,7 +382,7 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt)
+       return 0;
+ }
+ 
+-/* Post a FAST_REG Work Request to register a memory region
++/* Post a REG_MR Work Request to register a memory region
+  * for remote access via RDMA READ or RDMA WRITE.
+  */
+ static int
+@@ -394,8 +390,6 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct 
rpcrdma_mr_seg *seg,
+           int nsegs, bool writing)
+ {
+       struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+-      struct ib_device *device = ia->ri_device;
+-      enum dma_data_direction direction = rpcrdma_data_dir(writing);
+       struct rpcrdma_mr_seg *seg1 = seg;
+       struct rpcrdma_mw *mw;
+       struct rpcrdma_frmr *frmr;
+@@ -421,15 +415,14 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct 
rpcrdma_mr_seg *seg,
+ 
+       if (nsegs > ia->ri_max_frmr_depth)
+               nsegs = ia->ri_max_frmr_depth;
+-
+       for (i = 0; i < nsegs;) {
+               if (seg->mr_page)
+-                      sg_set_page(&frmr->fr_sg[i],
++                      sg_set_page(&mw->mw_sg[i],
+                                   seg->mr_page,
+                                   seg->mr_len,
+                                   offset_in_page(seg->mr_offset));
+               else
+-                      sg_set_buf(&frmr->fr_sg[i], seg->mr_offset,
++                      sg_set_buf(&mw->mw_sg[i], seg->mr_offset,
+                                  seg->mr_len);
+ 
+               ++seg;
+@@ -440,26 +433,20 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct 
rpcrdma_mr_seg *seg,
+                   offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
+                       break;
+       }
+-      frmr->fr_nents = i;
+-      frmr->fr_dir = direction;
+-
+-      dma_nents = ib_dma_map_sg(device, frmr->fr_sg, frmr->fr_nents, 
direction);
+-      if (!dma_nents) {
+-              pr_err("RPC:       %s: failed to dma map sg %p sg_nents %u\n",
+-                     __func__, frmr->fr_sg, frmr->fr_nents);
+-              return -ENOMEM;
+-      }
++      mw->mw_nents = i;
++      mw->mw_dir = rpcrdma_data_dir(writing);
+ 
+-      n = ib_map_mr_sg(mr, frmr->fr_sg, frmr->fr_nents, NULL, PAGE_SIZE);
+-      if (unlikely(n != frmr->fr_nents)) {
+-              pr_err("RPC:       %s: failed to map mr %p (%u/%u)\n",
+-                     __func__, frmr->fr_mr, n, frmr->fr_nents);
+-              rc = n < 0 ? n : -EINVAL;
+-              goto out_senderr;
+-      }
++      dma_nents = ib_dma_map_sg(ia->ri_device,
++                                mw->mw_sg, mw->mw_nents, mw->mw_dir);
++      if (!dma_nents)
++              goto out_dmamap_err;
++
++      n = ib_map_mr_sg(mr, mw->mw_sg, mw->mw_nents, NULL, PAGE_SIZE);
++      if (unlikely(n != mw->mw_nents))
++              goto out_mapmr_err;
+ 
+       dprintk("RPC:       %s: Using frmr %p to map %u segments (%u bytes)\n",
+-              __func__, mw, frmr->fr_nents, mr->length);
++              __func__, mw, mw->mw_nents, mr->length);
+ 
+       key = (u8)(mr->rkey & 0x000000FF);
+       ib_update_fast_reg_key(mr, ++key);
+@@ -484,13 +471,25 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct 
rpcrdma_mr_seg *seg,
+       seg1->rl_mw = mw;
+       seg1->mr_rkey = mr->rkey;
+       seg1->mr_base = mr->iova;
+-      seg1->mr_nsegs = frmr->fr_nents;
++      seg1->mr_nsegs = mw->mw_nents;
+       seg1->mr_len = mr->length;
+ 
+-      return frmr->fr_nents;
++      return mw->mw_nents;
++
++out_dmamap_err:
++      pr_err("rpcrdma: failed to dma map sg %p sg_nents %u\n",
++             mw->mw_sg, mw->mw_nents);
++      return -ENOMEM;
++
++out_mapmr_err:
++      pr_err("rpcrdma: failed to map mr %p (%u/%u)\n",
++             frmr->fr_mr, n, mw->mw_nents);
++      rc = n < 0 ? n : -EIO;
++      __frwr_queue_recovery(mw);
++      return rc;
+ 
+ out_senderr:
+-      dprintk("RPC:       %s: ib_post_send status %i\n", __func__, rc);
++      pr_err("rpcrdma: ib_post_send status %i\n", rc);
+       __frwr_queue_recovery(mw);
+       return rc;
+ }
+@@ -582,8 +581,8 @@ unmap:
+               mw = seg->rl_mw;
+               seg->rl_mw = NULL;
+ 
+-              ib_dma_unmap_sg(ia->ri_device, f->fr_sg, f->fr_nents,
+-                              f->fr_dir);
++              ib_dma_unmap_sg(ia->ri_device,
++                              mw->mw_sg, mw->mw_nents, mw->mw_dir);
+               rpcrdma_put_mw(r_xprt, mw);
+ 
+               i += seg->mr_nsegs;
+@@ -630,7 +629,7 @@ frwr_op_unmap_safe(struct rpcrdma_xprt *r_xprt, struct 
rpcrdma_req *req,
+               mw = seg->rl_mw;
+ 
+               if (sync)
+-                      __frwr_reset_and_unmap(r_xprt, mw);
++                      __frwr_reset_and_unmap(mw);
+               else
+                       __frwr_queue_recovery(mw);
+ 
+diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
+index 95cdc66225ee..c53abd1281b3 100644
+--- a/net/sunrpc/xprtrdma/xprt_rdma.h
++++ b/net/sunrpc/xprtrdma/xprt_rdma.h
+@@ -221,9 +221,6 @@ enum rpcrdma_frmr_state {
+ };
+ 
+ struct rpcrdma_frmr {
+-      struct scatterlist              *fr_sg;
+-      int                             fr_nents;
+-      enum dma_data_direction         fr_dir;
+       struct ib_mr                    *fr_mr;
+       struct ib_cqe                   fr_cqe;
+       enum rpcrdma_frmr_state         fr_state;
+@@ -240,13 +237,16 @@ struct rpcrdma_fmr {
+ };
+ 
+ struct rpcrdma_mw {
++      struct list_head        mw_list;
++      struct scatterlist      *mw_sg;
++      int                     mw_nents;
++      enum dma_data_direction mw_dir;
+       union {
+               struct rpcrdma_fmr      fmr;
+               struct rpcrdma_frmr     frmr;
+       };
+       struct work_struct      mw_work;
+       struct rpcrdma_xprt     *mw_xprt;
+-      struct list_head        mw_list;
+       struct list_head        mw_all;
+ };
+ 
+diff --git a/net/sysctl_net.c b/net/sysctl_net.c
+index ed98c1fc3de1..46a71c701e7c 100644
+--- a/net/sysctl_net.c
++++ b/net/sysctl_net.c
+@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ctl_table_header *head,
+       kgid_t root_gid = make_kgid(net->user_ns, 0);
+ 
+       /* Allow network administrator to have same access as root. */
+-      if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
++      if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) ||
+           uid_eq(root_uid, current_euid())) {
+               int mode = (table->mode >> 6) & 7;
+               return (mode << 6) | (mode << 3) | mode;
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index 705c2879d3a9..7347fcc4f451 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -766,7 +766,9 @@ struct aa_profile *aa_find_child(struct aa_profile 
*parent, const char *name)
+       struct aa_profile *profile;
+ 
+       rcu_read_lock();
+-      profile = aa_get_profile(__find_child(&parent->base.profiles, name));
++      do {
++              profile = __find_child(&parent->base.profiles, name);
++      } while (profile && !aa_get_profile_not0(profile));
+       rcu_read_unlock();
+ 
+       /* refcount released by caller */
+diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
+index 795437b10082..b450a27588c8 100644
+--- a/sound/core/rawmidi.c
++++ b/sound/core/rawmidi.c
+@@ -1633,11 +1633,13 @@ static int snd_rawmidi_dev_register(struct snd_device 
*device)
+               return -EBUSY;
+       }
+       list_add_tail(&rmidi->list, &snd_rawmidi_devices);
++      mutex_unlock(&register_mutex);
+       err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
+                                 rmidi->card, rmidi->device,
+                                 &snd_rawmidi_f_ops, rmidi, &rmidi->dev);
+       if (err < 0) {
+               rmidi_err(rmidi, "unable to register\n");
++              mutex_lock(&register_mutex);
+               list_del(&rmidi->list);
+               mutex_unlock(&register_mutex);
+               return err;
+@@ -1645,6 +1647,7 @@ static int snd_rawmidi_dev_register(struct snd_device 
*device)
+       if (rmidi->ops && rmidi->ops->dev_register &&
+           (err = rmidi->ops->dev_register(rmidi)) < 0) {
+               snd_unregister_device(&rmidi->dev);
++              mutex_lock(&register_mutex);
+               list_del(&rmidi->list);
+               mutex_unlock(&register_mutex);
+               return err;
+@@ -1677,7 +1680,6 @@ static int snd_rawmidi_dev_register(struct snd_device 
*device)
+               }
+       }
+ #endif /* CONFIG_SND_OSSEMUL */
+-      mutex_unlock(&register_mutex);
+       sprintf(name, "midi%d", rmidi->device);
+       entry = snd_info_create_card_entry(rmidi->card, name, 
rmidi->card->proc_root);
+       if (entry) {
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index 9a6157ea6881..fc144f43faa6 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -35,6 +35,9 @@
+ #include <sound/initval.h>
+ #include <linux/kmod.h>
+ 
++/* internal flags */
++#define SNDRV_TIMER_IFLG_PAUSED               0x00010000
++
+ #if IS_ENABLED(CONFIG_SND_HRTIMER)
+ #define DEFAULT_TIMER_LIMIT 4
+ #else
+@@ -294,8 +297,21 @@ int snd_timer_open(struct snd_timer_instance **ti,
+               get_device(&timer->card->card_dev);
+       timeri->slave_class = tid->dev_sclass;
+       timeri->slave_id = slave_id;
+-      if (list_empty(&timer->open_list_head) && timer->hw.open)
+-              timer->hw.open(timer);
++
++      if (list_empty(&timer->open_list_head) && timer->hw.open) {
++              int err = timer->hw.open(timer);
++              if (err) {
++                      kfree(timeri->owner);
++                      kfree(timeri);
++
++                      if (timer->card)
++                              put_device(&timer->card->card_dev);
++                      module_put(timer->module);
++                      mutex_unlock(&register_mutex);
++                      return err;
++              }
++      }
++
+       list_add_tail(&timeri->open_list, &timer->open_list_head);
+       snd_timer_check_master(timeri);
+       mutex_unlock(&register_mutex);
+@@ -526,6 +542,10 @@ static int snd_timer_stop1(struct snd_timer_instance 
*timeri, bool stop)
+               }
+       }
+       timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
++      if (stop)
++              timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED;
++      else
++              timeri->flags |= SNDRV_TIMER_IFLG_PAUSED;
+       snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
+                         SNDRV_TIMER_EVENT_CONTINUE);
+  unlock:
+@@ -587,6 +607,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
+  */
+ int snd_timer_continue(struct snd_timer_instance *timeri)
+ {
++      /* timer can continue only after pause */
++      if (!(timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
++              return -EINVAL;
++
+       if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+               return snd_timer_start_slave(timeri, false);
+       else
+@@ -813,6 +837,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct 
snd_timer_id *tid,
+       timer->tmr_subdevice = tid->subdevice;
+       if (id)
+               strlcpy(timer->id, id, sizeof(timer->id));
++      timer->sticks = 1;
+       INIT_LIST_HEAD(&timer->device_list);
+       INIT_LIST_HEAD(&timer->open_list_head);
+       INIT_LIST_HEAD(&timer->active_list_head);
+@@ -1817,6 +1842,9 @@ static int snd_timer_user_continue(struct file *file)
+       tu = file->private_data;
+       if (!tu->timeri)
+               return -EBADFD;
++      /* start timer instead of continue if it's not used before */
++      if (!(tu->timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
++              return snd_timer_user_start(file);
+       tu->timeri->lost = 0;
+       return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
+ }
+@@ -1958,6 +1986,7 @@ static ssize_t snd_timer_user_read(struct file *file, 
char __user *buffer,
+               tu->qused--;
+               spin_unlock_irq(&tu->qlock);
+ 
++              mutex_lock(&tu->ioctl_lock);
+               if (tu->tread) {
+                       if (copy_to_user(buffer, &tu->tqueue[qhead],
+                                        sizeof(struct snd_timer_tread)))
+@@ -1967,6 +1996,7 @@ static ssize_t snd_timer_user_read(struct file *file, 
char __user *buffer,
+                                        sizeof(struct snd_timer_read)))
+                               err = -EFAULT;
+               }
++              mutex_unlock(&tu->ioctl_lock);
+ 
+               spin_lock_irq(&tu->qlock);
+               if (err < 0)
+diff --git a/sound/firewire/fireworks/fireworks.h 
b/sound/firewire/fireworks/fireworks.h
+index 03ed35237e2b..d73c12b8753d 100644
+--- a/sound/firewire/fireworks/fireworks.h
++++ b/sound/firewire/fireworks/fireworks.h
+@@ -108,7 +108,6 @@ struct snd_efw {
+       u8 *resp_buf;
+       u8 *pull_ptr;
+       u8 *push_ptr;
+-      unsigned int resp_queues;
+ };
+ 
+ int snd_efw_transaction_cmd(struct fw_unit *unit,
+diff --git a/sound/firewire/fireworks/fireworks_hwdep.c 
b/sound/firewire/fireworks/fireworks_hwdep.c
+index 33df8655fe81..2e1d9a23920c 100644
+--- a/sound/firewire/fireworks/fireworks_hwdep.c
++++ b/sound/firewire/fireworks/fireworks_hwdep.c
+@@ -25,6 +25,7 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, 
long remained,
+ {
+       unsigned int length, till_end, type;
+       struct snd_efw_transaction *t;
++      u8 *pull_ptr;
+       long count = 0;
+ 
+       if (remained < sizeof(type) + sizeof(struct snd_efw_transaction))
+@@ -38,8 +39,17 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, 
long remained,
+       buf += sizeof(type);
+ 
+       /* write into buffer as many responses as possible */
+-      while (efw->resp_queues > 0) {
+-              t = (struct snd_efw_transaction *)(efw->pull_ptr);
++      spin_lock_irq(&efw->lock);
++
++      /*
++       * When another task reaches here during this task's access to user
++       * space, it picks up current position in buffer and can read the same
++       * series of responses.
++       */
++      pull_ptr = efw->pull_ptr;
++
++      while (efw->push_ptr != pull_ptr) {
++              t = (struct snd_efw_transaction *)(pull_ptr);
+               length = be32_to_cpu(t->length) * sizeof(__be32);
+ 
+               /* confirm enough space for this response */
+@@ -49,26 +59,39 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, 
long remained,
+               /* copy from ring buffer to user buffer */
+               while (length > 0) {
+                       till_end = snd_efw_resp_buf_size -
+-                              (unsigned int)(efw->pull_ptr - efw->resp_buf);
++                              (unsigned int)(pull_ptr - efw->resp_buf);
+                       till_end = min_t(unsigned int, length, till_end);
+ 
+-                      if (copy_to_user(buf, efw->pull_ptr, till_end))
++                      spin_unlock_irq(&efw->lock);
++
++                      if (copy_to_user(buf, pull_ptr, till_end))
+                               return -EFAULT;
+ 
+-                      efw->pull_ptr += till_end;
+-                      if (efw->pull_ptr >= efw->resp_buf +
+-                                           snd_efw_resp_buf_size)
+-                              efw->pull_ptr -= snd_efw_resp_buf_size;
++                      spin_lock_irq(&efw->lock);
++
++                      pull_ptr += till_end;
++                      if (pull_ptr >= efw->resp_buf + snd_efw_resp_buf_size)
++                              pull_ptr -= snd_efw_resp_buf_size;
+ 
+                       length -= till_end;
+                       buf += till_end;
+                       count += till_end;
+                       remained -= till_end;
+               }
+-
+-              efw->resp_queues--;
+       }
+ 
++      /*
++       * All of tasks can read from the buffer nearly simultaneously, but the
++       * last position for each task is different depending on the length of
++       * given buffer. Here, for simplicity, a position of buffer is set by
++       * the latest task. It's better for a listening application to allow one
++       * thread to read from the buffer. Unless, each task can read different
++       * sequence of responses depending on variation of buffer length.
++       */
++      efw->pull_ptr = pull_ptr;
++
++      spin_unlock_irq(&efw->lock);
++
+       return count;
+ }
+ 
+@@ -76,14 +99,17 @@ static long
+ hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count,
+                 loff_t *offset)
+ {
+-      union snd_firewire_event event;
++      union snd_firewire_event event = {
++              .lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
++      };
+ 
+-      memset(&event, 0, sizeof(event));
++      spin_lock_irq(&efw->lock);
+ 
+-      event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
+       event.lock_status.status = (efw->dev_lock_count > 0);
+       efw->dev_lock_changed = false;
+ 
++      spin_unlock_irq(&efw->lock);
++
+       count = min_t(long, count, sizeof(event.lock_status));
+ 
+       if (copy_to_user(buf, &event, count))
+@@ -98,10 +124,15 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, 
long count,
+ {
+       struct snd_efw *efw = hwdep->private_data;
+       DEFINE_WAIT(wait);
++      bool dev_lock_changed;
++      bool queued;
+ 
+       spin_lock_irq(&efw->lock);
+ 
+-      while ((!efw->dev_lock_changed) && (efw->resp_queues == 0)) {
++      dev_lock_changed = efw->dev_lock_changed;
++      queued = efw->push_ptr != efw->pull_ptr;
++
++      while (!dev_lock_changed && !queued) {
+               prepare_to_wait(&efw->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
+               spin_unlock_irq(&efw->lock);
+               schedule();
+@@ -109,15 +140,17 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, 
long count,
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+               spin_lock_irq(&efw->lock);
++              dev_lock_changed = efw->dev_lock_changed;
++              queued = efw->push_ptr != efw->pull_ptr;
+       }
+ 
+-      if (efw->dev_lock_changed)
++      spin_unlock_irq(&efw->lock);
++
++      if (dev_lock_changed)
+               count = hwdep_read_locked(efw, buf, count, offset);
+-      else if (efw->resp_queues > 0)
++      else if (queued)
+               count = hwdep_read_resp_buf(efw, buf, count, offset);
+ 
+-      spin_unlock_irq(&efw->lock);
+-
+       return count;
+ }
+ 
+@@ -160,7 +193,7 @@ hwdep_poll(struct snd_hwdep *hwdep, struct file *file, 
poll_table *wait)
+       poll_wait(file, &efw->hwdep_wait, wait);
+ 
+       spin_lock_irq(&efw->lock);
+-      if (efw->dev_lock_changed || (efw->resp_queues > 0))
++      if (efw->dev_lock_changed || efw->pull_ptr != efw->push_ptr)
+               events = POLLIN | POLLRDNORM;
+       else
+               events = 0;
+diff --git a/sound/firewire/fireworks/fireworks_proc.c 
b/sound/firewire/fireworks/fireworks_proc.c
+index 0639dcb13f7d..beb0a0ffee57 100644
+--- a/sound/firewire/fireworks/fireworks_proc.c
++++ b/sound/firewire/fireworks/fireworks_proc.c
+@@ -188,8 +188,8 @@ proc_read_queues_state(struct snd_info_entry *entry,
+       else
+               consumed = (unsigned int)(efw->push_ptr - efw->pull_ptr);
+ 
+-      snd_iprintf(buffer, "%d %d/%d\n",
+-                  efw->resp_queues, consumed, snd_efw_resp_buf_size);
++      snd_iprintf(buffer, "%d/%d\n",
++                  consumed, snd_efw_resp_buf_size);
+ }
+ 
+ static void
+diff --git a/sound/firewire/fireworks/fireworks_transaction.c 
b/sound/firewire/fireworks/fireworks_transaction.c
+index f550808d1784..36a08ba51ec7 100644
+--- a/sound/firewire/fireworks/fireworks_transaction.c
++++ b/sound/firewire/fireworks/fireworks_transaction.c
+@@ -121,11 +121,11 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t 
length, int *rcode)
+       size_t capacity, till_end;
+       struct snd_efw_transaction *t;
+ 
+-      spin_lock_irq(&efw->lock);
+-
+       t = (struct snd_efw_transaction *)data;
+       length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length);
+ 
++      spin_lock_irq(&efw->lock);
++
+       if (efw->push_ptr < efw->pull_ptr)
+               capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr);
+       else
+@@ -155,7 +155,6 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t 
length, int *rcode)
+       }
+ 
+       /* for hwdep */
+-      efw->resp_queues++;
+       wake_up(&efw->hwdep_wait);
+ 
+       *rcode = RCODE_COMPLETE;
+diff --git a/sound/firewire/tascam/tascam-hwdep.c 
b/sound/firewire/tascam/tascam-hwdep.c
+index 131267c3a042..106406cbfaa3 100644
+--- a/sound/firewire/tascam/tascam-hwdep.c
++++ b/sound/firewire/tascam/tascam-hwdep.c
+@@ -16,31 +16,14 @@
+ 
+ #include "tascam.h"
+ 
+-static long hwdep_read_locked(struct snd_tscm *tscm, char __user *buf,
+-                            long count)
+-{
+-      union snd_firewire_event event;
+-
+-      memset(&event, 0, sizeof(event));
+-
+-      event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
+-      event.lock_status.status = (tscm->dev_lock_count > 0);
+-      tscm->dev_lock_changed = false;
+-
+-      count = min_t(long, count, sizeof(event.lock_status));
+-
+-      if (copy_to_user(buf, &event, count))
+-              return -EFAULT;
+-
+-      return count;
+-}
+-
+ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
+                      loff_t *offset)
+ {
+       struct snd_tscm *tscm = hwdep->private_data;
+       DEFINE_WAIT(wait);
+-      union snd_firewire_event event;
++      union snd_firewire_event event = {
++              .lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
++      };
+ 
+       spin_lock_irq(&tscm->lock);
+ 
+@@ -54,10 +37,16 @@ static long hwdep_read(struct snd_hwdep *hwdep, char 
__user *buf, long count,
+               spin_lock_irq(&tscm->lock);
+       }
+ 
+-      memset(&event, 0, sizeof(event));
+-      count = hwdep_read_locked(tscm, buf, count);
++      event.lock_status.status = (tscm->dev_lock_count > 0);
++      tscm->dev_lock_changed = false;
++
+       spin_unlock_irq(&tscm->lock);
+ 
++      count = min_t(long, count, sizeof(event.lock_status));
++
++      if (copy_to_user(buf, &event, count))
++              return -EFAULT;
++
+       return count;
+ }
+ 
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f25479ba3981..eaee626ab185 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -4840,6 +4840,7 @@ enum {
+       ALC221_FIXUP_HP_FRONT_MIC,
+       ALC292_FIXUP_TPT460,
+       ALC298_FIXUP_SPK_VOLUME,
++      ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
+ };
+ 
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -5501,6 +5502,15 @@ static const struct hda_fixup alc269_fixups[] = {
+               .chained = true,
+               .chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+       },
++      [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1b, 0x90170151 },
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
++      },
+ };
+ 
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -5545,6 +5555,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1028, 0x06df, "Dell", 
ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", 
ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+       SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", 
ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
++      SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", 
ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
+       SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", 
ALC255_FIXUP_DELL_SPK_NOISE),
+       SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", 
ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+       SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
+@@ -5879,6 +5890,10 @@ static const struct snd_hda_pin_quirk 
alc269_pin_fixup_tbl[] = {
+               {0x12, 0x90a60170},
+               {0x14, 0x90170120},
+               {0x21, 0x02211030}),
++      SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", 
ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++              {0x12, 0x90a60180},
++              {0x14, 0x90170120},
++              {0x21, 0x02211030}),
+       SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", 
ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               ALC256_STANDARD_PINS),
+       SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
+diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
+index 1267e1af0fae..633d54ca78c8 100644
+--- a/sound/soc/atmel/atmel_ssc_dai.c
++++ b/sound/soc/atmel/atmel_ssc_dai.c
+@@ -299,8 +299,9 @@ static int atmel_ssc_startup(struct snd_pcm_substream 
*substream,
+       clk_enable(ssc_p->ssc->clk);
+       ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
+ 
+-      /* Reset the SSC to keep it at a clean status */
+-      ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
++      /* Reset the SSC unless initialized to keep it in a clean state */
++      if (!ssc_p->initialized)
++              ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
+ 
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               dir = 0;
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 6cf1f3597455..152292e5ee2b 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1141,6 +1141,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio 
*chip)
+       case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
+       case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
+       case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
++      case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
+       case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
+       case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
+       case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */

Reply via email to