commit:     08b477679e9842d315b7e455240f89e00bfdf694
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Aug 10 12:54:25 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Aug 10 12:54:25 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=08b47767

Linux patch 3.18.39

 0000_README              |    4 +
 1038_linux-3.18.39.patch | 1354 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1358 insertions(+)

diff --git a/0000_README b/0000_README
index b5306ef..2568ef1 100644
--- a/0000_README
+++ b/0000_README
@@ -195,6 +195,10 @@ Patch:  1037_linux-3.18.38.patch
 From:   http://www.kernel.org
 Desc:   Linux 3.18.38
 
+Patch:  1038_linux-3.18.39.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.18.39
+
 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/1038_linux-3.18.39.patch b/1038_linux-3.18.39.patch
new file mode 100644
index 0000000..1812d18
--- /dev/null
+++ b/1038_linux-3.18.39.patch
@@ -0,0 +1,1354 @@
+diff --git a/Makefile b/Makefile
+index 2940c7532661..758b8efbb881 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 18
+-SUBLEVEL = 38
++SUBLEVEL = 39
+ EXTRAVERSION =
+ NAME = Diseased Newt
+ 
+diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
+index 01efe130912e..9e5c29df91f5 100644
+--- a/arch/arm/mach-mvebu/coherency.c
++++ b/arch/arm/mach-mvebu/coherency.c
+@@ -315,22 +315,16 @@ static void __init armada_370_coherency_init(struct 
device_node *np)
+ }
+ 
+ /*
+- * This ioremap hook is used on Armada 375/38x to ensure that PCIe
+- * memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
+- * is needed as a workaround for a deadlock issue between the PCIe
+- * interface and the cache controller.
++ * This ioremap hook is used on Armada 375/38x to ensure that all MMIO
++ * areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
++ * needed for the HW I/O coherency mechanism to work properly without
++ * deadlock.
+  */
+ static void __iomem *
+-armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+-                            unsigned int mtype, void *caller)
++armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
++                       unsigned int mtype, void *caller)
+ {
+-      struct resource pcie_mem;
+-
+-      mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
+-
+-      if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
+-              mtype = MT_UNCACHED;
+-
++      mtype = MT_UNCACHED;
+       return __arm_ioremap_caller(phys_addr, size, mtype, caller);
+ }
+ 
+@@ -339,7 +333,7 @@ static void __init armada_375_380_coherency_init(struct 
device_node *np)
+       struct device_node *cache_dn;
+ 
+       coherency_cpu_base = of_iomap(np, 0);
+-      arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
++      arch_ioremap_caller = armada_wa_ioremap_caller;
+ 
+       /*
+        * We should switch the PL310 to I/O coherency mode only if
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index 2168355591f5..f3b635f86c39 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -685,9 +685,6 @@ static void __init arch_mem_init(char **cmdline_p)
+       for_each_memblock(reserved, reg)
+               if (reg->size != 0)
+                       reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
+-
+-      reserve_bootmem_region(__pa_symbol(&__nosave_begin),
+-                      __pa_symbol(&__nosave_end)); /* Reserve for hibernation 
*/
+ }
+ 
+ static void __init resource_init(void)
+diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
+index 7dd57626da19..c30a5ec6498c 100644
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -1300,18 +1300,10 @@ static int __init numa_parse_sun4u(void)
+ 
+ static int __init bootmem_init_numa(void)
+ {
+-      int i, j;
+       int err = -1;
+ 
+       numadbg("bootmem_init_numa()\n");
+ 
+-      /* Some sane defaults for numa latency values */
+-      for (i = 0; i < MAX_NUMNODES; i++) {
+-              for (j = 0; j < MAX_NUMNODES; j++)
+-                      numa_latency[i][j] = (i == j) ?
+-                              LOCAL_DISTANCE : REMOTE_DISTANCE;
+-      }
+-
+       if (numa_enabled) {
+               if (tlb_type == hypervisor)
+                       err = numa_parse_mdesc();
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
+index 2e1a6853e00c..2fa494f59828 100644
+--- a/arch/x86/kernel/early-quirks.c
++++ b/arch/x86/kernel/early-quirks.c
+@@ -11,7 +11,11 @@
+ 
+ #include <linux/pci.h>
+ #include <linux/acpi.h>
++#include <linux/delay.h>
++#include <linux/dmi.h>
+ #include <linux/pci_ids.h>
++#include <linux/bcma/bcma.h>
++#include <linux/bcma/bcma_regs.h>
+ #include <drm/i915_drm.h>
+ #include <asm/pci-direct.h>
+ #include <asm/dma.h>
+@@ -21,6 +25,9 @@
+ #include <asm/iommu.h>
+ #include <asm/gart.h>
+ #include <asm/irq_remapping.h>
++#include <asm/early_ioremap.h>
++
++#define dev_err(msg)  pr_err("pci 0000:%02x:%02x.%d: %s", bus, slot, func, 
msg)
+ 
+ static void __init fix_hypertransport_config(int num, int slot, int func)
+ {
+@@ -76,6 +83,13 @@ static void __init nvidia_bugs(int num, int slot, int func)
+ #ifdef CONFIG_ACPI
+ #ifdef CONFIG_X86_IO_APIC
+       /*
++       * Only applies to Nvidia root ports (bus 0) and not to
++       * Nvidia graphics cards with PCI ports on secondary buses.
++       */
++      if (num)
++              return;
++
++      /*
+        * All timer overrides on Nvidia are
+        * wrong unless HPET is enabled.
+        * Unfortunately that's not true on many Asus boards.
+@@ -565,6 +579,61 @@ static void __init force_disable_hpet(int num, int slot, 
int func)
+ #endif
+ }
+ 
++#define BCM4331_MMIO_SIZE     16384
++#define BCM4331_PM_CAP                0x40
++#define bcma_aread32(reg)     ioread32(mmio + 1 * BCMA_CORE_SIZE + reg)
++#define bcma_awrite32(reg, val)       iowrite32(val, mmio + 1 * 
BCMA_CORE_SIZE + reg)
++
++static void __init apple_airport_reset(int bus, int slot, int func)
++{
++      void __iomem *mmio;
++      u16 pmcsr;
++      u64 addr;
++      int i;
++
++      if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc."))
++              return;
++
++      /* Card may have been put into PCI_D3hot by grub quirk */
++      pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + 
PCI_PM_CTRL);
++
++      if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
++              pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
++              write_pci_config_16(bus, slot, func, BCM4331_PM_CAP + 
PCI_PM_CTRL, pmcsr);
++              mdelay(10);
++
++              pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + 
PCI_PM_CTRL);
++              if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
++                      dev_err("Cannot power up Apple AirPort card\n");
++                      return;
++              }
++      }
++
++      addr  =      read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
++      addr |= (u64)read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_1) << 32;
++      addr &= PCI_BASE_ADDRESS_MEM_MASK;
++
++      mmio = early_ioremap(addr, BCM4331_MMIO_SIZE);
++      if (!mmio) {
++              dev_err("Cannot iomap Apple AirPort card\n");
++              return;
++      }
++
++      pr_info("Resetting Apple AirPort card (left enabled by EFI)\n");
++
++      for (i = 0; bcma_aread32(BCMA_RESET_ST) && i < 30; i++)
++              udelay(10);
++
++      bcma_awrite32(BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
++      bcma_aread32(BCMA_RESET_CTL);
++      udelay(1);
++
++      bcma_awrite32(BCMA_RESET_CTL, 0);
++      bcma_aread32(BCMA_RESET_CTL);
++      udelay(10);
++
++      early_iounmap(mmio, BCM4331_MMIO_SIZE);
++}
+ 
+ #define QFLAG_APPLY_ONCE      0x1
+ #define QFLAG_APPLIED         0x2
+@@ -578,12 +647,6 @@ struct chipset {
+       void (*f)(int num, int slot, int func);
+ };
+ 
+-/*
+- * Only works for devices on the root bus. If you add any devices
+- * not on bus 0 readd another loop level in early_quirks(). But
+- * be careful because at least the Nvidia quirk here relies on
+- * only matching on bus 0.
+- */
+ static struct chipset early_qrk[] __initdata = {
+       { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+         PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
+@@ -609,9 +672,13 @@ static struct chipset early_qrk[] __initdata = {
+        */
+       { PCI_VENDOR_ID_INTEL, 0x0f00,
+               PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
++      { PCI_VENDOR_ID_BROADCOM, 0x4331,
++        PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
+       {}
+ };
+ 
++static void __init early_pci_scan_bus(int bus);
++
+ /**
+  * check_dev_quirk - apply early quirks to a given PCI device
+  * @num: bus number
+@@ -620,7 +687,7 @@ static struct chipset early_qrk[] __initdata = {
+  *
+  * Check the vendor & device ID against the early quirks table.
+  *
+- * If the device is single function, let early_quirks() know so we don't
++ * If the device is single function, let early_pci_scan_bus() know so we don't
+  * poke at this device again.
+  */
+ static int __init check_dev_quirk(int num, int slot, int func)
+@@ -629,6 +696,7 @@ static int __init check_dev_quirk(int num, int slot, int 
func)
+       u16 vendor;
+       u16 device;
+       u8 type;
++      u8 sec;
+       int i;
+ 
+       class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
+@@ -656,25 +724,36 @@ static int __init check_dev_quirk(int num, int slot, int 
func)
+ 
+       type = read_pci_config_byte(num, slot, func,
+                                   PCI_HEADER_TYPE);
++
++      if ((type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
++              sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS);
++              if (sec > num)
++                      early_pci_scan_bus(sec);
++      }
++
+       if (!(type & 0x80))
+               return -1;
+ 
+       return 0;
+ }
+ 
+-void __init early_quirks(void)
++static void __init early_pci_scan_bus(int bus)
+ {
+       int slot, func;
+ 
+-      if (!early_pci_allowed())
+-              return;
+-
+       /* Poor man's PCI discovery */
+-      /* Only scan the root bus */
+       for (slot = 0; slot < 32; slot++)
+               for (func = 0; func < 8; func++) {
+                       /* Only probe function 0 on single fn devices */
+-                      if (check_dev_quirk(0, slot, func))
++                      if (check_dev_quirk(bus, slot, func))
+                               break;
+               }
+ }
++
++void __init early_quirks(void)
++{
++      if (!early_pci_allowed())
++              return;
++
++      early_pci_scan_bus(0);
++}
+diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
+index b6412b2d748d..150def7afc17 100644
+--- a/drivers/bcma/bcma_private.h
++++ b/drivers/bcma/bcma_private.h
+@@ -8,8 +8,6 @@
+ #include <linux/bcma/bcma.h>
+ #include <linux/delay.h>
+ 
+-#define BCMA_CORE_SIZE                0x1000
+-
+ #define bcma_err(bus, fmt, ...) \
+       pr_err("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
+ #define bcma_warn(bus, fmt, ...) \
+diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
+index d395b0bef73b..7370202c2022 100644
+--- a/drivers/gpu/drm/ttm/ttm_bo.c
++++ b/drivers/gpu/drm/ttm/ttm_bo.c
+@@ -1000,9 +1000,9 @@ out_unlock:
+       return ret;
+ }
+ 
+-static bool ttm_bo_mem_compat(struct ttm_placement *placement,
+-                            struct ttm_mem_reg *mem,
+-                            uint32_t *new_flags)
++bool ttm_bo_mem_compat(struct ttm_placement *placement,
++                     struct ttm_mem_reg *mem,
++                     uint32_t *new_flags)
+ {
+       int i;
+ 
+@@ -1034,6 +1034,7 @@ static bool ttm_bo_mem_compat(struct ttm_placement 
*placement,
+ 
+       return false;
+ }
++EXPORT_SYMBOL(ttm_bo_mem_compat);
+ 
+ int ttm_bo_validate(struct ttm_buffer_object *bo,
+                       struct ttm_placement *placement,
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index fc55f0d15b70..7b41d543a41f 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -1006,6 +1006,9 @@ static int xpad_probe(struct usb_interface *intf, const 
struct usb_device_id *id
+       int ep_irq_in_idx;
+       int i, error;
+ 
++      if (intf->cur_altsetting->desc.bNumEndpoints != 2)
++              return -ENODEV;
++
+       for (i = 0; xpad_device[i].idVendor; i++) {
+               if ((le16_to_cpu(udev->descriptor.idVendor) == 
xpad_device[i].idVendor) &&
+                   (le16_to_cpu(udev->descriptor.idProduct) == 
xpad_device[i].idProduct))
+diff --git a/drivers/media/usb/airspy/airspy.c 
b/drivers/media/usb/airspy/airspy.c
+index 4069234abed5..cc92ae7ba462 100644
+--- a/drivers/media/usb/airspy/airspy.c
++++ b/drivers/media/usb/airspy/airspy.c
+@@ -1072,7 +1072,7 @@ static int airspy_probe(struct usb_interface *intf,
+       if (ret) {
+               dev_err(s->dev, "Failed to register as video device (%d)\n",
+                               ret);
+-              goto err_unregister_v4l2_dev;
++              goto err_free_controls;
+       }
+       dev_info(s->dev, "Registered as %s\n",
+                       video_device_node_name(&s->vdev));
+@@ -1081,7 +1081,6 @@ static int airspy_probe(struct usb_interface *intf,
+ 
+ err_free_controls:
+       v4l2_ctrl_handler_free(&s->hdl);
+-err_unregister_v4l2_dev:
+       v4l2_device_unregister(&s->v4l2_dev);
+ err_free_mem:
+       kfree(s);
+diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
+index 5027ae76fde8..4078ebe81c45 100644
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -1669,8 +1669,8 @@ static void mmc_blk_packed_hdr_wrq_prep(struct 
mmc_queue_req *mqrq,
+ 
+       packed_cmd_hdr = packed->cmd_hdr;
+       memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr));
+-      packed_cmd_hdr[0] = (packed->nr_entries << 16) |
+-              (PACKED_CMD_WR << 8) | PACKED_CMD_VER;
++      packed_cmd_hdr[0] = cpu_to_le32((packed->nr_entries << 16) |
++              (PACKED_CMD_WR << 8) | PACKED_CMD_VER);
+       hdr_blocks = mmc_large_sector(card) ? 8 : 1;
+ 
+       /*
+@@ -1684,14 +1684,14 @@ static void mmc_blk_packed_hdr_wrq_prep(struct 
mmc_queue_req *mqrq,
+                       ((brq->data.blocks * brq->data.blksz) >=
+                        card->ext_csd.data_tag_unit_size);
+               /* Argument of CMD23 */
+-              packed_cmd_hdr[(i * 2)] =
++              packed_cmd_hdr[(i * 2)] = cpu_to_le32(
+                       (do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) |
+                       (do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) |
+-                      blk_rq_sectors(prq);
++                      blk_rq_sectors(prq));
+               /* Argument of CMD18 or CMD25 */
+-              packed_cmd_hdr[((i * 2)) + 1] =
++              packed_cmd_hdr[((i * 2)) + 1] = cpu_to_le32(
+                       mmc_card_blockaddr(card) ?
+-                      blk_rq_pos(prq) : blk_rq_pos(prq) << 9;
++                      blk_rq_pos(prq) : blk_rq_pos(prq) << 9);
+               packed->blocks += blk_rq_sectors(prq);
+               i++;
+       }
+diff --git a/drivers/net/ethernet/marvell/mvneta.c 
b/drivers/net/ethernet/marvell/mvneta.c
+index 3bd7e3d8fe5a..e6a7b50a4781 100644
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -216,7 +216,7 @@
+ /* Various constants */
+ 
+ /* Coalescing */
+-#define MVNETA_TXDONE_COAL_PKTS               1
++#define MVNETA_TXDONE_COAL_PKTS               0       /* interrupt per packet 
*/
+ #define MVNETA_RX_COAL_PKTS           32
+ #define MVNETA_RX_COAL_USEC           100
+ 
+diff --git a/drivers/pps/clients/pps_parport.c 
b/drivers/pps/clients/pps_parport.c
+index 38a8bbe74810..83797d89c30f 100644
+--- a/drivers/pps/clients/pps_parport.c
++++ b/drivers/pps/clients/pps_parport.c
+@@ -195,7 +195,7 @@ static void parport_detach(struct parport *port)
+       struct pps_client_pp *device;
+ 
+       /* FIXME: oooh, this is ugly! */
+-      if (strcmp(pardev->name, KBUILD_MODNAME))
++      if (!pardev || strcmp(pardev->name, KBUILD_MODNAME))
+               /* not our port */
+               return;
+ 
+diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
+index c039cfea5b11..15c22d00df03 100644
+--- a/drivers/tty/vt/keyboard.c
++++ b/drivers/tty/vt/keyboard.c
+@@ -365,34 +365,22 @@ static void to_utf8(struct vc_data *vc, uint c)
+ 
+ static void do_compute_shiftstate(void)
+ {
+-      unsigned int i, j, k, sym, val;
++      unsigned int k, sym, val;
+ 
+       shift_state = 0;
+       memset(shift_down, 0, sizeof(shift_down));
+ 
+-      for (i = 0; i < ARRAY_SIZE(key_down); i++) {
+-
+-              if (!key_down[i])
++      for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
++              sym = U(key_maps[0][k]);
++              if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
+                       continue;
+ 
+-              k = i * BITS_PER_LONG;
+-
+-              for (j = 0; j < BITS_PER_LONG; j++, k++) {
+-
+-                      if (!test_bit(k, key_down))
+-                              continue;
++              val = KVAL(sym);
++              if (val == KVAL(K_CAPSSHIFT))
++                      val = KVAL(K_SHIFT);
+ 
+-                      sym = U(key_maps[0][k]);
+-                      if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
+-                              continue;
+-
+-                      val = KVAL(sym);
+-                      if (val == KVAL(K_CAPSSHIFT))
+-                              val = KVAL(K_SHIFT);
+-
+-                      shift_down[val]++;
+-                      shift_state |= (1 << val);
+-              }
++              shift_down[val]++;
++              shift_state |= BIT(val);
+       }
+ }
+ 
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index ddb1dc97859e..d124faf087f9 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -505,6 +505,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, 
bool is_dir)
+       struct dentry *upper;
+       struct dentry *opaquedir = NULL;
+       int err;
++      int flags = 0;
+ 
+       if (is_dir) {
+               opaquedir = ovl_check_empty_and_clear(dentry);
+@@ -517,46 +518,39 @@ static int ovl_remove_and_whiteout(struct dentry 
*dentry, bool is_dir)
+       if (err)
+               goto out_dput;
+ 
+-      whiteout = ovl_whiteout(workdir, dentry);
+-      err = PTR_ERR(whiteout);
+-      if (IS_ERR(whiteout))
++      upper = lookup_one_len(dentry->d_name.name, upperdir,
++                             dentry->d_name.len);
++      err = PTR_ERR(upper);
++      if (IS_ERR(upper))
+               goto out_unlock;
+ 
+-      upper = ovl_dentry_upper(dentry);
+-      if (!upper) {
+-              upper = lookup_one_len(dentry->d_name.name, upperdir,
+-                                     dentry->d_name.len);
+-              err = PTR_ERR(upper);
+-              if (IS_ERR(upper))
+-                      goto kill_whiteout;
+-
+-              err = ovl_do_rename(wdir, whiteout, udir, upper, 0);
+-              dput(upper);
+-              if (err)
+-                      goto kill_whiteout;
+-      } else {
+-              int flags = 0;
++      err = -ESTALE;
++      if ((opaquedir && upper != opaquedir) ||
++          (!opaquedir && ovl_dentry_upper(dentry) &&
++           upper != ovl_dentry_upper(dentry))) {
++              goto out_dput_upper;
++      }
+ 
+-              if (opaquedir)
+-                      upper = opaquedir;
+-              err = -ESTALE;
+-              if (upper->d_parent != upperdir)
+-                      goto kill_whiteout;
++      whiteout = ovl_whiteout(workdir, dentry);
++      err = PTR_ERR(whiteout);
++      if (IS_ERR(whiteout))
++              goto out_dput_upper;
+ 
+-              if (is_dir)
+-                      flags |= RENAME_EXCHANGE;
++      if (d_is_dir(upper))
++              flags = RENAME_EXCHANGE;
+ 
+-              err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
+-              if (err)
+-                      goto kill_whiteout;
++      err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
++      if (err)
++              goto kill_whiteout;
++      if (flags)
++              ovl_cleanup(wdir, upper);
+ 
+-              if (is_dir)
+-                      ovl_cleanup(wdir, upper);
+-      }
+       ovl_dentry_version_inc(dentry->d_parent);
+ out_d_drop:
+       d_drop(dentry);
+       dput(whiteout);
++out_dput_upper:
++      dput(upper);
+ out_unlock:
+       unlock_rename(workdir, upperdir);
+ out_dput:
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index e696ba32a2b5..fefce48e0f31 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -54,6 +54,10 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
+               upperdentry = ovl_dentry_upper(dentry);
+ 
+               mutex_lock(&upperdentry->d_inode->i_mutex);
++
++              if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
++                      attr->ia_valid &= ~ATTR_MODE;
++
+               err = notify_change(upperdentry, attr, NULL);
+               if (!err)
+                       ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
+@@ -395,12 +399,11 @@ struct inode *ovl_new_inode(struct super_block *sb, 
umode_t mode,
+       if (!inode)
+               return NULL;
+ 
+-      mode &= S_IFMT;
+-
+       inode->i_ino = get_next_ino();
+       inode->i_mode = mode;
+       inode->i_flags |= S_NOATIME | S_NOCMTIME;
+ 
++      mode &= S_IFMT;
+       switch (mode) {
+       case S_IFDIR:
+               inode->i_private = oe;
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index 1714fcc7603e..00eb848faad8 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -173,6 +173,7 @@ static inline void ovl_copyattr(struct inode *from, struct 
inode *to)
+ {
+       to->i_uid = from->i_uid;
+       to->i_gid = from->i_gid;
++      to->i_mode = from->i_mode;
+ }
+ 
+ /* dir.c */
+diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
+index 0ccf7f267ff9..3f3367c42896 100644
+--- a/include/drm/ttm/ttm_bo_api.h
++++ b/include/drm/ttm/ttm_bo_api.h
+@@ -316,6 +316,20 @@ ttm_bo_reference(struct ttm_buffer_object *bo)
+  */
+ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
+                      bool interruptible, bool no_wait);
++
++/**
++ * ttm_bo_mem_compat - Check if proposed placement is compatible with a bo
++ *
++ * @placement:  Return immediately if buffer is busy.
++ * @mem:  The struct ttm_mem_reg indicating the region where the bo resides
++ * @new_flags: Describes compatible placement found
++ *
++ * Returns true if the placement is compatible
++ */
++extern bool ttm_bo_mem_compat(struct ttm_placement *placement,
++                            struct ttm_mem_reg *mem,
++                            uint32_t *new_flags);
++
+ /**
+  * ttm_bo_validate
+  *
+diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
+index 729f48e6b20b..828198db5614 100644
+--- a/include/linux/bcma/bcma.h
++++ b/include/linux/bcma/bcma.h
+@@ -154,6 +154,7 @@ struct bcma_host_ops {
+ #define BCMA_CORE_DEFAULT             0xFFF
+ 
+ #define BCMA_MAX_NR_CORES             16
++#define BCMA_CORE_SIZE                        0x1000
+ 
+ /* Chip IDs of PCIe devices */
+ #define BCMA_CHIP_ID_BCM4313  0x4313
+diff --git a/include/linux/netfilter/x_tables.h 
b/include/linux/netfilter/x_tables.h
+index 7741efa43b35..cc615e273f80 100644
+--- a/include/linux/netfilter/x_tables.h
++++ b/include/linux/netfilter/x_tables.h
+@@ -243,6 +243,10 @@ int xt_check_entry_offsets(const void *base, const char 
*elems,
+                          unsigned int target_offset,
+                          unsigned int next_offset);
+ 
++unsigned int *xt_alloc_entry_offsets(unsigned int size);
++bool xt_find_jump_offset(const unsigned int *offsets,
++                       unsigned int target, unsigned int size);
++
+ int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto,
+                  bool inv_proto);
+ int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t 
proto,
+diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
+index 5d5174b59802..673dee29a9b9 100644
+--- a/include/linux/radix-tree.h
++++ b/include/linux/radix-tree.h
+@@ -382,6 +382,7 @@ static inline __must_check
+ void **radix_tree_iter_retry(struct radix_tree_iter *iter)
+ {
+       iter->next_index = iter->index;
++      iter->tags = 0;
+       return NULL;
+ }
+ 
+diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
+index a16b67859e2a..731d7a342670 100644
+--- a/kernel/time/posix-cpu-timers.c
++++ b/kernel/time/posix-cpu-timers.c
+@@ -784,6 +784,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, 
struct itimerspec *itp)
+                       timer->it.cpu.expires = 0;
+                       sample_to_timespec(timer->it_clock, 
timer->it.cpu.expires,
+                                          &itp->it_value);
++                      return;
+               } else {
+                       cpu_timer_sample_group(timer->it_clock, p, &now);
+                       unlock_task_sighand(p, &flags);
+diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
+index b8c3fde5b04f..60441b6a9546 100644
+--- a/net/ceph/osdmap.c
++++ b/net/ceph/osdmap.c
+@@ -1167,6 +1167,115 @@ struct ceph_osdmap *ceph_osdmap_decode(void **p, void 
*end)
+ }
+ 
+ /*
++ * Encoding order is (new_up_client, new_state, new_weight).  Need to
++ * apply in the (new_weight, new_state, new_up_client) order, because
++ * an incremental map may look like e.g.
++ *
++ *     new_up_client: { osd=6, addr=... } # set osd_state and addr
++ *     new_state: { osd=6, xorstate=EXISTS } # clear osd_state
++ */
++static int decode_new_up_state_weight(void **p, void *end,
++                                    struct ceph_osdmap *map)
++{
++      void *new_up_client;
++      void *new_state;
++      void *new_weight_end;
++      u32 len;
++
++      new_up_client = *p;
++      ceph_decode_32_safe(p, end, len, e_inval);
++      len *= sizeof(u32) + sizeof(struct ceph_entity_addr);
++      ceph_decode_need(p, end, len, e_inval);
++      *p += len;
++
++      new_state = *p;
++      ceph_decode_32_safe(p, end, len, e_inval);
++      len *= sizeof(u32) + sizeof(u8);
++      ceph_decode_need(p, end, len, e_inval);
++      *p += len;
++
++      /* new_weight */
++      ceph_decode_32_safe(p, end, len, e_inval);
++      while (len--) {
++              s32 osd;
++              u32 w;
++
++              ceph_decode_need(p, end, 2*sizeof(u32), e_inval);
++              osd = ceph_decode_32(p);
++              w = ceph_decode_32(p);
++              BUG_ON(osd >= map->max_osd);
++              pr_info("osd%d weight 0x%x %s\n", osd, w,
++                   w == CEPH_OSD_IN ? "(in)" :
++                   (w == CEPH_OSD_OUT ? "(out)" : ""));
++              map->osd_weight[osd] = w;
++
++              /*
++               * If we are marking in, set the EXISTS, and clear the
++               * AUTOOUT and NEW bits.
++               */
++              if (w) {
++                      map->osd_state[osd] |= CEPH_OSD_EXISTS;
++                      map->osd_state[osd] &= ~(CEPH_OSD_AUTOOUT |
++                                               CEPH_OSD_NEW);
++              }
++      }
++      new_weight_end = *p;
++
++      /* new_state (up/down) */
++      *p = new_state;
++      len = ceph_decode_32(p);
++      while (len--) {
++              s32 osd;
++              u8 xorstate;
++              int ret;
++
++              osd = ceph_decode_32(p);
++              xorstate = ceph_decode_8(p);
++              if (xorstate == 0)
++                      xorstate = CEPH_OSD_UP;
++              BUG_ON(osd >= map->max_osd);
++              if ((map->osd_state[osd] & CEPH_OSD_UP) &&
++                  (xorstate & CEPH_OSD_UP))
++                      pr_info("osd%d down\n", osd);
++              if ((map->osd_state[osd] & CEPH_OSD_EXISTS) &&
++                  (xorstate & CEPH_OSD_EXISTS)) {
++                      pr_info("osd%d does not exist\n", osd);
++                      map->osd_weight[osd] = CEPH_OSD_IN;
++                      ret = set_primary_affinity(map, osd,
++                                                 
CEPH_OSD_DEFAULT_PRIMARY_AFFINITY);
++                      if (ret)
++                              return ret;
++                      memset(map->osd_addr + osd, 0, sizeof(*map->osd_addr));
++                      map->osd_state[osd] = 0;
++              } else {
++                      map->osd_state[osd] ^= xorstate;
++              }
++      }
++
++      /* new_up_client */
++      *p = new_up_client;
++      len = ceph_decode_32(p);
++      while (len--) {
++              s32 osd;
++              struct ceph_entity_addr addr;
++
++              osd = ceph_decode_32(p);
++              ceph_decode_copy(p, &addr, sizeof(addr));
++              ceph_decode_addr(&addr);
++              BUG_ON(osd >= map->max_osd);
++              pr_info("osd%d up\n", osd);
++              map->osd_state[osd] |= CEPH_OSD_EXISTS | CEPH_OSD_UP;
++              map->osd_addr[osd] = addr;
++      }
++
++      *p = new_weight_end;
++      return 0;
++
++e_inval:
++      return -EINVAL;
++}
++
++/*
+  * decode and apply an incremental map update.
+  */
+ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+@@ -1265,49 +1374,10 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, 
void *end,
+                       __remove_pg_pool(&map->pg_pools, pi);
+       }
+ 
+-      /* new_up */
+-      ceph_decode_32_safe(p, end, len, e_inval);
+-      while (len--) {
+-              u32 osd;
+-              struct ceph_entity_addr addr;
+-              ceph_decode_32_safe(p, end, osd, e_inval);
+-              ceph_decode_copy_safe(p, end, &addr, sizeof(addr), e_inval);
+-              ceph_decode_addr(&addr);
+-              pr_info("osd%d up\n", osd);
+-              BUG_ON(osd >= map->max_osd);
+-              map->osd_state[osd] |= CEPH_OSD_UP;
+-              map->osd_addr[osd] = addr;
+-      }
+-
+-      /* new_state */
+-      ceph_decode_32_safe(p, end, len, e_inval);
+-      while (len--) {
+-              u32 osd;
+-              u8 xorstate;
+-              ceph_decode_32_safe(p, end, osd, e_inval);
+-              xorstate = **(u8 **)p;
+-              (*p)++;  /* clean flag */
+-              if (xorstate == 0)
+-                      xorstate = CEPH_OSD_UP;
+-              if (xorstate & CEPH_OSD_UP)
+-                      pr_info("osd%d down\n", osd);
+-              if (osd < map->max_osd)
+-                      map->osd_state[osd] ^= xorstate;
+-      }
+-
+-      /* new_weight */
+-      ceph_decode_32_safe(p, end, len, e_inval);
+-      while (len--) {
+-              u32 osd, off;
+-              ceph_decode_need(p, end, sizeof(u32)*2, e_inval);
+-              osd = ceph_decode_32(p);
+-              off = ceph_decode_32(p);
+-              pr_info("osd%d weight 0x%x %s\n", osd, off,
+-                   off == CEPH_OSD_IN ? "(in)" :
+-                   (off == CEPH_OSD_OUT ? "(out)" : ""));
+-              if (osd < map->max_osd)
+-                      map->osd_weight[osd] = off;
+-      }
++      /* new_up_client, new_state, new_weight */
++      err = decode_new_up_state_weight(p, end, map);
++      if (err)
++              goto bad;
+ 
+       /* new_pg_temp */
+       err = decode_new_pg_temp(p, end, map);
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 655e1b05ff74..b3bfa5111799 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -363,23 +363,12 @@ static inline bool unconditional(const struct arpt_entry 
*e)
+              memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
+ }
+ 
+-static bool find_jump_target(const struct xt_table_info *t,
+-                           const struct arpt_entry *target)
+-{
+-      struct arpt_entry *iter;
+-
+-      xt_entry_foreach(iter, t->entries, t->size) {
+-               if (iter == target)
+-                      return true;
+-      }
+-      return false;
+-}
+-
+ /* Figures out from what hook each rule can be called: returns 0 if
+  * there are loops.  Puts hook bitmask in comefrom.
+  */
+ static int mark_source_chains(const struct xt_table_info *newinfo,
+-                            unsigned int valid_hooks, void *entry0)
++                            unsigned int valid_hooks, void *entry0,
++                            unsigned int *offsets)
+ {
+       unsigned int hook;
+ 
+@@ -468,10 +457,11 @@ static int mark_source_chains(const struct xt_table_info 
*newinfo,
+                                       /* This a jump; chase it. */
+                                       duprintf("Jump rule %u -> %u\n",
+                                                pos, newpos);
++                                      if (!xt_find_jump_offset(offsets, 
newpos,
++                                                               
newinfo->number))
++                                              return 0;
+                                       e = (struct arpt_entry *)
+                                               (entry0 + newpos);
+-                                      if (!find_jump_target(newinfo, e))
+-                                              return 0;
+                               } else {
+                                       /* ... this is a fallthru */
+                                       newpos = pos + e->next_offset;
+@@ -631,6 +621,7 @@ static int translate_table(struct xt_table_info *newinfo, 
void *entry0,
+                            const struct arpt_replace *repl)
+ {
+       struct arpt_entry *iter;
++      unsigned int *offsets;
+       unsigned int i;
+       int ret = 0;
+ 
+@@ -644,8 +635,10 @@ static int translate_table(struct xt_table_info *newinfo, 
void *entry0,
+       }
+ 
+       duprintf("translate_table: size %u\n", newinfo->size);
++      offsets = xt_alloc_entry_offsets(newinfo->number);
++      if (!offsets)
++              return -ENOMEM;
+       i = 0;
+-
+       /* Walk through entries, checking offsets. */
+       xt_entry_foreach(iter, entry0, newinfo->size) {
+               ret = check_entry_size_and_hooks(iter, newinfo, entry0,
+@@ -654,7 +647,9 @@ static int translate_table(struct xt_table_info *newinfo, 
void *entry0,
+                                                repl->underflow,
+                                                repl->valid_hooks);
+               if (ret != 0)
+-                      break;
++                      goto out_free;
++              if (i < repl->num_entries)
++                      offsets[i] = (void *)iter - entry0;
+               ++i;
+               if (strcmp(arpt_get_target(iter)->u.user.name,
+                   XT_ERROR_TARGET) == 0)
+@@ -662,12 +657,13 @@ static int translate_table(struct xt_table_info 
*newinfo, void *entry0,
+       }
+       duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
+       if (ret != 0)
+-              return ret;
++              goto out_free;
+ 
++      ret = -EINVAL;
+       if (i != repl->num_entries) {
+               duprintf("translate_table: %u not %u entries\n",
+                        i, repl->num_entries);
+-              return -EINVAL;
++              goto out_free;
+       }
+ 
+       /* Check hooks all assigned */
+@@ -678,17 +674,20 @@ static int translate_table(struct xt_table_info 
*newinfo, void *entry0,
+               if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid hook entry %u %u\n",
+                                i, repl->hook_entry[i]);
+-                      return -EINVAL;
++                      goto out_free;
+               }
+               if (newinfo->underflow[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid underflow %u %u\n",
+                                i, repl->underflow[i]);
+-                      return -EINVAL;
++                      goto out_free;
+               }
+       }
+ 
+-      if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
+-              return -ELOOP;
++      if (!mark_source_chains(newinfo, repl->valid_hooks, entry0, offsets)) {
++              ret = -ELOOP;
++              goto out_free;
++      }
++      kvfree(offsets);
+ 
+       /* Finally, each sanity check must pass */
+       i = 0;
+@@ -715,6 +714,9 @@ static int translate_table(struct xt_table_info *newinfo, 
void *entry0,
+       }
+ 
+       return ret;
++ out_free:
++      kvfree(offsets);
++      return ret;
+ }
+ 
+ static void get_counters(const struct xt_table_info *t,
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 865e738d3804..4e40f2ec2b68 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -439,23 +439,12 @@ ipt_do_table(struct sk_buff *skb,
+ #endif
+ }
+ 
+-static bool find_jump_target(const struct xt_table_info *t,
+-                           const struct ipt_entry *target)
+-{
+-      struct ipt_entry *iter;
+-
+-      xt_entry_foreach(iter, t->entries, t->size) {
+-               if (iter == target)
+-                      return true;
+-      }
+-      return false;
+-}
+-
+ /* Figures out from what hook each rule can be called: returns 0 if
+    there are loops.  Puts hook bitmask in comefrom. */
+ static int
+ mark_source_chains(const struct xt_table_info *newinfo,
+-                 unsigned int valid_hooks, void *entry0)
++                 unsigned int valid_hooks, void *entry0,
++                 unsigned int *offsets)
+ {
+       unsigned int hook;
+ 
+@@ -548,10 +537,11 @@ mark_source_chains(const struct xt_table_info *newinfo,
+                                       /* This a jump; chase it. */
+                                       duprintf("Jump rule %u -> %u\n",
+                                                pos, newpos);
++                                      if (!xt_find_jump_offset(offsets, 
newpos,
++                                                               
newinfo->number))
++                                              return 0;
+                                       e = (struct ipt_entry *)
+                                               (entry0 + newpos);
+-                                      if (!find_jump_target(newinfo, e))
+-                                              return 0;
+                               } else {
+                                       /* ... this is a fallthru */
+                                       newpos = pos + e->next_offset;
+@@ -798,6 +788,7 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+                 const struct ipt_replace *repl)
+ {
+       struct ipt_entry *iter;
++      unsigned int *offsets;
+       unsigned int i;
+       int ret = 0;
+ 
+@@ -811,6 +802,9 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+       }
+ 
+       duprintf("translate_table: size %u\n", newinfo->size);
++      offsets = xt_alloc_entry_offsets(newinfo->number);
++      if (!offsets)
++              return -ENOMEM;
+       i = 0;
+       /* Walk through entries, checking offsets. */
+       xt_entry_foreach(iter, entry0, newinfo->size) {
+@@ -820,17 +814,20 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+                                                repl->underflow,
+                                                repl->valid_hooks);
+               if (ret != 0)
+-                      return ret;
++                      goto out_free;
++              if (i < repl->num_entries)
++                      offsets[i] = (void *)iter - entry0;
+               ++i;
+               if (strcmp(ipt_get_target(iter)->u.user.name,
+                   XT_ERROR_TARGET) == 0)
+                       ++newinfo->stacksize;
+       }
+ 
++      ret = -EINVAL;
+       if (i != repl->num_entries) {
+               duprintf("translate_table: %u not %u entries\n",
+                        i, repl->num_entries);
+-              return -EINVAL;
++              goto out_free;
+       }
+ 
+       /* Check hooks all assigned */
+@@ -841,17 +838,20 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+               if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid hook entry %u %u\n",
+                                i, repl->hook_entry[i]);
+-                      return -EINVAL;
++                      goto out_free;
+               }
+               if (newinfo->underflow[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid underflow %u %u\n",
+                                i, repl->underflow[i]);
+-                      return -EINVAL;
++                      goto out_free;
+               }
+       }
+ 
+-      if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
+-              return -ELOOP;
++      if (!mark_source_chains(newinfo, repl->valid_hooks, entry0, offsets)) {
++              ret = -ELOOP;
++              goto out_free;
++      }
++      kvfree(offsets);
+ 
+       /* Finally, each sanity check must pass */
+       i = 0;
+@@ -878,6 +878,9 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+       }
+ 
+       return ret;
++ out_free:
++      kvfree(offsets);
++      return ret;
+ }
+ 
+ static void
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 1b6ed70bab37..cb3cc2a4426a 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -449,23 +449,12 @@ ip6t_do_table(struct sk_buff *skb,
+ #endif
+ }
+ 
+-static bool find_jump_target(const struct xt_table_info *t,
+-                           const struct ip6t_entry *target)
+-{
+-      struct ip6t_entry *iter;
+-
+-      xt_entry_foreach(iter, t->entries, t->size) {
+-               if (iter == target)
+-                      return true;
+-      }
+-      return false;
+-}
+-
+ /* Figures out from what hook each rule can be called: returns 0 if
+    there are loops.  Puts hook bitmask in comefrom. */
+ static int
+ mark_source_chains(const struct xt_table_info *newinfo,
+-                 unsigned int valid_hooks, void *entry0)
++                 unsigned int valid_hooks, void *entry0,
++                 unsigned int *offsets)
+ {
+       unsigned int hook;
+ 
+@@ -558,10 +547,11 @@ mark_source_chains(const struct xt_table_info *newinfo,
+                                       /* This a jump; chase it. */
+                                       duprintf("Jump rule %u -> %u\n",
+                                                pos, newpos);
++                                      if (!xt_find_jump_offset(offsets, 
newpos,
++                                                               
newinfo->number))
++                                              return 0;
+                                       e = (struct ip6t_entry *)
+                                               (entry0 + newpos);
+-                                      if (!find_jump_target(newinfo, e))
+-                                              return 0;
+                               } else {
+                                       /* ... this is a fallthru */
+                                       newpos = pos + e->next_offset;
+@@ -808,6 +798,7 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+                 const struct ip6t_replace *repl)
+ {
+       struct ip6t_entry *iter;
++      unsigned int *offsets;
+       unsigned int i;
+       int ret = 0;
+ 
+@@ -821,6 +812,9 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+       }
+ 
+       duprintf("translate_table: size %u\n", newinfo->size);
++      offsets = xt_alloc_entry_offsets(newinfo->number);
++      if (!offsets)
++              return -ENOMEM;
+       i = 0;
+       /* Walk through entries, checking offsets. */
+       xt_entry_foreach(iter, entry0, newinfo->size) {
+@@ -830,17 +824,20 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+                                                repl->underflow,
+                                                repl->valid_hooks);
+               if (ret != 0)
+-                      return ret;
++                      goto out_free;
++              if (i < repl->num_entries)
++                      offsets[i] = (void *)iter - entry0;
+               ++i;
+               if (strcmp(ip6t_get_target(iter)->u.user.name,
+                   XT_ERROR_TARGET) == 0)
+                       ++newinfo->stacksize;
+       }
+ 
++      ret = -EINVAL;
+       if (i != repl->num_entries) {
+               duprintf("translate_table: %u not %u entries\n",
+                        i, repl->num_entries);
+-              return -EINVAL;
++              goto out_free;
+       }
+ 
+       /* Check hooks all assigned */
+@@ -851,17 +848,20 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+               if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid hook entry %u %u\n",
+                                i, repl->hook_entry[i]);
+-                      return -EINVAL;
++                      goto out_free;
+               }
+               if (newinfo->underflow[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid underflow %u %u\n",
+                                i, repl->underflow[i]);
+-                      return -EINVAL;
++                      goto out_free;
+               }
+       }
+ 
+-      if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
+-              return -ELOOP;
++      if (!mark_source_chains(newinfo, repl->valid_hooks, entry0, offsets)) {
++              ret = -ELOOP;
++              goto out_free;
++      }
++      kvfree(offsets);
+ 
+       /* Finally, each sanity check must pass */
+       i = 0;
+@@ -888,6 +888,9 @@ translate_table(struct net *net, struct xt_table_info 
*newinfo, void *entry0,
+       }
+ 
+       return ret;
++ out_free:
++      kvfree(offsets);
++      return ret;
+ }
+ 
+ static void
+diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
+index 0c01ad4e078f..489899325bf7 100644
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -704,6 +704,56 @@ int xt_check_entry_offsets(const void *base,
+ }
+ EXPORT_SYMBOL(xt_check_entry_offsets);
+ 
++/**
++ * xt_alloc_entry_offsets - allocate array to store rule head offsets
++ *
++ * @size: number of entries
++ *
++ * Return: NULL or kmalloc'd or vmalloc'd array
++ */
++unsigned int *xt_alloc_entry_offsets(unsigned int size)
++{
++      unsigned int *off;
++
++      off = kcalloc(size, sizeof(unsigned int), GFP_KERNEL | __GFP_NOWARN);
++
++      if (off)
++              return off;
++
++      if (size < (SIZE_MAX / sizeof(unsigned int)))
++              off = vmalloc(size * sizeof(unsigned int));
++
++      return off;
++}
++EXPORT_SYMBOL(xt_alloc_entry_offsets);
++
++/**
++ * xt_find_jump_offset - check if target is a valid jump offset
++ *
++ * @offsets: array containing all valid rule start offsets of a rule blob
++ * @target: the jump target to search for
++ * @size: entries in @offset
++ */
++bool xt_find_jump_offset(const unsigned int *offsets,
++                       unsigned int target, unsigned int size)
++{
++      int m, low = 0, hi = size;
++
++      while (hi > low) {
++              m = (low + hi) / 2u;
++
++              if (offsets[m] > target)
++                      hi = m;
++              else if (offsets[m] < target)
++                      low = m + 1;
++              else
++                      return true;
++      }
++
++      return false;
++}
++EXPORT_SYMBOL(xt_find_jump_offset);
++
+ int xt_check_target(struct xt_tgchk_param *par,
+                   unsigned int size, u_int8_t proto, bool inv_proto)
+ {
+diff --git a/sound/core/control.c b/sound/core/control.c
+index 82a638a01b24..733b803af271 100644
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -150,6 +150,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int 
mask,
+       
+       if (snd_BUG_ON(!card || !id))
+               return;
++      if (card->shutdown)
++              return;
+       read_lock(&card->ctl_files_rwlock);
+ #if IS_ENABLED(CONFIG_SND_MIXER_OSS)
+       card->mixer_oss_change_count++;
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 58f82733c893..bc9ed75c651c 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -1119,8 +1119,10 @@ static int azx_free(struct azx *chip)
+       if (use_vga_switcheroo(hda)) {
+               if (chip->disabled && chip->bus)
+                       snd_hda_unlock_devices(chip->bus);
+-              if (hda->vga_switcheroo_registered)
++              if (hda->vga_switcheroo_registered) {
+                       vga_switcheroo_unregister_client(chip->pci);
++                      vga_switcheroo_fini_domain_pm_ops(chip->card->dev);
++              }
+       }
+ 
+       if (chip->initialized) {
+@@ -2093,6 +2095,10 @@ static const struct pci_device_id azx_ids[] = {
+       /* ATI HDMI */
+       { PCI_DEVICE(0x1002, 0x1308),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
++      { PCI_DEVICE(0x1002, 0x157a),
++        .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
++      { PCI_DEVICE(0x1002, 0x15b3),
++        .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+       { PCI_DEVICE(0x1002, 0x793b),
+         .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+       { PCI_DEVICE(0x1002, 0x7919),
+@@ -2147,8 +2153,14 @@ static const struct pci_device_id azx_ids[] = {
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+       { PCI_DEVICE(0x1002, 0xaab0),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
++      { PCI_DEVICE(0x1002, 0xaac0),
++        .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+       { PCI_DEVICE(0x1002, 0xaac8),
+         .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
++      { PCI_DEVICE(0x1002, 0xaad8),
++        .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
++      { PCI_DEVICE(0x1002, 0xaae8),
++        .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+       /* VIA VT8251/VT8237A */
+       { PCI_DEVICE(0x1106, 0x3288),
+         .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 77bd16739dbd..c35960b74026 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5496,7 +5496,6 @@ static const struct hda_model_fixup 
alc269_fixup_models[] = {
+       {}
+ };
+ #define ALC225_STANDARD_PINS \
+-      {0x12, 0xb7a60130}, \
+       {0x21, 0x04211020}
+ 
+ #define ALC255_STANDARD_PINS \
+@@ -5562,10 +5561,24 @@ static const struct snd_hda_pin_quirk 
alc269_pin_fixup_tbl[] = {
+               {0x14, 0x901701b0}),
+       SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", 
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+               ALC225_STANDARD_PINS,
++              {0x12, 0xb7a60130},
+               {0x14, 0x901701a0}),
+       SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", 
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+               ALC225_STANDARD_PINS,
++              {0x12, 0xb7a60130},
+               {0x14, 0x901701b0}),
++      SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", 
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++              ALC225_STANDARD_PINS,
++              {0x12, 0xb7a60150},
++              {0x14, 0x901701a0}),
++      SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", 
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++              ALC225_STANDARD_PINS,
++              {0x12, 0xb7a60150},
++              {0x14, 0x901701b0}),
++      SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", 
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++              ALC225_STANDARD_PINS,
++              {0x12, 0xb7a60130},
++              {0x1b, 0x90170110}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", 
ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
+               ALC255_STANDARD_PINS,
+               {0x12, 0x40300000},

Reply via email to