commit:     eb8231c271266cfd53d5404c03a12517c643c7c7
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Aug 26 11:12:36 2020 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Aug 26 11:12:36 2020 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=eb8231c2

Linux patch 4.4.234

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |   4 +
 1233_linux-4.4.234.patch | 934 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 938 insertions(+)

diff --git a/0000_README b/0000_README
index 9a38dca..16dd710 100644
--- a/0000_README
+++ b/0000_README
@@ -975,6 +975,10 @@ Patch:  1232_linux-4.4.233.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.4.233
 
+Patch:  1233_linux-4.4.234.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.4.234
+
 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/1233_linux-4.4.234.patch b/1233_linux-4.4.234.patch
new file mode 100644
index 0000000..2762e22
--- /dev/null
+++ b/1233_linux-4.4.234.patch
@@ -0,0 +1,934 @@
+diff --git a/Makefile b/Makefile
+index 8f363a3bcaf81..573b646a19936 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 4
+-SUBLEVEL = 233
++SUBLEVEL = 234
+ EXTRAVERSION =
+ NAME = Blurry Fish Butt
+ 
+diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
+index ff4049155c840..355aec0867f4d 100644
+--- a/arch/alpha/include/asm/io.h
++++ b/arch/alpha/include/asm/io.h
+@@ -491,10 +491,10 @@ extern inline void writeq(u64 b, volatile void __iomem 
*addr)
+ }
+ #endif
+ 
+-#define ioread16be(p) be16_to_cpu(ioread16(p))
+-#define ioread32be(p) be32_to_cpu(ioread32(p))
+-#define iowrite16be(v,p) iowrite16(cpu_to_be16(v), (p))
+-#define iowrite32be(v,p) iowrite32(cpu_to_be32(v), (p))
++#define ioread16be(p) swab16(ioread16(p))
++#define ioread32be(p) swab32(ioread32(p))
++#define iowrite16be(v,p) iowrite16(swab16(v), (p))
++#define iowrite32be(v,p) iowrite32(swab32(v), (p))
+ 
+ #define inb_p         inb
+ #define inw_p         inw
+diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
+index e0267532bd4e0..edd392fdc14bb 100644
+--- a/arch/arm/kvm/mmu.c
++++ b/arch/arm/kvm/mmu.c
+@@ -300,14 +300,6 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
+               next = kvm_pgd_addr_end(addr, end);
+               if (!pgd_none(*pgd))
+                       unmap_puds(kvm, pgd, addr, next);
+-              /*
+-               * If we are dealing with a large range in
+-               * stage2 table, release the kvm->mmu_lock
+-               * to prevent starvation and lockup detector
+-               * warnings.
+-               */
+-              if (kvm && (next != end))
+-                      cond_resched_lock(&kvm->mmu_lock);
+       } while (pgd++, addr = next, addr != end);
+ }
+ 
+diff --git a/arch/m68k/include/asm/m53xxacr.h 
b/arch/m68k/include/asm/m53xxacr.h
+index 3177ce8331d69..baee0c77b9818 100644
+--- a/arch/m68k/include/asm/m53xxacr.h
++++ b/arch/m68k/include/asm/m53xxacr.h
+@@ -88,9 +88,9 @@
+  * coherency though in all cases. And for copyback caches we will need
+  * to push cached data as well.
+  */
+-#define CACHE_INIT      CACR_CINVA
+-#define CACHE_INVALIDATE  CACR_CINVA
+-#define CACHE_INVALIDATED CACR_CINVA
++#define CACHE_INIT        (CACHE_MODE + CACR_CINVA - CACR_EC)
++#define CACHE_INVALIDATE  (CACHE_MODE + CACR_CINVA)
++#define CACHE_INVALIDATED (CACHE_MODE + CACR_CINVA)
+ 
+ #define ACR0_MODE     ((CONFIG_RAMBASE & 0xff000000) + \
+                        (0x000f0000) + \
+diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
+index d1f860ca03ade..101c202c813c8 100644
+--- a/arch/powerpc/mm/fault.c
++++ b/arch/powerpc/mm/fault.c
+@@ -192,6 +192,9 @@ static int mm_fault_error(struct pt_regs *regs, unsigned 
long addr, int fault)
+       return MM_FAULT_CONTINUE;
+ }
+ 
++// This comes from 64-bit struct rt_sigframe + __SIGNAL_FRAMESIZE
++#define SIGFRAME_MAX_SIZE     (4096 + 128)
++
+ /*
+  * For 600- and 800-family processors, the error_code parameter is DSISR
+  * for a data fault, SRR1 for an instruction fault. For 400-family processors
+@@ -341,7 +344,7 @@ retry:
+       /*
+        * N.B. The POWER/Open ABI allows programs to access up to
+        * 288 bytes below the stack pointer.
+-       * The kernel signal delivery code writes up to about 1.5kB
++       * The kernel signal delivery code writes up to about 4kB
+        * below the stack pointer (r1) before decrementing it.
+        * The exec code can write slightly over 640kB to the stack
+        * before setting the user r1.  Thus we allow the stack to
+@@ -365,7 +368,7 @@ retry:
+                * between the last mapped region and the stack will
+                * expand the stack rather than segfaulting.
+                */
+-              if (address + 2048 < uregs->gpr[1] && !store_update_sp)
++              if (address + SIGFRAME_MAX_SIZE < uregs->gpr[1] && 
!store_update_sp)
+                       goto bad_area;
+       }
+       if (expand_stack(vma, address))
+diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
+index 31ca56e593f58..b9dc2ef64ed88 100644
+--- a/drivers/gpu/drm/imx/imx-ldb.c
++++ b/drivers/gpu/drm/imx/imx-ldb.c
+@@ -305,6 +305,7 @@ static void imx_ldb_encoder_disable(struct drm_encoder 
*encoder)
+ {
+       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+       struct imx_ldb *ldb = imx_ldb_ch->ldb;
++      int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+       int mux, ret;
+ 
+       /*
+@@ -321,14 +322,14 @@ static void imx_ldb_encoder_disable(struct drm_encoder 
*encoder)
+ 
+       drm_panel_disable(imx_ldb_ch->panel);
+ 
+-      if (imx_ldb_ch == &ldb->channel[0])
++      if (imx_ldb_ch == &ldb->channel[0] || dual)
+               ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
+-      else if (imx_ldb_ch == &ldb->channel[1])
++      if (imx_ldb_ch == &ldb->channel[1] || dual)
+               ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
+ 
+       regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
+ 
+-      if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
++      if (dual) {
+               clk_disable_unprepare(ldb->clk[0]);
+               clk_disable_unprepare(ldb->clk[1]);
+       }
+diff --git a/drivers/input/mouse/psmouse-base.c 
b/drivers/input/mouse/psmouse-base.c
+index ad18dab0ac476..5bd9633541b07 100644
+--- a/drivers/input/mouse/psmouse-base.c
++++ b/drivers/input/mouse/psmouse-base.c
+@@ -1911,7 +1911,7 @@ static int psmouse_get_maxproto(char *buffer, const 
struct kernel_param *kp)
+ {
+       int type = *((unsigned int *)kp->arg);
+ 
+-      return sprintf(buffer, "%s", psmouse_protocol_by_type(type)->name);
++      return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name);
+ }
+ 
+ static int __init psmouse_init(void)
+diff --git a/drivers/media/pci/ttpci/budget-core.c 
b/drivers/media/pci/ttpci/budget-core.c
+index e9674b40007c1..6107c469efa07 100644
+--- a/drivers/media/pci/ttpci/budget-core.c
++++ b/drivers/media/pci/ttpci/budget-core.c
+@@ -386,20 +386,25 @@ static int budget_register(struct budget *budget)
+       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);
+ 
+       if (ret < 0)
+-              return ret;
++              goto err_release_dmx;
+ 
+       budget->mem_frontend.source = DMX_MEMORY_FE;
+       ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend);
+       if (ret < 0)
+-              return ret;
++              goto err_release_dmx;
+ 
+       ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, 
&budget->hw_frontend);
+       if (ret < 0)
+-              return ret;
++              goto err_release_dmx;
+ 
+       dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
+ 
+       return 0;
++
++err_release_dmx:
++      dvb_dmxdev_release(&budget->dmxdev);
++      dvb_dmx_release(&budget->demux);
++      return ret;
+ }
+ 
+ static void budget_unregister(struct budget *budget)
+diff --git a/drivers/media/platform/davinci/vpss.c 
b/drivers/media/platform/davinci/vpss.c
+index c2c68988e38ac..9884b34d6f406 100644
+--- a/drivers/media/platform/davinci/vpss.c
++++ b/drivers/media/platform/davinci/vpss.c
+@@ -519,19 +519,31 @@ static void vpss_exit(void)
+ 
+ static int __init vpss_init(void)
+ {
++      int ret;
++
+       if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control"))
+               return -EBUSY;
+ 
+       oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);
+       if (unlikely(!oper_cfg.vpss_regs_base2)) {
+-              release_mem_region(VPSS_CLK_CTRL, 4);
+-              return -ENOMEM;
++              ret = -ENOMEM;
++              goto err_ioremap;
+       }
+ 
+       writel(VPSS_CLK_CTRL_VENCCLKEN |
+-                   VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
++             VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
++
++      ret = platform_driver_register(&vpss_driver);
++      if (ret)
++              goto err_pd_register;
++
++      return 0;
+ 
+-      return platform_driver_register(&vpss_driver);
++err_pd_register:
++      iounmap(oper_cfg.vpss_regs_base2);
++err_ioremap:
++      release_mem_region(VPSS_CLK_CTRL, 4);
++      return ret;
+ }
+ subsys_initcall(vpss_init);
+ module_exit(vpss_exit);
+diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
+index 880a9068ca126..ef06af4e3611d 100644
+--- a/drivers/scsi/libfc/fc_disc.c
++++ b/drivers/scsi/libfc/fc_disc.c
+@@ -595,8 +595,12 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct 
fc_frame *fp,
+       mutex_lock(&disc->disc_mutex);
+       if (PTR_ERR(fp) == -FC_EX_CLOSED)
+               goto out;
+-      if (IS_ERR(fp))
+-              goto redisc;
++      if (IS_ERR(fp)) {
++              mutex_lock(&disc->disc_mutex);
++              fc_disc_restart(disc);
++              mutex_unlock(&disc->disc_mutex);
++              goto out;
++      }
+ 
+       cp = fc_frame_payload_get(fp, sizeof(*cp));
+       if (!cp)
+@@ -621,7 +625,7 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct 
fc_frame *fp,
+                               new_rdata->disc_id = disc->disc_id;
+                               lport->tt.rport_login(new_rdata);
+                       }
+-                      goto out;
++                      goto free_fp;
+               }
+               rdata->disc_id = disc->disc_id;
+               lport->tt.rport_login(rdata);
+@@ -635,6 +639,8 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct 
fc_frame *fp,
+ redisc:
+               fc_disc_restart(disc);
+       }
++free_fp:
++      fc_frame_free(fp);
+ out:
+       mutex_unlock(&disc->disc_mutex);
+       kref_put(&rdata->kref, lport->tt.rport_destroy);
+diff --git a/drivers/video/fbdev/omap2/dss/dss.c 
b/drivers/video/fbdev/omap2/dss/dss.c
+index 9200a8668b498..a57c3a5f4bf8b 100644
+--- a/drivers/video/fbdev/omap2/dss/dss.c
++++ b/drivers/video/fbdev/omap2/dss/dss.c
+@@ -843,7 +843,7 @@ static const struct dss_features omap34xx_dss_feats = {
+ };
+ 
+ static const struct dss_features omap3630_dss_feats = {
+-      .fck_div_max            =       32,
++      .fck_div_max            =       31,
+       .dss_fck_multiplier     =       1,
+       .parent_clk_name        =       "dpll4_ck",
+       .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
+index a01a41a412693..6b3565feddb21 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -603,6 +603,9 @@ bool virtqueue_poll(struct virtqueue *_vq, unsigned 
last_used_idx)
+ {
+       struct vring_virtqueue *vq = to_vvq(_vq);
+ 
++      if (unlikely(vq->broken))
++              return false;
++
+       virtio_mb(vq->weak_barriers);
+       return (u16)last_used_idx != virtio16_to_cpu(_vq->vdev, 
vq->vring.used->idx);
+ }
+diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
+index 2048aad91add8..2b12ef019ae02 100644
+--- a/drivers/watchdog/f71808e_wdt.c
++++ b/drivers/watchdog/f71808e_wdt.c
+@@ -642,9 +642,9 @@ static int __init watchdog_init(int sioaddr)
+        * into the module have been registered yet.
+        */
+       watchdog.sioaddr = sioaddr;
+-      watchdog.ident.options = WDIOC_SETTIMEOUT
+-                              | WDIOF_MAGICCLOSE
+-                              | WDIOF_KEEPALIVEPING;
++      watchdog.ident.options = WDIOF_MAGICCLOSE
++                              | WDIOF_KEEPALIVEPING
++                              | WDIOF_CARDRESET;
+ 
+       snprintf(watchdog.ident.identity,
+               sizeof(watchdog.ident.identity), "%s watchdog",
+diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c
+index 5f6b77ea34fb5..128375ff80b8c 100644
+--- a/drivers/xen/preempt.c
++++ b/drivers/xen/preempt.c
+@@ -31,7 +31,7 @@ EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall);
+ asmlinkage __visible void xen_maybe_preempt_hcall(void)
+ {
+       if (unlikely(__this_cpu_read(xen_in_preemptible_hcall)
+-                   && need_resched())) {
++                   && need_resched() && !preempt_count())) {
+               /*
+                * Clear flag as we may be rescheduled on a different
+                * cpu.
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 0b06d4942da77..8fb9a1e0048be 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -4096,6 +4096,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char 
*buffer, size_t size);
+ /* super.c */
+ int btrfs_parse_options(struct btrfs_root *root, char *options);
+ int btrfs_sync_fs(struct super_block *sb, int wait);
++char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
++                                        u64 subvol_objectid);
+ 
+ #ifdef CONFIG_PRINTK
+ __printf(2, 3)
+diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
+index 2513a7f533342..92f80ed642194 100644
+--- a/fs/btrfs/export.c
++++ b/fs/btrfs/export.c
+@@ -55,9 +55,9 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int 
*max_len,
+       return type;
+ }
+ 
+-static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+-                                     u64 root_objectid, u32 generation,
+-                                     int check_generation)
++struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
++                              u64 root_objectid, u32 generation,
++                              int check_generation)
+ {
+       struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+       struct btrfs_root *root;
+@@ -150,7 +150,7 @@ static struct dentry *btrfs_fh_to_dentry(struct 
super_block *sb, struct fid *fh,
+       return btrfs_get_dentry(sb, objectid, root_objectid, generation, 1);
+ }
+ 
+-static struct dentry *btrfs_get_parent(struct dentry *child)
++struct dentry *btrfs_get_parent(struct dentry *child)
+ {
+       struct inode *dir = d_inode(child);
+       struct btrfs_root *root = BTRFS_I(dir)->root;
+diff --git a/fs/btrfs/export.h b/fs/btrfs/export.h
+index 074348a95841f..7a305e5549991 100644
+--- a/fs/btrfs/export.h
++++ b/fs/btrfs/export.h
+@@ -16,4 +16,9 @@ struct btrfs_fid {
+       u64 parent_root_objectid;
+ } __attribute__ ((packed));
+ 
++struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
++                              u64 root_objectid, u32 generation,
++                              int check_generation);
++struct dentry *btrfs_get_parent(struct dentry *child);
++
+ #endif
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index 404051bf5cba9..77e6ce0e1e351 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -843,8 +843,8 @@ out:
+       return error;
+ }
+ 
+-static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
+-                                         u64 subvol_objectid)
++char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
++                                        u64 subvol_objectid)
+ {
+       struct btrfs_root *root = fs_info->tree_root;
+       struct btrfs_root *fs_root;
+@@ -1120,6 +1120,7 @@ static int btrfs_show_options(struct seq_file *seq, 
struct dentry *dentry)
+       struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
+       struct btrfs_root *root = info->tree_root;
+       char *compress_type;
++      const char *subvol_name;
+ 
+       if (btrfs_test_opt(root, DEGRADED))
+               seq_puts(seq, ",degraded");
+@@ -1204,8 +1205,13 @@ static int btrfs_show_options(struct seq_file *seq, 
struct dentry *dentry)
+ #endif
+       seq_printf(seq, ",subvolid=%llu",
+                 BTRFS_I(d_inode(dentry))->root->root_key.objectid);
+-      seq_puts(seq, ",subvol=");
+-      seq_dentry(seq, dentry, " \t\n\\");
++      subvol_name = btrfs_get_subvol_name_from_objectid(info,
++                      BTRFS_I(d_inode(dentry))->root->root_key.objectid);
++      if (!IS_ERR(subvol_name)) {
++              seq_puts(seq, ",subvol=");
++              seq_escape(seq, subvol_name, " \t\n\\");
++              kfree(subvol_name);
++      }
+       return 0;
+ }
+ 
+@@ -1323,8 +1329,8 @@ static struct dentry *mount_subvol(const char 
*subvol_name, u64 subvol_objectid,
+                               goto out;
+                       }
+               }
+-              subvol_name = 
get_subvol_name_from_objectid(btrfs_sb(mnt->mnt_sb),
+-                                                          subvol_objectid);
++              subvol_name = btrfs_get_subvol_name_from_objectid(
++                                      btrfs_sb(mnt->mnt_sb), subvol_objectid);
+               if (IS_ERR(subvol_name)) {
+                       root = ERR_CAST(subvol_name);
+                       subvol_name = NULL;
+diff --git a/fs/eventpoll.c b/fs/eventpoll.c
+index 240d9ceb8d0c6..b8959d0d4c723 100644
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -1719,9 +1719,11 @@ static int ep_loop_check_proc(void *priv, void *cookie, 
int call_nests)
+                        * not already there, and calling reverse_path_check()
+                        * during ep_insert().
+                        */
+-                      if (list_empty(&epi->ffd.file->f_tfile_llink))
++                      if (list_empty(&epi->ffd.file->f_tfile_llink)) {
++                              get_file(epi->ffd.file);
+                               list_add(&epi->ffd.file->f_tfile_llink,
+                                        &tfile_check_list);
++                      }
+               }
+       }
+       mutex_unlock(&ep->mtx);
+@@ -1765,6 +1767,7 @@ static void clear_tfile_check_list(void)
+               file = list_first_entry(&tfile_check_list, struct file,
+                                       f_tfile_llink);
+               list_del_init(&file->f_tfile_llink);
++              fput(file);
+       }
+       INIT_LIST_HEAD(&tfile_check_list);
+ }
+@@ -1902,13 +1905,13 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
+                       mutex_lock(&epmutex);
+                       if (is_file_epoll(tf.file)) {
+                               error = -ELOOP;
+-                              if (ep_loop_check(ep, tf.file) != 0) {
+-                                      clear_tfile_check_list();
++                              if (ep_loop_check(ep, tf.file) != 0)
+                                       goto error_tgt_fput;
+-                              }
+-                      } else
++                      } else {
++                              get_file(tf.file);
+                               list_add(&tf.file->f_tfile_llink,
+                                                       &tfile_check_list);
++                      }
+                       mutex_lock_nested(&ep->mtx, 0);
+                       if (is_file_epoll(tf.file)) {
+                               tep = tf.file->private_data;
+@@ -1932,8 +1935,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
+                       error = ep_insert(ep, &epds, tf.file, fd, full_check);
+               } else
+                       error = -EEXIST;
+-              if (full_check)
+-                      clear_tfile_check_list();
+               break;
+       case EPOLL_CTL_DEL:
+               if (epi)
+@@ -1954,8 +1955,10 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
+       mutex_unlock(&ep->mtx);
+ 
+ error_tgt_fput:
+-      if (full_check)
++      if (full_check) {
++              clear_tfile_check_list();
+               mutex_unlock(&epmutex);
++      }
+ 
+       fdput(tf);
+ error_fput:
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 566a8b08ccdd6..061b026e464c5 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1226,19 +1226,18 @@ static void dx_insert_block(struct dx_frame *frame, 
u32 hash, ext4_lblk_t block)
+ }
+ 
+ /*
+- * NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure.
++ * Test whether a directory entry matches the filename being searched for.
+  *
+- * `len <= EXT4_NAME_LEN' is guaranteed by caller.
+- * `de != NULL' is guaranteed by caller.
++ * Return: %true if the directory entry matches, otherwise %false.
+  */
+-static inline int ext4_match(struct ext4_filename *fname,
+-                           struct ext4_dir_entry_2 *de)
++static inline bool ext4_match(const struct ext4_filename *fname,
++                            const struct ext4_dir_entry_2 *de)
+ {
+       const void *name = fname_name(fname);
+       u32 len = fname_len(fname);
+ 
+       if (!de->inode)
+-              return 0;
++              return false;
+ 
+ #ifdef CONFIG_EXT4_FS_ENCRYPTION
+       if (unlikely(!name)) {
+@@ -1270,48 +1269,31 @@ int ext4_search_dir(struct buffer_head *bh, char 
*search_buf, int buf_size,
+       struct ext4_dir_entry_2 * de;
+       char * dlimit;
+       int de_len;
+-      int res;
+ 
+       de = (struct ext4_dir_entry_2 *)search_buf;
+       dlimit = search_buf + buf_size;
+       while ((char *) de < dlimit) {
+               /* this code is executed quadratically often */
+               /* do minimal checking `by hand' */
+-              if ((char *) de + de->name_len <= dlimit) {
+-                      res = ext4_match(fname, de);
+-                      if (res < 0) {
+-                              res = -1;
+-                              goto return_result;
+-                      }
+-                      if (res > 0) {
+-                              /* found a match - just to be sure, do
+-                               * a full check */
+-                              if (ext4_check_dir_entry(dir, NULL, de, bh,
+-                                              bh->b_data,
+-                                               bh->b_size, offset)) {
+-                                      res = -1;
+-                                      goto return_result;
+-                              }
+-                              *res_dir = de;
+-                              res = 1;
+-                              goto return_result;
+-                      }
+-
++              if ((char *) de + de->name_len <= dlimit &&
++                  ext4_match(fname, de)) {
++                      /* found a match - just to be sure, do
++                       * a full check */
++                      if (ext4_check_dir_entry(dir, NULL, de, bh, search_buf,
++                                               buf_size, offset))
++                              return -1;
++                      *res_dir = de;
++                      return 1;
+               }
+               /* prevent looping on a bad block */
+               de_len = ext4_rec_len_from_disk(de->rec_len,
+                                               dir->i_sb->s_blocksize);
+-              if (de_len <= 0) {
+-                      res = -1;
+-                      goto return_result;
+-              }
++              if (de_len <= 0)
++                      return -1;
+               offset += de_len;
+               de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
+       }
+-
+-      res = 0;
+-return_result:
+-      return res;
++      return 0;
+ }
+ 
+ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
+@@ -1748,7 +1730,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t 
*handle, struct inode *dir,
+                            blocksize, hinfo, map);
+       map -= count;
+       dx_sort_map(map, count);
+-      /* Split the existing block in the middle, size-wise */
++      /* Ensure that neither split block is over half full */
+       size = 0;
+       move = 0;
+       for (i = count-1; i >= 0; i--) {
+@@ -1758,8 +1740,18 @@ static struct ext4_dir_entry_2 *do_split(handle_t 
*handle, struct inode *dir,
+               size += map[i].size;
+               move++;
+       }
+-      /* map index at which we will split */
+-      split = count - move;
++      /*
++       * map index at which we will split
++       *
++       * If the sum of active entries didn't exceed half the block size, just
++       * split it in half by count; each resulting block will have at least
++       * half the space free.
++       */
++      if (i > 0)
++              split = count - move;
++      else
++              split = count/2;
++
+       hash2 = map[split].hash;
+       continued = hash2 == map[split - 1].hash;
+       dxtrace(printk(KERN_INFO "Split block %lu at %x, %i/%i\n",
+@@ -1824,24 +1816,15 @@ int ext4_find_dest_de(struct inode *dir, struct inode 
*inode,
+       int nlen, rlen;
+       unsigned int offset = 0;
+       char *top;
+-      int res;
+ 
+       de = (struct ext4_dir_entry_2 *)buf;
+       top = buf + buf_size - reclen;
+       while ((char *) de <= top) {
+               if (ext4_check_dir_entry(dir, NULL, de, bh,
+-                                       buf, buf_size, offset)) {
+-                      res = -EFSCORRUPTED;
+-                      goto return_result;
+-              }
+-              /* Provide crypto context and crypto buffer to ext4 match */
+-              res = ext4_match(fname, de);
+-              if (res < 0)
+-                      goto return_result;
+-              if (res > 0) {
+-                      res = -EEXIST;
+-                      goto return_result;
+-              }
++                                       buf, buf_size, offset))
++                      return -EFSCORRUPTED;
++              if (ext4_match(fname, de))
++                      return -EEXIST;
+               nlen = EXT4_DIR_REC_LEN(de->name_len);
+               rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
+               if ((de->inode ? rlen - nlen : rlen) >= reclen)
+@@ -1849,15 +1832,11 @@ int ext4_find_dest_de(struct inode *dir, struct inode 
*inode,
+               de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
+               offset += rlen;
+       }
+-
+       if ((char *) de > top)
+-              res = -ENOSPC;
+-      else {
+-              *dest_de = de;
+-              res = 0;
+-      }
+-return_result:
+-      return res;
++              return -ENOSPC;
++
++      *dest_de = de;
++      return 0;
+ }
+ 
+ int ext4_insert_dentry(struct inode *dir,
+@@ -2343,7 +2322,7 @@ int ext4_generic_delete_entry(handle_t *handle,
+       de = (struct ext4_dir_entry_2 *)entry_buf;
+       while (i < buf_size - csum_size) {
+               if (ext4_check_dir_entry(dir, NULL, de, bh,
+-                                       bh->b_data, bh->b_size, i))
++                                       entry_buf, buf_size, i))
+                       return -EFSCORRUPTED;
+               if (de == de_del)  {
+                       if (pde)
+diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
+index e273171696972..7a3368929245d 100644
+--- a/fs/jffs2/dir.c
++++ b/fs/jffs2/dir.c
+@@ -588,10 +588,14 @@ static int jffs2_rmdir (struct inode *dir_i, struct 
dentry *dentry)
+       int ret;
+       uint32_t now = get_seconds();
+ 
++      mutex_lock(&f->sem);
+       for (fd = f->dents ; fd; fd = fd->next) {
+-              if (fd->ino)
++              if (fd->ino) {
++                      mutex_unlock(&f->sem);
+                       return -ENOTEMPTY;
++              }
+       }
++      mutex_unlock(&f->sem);
+ 
+       ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
+                             dentry->d_name.len, f, now);
+diff --git a/fs/romfs/storage.c b/fs/romfs/storage.c
+index f86f51f99aceb..1dcadd22b440d 100644
+--- a/fs/romfs/storage.c
++++ b/fs/romfs/storage.c
+@@ -221,10 +221,8 @@ int romfs_dev_read(struct super_block *sb, unsigned long 
pos,
+       size_t limit;
+ 
+       limit = romfs_maxsize(sb);
+-      if (pos >= limit)
++      if (pos >= limit || buflen > limit - pos)
+               return -EIO;
+-      if (buflen > limit - pos)
+-              buflen = limit - pos;
+ 
+ #ifdef CONFIG_ROMFS_ON_MTD
+       if (sb->s_mtd)
+diff --git a/fs/xfs/xfs_sysfs.h b/fs/xfs/xfs_sysfs.h
+index be692e59938db..c457b010c623d 100644
+--- a/fs/xfs/xfs_sysfs.h
++++ b/fs/xfs/xfs_sysfs.h
+@@ -44,9 +44,11 @@ xfs_sysfs_init(
+       struct xfs_kobj         *parent_kobj,
+       const char              *name)
+ {
++      struct kobject          *parent;
++
++      parent = parent_kobj ? &parent_kobj->kobject : NULL;
+       init_completion(&kobj->complete);
+-      return kobject_init_and_add(&kobj->kobject, ktype,
+-                                  &parent_kobj->kobject, "%s", name);
++      return kobject_init_and_add(&kobj->kobject, ktype, parent, "%s", name);
+ }
+ 
+ static inline void
+diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
+index ce78534a047ee..bb8de2dddabe2 100644
+--- a/fs/xfs/xfs_trans_dquot.c
++++ b/fs/xfs/xfs_trans_dquot.c
+@@ -662,7 +662,7 @@ xfs_trans_dqresv(
+                       }
+               }
+               if (ninos > 0) {
+-                      total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos;
++                      total_count = dqp->q_res_icount + ninos;
+                       timer = be32_to_cpu(dqp->q_core.d_itimer);
+                       warns = be16_to_cpu(dqp->q_core.d_iwarns);
+                       warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit;
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 03cf5526e4456..2b17d2fca4299 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1123,6 +1123,10 @@ void unmap_vmas(struct mmu_gather *tlb, struct 
vm_area_struct *start_vma,
+  * followed by taking the mmap_sem for writing before modifying the
+  * vmas or anything the coredump pretends not to change from under it.
+  *
++ * It also has to be called when mmgrab() is used in the context of
++ * the process, but then the mm_count refcount is transferred outside
++ * the context of the process to run down_write() on that pinned mm.
++ *
+  * NOTE: find_extend_vma() called from GUP context is the only place
+  * that can modify the "mm" (notably the vm_start/end) under mmap_sem
+  * for reading and outside the context of the process, so it is also
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 426a57874964c..31198b32d9122 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -779,6 +779,8 @@ static inline int sk_memalloc_socks(void)
+ {
+       return static_key_false(&memalloc_socks);
+ }
++
++void __receive_sock(struct file *file);
+ #else
+ 
+ static inline int sk_memalloc_socks(void)
+@@ -786,6 +788,8 @@ static inline int sk_memalloc_socks(void)
+       return 0;
+ }
+ 
++static inline void __receive_sock(struct file *file)
++{ }
+ #endif
+ 
+ static inline gfp_t sk_gfp_atomic(const struct sock *sk, gfp_t gfp_mask)
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index 465786cd6490e..f38d24bb8a1bc 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2136,7 +2136,7 @@ static void insert_to_mm_slots_hash(struct mm_struct *mm,
+ 
+ static inline int khugepaged_test_exit(struct mm_struct *mm)
+ {
+-      return atomic_read(&mm->mm_users) == 0;
++      return atomic_read(&mm->mm_users) == 0 || !mmget_still_valid(mm);
+ }
+ 
+ int __khugepaged_enter(struct mm_struct *mm)
+@@ -2149,7 +2149,7 @@ int __khugepaged_enter(struct mm_struct *mm)
+               return -ENOMEM;
+ 
+       /* __khugepaged_exit() must not run from under us */
+-      VM_BUG_ON_MM(khugepaged_test_exit(mm), mm);
++      VM_BUG_ON_MM(atomic_read(&mm->mm_users) == 0, mm);
+       if (unlikely(test_and_set_bit(MMF_VM_HUGEPAGE, &mm->flags))) {
+               free_mm_slot(mm_slot);
+               return 0;
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 3a1501e854832..baac9a09ec0a1 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -4257,6 +4257,7 @@ static bool vma_shareable(struct vm_area_struct *vma, 
unsigned long addr)
+       return false;
+ }
+ 
++#define ALIGN_DOWN(x, a)      __ALIGN_KERNEL((x) - ((a) - 1), (a))
+ /*
+  * Determine if start,end range within vma could be mapped by shared pmd.
+  * If yes, adjust start and end to cover range associated with possible
+@@ -4265,25 +4266,21 @@ static bool vma_shareable(struct vm_area_struct *vma, 
unsigned long addr)
+ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
+                               unsigned long *start, unsigned long *end)
+ {
+-      unsigned long check_addr = *start;
++      unsigned long a_start, a_end;
+ 
+       if (!(vma->vm_flags & VM_MAYSHARE))
+               return;
+ 
+-      for (check_addr = *start; check_addr < *end; check_addr += PUD_SIZE) {
+-              unsigned long a_start = check_addr & PUD_MASK;
+-              unsigned long a_end = a_start + PUD_SIZE;
++      /* Extend the range to be PUD aligned for a worst case scenario */
++      a_start = ALIGN_DOWN(*start, PUD_SIZE);
++      a_end = ALIGN(*end, PUD_SIZE);
+ 
+-              /*
+-               * If sharing is possible, adjust start/end if necessary.
+-               */
+-              if (range_in_vma(vma, a_start, a_end)) {
+-                      if (a_start < *start)
+-                              *start = a_start;
+-                      if (a_end > *end)
+-                              *end = a_end;
+-              }
+-      }
++      /*
++       * Intersect the range with the vma range, since pmd sharing won't be
++       * across vma after all
++       */
++      *start = max(vma->vm_start, a_start);
++      *end = min(vma->vm_end, a_end);
+ }
+ 
+ /*
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index df589416ace6c..14bab5fa1b656 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -843,6 +843,11 @@ static void free_pcppages_bulk(struct zone *zone, int 
count,
+       if (nr_scanned)
+               __mod_zone_page_state(zone, NR_PAGES_SCANNED, -nr_scanned);
+ 
++      /*
++       * Ensure proper count is passed which otherwise would stuck in the
++       * below while (list_empty(list)) loop.
++       */
++      count = min(pcp->count, count);
+       while (to_free) {
+               struct page *page;
+               struct list_head *list;
+@@ -6285,7 +6290,7 @@ int __meminit init_per_zone_wmark_min(void)
+       setup_per_zone_inactive_ratio();
+       return 0;
+ }
+-core_initcall(init_per_zone_wmark_min)
++postcore_initcall(init_per_zone_wmark_min)
+ 
+ /*
+  * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so
+diff --git a/net/compat.c b/net/compat.c
+index d676840104556..20c5e5f215f23 100644
+--- a/net/compat.c
++++ b/net/compat.c
+@@ -284,6 +284,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct 
scm_cookie *scm)
+                       break;
+               }
+               /* Bump the usage count and install the file. */
++              __receive_sock(fp[i]);
+               fd_install(new_fd, get_file(fp[i]));
+       }
+ 
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 120d5058d81ae..82f9a7dbea6fe 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2275,6 +2275,27 @@ int sock_no_mmap(struct file *file, struct socket 
*sock, struct vm_area_struct *
+ }
+ EXPORT_SYMBOL(sock_no_mmap);
+ 
++/*
++ * When a file is received (via SCM_RIGHTS, etc), we must bump the
++ * various sock-based usage counts.
++ */
++void __receive_sock(struct file *file)
++{
++      struct socket *sock;
++      int error;
++
++      /*
++       * The resulting value of "error" is ignored here since we only
++       * need to take action when the file is a socket and testing
++       * "sock" for NULL is sufficient.
++       */
++      sock = sock_from_file(file, &error);
++      if (sock) {
++              sock_update_netprioidx(sock->sk);
++              sock_update_classid(sock->sk);
++      }
++}
++
+ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, 
size_t size, int flags)
+ {
+       ssize_t res;
+diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c 
b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+index 1d9dfb92b3b48..edb244331e6e9 100644
+--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
++++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+@@ -338,7 +338,7 @@ static int sst_media_open(struct snd_pcm_substream 
*substream,
+ 
+       ret_val = power_up_sst(stream);
+       if (ret_val < 0)
+-              return ret_val;
++              goto out_power_up;
+ 
+       /* Make sure, that the period size is always even */
+       snd_pcm_hw_constraint_step(substream->runtime, 0,
+@@ -347,8 +347,9 @@ static int sst_media_open(struct snd_pcm_substream 
*substream,
+       return snd_pcm_hw_constraint_integer(runtime,
+                        SNDRV_PCM_HW_PARAM_PERIODS);
+ out_ops:
+-      kfree(stream);
+       mutex_unlock(&sst_lock);
++out_power_up:
++      kfree(stream);
+       return ret_val;
+ }
+ 
+diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
+index c694f10d004cc..1b73537af91db 100644
+--- a/tools/perf/util/probe-finder.c
++++ b/tools/perf/util/probe-finder.c
+@@ -1274,7 +1274,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
+       tf.ntevs = 0;
+ 
+       ret = debuginfo__find_probes(dbg, &tf.pf);
+-      if (ret < 0) {
++      if (ret < 0 || tf.ntevs == 0) {
+               for (i = 0; i < tf.ntevs; i++)
+                       clear_probe_trace_event(&tf.tevs[i]);
+               zfree(tevs);

Reply via email to