commit:     f6b7dd03deac6395d6e2c321ff32c5df7296c3a8
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 24 11:46:20 2018 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Aug 24 11:46:20 2018 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f6b7dd03

Linux patch 4.18.5

 0000_README             |   4 +
 1004_linux-4.18.5.patch | 742 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 746 insertions(+)

diff --git a/0000_README b/0000_README
index c7d6cc0..8da0979 100644
--- a/0000_README
+++ b/0000_README
@@ -59,6 +59,10 @@ Patch:  1003_linux-4.18.4.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.18.4
 
+Patch:  1004_linux-4.18.5.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.18.5
+
 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/1004_linux-4.18.5.patch b/1004_linux-4.18.5.patch
new file mode 100644
index 0000000..abf70a2
--- /dev/null
+++ b/1004_linux-4.18.5.patch
@@ -0,0 +1,742 @@
+diff --git a/Makefile b/Makefile
+index ef0dd566c104..a41692c5827a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 18
+-SUBLEVEL = 4
++SUBLEVEL = 5
+ EXTRAVERSION =
+ NAME = Merciless Moray
+ 
+diff --git a/arch/parisc/include/asm/spinlock.h 
b/arch/parisc/include/asm/spinlock.h
+index 6f84b6acc86e..8a63515f03bf 100644
+--- a/arch/parisc/include/asm/spinlock.h
++++ b/arch/parisc/include/asm/spinlock.h
+@@ -20,7 +20,6 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x,
+ {
+       volatile unsigned int *a;
+ 
+-      mb();
+       a = __ldcw_align(x);
+       while (__ldcw(a) == 0)
+               while (*a == 0)
+@@ -30,17 +29,16 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x,
+                               local_irq_disable();
+                       } else
+                               cpu_relax();
+-      mb();
+ }
+ #define arch_spin_lock_flags arch_spin_lock_flags
+ 
+ static inline void arch_spin_unlock(arch_spinlock_t *x)
+ {
+       volatile unsigned int *a;
+-      mb();
++
+       a = __ldcw_align(x);
+-      *a = 1;
+       mb();
++      *a = 1;
+ }
+ 
+ static inline int arch_spin_trylock(arch_spinlock_t *x)
+@@ -48,10 +46,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *x)
+       volatile unsigned int *a;
+       int ret;
+ 
+-      mb();
+       a = __ldcw_align(x);
+         ret = __ldcw(a) != 0;
+-      mb();
+ 
+       return ret;
+ }
+diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
+index 4886a6db42e9..5f7e57fcaeef 100644
+--- a/arch/parisc/kernel/syscall.S
++++ b/arch/parisc/kernel/syscall.S
+@@ -629,12 +629,12 @@ cas_action:
+       stw     %r1, 4(%sr2,%r20)
+ #endif
+       /* The load and store could fail */
+-1:    ldw,ma  0(%r26), %r28
++1:    ldw     0(%r26), %r28
+       sub,<>  %r28, %r25, %r0
+-2:    stw,ma  %r24, 0(%r26)
++2:    stw     %r24, 0(%r26)
+       /* Free lock */
+       sync
+-      stw,ma  %r20, 0(%sr2,%r20)
++      stw     %r20, 0(%sr2,%r20)
+ #if ENABLE_LWS_DEBUG
+       /* Clear thread register indicator */
+       stw     %r0, 4(%sr2,%r20)
+@@ -798,30 +798,30 @@ cas2_action:
+       ldo     1(%r0),%r28
+ 
+       /* 8bit CAS */
+-13:   ldb,ma  0(%r26), %r29
++13:   ldb     0(%r26), %r29
+       sub,=   %r29, %r25, %r0
+       b,n     cas2_end
+-14:   stb,ma  %r24, 0(%r26)
++14:   stb     %r24, 0(%r26)
+       b       cas2_end
+       copy    %r0, %r28
+       nop
+       nop
+ 
+       /* 16bit CAS */
+-15:   ldh,ma  0(%r26), %r29
++15:   ldh     0(%r26), %r29
+       sub,=   %r29, %r25, %r0
+       b,n     cas2_end
+-16:   sth,ma  %r24, 0(%r26)
++16:   sth     %r24, 0(%r26)
+       b       cas2_end
+       copy    %r0, %r28
+       nop
+       nop
+ 
+       /* 32bit CAS */
+-17:   ldw,ma  0(%r26), %r29
++17:   ldw     0(%r26), %r29
+       sub,=   %r29, %r25, %r0
+       b,n     cas2_end
+-18:   stw,ma  %r24, 0(%r26)
++18:   stw     %r24, 0(%r26)
+       b       cas2_end
+       copy    %r0, %r28
+       nop
+@@ -829,10 +829,10 @@ cas2_action:
+ 
+       /* 64bit CAS */
+ #ifdef CONFIG_64BIT
+-19:   ldd,ma  0(%r26), %r29
++19:   ldd     0(%r26), %r29
+       sub,*=  %r29, %r25, %r0
+       b,n     cas2_end
+-20:   std,ma  %r24, 0(%r26)
++20:   std     %r24, 0(%r26)
+       copy    %r0, %r28
+ #else
+       /* Compare first word */
+@@ -851,7 +851,7 @@ cas2_action:
+ cas2_end:
+       /* Free lock */
+       sync
+-      stw,ma  %r20, 0(%sr2,%r20)
++      stw     %r20, 0(%sr2,%r20)
+       /* Enable interrupts */
+       ssm     PSW_SM_I, %r0
+       /* Return to userspace, set no error */
+diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
+index a8b277362931..4cb8f1f7b593 100644
+--- a/arch/powerpc/kernel/security.c
++++ b/arch/powerpc/kernel/security.c
+@@ -117,25 +117,35 @@ ssize_t cpu_show_meltdown(struct device *dev, struct 
device_attribute *attr, cha
+ 
+ ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute 
*attr, char *buf)
+ {
+-      if (!security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR))
+-              return sprintf(buf, "Not affected\n");
++      struct seq_buf s;
++
++      seq_buf_init(&s, buf, PAGE_SIZE - 1);
+ 
+-      if (barrier_nospec_enabled)
+-              return sprintf(buf, "Mitigation: __user pointer 
sanitization\n");
++      if (security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) {
++              if (barrier_nospec_enabled)
++                      seq_buf_printf(&s, "Mitigation: __user pointer 
sanitization");
++              else
++                      seq_buf_printf(&s, "Vulnerable");
+ 
+-      return sprintf(buf, "Vulnerable\n");
++              if (security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31))
++                      seq_buf_printf(&s, ", ori31 speculation barrier 
enabled");
++
++              seq_buf_printf(&s, "\n");
++      } else
++              seq_buf_printf(&s, "Not affected\n");
++
++      return s.len;
+ }
+ 
+ ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute 
*attr, char *buf)
+ {
+-      bool bcs, ccd, ori;
+       struct seq_buf s;
++      bool bcs, ccd;
+ 
+       seq_buf_init(&s, buf, PAGE_SIZE - 1);
+ 
+       bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
+       ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
+-      ori = security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31);
+ 
+       if (bcs || ccd) {
+               seq_buf_printf(&s, "Mitigation: ");
+@@ -151,9 +161,6 @@ ssize_t cpu_show_spectre_v2(struct device *dev, struct 
device_attribute *attr, c
+       } else
+               seq_buf_printf(&s, "Vulnerable");
+ 
+-      if (ori)
+-              seq_buf_printf(&s, ", ori31 speculation barrier enabled");
+-
+       seq_buf_printf(&s, "\n");
+ 
+       return s.len;
+diff --git a/arch/x86/include/asm/processor.h 
b/arch/x86/include/asm/processor.h
+index 79e409974ccc..682286aca881 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -971,6 +971,7 @@ static inline uint32_t hypervisor_cpuid_base(const char 
*sig, uint32_t leaves)
+ 
+ extern unsigned long arch_align_stack(unsigned long sp);
+ extern void free_init_pages(char *what, unsigned long begin, unsigned long 
end);
++extern void free_kernel_image_pages(void *begin, void *end);
+ 
+ void default_idle(void);
+ #ifdef        CONFIG_XEN
+diff --git a/arch/x86/include/asm/set_memory.h 
b/arch/x86/include/asm/set_memory.h
+index bd090367236c..34cffcef7375 100644
+--- a/arch/x86/include/asm/set_memory.h
++++ b/arch/x86/include/asm/set_memory.h
+@@ -46,6 +46,7 @@ int set_memory_np(unsigned long addr, int numpages);
+ int set_memory_4k(unsigned long addr, int numpages);
+ int set_memory_encrypted(unsigned long addr, int numpages);
+ int set_memory_decrypted(unsigned long addr, int numpages);
++int set_memory_np_noalias(unsigned long addr, int numpages);
+ 
+ int set_memory_array_uc(unsigned long *addr, int addrinarray);
+ int set_memory_array_wc(unsigned long *addr, int addrinarray);
+diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
+index 83241eb71cd4..acfab322fbe0 100644
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -775,13 +775,44 @@ void free_init_pages(char *what, unsigned long begin, 
unsigned long end)
+       }
+ }
+ 
++/*
++ * begin/end can be in the direct map or the "high kernel mapping"
++ * used for the kernel image only.  free_init_pages() will do the
++ * right thing for either kind of address.
++ */
++void free_kernel_image_pages(void *begin, void *end)
++{
++      unsigned long begin_ul = (unsigned long)begin;
++      unsigned long end_ul = (unsigned long)end;
++      unsigned long len_pages = (end_ul - begin_ul) >> PAGE_SHIFT;
++
++
++      free_init_pages("unused kernel image", begin_ul, end_ul);
++
++      /*
++       * PTI maps some of the kernel into userspace.  For performance,
++       * this includes some kernel areas that do not contain secrets.
++       * Those areas might be adjacent to the parts of the kernel image
++       * being freed, which may contain secrets.  Remove the "high kernel
++       * image mapping" for these freed areas, ensuring they are not even
++       * potentially vulnerable to Meltdown regardless of the specific
++       * optimizations PTI is currently using.
++       *
++       * The "noalias" prevents unmapping the direct map alias which is
++       * needed to access the freed pages.
++       *
++       * This is only valid for 64bit kernels. 32bit has only one mapping
++       * which can't be treated in this way for obvious reasons.
++       */
++      if (IS_ENABLED(CONFIG_X86_64) && cpu_feature_enabled(X86_FEATURE_PTI))
++              set_memory_np_noalias(begin_ul, len_pages);
++}
++
+ void __ref free_initmem(void)
+ {
+       e820__reallocate_tables();
+ 
+-      free_init_pages("unused kernel",
+-                      (unsigned long)(&__init_begin),
+-                      (unsigned long)(&__init_end));
++      free_kernel_image_pages(&__init_begin, &__init_end);
+ }
+ 
+ #ifdef CONFIG_BLK_DEV_INITRD
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index a688617c727e..68c292cb1ebf 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -1283,12 +1283,8 @@ void mark_rodata_ro(void)
+       set_memory_ro(start, (end-start) >> PAGE_SHIFT);
+ #endif
+ 
+-      free_init_pages("unused kernel",
+-                      (unsigned long) __va(__pa_symbol(text_end)),
+-                      (unsigned long) __va(__pa_symbol(rodata_start)));
+-      free_init_pages("unused kernel",
+-                      (unsigned long) __va(__pa_symbol(rodata_end)),
+-                      (unsigned long) __va(__pa_symbol(_sdata)));
++      free_kernel_image_pages((void *)text_end, (void *)rodata_start);
++      free_kernel_image_pages((void *)rodata_end, (void *)_sdata);
+ 
+       debug_checkwx();
+ 
+diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
+index 29505724202a..8d6c34fe49be 100644
+--- a/arch/x86/mm/pageattr.c
++++ b/arch/x86/mm/pageattr.c
+@@ -53,6 +53,7 @@ static DEFINE_SPINLOCK(cpa_lock);
+ #define CPA_FLUSHTLB 1
+ #define CPA_ARRAY 2
+ #define CPA_PAGES_ARRAY 4
++#define CPA_NO_CHECK_ALIAS 8 /* Do not search for aliases */
+ 
+ #ifdef CONFIG_PROC_FS
+ static unsigned long direct_pages_count[PG_LEVEL_NUM];
+@@ -1486,6 +1487,9 @@ static int change_page_attr_set_clr(unsigned long *addr, 
int numpages,
+ 
+       /* No alias checking for _NX bit modifications */
+       checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX;
++      /* Has caller explicitly disabled alias checking? */
++      if (in_flag & CPA_NO_CHECK_ALIAS)
++              checkalias = 0;
+ 
+       ret = __change_page_attr_set_clr(&cpa, checkalias);
+ 
+@@ -1772,6 +1776,15 @@ int set_memory_np(unsigned long addr, int numpages)
+       return change_page_attr_clear(&addr, numpages, __pgprot(_PAGE_PRESENT), 
0);
+ }
+ 
++int set_memory_np_noalias(unsigned long addr, int numpages)
++{
++      int cpa_flags = CPA_NO_CHECK_ALIAS;
++
++      return change_page_attr_set_clr(&addr, numpages, __pgprot(0),
++                                      __pgprot(_PAGE_PRESENT), 0,
++                                      cpa_flags, NULL);
++}
++
+ int set_memory_4k(unsigned long addr, int numpages)
+ {
+       return change_page_attr_set_clr(&addr, numpages, __pgprot(0),
+diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
+index 3bb82e511eca..7d3edd713932 100644
+--- a/drivers/edac/edac_mc.c
++++ b/drivers/edac/edac_mc.c
+@@ -215,6 +215,7 @@ const char * const edac_mem_types[] = {
+       [MEM_LRDDR3]    = "Load-Reduced-DDR3-RAM",
+       [MEM_DDR4]      = "Unbuffered-DDR4",
+       [MEM_RDDR4]     = "Registered-DDR4",
++      [MEM_LRDDR4]    = "Load-Reduced-DDR4-RAM",
+       [MEM_NVDIMM]    = "Non-volatile-RAM",
+ };
+ EXPORT_SYMBOL_GPL(edac_mem_types);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+index fc818b4d849c..a44c3d58fef4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+@@ -31,7 +31,7 @@
+ #include <linux/power_supply.h>
+ #include <linux/hwmon.h>
+ #include <linux/hwmon-sysfs.h>
+-
++#include <linux/nospec.h>
+ 
+ static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
+ 
+@@ -393,6 +393,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device 
*dev,
+                       count = -EINVAL;
+                       goto fail;
+               }
++              idx = array_index_nospec(idx, ARRAY_SIZE(data.states));
+ 
+               amdgpu_dpm_get_pp_num_states(adev, &data);
+               state = data.states[idx];
+diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c 
b/drivers/gpu/drm/i915/gvt/kvmgt.c
+index df4e4a07db3d..14dce5c201d5 100644
+--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
+@@ -43,6 +43,8 @@
+ #include <linux/mdev.h>
+ #include <linux/debugfs.h>
+ 
++#include <linux/nospec.h>
++
+ #include "i915_drv.h"
+ #include "gvt.h"
+ 
+@@ -1084,7 +1086,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
+       } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
+               struct vfio_region_info info;
+               struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
+-              int i, ret;
++              unsigned int i;
++              int ret;
+               struct vfio_region_info_cap_sparse_mmap *sparse = NULL;
+               size_t size;
+               int nr_areas = 1;
+@@ -1169,6 +1172,10 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
unsigned int cmd,
+                               if (info.index >= VFIO_PCI_NUM_REGIONS +
+                                               vgpu->vdev.num_regions)
+                                       return -EINVAL;
++                              info.index =
++                                      array_index_nospec(info.index,
++                                                      VFIO_PCI_NUM_REGIONS +
++                                                      vgpu->vdev.num_regions);
+ 
+                               i = info.index - VFIO_PCI_NUM_REGIONS;
+ 
+diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
+index 498c5e891649..ad6adefb64da 100644
+--- a/drivers/i2c/busses/i2c-imx.c
++++ b/drivers/i2c/busses/i2c-imx.c
+@@ -668,9 +668,6 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
+       struct imx_i2c_dma *dma = i2c_imx->dma;
+       struct device *dev = &i2c_imx->adapter.dev;
+ 
+-      temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+-      temp |= I2CR_DMAEN;
+-      imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+ 
+       dma->chan_using = dma->chan_rx;
+       dma->dma_transfer_dir = DMA_DEV_TO_MEM;
+@@ -783,6 +780,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, 
struct i2c_msg *msgs, bo
+       int i, result;
+       unsigned int temp;
+       int block_data = msgs->flags & I2C_M_RECV_LEN;
++      int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data;
+ 
+       dev_dbg(&i2c_imx->adapter.dev,
+               "<%s> write slave address: addr=0x%x\n",
+@@ -809,12 +807,14 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, 
struct i2c_msg *msgs, bo
+        */
+       if ((msgs->len - 1) || block_data)
+               temp &= ~I2CR_TXAK;
++      if (use_dma)
++              temp |= I2CR_DMAEN;
+       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+       imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); /* dummy read */
+ 
+       dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);
+ 
+-      if (i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data)
++      if (use_dma)
+               return i2c_imx_dma_read(i2c_imx, msgs, is_lastmsg);
+ 
+       /* read data */
+diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
+index 7c3b4740b94b..b8f303dea305 100644
+--- a/drivers/i2c/i2c-core-acpi.c
++++ b/drivers/i2c/i2c-core-acpi.c
+@@ -482,11 +482,16 @@ static int acpi_gsb_i2c_write_bytes(struct i2c_client 
*client,
+       msgs[0].buf = buffer;
+ 
+       ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+-      if (ret < 0)
+-              dev_err(&client->adapter->dev, "i2c write failed\n");
+ 
+       kfree(buffer);
+-      return ret;
++
++      if (ret < 0) {
++              dev_err(&client->adapter->dev, "i2c write failed: %d\n", ret);
++              return ret;
++      }
++
++      /* 1 transfer must have completed successfully */
++      return (ret == 1) ? 0 : -EIO;
+ }
+ 
+ static acpi_status
+diff --git a/drivers/pci/controller/pci-aardvark.c 
b/drivers/pci/controller/pci-aardvark.c
+index 0fae816fba39..44604af23b3a 100644
+--- a/drivers/pci/controller/pci-aardvark.c
++++ b/drivers/pci/controller/pci-aardvark.c
+@@ -952,6 +952,7 @@ static int advk_pcie_probe(struct platform_device *pdev)
+ 
+       bus = bridge->bus;
+ 
++      pci_bus_size_bridges(bus);
+       pci_bus_assign_resources(bus);
+ 
+       list_for_each_entry(child, &bus->children, node)
+diff --git a/drivers/pci/hotplug/pci_hotplug_core.c 
b/drivers/pci/hotplug/pci_hotplug_core.c
+index af92fed46ab7..fd93783a87b0 100644
+--- a/drivers/pci/hotplug/pci_hotplug_core.c
++++ b/drivers/pci/hotplug/pci_hotplug_core.c
+@@ -438,8 +438,17 @@ int __pci_hp_register(struct hotplug_slot *slot, struct 
pci_bus *bus,
+       list_add(&slot->slot_list, &pci_hotplug_slot_list);
+ 
+       result = fs_add_slot(pci_slot);
++      if (result)
++              goto err_list_del;
++
+       kobject_uevent(&pci_slot->kobj, KOBJ_ADD);
+       dbg("Added slot %s to the list\n", name);
++      goto out;
++
++err_list_del:
++      list_del(&slot->slot_list);
++      pci_slot->hotplug = NULL;
++      pci_destroy_slot(pci_slot);
+ out:
+       mutex_unlock(&pci_hp_mutex);
+       return result;
+diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
+index 5f892065585e..fca87a1a2b22 100644
+--- a/drivers/pci/hotplug/pciehp.h
++++ b/drivers/pci/hotplug/pciehp.h
+@@ -119,6 +119,7 @@ int pciehp_unconfigure_device(struct slot *p_slot);
+ void pciehp_queue_pushbutton_work(struct work_struct *work);
+ struct controller *pcie_init(struct pcie_device *dev);
+ int pcie_init_notification(struct controller *ctrl);
++void pcie_shutdown_notification(struct controller *ctrl);
+ int pciehp_enable_slot(struct slot *p_slot);
+ int pciehp_disable_slot(struct slot *p_slot);
+ void pcie_reenable_notification(struct controller *ctrl);
+diff --git a/drivers/pci/hotplug/pciehp_core.c 
b/drivers/pci/hotplug/pciehp_core.c
+index 44a6a63802d5..2ba59fc94827 100644
+--- a/drivers/pci/hotplug/pciehp_core.c
++++ b/drivers/pci/hotplug/pciehp_core.c
+@@ -62,6 +62,12 @@ static int reset_slot(struct hotplug_slot *slot, int probe);
+  */
+ static void release_slot(struct hotplug_slot *hotplug_slot)
+ {
++      struct slot *slot = hotplug_slot->private;
++
++      /* queued work needs hotplug_slot name */
++      cancel_delayed_work(&slot->work);
++      drain_workqueue(slot->wq);
++
+       kfree(hotplug_slot->ops);
+       kfree(hotplug_slot->info);
+       kfree(hotplug_slot);
+@@ -264,6 +270,7 @@ static void pciehp_remove(struct pcie_device *dev)
+ {
+       struct controller *ctrl = get_service_data(dev);
+ 
++      pcie_shutdown_notification(ctrl);
+       cleanup_slot(ctrl);
+       pciehp_release_ctrl(ctrl);
+ }
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c 
b/drivers/pci/hotplug/pciehp_hpc.c
+index 718b6073afad..aff191b4552c 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -539,8 +539,6 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
+ {
+       struct controller *ctrl = (struct controller *)dev_id;
+       struct pci_dev *pdev = ctrl_dev(ctrl);
+-      struct pci_bus *subordinate = pdev->subordinate;
+-      struct pci_dev *dev;
+       struct slot *slot = ctrl->slot;
+       u16 status, events;
+       u8 present;
+@@ -588,14 +586,9 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
+               wake_up(&ctrl->queue);
+       }
+ 
+-      if (subordinate) {
+-              list_for_each_entry(dev, &subordinate->devices, bus_list) {
+-                      if (dev->ignore_hotplug) {
+-                              ctrl_dbg(ctrl, "ignoring hotplug event %#06x 
(%s requested no hotplug)\n",
+-                                       events, pci_name(dev));
+-                              return IRQ_HANDLED;
+-                      }
+-              }
++      if (pdev->ignore_hotplug) {
++              ctrl_dbg(ctrl, "ignoring hotplug event %#06x\n", events);
++              return IRQ_HANDLED;
+       }
+ 
+       /* Check Attention Button Pressed */
+@@ -765,7 +758,7 @@ int pcie_init_notification(struct controller *ctrl)
+       return 0;
+ }
+ 
+-static void pcie_shutdown_notification(struct controller *ctrl)
++void pcie_shutdown_notification(struct controller *ctrl)
+ {
+       if (ctrl->notification_enabled) {
+               pcie_disable_notification(ctrl);
+@@ -800,7 +793,7 @@ abort:
+ static void pcie_cleanup_slot(struct controller *ctrl)
+ {
+       struct slot *slot = ctrl->slot;
+-      cancel_delayed_work(&slot->work);
++
+       destroy_workqueue(slot->wq);
+       kfree(slot);
+ }
+@@ -893,7 +886,6 @@ abort:
+ 
+ void pciehp_release_ctrl(struct controller *ctrl)
+ {
+-      pcie_shutdown_notification(ctrl);
+       pcie_cleanup_slot(ctrl);
+       kfree(ctrl);
+ }
+diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
+index 89ee6a2b6eb8..5d1698265da5 100644
+--- a/drivers/pci/pci-acpi.c
++++ b/drivers/pci/pci-acpi.c
+@@ -632,13 +632,11 @@ static bool acpi_pci_need_resume(struct pci_dev *dev)
+       /*
+        * In some cases (eg. Samsung 305V4A) leaving a bridge in suspend over
+        * system-wide suspend/resume confuses the platform firmware, so avoid
+-       * doing that, unless the bridge has a driver that should take care of
+-       * the PM handling.  According to Section 16.1.6 of ACPI 6.2, endpoint
++       * doing that.  According to Section 16.1.6 of ACPI 6.2, endpoint
+        * devices are expected to be in D3 before invoking the S3 entry path
+        * from the firmware, so they should not be affected by this issue.
+        */
+-      if (pci_is_bridge(dev) && !dev->driver &&
+-          acpi_target_system_state() != ACPI_STATE_S0)
++      if (pci_is_bridge(dev) && acpi_target_system_state() != ACPI_STATE_S0)
+               return true;
+ 
+       if (!adev || !acpi_device_power_manageable(adev))
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 316496e99da9..0abe2865a3a5 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1171,6 +1171,33 @@ static void pci_restore_config_space(struct pci_dev 
*pdev)
+       }
+ }
+ 
++static void pci_restore_rebar_state(struct pci_dev *pdev)
++{
++      unsigned int pos, nbars, i;
++      u32 ctrl;
++
++      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
++      if (!pos)
++              return;
++
++      pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++      nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >>
++                  PCI_REBAR_CTRL_NBAR_SHIFT;
++
++      for (i = 0; i < nbars; i++, pos += 8) {
++              struct resource *res;
++              int bar_idx, size;
++
++              pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++              bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
++              res = pdev->resource + bar_idx;
++              size = order_base_2((resource_size(res) >> 20) | 1) - 1;
++              ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE;
++              ctrl |= size << 8;
++              pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
++      }
++}
++
+ /**
+  * pci_restore_state - Restore the saved state of a PCI device
+  * @dev: - PCI device that we're dealing with
+@@ -1186,6 +1213,7 @@ void pci_restore_state(struct pci_dev *dev)
+       pci_restore_pri_state(dev);
+       pci_restore_ats_state(dev);
+       pci_restore_vc_state(dev);
++      pci_restore_rebar_state(dev);
+ 
+       pci_cleanup_aer_error_status_regs(dev);
+ 
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 611adcd9c169..b2857865c0aa 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -1730,6 +1730,10 @@ static void pci_configure_mps(struct pci_dev *dev)
+       if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
+               return;
+ 
++      /* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */
++      if (dev->is_virtfn)
++              return;
++
+       mps = pcie_get_mps(dev);
+       p_mps = pcie_get_mps(bridge);
+ 
+diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
+index b0e2c4847a5d..678406e0948b 100644
+--- a/drivers/tty/pty.c
++++ b/drivers/tty/pty.c
+@@ -625,7 +625,7 @@ int ptm_open_peer(struct file *master, struct tty_struct 
*tty, int flags)
+       if (tty->driver != ptm_driver)
+               return -EIO;
+ 
+-      fd = get_unused_fd_flags(0);
++      fd = get_unused_fd_flags(flags);
+       if (fd < 0) {
+               retval = fd;
+               goto err;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index f7ab34088162..8b24d3d42cb3 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -14,6 +14,7 @@
+ #include <linux/log2.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/nospec.h>
+ #include <linux/backing-dev.h>
+ #include <trace/events/ext4.h>
+ 
+@@ -2140,7 +2141,8 @@ ext4_mb_regular_allocator(struct ext4_allocation_context 
*ac)
+                * This should tell if fe_len is exactly power of 2
+                */
+               if ((ac->ac_g_ex.fe_len & (~(1 << (i - 1)))) == 0)
+-                      ac->ac_2order = i - 1;
++                      ac->ac_2order = array_index_nospec(i - 1,
++                                                         sb->s_blocksize_bits 
+ 2);
+       }
+ 
+       /* if stream allocation is enabled, use global goal */
+diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
+index ff94fad477e4..48cdfc81fe10 100644
+--- a/fs/reiserfs/xattr.c
++++ b/fs/reiserfs/xattr.c
+@@ -792,8 +792,10 @@ static int listxattr_filler(struct dir_context *ctx, 
const char *name,
+                       return 0;
+               size = namelen + 1;
+               if (b->buf) {
+-                      if (size > b->size)
++                      if (b->pos + size > b->size) {
++                              b->pos = -ERANGE;
+                               return -ERANGE;
++                      }
+                       memcpy(b->buf + b->pos, name, namelen);
+                       b->buf[b->pos + namelen] = 0;
+               }
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index a790ef4be74e..3222193c46c6 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -6939,9 +6939,21 @@ unsigned long free_reserved_area(void *start, void 
*end, int poison, char *s)
+       start = (void *)PAGE_ALIGN((unsigned long)start);
+       end = (void *)((unsigned long)end & PAGE_MASK);
+       for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
++              struct page *page = virt_to_page(pos);
++              void *direct_map_addr;
++
++              /*
++               * 'direct_map_addr' might be different from 'pos'
++               * because some architectures' virt_to_page()
++               * work with aliases.  Getting the direct map
++               * address ensures that we get a _writeable_
++               * alias for the memset().
++               */
++              direct_map_addr = page_address(page);
+               if ((unsigned int)poison <= 0xFF)
+-                      memset(pos, poison, PAGE_SIZE);
+-              free_reserved_page(virt_to_page(pos));
++                      memset(direct_map_addr, poison, PAGE_SIZE);
++
++              free_reserved_page(page);
+       }
+ 
+       if (pages && s)

Reply via email to