commit:     6ccb304d9415004ac7a86a17614c9258510cff2b
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Sep  7 22:41:47 2017 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Sep  7 22:41:47 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6ccb304d

Linux patch 4.4.87

 0000_README             |   4 +
 1086_linux-4.4.87.patch | 408 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 412 insertions(+)

diff --git a/0000_README b/0000_README
index 9eb8ca5..99f6582 100644
--- a/0000_README
+++ b/0000_README
@@ -387,6 +387,10 @@ Patch:  1085_linux-4.4.86.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.4.86
 
+Patch:  1086_linux-4.4.87.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.4.87
+
 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/1086_linux-4.4.87.patch b/1086_linux-4.4.87.patch
new file mode 100644
index 0000000..5292853
--- /dev/null
+++ b/1086_linux-4.4.87.patch
@@ -0,0 +1,408 @@
+diff --git a/Makefile b/Makefile
+index 1207bf6a0e7a..f6838187b568 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 4
+-SUBLEVEL = 86
++SUBLEVEL = 87
+ EXTRAVERSION =
+ NAME = Blurry Fish Butt
+ 
+diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h
+index 4cb4b6d3452c..0bc66e1d3a7e 100644
+--- a/arch/alpha/include/asm/types.h
++++ b/arch/alpha/include/asm/types.h
+@@ -1,6 +1,6 @@
+ #ifndef _ALPHA_TYPES_H
+ #define _ALPHA_TYPES_H
+ 
+-#include <asm-generic/int-ll64.h>
++#include <uapi/asm/types.h>
+ 
+ #endif /* _ALPHA_TYPES_H */
+diff --git a/arch/alpha/include/uapi/asm/types.h 
b/arch/alpha/include/uapi/asm/types.h
+index 9fd3cd459777..8d1024d7be05 100644
+--- a/arch/alpha/include/uapi/asm/types.h
++++ b/arch/alpha/include/uapi/asm/types.h
+@@ -9,8 +9,18 @@
+  * need to be careful to avoid a name clashes.
+  */
+ 
+-#ifndef __KERNEL__
++/*
++ * This is here because we used to use l64 for alpha
++ * and we don't want to impact user mode with our change to ll64
++ * in the kernel.
++ *
++ * However, some user programs are fine with this.  They can
++ * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here.
++ */
++#if !defined(__SANE_USERSPACE_TYPES__) && !defined(__KERNEL__)
+ #include <asm-generic/int-l64.h>
++#else
++#include <asm-generic/int-ll64.h>
+ #endif
+ 
+ #endif /* _UAPI_ALPHA_TYPES_H */
+diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
+index ba079e279b58..e8835d4e173c 100644
+--- a/arch/arm/kvm/mmu.c
++++ b/arch/arm/kvm/mmu.c
+@@ -824,24 +824,25 @@ void stage2_unmap_vm(struct kvm *kvm)
+  * Walks the level-1 page table pointed to by kvm->arch.pgd and frees all
+  * underlying level-2 and level-3 tables before freeing the actual level-1 
table
+  * and setting the struct pointer to NULL.
+- *
+- * Note we don't need locking here as this is only called when the VM is
+- * destroyed, which can only be done once.
+  */
+ void kvm_free_stage2_pgd(struct kvm *kvm)
+ {
+-      if (kvm->arch.pgd == NULL)
+-              return;
++      void *pgd = NULL;
++      void *hwpgd = NULL;
+ 
+       spin_lock(&kvm->mmu_lock);
+-      unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
++      if (kvm->arch.pgd) {
++              unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
++              pgd = READ_ONCE(kvm->arch.pgd);
++              hwpgd = kvm_get_hwpgd(kvm);
++              kvm->arch.pgd = NULL;
++      }
+       spin_unlock(&kvm->mmu_lock);
+ 
+-      kvm_free_hwpgd(kvm_get_hwpgd(kvm));
+-      if (KVM_PREALLOC_LEVEL > 0)
+-              kfree(kvm->arch.pgd);
+-
+-      kvm->arch.pgd = NULL;
++      if (hwpgd)
++              kvm_free_hwpgd(hwpgd);
++      if (KVM_PREALLOC_LEVEL > 0 && pgd)
++              kfree(pgd);
+ }
+ 
+ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache 
*cache,
+diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
+index f5e9f9310b48..b3b0004ea8ac 100644
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -86,8 +86,13 @@ static void skcipher_free_async_sgls(struct 
skcipher_async_req *sreq)
+       }
+       sgl = sreq->tsg;
+       n = sg_nents(sgl);
+-      for_each_sg(sgl, sg, n, i)
+-              put_page(sg_page(sg));
++      for_each_sg(sgl, sg, n, i) {
++              struct page *page = sg_page(sg);
++
++              /* some SGs may not have a page mapped */
++              if (page && atomic_read(&page->_count))
++                      put_page(page);
++      }
+ 
+       kfree(sreq->tsg);
+ }
+diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c 
b/drivers/gpu/drm/ttm/ttm_page_alloc.c
+index 025c429050c0..5d8dfe027b30 100644
+--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
++++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
+@@ -612,7 +612,7 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool 
*pool,
+               } else {
+                       pr_err("Failed to fill pool (%p)\n", pool);
+                       /* If we have any pages left put them to the pool. */
+-                      list_for_each_entry(p, &pool->list, lru) {
++                      list_for_each_entry(p, &new_pages, lru) {
+                               ++cpages;
+                       }
+                       list_splice(&new_pages, &pool->list);
+diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
+index 7ba795b24e75..639d1a9c8793 100644
+--- a/drivers/i2c/busses/i2c-ismt.c
++++ b/drivers/i2c/busses/i2c-ismt.c
+@@ -339,8 +339,10 @@ static int ismt_process_desc(const struct ismt_desc *desc,
+                       break;
+               case I2C_SMBUS_BLOCK_DATA:
+               case I2C_SMBUS_I2C_BLOCK_DATA:
+-                      memcpy(&data->block[1], dma_buffer, desc->rxbytes);
+-                      data->block[0] = desc->rxbytes;
++                      if (desc->rxbytes != dma_buffer[0] + 1)
++                              return -EMSGSIZE;
++
++                      memcpy(data->block, dma_buffer, desc->rxbytes);
+                       break;
+               }
+               return 0;
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index 9e17ef27a183..6f1dbd52ec91 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -915,8 +915,11 @@ static int __init gic_of_init(struct device_node *node,
+               gic_len = resource_size(&res);
+       }
+ 
+-      if (mips_cm_present())
++      if (mips_cm_present()) {
+               write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK);
++              /* Ensure GIC region is enabled before trying to access it */
++              __sync();
++      }
+       gic_present = true;
+ 
+       __gic_init(gic_base, gic_len, cpu_vec, 0, node);
+diff --git a/drivers/net/wireless/ti/wl1251/main.c 
b/drivers/net/wireless/ti/wl1251/main.c
+index cd4777954f87..9bee3f11898a 100644
+--- a/drivers/net/wireless/ti/wl1251/main.c
++++ b/drivers/net/wireless/ti/wl1251/main.c
+@@ -1567,6 +1567,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
+ 
+       wl->state = WL1251_STATE_OFF;
+       mutex_init(&wl->mutex);
++      spin_lock_init(&wl->wl_lock);
+ 
+       wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
+       wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
+diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
+index c6a1ec110c01..22bae2b434e2 100644
+--- a/fs/ceph/addr.c
++++ b/fs/ceph/addr.c
+@@ -189,7 +189,7 @@ static int ceph_releasepage(struct page *page, gfp_t g)
+ /*
+  * read a single page, without unlocking it.
+  */
+-static int readpage_nounlock(struct file *filp, struct page *page)
++static int ceph_do_readpage(struct file *filp, struct page *page)
+ {
+       struct inode *inode = file_inode(filp);
+       struct ceph_inode_info *ci = ceph_inode(inode);
+@@ -219,7 +219,7 @@ static int readpage_nounlock(struct file *filp, struct 
page *page)
+ 
+       err = ceph_readpage_from_fscache(inode, page);
+       if (err == 0)
+-              goto out;
++              return -EINPROGRESS;
+ 
+       dout("readpage inode %p file %p page %p index %lu\n",
+            inode, filp, page, page->index);
+@@ -249,8 +249,11 @@ out:
+ 
+ static int ceph_readpage(struct file *filp, struct page *page)
+ {
+-      int r = readpage_nounlock(filp, page);
+-      unlock_page(page);
++      int r = ceph_do_readpage(filp, page);
++      if (r != -EINPROGRESS)
++              unlock_page(page);
++      else
++              r = 0;
+       return r;
+ }
+ 
+@@ -1094,7 +1097,7 @@ retry_locked:
+                       goto retry_locked;
+               r = writepage_nounlock(page, NULL);
+               if (r < 0)
+-                      goto fail_nosnap;
++                      goto fail_unlock;
+               goto retry_locked;
+       }
+ 
+@@ -1122,11 +1125,14 @@ retry_locked:
+       }
+ 
+       /* we need to read it. */
+-      r = readpage_nounlock(file, page);
+-      if (r < 0)
+-              goto fail_nosnap;
++      r = ceph_do_readpage(file, page);
++      if (r < 0) {
++              if (r == -EINPROGRESS)
++                      return -EAGAIN;
++              goto fail_unlock;
++      }
+       goto retry_locked;
+-fail_nosnap:
++fail_unlock:
+       unlock_page(page);
+       return r;
+ }
+diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
+index a4766ded1ba7..ff1cfd7b1083 100644
+--- a/fs/ceph/cache.c
++++ b/fs/ceph/cache.c
+@@ -224,13 +224,7 @@ void ceph_fscache_unregister_inode_cookie(struct 
ceph_inode_info* ci)
+       fscache_relinquish_cookie(cookie, 0);
+ }
+ 
+-static void ceph_vfs_readpage_complete(struct page *page, void *data, int 
error)
+-{
+-      if (!error)
+-              SetPageUptodate(page);
+-}
+-
+-static void ceph_vfs_readpage_complete_unlock(struct page *page, void *data, 
int error)
++static void ceph_readpage_from_fscache_complete(struct page *page, void 
*data, int error)
+ {
+       if (!error)
+               SetPageUptodate(page);
+@@ -259,7 +253,7 @@ int ceph_readpage_from_fscache(struct inode *inode, struct 
page *page)
+               return -ENOBUFS;
+ 
+       ret = fscache_read_or_alloc_page(ci->fscache, page,
+-                                       ceph_vfs_readpage_complete, NULL,
++                                       ceph_readpage_from_fscache_complete, 
NULL,
+                                        GFP_KERNEL);
+ 
+       switch (ret) {
+@@ -288,7 +282,7 @@ int ceph_readpages_from_fscache(struct inode *inode,
+               return -ENOBUFS;
+ 
+       ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages,
+-                                        ceph_vfs_readpage_complete_unlock,
++                                        ceph_readpage_from_fscache_complete,
+                                         NULL, mapping_gfp_mask(mapping));
+ 
+       switch (ret) {
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index fa8df3fef6fc..297e05c9e2b0 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -194,7 +194,7 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon)
+       int i;
+ 
+       if (unlikely(direntry->d_name.len >
+-                   tcon->fsAttrInfo.MaxPathNameComponentLength))
++                   le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength)))
+               return -ENAMETOOLONG;
+ 
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
+diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
+index b8f553b32dda..aacb15bd56fe 100644
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -82,8 +82,8 @@
+ 
+ #define NUMBER_OF_SMB2_COMMANDS       0x0013
+ 
+-/* BB FIXME - analyze following length BB */
+-#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad 
*/
++/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */
++#define MAX_SMB2_HDR_SIZE 0x00b0
+ 
+ #define SMB2_PROTO_NUMBER cpu_to_le32(0x424d53fe)
+ 
+diff --git a/fs/eventpoll.c b/fs/eventpoll.c
+index 1e009cad8d5c..1b08556776ce 100644
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -518,8 +518,13 @@ static void ep_remove_wait_queue(struct eppoll_entry *pwq)
+       wait_queue_head_t *whead;
+ 
+       rcu_read_lock();
+-      /* If it is cleared by POLLFREE, it should be rcu-safe */
+-      whead = rcu_dereference(pwq->whead);
++      /*
++       * If it is cleared by POLLFREE, it should be rcu-safe.
++       * If we read NULL we need a barrier paired with
++       * smp_store_release() in ep_poll_callback(), otherwise
++       * we rely on whead->lock.
++       */
++      whead = smp_load_acquire(&pwq->whead);
+       if (whead)
+               remove_wait_queue(whead, &pwq->wait);
+       rcu_read_unlock();
+@@ -1003,17 +1008,6 @@ static int ep_poll_callback(wait_queue_t *wait, 
unsigned mode, int sync, void *k
+       struct epitem *epi = ep_item_from_wait(wait);
+       struct eventpoll *ep = epi->ep;
+ 
+-      if ((unsigned long)key & POLLFREE) {
+-              ep_pwq_from_wait(wait)->whead = NULL;
+-              /*
+-               * whead = NULL above can race with ep_remove_wait_queue()
+-               * which can do another remove_wait_queue() after us, so we
+-               * can't use __remove_wait_queue(). whead->lock is held by
+-               * the caller.
+-               */
+-              list_del_init(&wait->task_list);
+-      }
+-
+       spin_lock_irqsave(&ep->lock, flags);
+ 
+       /*
+@@ -1078,6 +1072,23 @@ out_unlock:
+       if (pwake)
+               ep_poll_safewake(&ep->poll_wait);
+ 
++
++      if ((unsigned long)key & POLLFREE) {
++              /*
++               * If we race with ep_remove_wait_queue() it can miss
++               * ->whead = NULL and do another remove_wait_queue() after
++               * us, so we can't use __remove_wait_queue().
++               */
++              list_del_init(&wait->task_list);
++              /*
++               * ->whead != NULL protects us from the race with ep_free()
++               * or ep_remove(), ep_remove_wait_queue() takes whead->lock
++               * held by the caller. Once we nullify it, nothing protects
++               * ep/epi or even wait.
++               */
++              smp_store_release(&ep_pwq_from_wait(wait)->whead, NULL);
++      }
++
+       return 1;
+ }
+ 
+diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h
+index fc824e2828f3..5d2add1a6c96 100644
+--- a/include/asm-generic/topology.h
++++ b/include/asm-generic/topology.h
+@@ -48,7 +48,11 @@
+ #define parent_node(node)     ((void)(node),0)
+ #endif
+ #ifndef cpumask_of_node
+-#define cpumask_of_node(node) ((void)node, cpu_online_mask)
++  #ifdef CONFIG_NEED_MULTIPLE_NODES
++    #define cpumask_of_node(node)     ((node) == 0 ? cpu_online_mask : 
cpu_none_mask)
++  #else
++    #define cpumask_of_node(node)     ((void)node, cpu_online_mask)
++  #endif
+ #endif
+ #ifndef pcibus_to_node
+ #define pcibus_to_node(bus)   ((void)(bus), -1)
+diff --git a/kernel/cpuset.c b/kernel/cpuset.c
+index 8ccd66a97c8b..2924b6faa469 100644
+--- a/kernel/cpuset.c
++++ b/kernel/cpuset.c
+@@ -1910,6 +1910,7 @@ static struct cftype files[] = {
+       {
+               .name = "memory_pressure",
+               .read_u64 = cpuset_read_u64,
++              .private = FILE_MEMORY_PRESSURE,
+       },
+ 
+       {
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 77055a362041..0e01250f2072 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -3275,9 +3275,15 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 
dir, u8 type,
+       struct xfrm_state *x_new[XFRM_MAX_DEPTH];
+       struct xfrm_migrate *mp;
+ 
++      /* Stage 0 - sanity checks */
+       if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
+               goto out;
+ 
++      if (dir >= XFRM_POLICY_MAX) {
++              err = -EINVAL;
++              goto out;
++      }
++
+       /* Stage 1 - find policy */
+       if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) {
+               err = -ENOENT;

Reply via email to