diff -druNp --no-dereference linux-libre-4.4.76-gnu/arch/x86/include/asm/pat.h linux-libre-4.4.77-gnu/arch/x86/include/asm/pat.h
--- linux-libre-4.4.76-gnu/arch/x86/include/asm/pat.h	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/arch/x86/include/asm/pat.h	2017-07-15 05:58:03.000000000 -0400
@@ -7,6 +7,7 @@
 bool pat_enabled(void);
 void pat_disable(const char *reason);
 extern void pat_init(void);
+extern void init_cache_modes(void);
 
 extern int reserve_memtype(u64 start, u64 end,
 		enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/arch/x86/kernel/setup.c linux-libre-4.4.77-gnu/arch/x86/kernel/setup.c
--- linux-libre-4.4.76-gnu/arch/x86/kernel/setup.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/arch/x86/kernel/setup.c	2017-07-15 05:58:03.000000000 -0400
@@ -1048,6 +1048,13 @@ void __init setup_arch(char **cmdline_p)
 	if (mtrr_trim_uncached_memory(max_pfn))
 		max_pfn = e820_end_of_ram_pfn();
 
+	/*
+	 * This call is required when the CPU does not support PAT. If
+	 * mtrr_bp_init() invoked it already via pat_init() the call has no
+	 * effect.
+	 */
+	init_cache_modes();
+
 #ifdef CONFIG_X86_32
 	/* max_low_pfn get updated here */
 	find_low_pfn_range();
diff -druNp --no-dereference linux-libre-4.4.76-gnu/arch/x86/lib/copy_user_64.S linux-libre-4.4.77-gnu/arch/x86/lib/copy_user_64.S
--- linux-libre-4.4.76-gnu/arch/x86/lib/copy_user_64.S	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/arch/x86/lib/copy_user_64.S	2017-07-15 05:58:03.000000000 -0400
@@ -80,7 +80,7 @@ ENTRY(copy_user_generic_unrolled)
 	movl %edx,%ecx
 	andl $63,%edx
 	shrl $6,%ecx
-	jz 17f
+	jz .L_copy_short_string
 1:	movq (%rsi),%r8
 2:	movq 1*8(%rsi),%r9
 3:	movq 2*8(%rsi),%r10
@@ -101,7 +101,8 @@ ENTRY(copy_user_generic_unrolled)
 	leaq 64(%rdi),%rdi
 	decl %ecx
 	jnz 1b
-17:	movl %edx,%ecx
+.L_copy_short_string:
+	movl %edx,%ecx
 	andl $7,%edx
 	shrl $3,%ecx
 	jz 20f
@@ -215,6 +216,8 @@ ENDPROC(copy_user_generic_string)
  */
 ENTRY(copy_user_enhanced_fast_string)
 	ASM_STAC
+	cmpl $64,%edx
+	jb .L_copy_short_string	/* less then 64 bytes, avoid the costly 'rep' */
 	movl %edx,%ecx
 1:	rep
 	movsb
diff -druNp --no-dereference linux-libre-4.4.76-gnu/arch/x86/mm/pat.c linux-libre-4.4.77-gnu/arch/x86/mm/pat.c
--- linux-libre-4.4.76-gnu/arch/x86/mm/pat.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/arch/x86/mm/pat.c	2017-07-15 05:58:03.000000000 -0400
@@ -36,14 +36,14 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "" fmt
 
-static bool boot_cpu_done;
-
-static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
-static void init_cache_modes(void);
+static bool __read_mostly boot_cpu_done;
+static bool __read_mostly pat_disabled = !IS_ENABLED(CONFIG_X86_PAT);
+static bool __read_mostly pat_initialized;
+static bool __read_mostly init_cm_done;
 
 void pat_disable(const char *reason)
 {
-	if (!__pat_enabled)
+	if (pat_disabled)
 		return;
 
 	if (boot_cpu_done) {
@@ -51,10 +51,8 @@ void pat_disable(const char *reason)
 		return;
 	}
 
-	__pat_enabled = 0;
+	pat_disabled = true;
 	pr_info("x86/PAT: %s\n", reason);
-
-	init_cache_modes();
 }
 
 static int __init nopat(char *str)
@@ -66,7 +64,7 @@ early_param("nopat", nopat);
 
 bool pat_enabled(void)
 {
-	return !!__pat_enabled;
+	return pat_initialized;
 }
 EXPORT_SYMBOL_GPL(pat_enabled);
 
@@ -204,6 +202,8 @@ static void __init_cache_modes(u64 pat)
 		update_cache_mode_entry(i, cache);
 	}
 	pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg);
+
+	init_cm_done = true;
 }
 
 #define PAT(x, y)	((u64)PAT_ ## y << ((x)*8))
@@ -224,6 +224,7 @@ static void pat_bsp_init(u64 pat)
 	}
 
 	wrmsrl(MSR_IA32_CR_PAT, pat);
+	pat_initialized = true;
 
 	__init_cache_modes(pat);
 }
@@ -241,10 +242,9 @@ static void pat_ap_init(u64 pat)
 	wrmsrl(MSR_IA32_CR_PAT, pat);
 }
 
-static void init_cache_modes(void)
+void init_cache_modes(void)
 {
 	u64 pat = 0;
-	static int init_cm_done;
 
 	if (init_cm_done)
 		return;
@@ -286,8 +286,6 @@ static void init_cache_modes(void)
 	}
 
 	__init_cache_modes(pat);
-
-	init_cm_done = 1;
 }
 
 /**
@@ -305,10 +303,8 @@ void pat_init(void)
 	u64 pat;
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 
-	if (!pat_enabled()) {
-		init_cache_modes();
+	if (pat_disabled)
 		return;
-	}
 
 	if ((c->x86_vendor == X86_VENDOR_INTEL) &&
 	    (((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
diff -druNp --no-dereference linux-libre-4.4.76-gnu/arch/x86/tools/relocs.c linux-libre-4.4.77-gnu/arch/x86/tools/relocs.c
--- linux-libre-4.4.76-gnu/arch/x86/tools/relocs.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/arch/x86/tools/relocs.c	2017-07-15 05:58:03.000000000 -0400
@@ -992,11 +992,12 @@ static void emit_relocs(int as_text, int
 		die("Segment relocations found but --realmode not specified\n");
 
 	/* Order the relocations for more efficient processing */
-	sort_relocs(&relocs16);
 	sort_relocs(&relocs32);
 #if ELF_BITS == 64
 	sort_relocs(&relocs32neg);
 	sort_relocs(&relocs64);
+#else
+	sort_relocs(&relocs16);
 #endif
 
 	/* Print the relocations */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/base/platform.c linux-libre-4.4.77-gnu/drivers/base/platform.c
--- linux-libre-4.4.76-gnu/drivers/base/platform.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/base/platform.c	2017-07-15 05:58:03.000000000 -0400
@@ -807,7 +807,7 @@ static ssize_t driver_override_store(str
 				     const char *buf, size_t count)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	char *driver_override, *old = pdev->driver_override, *cp;
+	char *driver_override, *old, *cp;
 
 	if (count > PATH_MAX)
 		return -EINVAL;
@@ -820,12 +820,15 @@ static ssize_t driver_override_store(str
 	if (cp)
 		*cp = '\0';
 
+	device_lock(dev);
+	old = pdev->driver_override;
 	if (strlen(driver_override)) {
 		pdev->driver_override = driver_override;
 	} else {
 		kfree(driver_override);
 		pdev->driver_override = NULL;
 	}
+	device_unlock(dev);
 
 	kfree(old);
 
@@ -836,8 +839,12 @@ static ssize_t driver_override_show(stru
 				    struct device_attribute *attr, char *buf)
 {
 	struct platform_device *pdev = to_platform_device(dev);
+	ssize_t len;
 
-	return sprintf(buf, "%s\n", pdev->driver_override);
+	device_lock(dev);
+	len = sprintf(buf, "%s\n", pdev->driver_override);
+	device_unlock(dev);
+	return len;
 }
 static DEVICE_ATTR_RW(driver_override);
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/gpu/drm/virtio/virtgpu_object.c linux-libre-4.4.77-gnu/drivers/gpu/drm/virtio/virtgpu_object.c
--- linux-libre-4.4.76-gnu/drivers/gpu/drm/virtio/virtgpu_object.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/gpu/drm/virtio/virtgpu_object.c	2017-07-15 05:58:03.000000000 -0400
@@ -81,8 +81,10 @@ int virtio_gpu_object_create(struct virt
 		return -ENOMEM;
 	size = roundup(size, PAGE_SIZE);
 	ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size);
-	if (ret != 0)
+	if (ret != 0) {
+		kfree(bo);
 		return ret;
+	}
 	bo->dumb = false;
 	virtio_gpu_init_ttm_placement(bo, pinned);
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/infiniband/core/uverbs_cmd.c linux-libre-4.4.77-gnu/drivers/infiniband/core/uverbs_cmd.c
--- linux-libre-4.4.76-gnu/drivers/infiniband/core/uverbs_cmd.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/infiniband/core/uverbs_cmd.c	2017-07-15 05:58:03.000000000 -0400
@@ -2287,6 +2287,10 @@ ssize_t ib_uverbs_modify_qp(struct ib_uv
 	if (copy_from_user(&cmd, buf, sizeof cmd))
 		return -EFAULT;
 
+	if (cmd.port_num < rdma_start_port(ib_dev) ||
+	    cmd.port_num > rdma_end_port(ib_dev))
+		return -EINVAL;
+
 	INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
 		   out_len);
 
@@ -2827,6 +2831,10 @@ ssize_t ib_uverbs_create_ah(struct ib_uv
 	if (copy_from_user(&cmd, buf, sizeof cmd))
 		return -EFAULT;
 
+	if (cmd.attr.port_num < rdma_start_port(ib_dev) ||
+	    cmd.attr.port_num > rdma_end_port(ib_dev))
+		return -EINVAL;
+
 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
 	if (!uobj)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/md/md.c linux-libre-4.4.77-gnu/drivers/md/md.c
--- linux-libre-4.4.76-gnu/drivers/md/md.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/md/md.c	2017-07-15 05:58:03.000000000 -0400
@@ -1866,7 +1866,7 @@ super_1_rdev_size_change(struct md_rdev
 	}
 	sb = page_address(rdev->sb_page);
 	sb->data_size = cpu_to_le64(num_sectors);
-	sb->super_offset = rdev->sb_start;
+	sb->super_offset = cpu_to_le64(rdev->sb_start);
 	sb->sb_csum = calc_sb_1_csum(sb);
 	md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
 		       rdev->sb_page);
@@ -2273,7 +2273,7 @@ static bool does_sb_need_changing(struct
 	/* Check if any mddev parameters have changed */
 	if ((mddev->dev_sectors != le64_to_cpu(sb->size)) ||
 	    (mddev->reshape_position != le64_to_cpu(sb->reshape_position)) ||
-	    (mddev->layout != le64_to_cpu(sb->layout)) ||
+	    (mddev->layout != le32_to_cpu(sb->layout)) ||
 	    (mddev->raid_disks != le32_to_cpu(sb->raid_disks)) ||
 	    (mddev->chunk_sectors != le32_to_cpu(sb->chunksize)))
 		return true;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/media/pci/saa7134/saa7134-i2c.c linux-libre-4.4.77-gnu/drivers/media/pci/saa7134/saa7134-i2c.c
--- linux-libre-4.4.76-gnu/drivers/media/pci/saa7134/saa7134-i2c.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/media/pci/saa7134/saa7134-i2c.c	2017-07-15 05:58:03.000000000 -0400
@@ -355,12 +355,43 @@ static struct i2c_client saa7134_client_
 
 /* ----------------------------------------------------------- */
 
+/* On Medion 7134 reading EEPROM needs DVB-T demod i2c gate open */
+static void saa7134_i2c_eeprom_md7134_gate(struct saa7134_dev *dev)
+{
+	u8 subaddr = 0x7, dmdregval;
+	u8 data[2];
+	int ret;
+	struct i2c_msg i2cgatemsg_r[] = { {.addr = 0x08, .flags = 0,
+					   .buf = &subaddr, .len = 1},
+					  {.addr = 0x08,
+					   .flags = I2C_M_RD,
+					   .buf = &dmdregval, .len = 1}
+					};
+	struct i2c_msg i2cgatemsg_w[] = { {.addr = 0x08, .flags = 0,
+					   .buf = data, .len = 2} };
+
+	ret = i2c_transfer(&dev->i2c_adap, i2cgatemsg_r, 2);
+	if ((ret == 2) && (dmdregval & 0x2)) {
+		pr_debug("%s: DVB-T demod i2c gate was left closed\n",
+			 dev->name);
+
+		data[0] = subaddr;
+		data[1] = (dmdregval & ~0x2);
+		if (i2c_transfer(&dev->i2c_adap, i2cgatemsg_w, 1) != 1)
+			pr_err("%s: EEPROM i2c gate open failure\n",
+			  dev->name);
+	}
+}
+
 static int
 saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)
 {
 	unsigned char buf;
 	int i,err;
 
+	if (dev->board == SAA7134_BOARD_MD7134)
+		saa7134_i2c_eeprom_md7134_gate(dev);
+
 	dev->i2c_client.addr = 0xa0 >> 1;
 	buf = 0;
 	if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/net/ethernet/broadcom/bgmac.c linux-libre-4.4.77-gnu/drivers/net/ethernet/broadcom/bgmac.c
--- linux-libre-4.4.76-gnu/drivers/net/ethernet/broadcom/bgmac.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/net/ethernet/broadcom/bgmac.c	2017-07-15 05:58:03.000000000 -0400
@@ -1583,6 +1583,11 @@ static int bgmac_probe(struct bcma_devic
 		dev_warn(&core->dev, "Using random MAC: %pM\n", mac);
 	}
 
+	/* This (reset &) enable is not preset in specs or reference driver but
+	 * Broadcom does it in arch PCI code when enabling fake PCI device.
+	 */
+	bcma_core_enable(core, 0);
+
 	/* Allocation and references */
 	net_dev = alloc_etherdev(sizeof(*bgmac));
 	if (!net_dev)
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/net/wireless/ath/ath10k/pci.c linux-libre-4.4.77-gnu/drivers/net/wireless/ath/ath10k/pci.c
--- linux-libre-4.4.76-gnu/drivers/net/wireless/ath/ath10k/pci.c	2017-07-05 13:20:12.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/net/wireless/ath/ath10k/pci.c	2017-07-15 13:56:18.000000000 -0400
@@ -3050,7 +3050,7 @@ static int ath10k_pci_probe(struct pci_d
 		goto err_core_destroy;
 	}
 
-	if (QCA_REV_6174(ar))
+	if (QCA_REV_6174(ar) || QCA_REV_9377(ar))
 		ath10k_pci_override_ce_config(ar);
 
 	ret = ath10k_pci_alloc_pipes(ar);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/net/wireless/mac80211_hwsim.c linux-libre-4.4.77-gnu/drivers/net/wireless/mac80211_hwsim.c
--- linux-libre-4.4.76-gnu/drivers/net/wireless/mac80211_hwsim.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/net/wireless/mac80211_hwsim.c	2017-07-15 05:58:03.000000000 -0400
@@ -2539,7 +2539,7 @@ static int mac80211_hwsim_new_radio(stru
 
 	tasklet_hrtimer_init(&data->beacon_timer,
 			     mac80211_hwsim_beacon,
-			     CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
+			     CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
 
 	spin_lock_bh(&hwsim_radio_lock);
 	list_add_tail(&data->list, &hwsim_radios);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/pinctrl/freescale/pinctrl-mxs.c linux-libre-4.4.77-gnu/drivers/pinctrl/freescale/pinctrl-mxs.c
--- linux-libre-4.4.76-gnu/drivers/pinctrl/freescale/pinctrl-mxs.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/pinctrl/freescale/pinctrl-mxs.c	2017-07-15 05:58:03.000000000 -0400
@@ -195,6 +195,16 @@ static int mxs_pinctrl_get_func_groups(s
 	return 0;
 }
 
+static void mxs_pinctrl_rmwl(u32 value, u32 mask, u8 shift, void __iomem *reg)
+{
+	u32 tmp;
+
+	tmp = readl(reg);
+	tmp &= ~(mask << shift);
+	tmp |= value << shift;
+	writel(tmp, reg);
+}
+
 static int mxs_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
 			       unsigned group)
 {
@@ -212,8 +222,7 @@ static int mxs_pinctrl_set_mux(struct pi
 		reg += bank * 0x20 + pin / 16 * 0x10;
 		shift = pin % 16 * 2;
 
-		writel(0x3 << shift, reg + CLR);
-		writel(g->muxsel[i] << shift, reg + SET);
+		mxs_pinctrl_rmwl(g->muxsel[i], 0x3, shift, reg);
 	}
 
 	return 0;
@@ -280,8 +289,7 @@ static int mxs_pinconf_group_set(struct
 			/* mA */
 			if (config & MA_PRESENT) {
 				shift = pin % 8 * 4;
-				writel(0x3 << shift, reg + CLR);
-				writel(ma << shift, reg + SET);
+				mxs_pinctrl_rmwl(ma, 0x3, shift, reg);
 			}
 
 			/* vol */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/pinctrl/meson/pinctrl-meson8b.c linux-libre-4.4.77-gnu/drivers/pinctrl/meson/pinctrl-meson8b.c
--- linux-libre-4.4.76-gnu/drivers/pinctrl/meson/pinctrl-meson8b.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/pinctrl/meson/pinctrl-meson8b.c	2017-07-15 05:58:03.000000000 -0400
@@ -732,8 +732,8 @@ static const char * const sdxc_c_groups[
 static const char * const nand_groups[] = {
 	"nand_io", "nand_io_ce0", "nand_io_ce1",
 	"nand_io_rb0", "nand_ale", "nand_cle",
-	"nand_wen_clk", "nand_ren_clk", "nand_dqs0",
-	"nand_dqs1"
+	"nand_wen_clk", "nand_ren_clk", "nand_dqs_0",
+	"nand_dqs_1"
 };
 
 static const char * const nor_groups[] = {
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/pinctrl/sh-pfc/core.c linux-libre-4.4.77-gnu/drivers/pinctrl/sh-pfc/core.c
--- linux-libre-4.4.76-gnu/drivers/pinctrl/sh-pfc/core.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/pinctrl/sh-pfc/core.c	2017-07-15 05:58:03.000000000 -0400
@@ -543,6 +543,9 @@ static int sh_pfc_probe(struct platform_
 		ret = info->ops->init(pfc);
 		if (ret < 0)
 			return ret;
+
+		/* .init() may have overridden pfc->info */
+		info = pfc->info;
 	}
 
 	/* Enable dummy states for those platforms without pinctrl support */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7791.c linux-libre-4.4.77-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
--- linux-libre-4.4.76-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7791.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7791.c	2017-07-15 05:58:03.000000000 -0400
@@ -1102,7 +1102,7 @@ static const u16 pinmux_data[] = {
 	PINMUX_IPSR_MSEL(IP6_5_3, FMIN_E, SEL_FM_4),
 	PINMUX_IPSR_DATA(IP6_7_6, AUDIO_CLKOUT),
 	PINMUX_IPSR_MSEL(IP6_7_6, MSIOF1_SS1_B, SEL_SOF1_1),
-	PINMUX_IPSR_MSEL(IP6_5_3, TX2, SEL_SCIF2_0),
+	PINMUX_IPSR_MSEL(IP6_7_6, TX2, SEL_SCIF2_0),
 	PINMUX_IPSR_MSEL(IP6_7_6, SCIFA2_TXD, SEL_SCIFA2_0),
 	PINMUX_IPSR_DATA(IP6_9_8, IRQ0),
 	PINMUX_IPSR_MSEL(IP6_9_8, SCIFB1_RXD_D, SEL_SCIFB1_3),
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c linux-libre-4.4.77-gnu/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c
--- linux-libre-4.4.76-gnu/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c	2017-07-15 05:58:03.000000000 -0400
@@ -394,7 +394,7 @@ static const struct sunxi_desc_pin sun8i
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 18),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x3, "owa")),		/* DOUT */
+		  SUNXI_FUNCTION(0x3, "spdif")),	/* DOUT */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 19),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out")),
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/staging/comedi/comedi_fops.c linux-libre-4.4.77-gnu/drivers/staging/comedi/comedi_fops.c
--- linux-libre-4.4.76-gnu/drivers/staging/comedi/comedi_fops.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/staging/comedi/comedi_fops.c	2017-07-15 05:58:03.000000000 -0400
@@ -2911,6 +2911,7 @@ static int __init comedi_init(void)
 		dev = comedi_alloc_board_minor(NULL);
 		if (IS_ERR(dev)) {
 			comedi_cleanup_board_minors();
+			class_destroy(comedi_class);
 			cdev_del(&comedi_cdev);
 			unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
 						 COMEDI_NUM_MINORS);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/staging/vt6656/main_usb.c linux-libre-4.4.77-gnu/drivers/staging/vt6656/main_usb.c
--- linux-libre-4.4.76-gnu/drivers/staging/vt6656/main_usb.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/staging/vt6656/main_usb.c	2017-07-15 05:58:03.000000000 -0400
@@ -529,6 +529,9 @@ static int vnt_start(struct ieee80211_hw
 		goto free_all;
 	}
 
+	if (vnt_key_init_table(priv))
+		goto free_all;
+
 	priv->int_interval = 1;  /* bInterval is set to 1 */
 
 	vnt_int_start_interrupt(priv);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/core/quirks.c linux-libre-4.4.77-gnu/drivers/usb/core/quirks.c
--- linux-libre-4.4.76-gnu/drivers/usb/core/quirks.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/core/quirks.c	2017-07-15 05:58:03.000000000 -0400
@@ -223,6 +223,10 @@ static const struct usb_device_id usb_qu
 	/* Blackmagic Design UltraStudio SDI */
 	{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
 
+	/* Hauppauge HVR-950q */
+	{ USB_DEVICE(0x2040, 0x7200), .driver_info =
+			USB_QUIRK_CONFIG_INTF_STRINGS },
+
 	/* INTEL VALUE SSD */
 	{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/dwc3/dwc3-st.c linux-libre-4.4.77-gnu/drivers/usb/dwc3/dwc3-st.c
--- linux-libre-4.4.76-gnu/drivers/usb/dwc3/dwc3-st.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/dwc3/dwc3-st.c	2017-07-15 05:58:03.000000000 -0400
@@ -224,7 +224,7 @@ static int st_dwc3_probe(struct platform
 
 	dwc3_data->syscfg_reg_off = res->start;
 
-	dev_vdbg(&pdev->dev, "glue-logic addr 0x%p, syscfg-reg offset 0x%x\n",
+	dev_vdbg(&pdev->dev, "glue-logic addr 0x%pK, syscfg-reg offset 0x%x\n",
 		 dwc3_data->glue_base, dwc3_data->syscfg_reg_off);
 
 	dwc3_data->rstc_pwrdn = devm_reset_control_get(dev, "powerdown");
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/dwc3/gadget.c linux-libre-4.4.77-gnu/drivers/usb/dwc3/gadget.c
--- linux-libre-4.4.76-gnu/drivers/usb/dwc3/gadget.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/dwc3/gadget.c	2017-07-15 05:58:03.000000000 -0400
@@ -1219,7 +1219,7 @@ static int dwc3_gadget_ep_queue(struct u
 		goto out;
 	}
 
-	if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
+	if (WARN(req->dep != dep, "request %pK belongs to '%s'\n",
 				request, req->dep->name)) {
 		ret = -EINVAL;
 		goto out;
@@ -1264,7 +1264,7 @@ static int dwc3_gadget_ep_dequeue(struct
 			dwc3_stop_active_transfer(dwc, dep->number, true);
 			goto out1;
 		}
-		dev_err(dwc->dev, "request %p was not queued to %s\n",
+		dev_err(dwc->dev, "request %pK was not queued to %s\n",
 				request, ep->name);
 		ret = -EINVAL;
 		goto out0;
@@ -1866,7 +1866,7 @@ static int __dwc3_cleanup_done_trbs(stru
 		 * would help. Lets hope that if this occurs, someone
 		 * fixes the root cause instead of looking away :)
 		 */
-		dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n",
+		dev_err(dwc->dev, "%s's TRB (%pK) still owned by HW\n",
 				dep->name, trb);
 	count = trb->size & DWC3_TRB_SIZE_MASK;
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/serial/cp210x.c linux-libre-4.4.77-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-4.4.76-gnu/drivers/usb/serial/cp210x.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/serial/cp210x.c	2017-07-15 05:58:03.000000000 -0400
@@ -134,6 +134,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0x8977) },	/* CEL MeshWorks DevKit Device */
 	{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
 	{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
+	{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/serial/option.c linux-libre-4.4.77-gnu/drivers/usb/serial/option.c
--- linux-libre-4.4.76-gnu/drivers/usb/serial/option.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/serial/option.c	2017-07-15 05:58:03.000000000 -0400
@@ -1877,6 +1877,10 @@ static const struct usb_device_id option
 	  .driver_info = (kernel_ulong_t)&four_g_w100_blacklist
 	},
 	{ USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) },
+	{ USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff),
+	  .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
+	{ USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff),
+	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
 	{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/serial/qcserial.c linux-libre-4.4.77-gnu/drivers/usb/serial/qcserial.c
--- linux-libre-4.4.76-gnu/drivers/usb/serial/qcserial.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/serial/qcserial.c	2017-07-15 05:58:03.000000000 -0400
@@ -158,6 +158,7 @@ static const struct usb_device_id id_tab
 	{DEVICE_SWI(0x1199, 0x9056)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9060)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9061)},	/* Sierra Wireless Modem */
+	{DEVICE_SWI(0x1199, 0x9063)},	/* Sierra Wireless EM7305 */
 	{DEVICE_SWI(0x1199, 0x9070)},	/* Sierra Wireless MC74xx */
 	{DEVICE_SWI(0x1199, 0x9071)},	/* Sierra Wireless MC74xx */
 	{DEVICE_SWI(0x1199, 0x9078)},	/* Sierra Wireless EM74xx */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/usbip/stub_main.c linux-libre-4.4.77-gnu/drivers/usb/usbip/stub_main.c
--- linux-libre-4.4.76-gnu/drivers/usb/usbip/stub_main.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/usbip/stub_main.c	2017-07-15 05:58:03.000000000 -0400
@@ -262,7 +262,11 @@ void stub_device_cleanup_urbs(struct stu
 		kmem_cache_free(stub_priv_cache, priv);
 
 		kfree(urb->transfer_buffer);
+		urb->transfer_buffer = NULL;
+
 		kfree(urb->setup_packet);
+		urb->setup_packet = NULL;
+
 		usb_free_urb(urb);
 	}
 }
diff -druNp --no-dereference linux-libre-4.4.76-gnu/drivers/usb/usbip/stub_tx.c linux-libre-4.4.77-gnu/drivers/usb/usbip/stub_tx.c
--- linux-libre-4.4.76-gnu/drivers/usb/usbip/stub_tx.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/drivers/usb/usbip/stub_tx.c	2017-07-15 05:58:03.000000000 -0400
@@ -28,7 +28,11 @@ static void stub_free_priv_and_urb(struc
 	struct urb *urb = priv->urb;
 
 	kfree(urb->setup_packet);
+	urb->setup_packet = NULL;
+
 	kfree(urb->transfer_buffer);
+	urb->transfer_buffer = NULL;
+
 	list_del(&priv->list);
 	kmem_cache_free(stub_priv_cache, priv);
 	usb_free_urb(urb);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/fs/ext4/sysfs.c linux-libre-4.4.77-gnu/fs/ext4/sysfs.c
--- linux-libre-4.4.76-gnu/fs/ext4/sysfs.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/fs/ext4/sysfs.c	2017-07-15 05:58:03.000000000 -0400
@@ -100,7 +100,7 @@ static ssize_t reserved_clusters_store(s
 	int ret;
 
 	ret = kstrtoull(skip_spaces(buf), 0, &val);
-	if (!ret || val >= clusters)
+	if (ret || val >= clusters)
 		return -EINVAL;
 
 	atomic64_set(&sbi->s_resv_clusters, val);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/fs/fcntl.c linux-libre-4.4.77-gnu/fs/fcntl.c
--- linux-libre-4.4.76-gnu/fs/fcntl.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/fs/fcntl.c	2017-07-15 05:58:03.000000000 -0400
@@ -740,16 +740,10 @@ static int __init fcntl_init(void)
 	 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
 	 * is defined as O_NONBLOCK on some platforms and not on others.
 	 */
-	BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
-		O_RDONLY	| O_WRONLY	| O_RDWR	|
-		O_CREAT		| O_EXCL	| O_NOCTTY	|
-		O_TRUNC		| O_APPEND	| /* O_NONBLOCK	| */
-		__O_SYNC	| O_DSYNC	| FASYNC	|
-		O_DIRECT	| O_LARGEFILE	| O_DIRECTORY	|
-		O_NOFOLLOW	| O_NOATIME	| O_CLOEXEC	|
-		__FMODE_EXEC	| O_PATH	| __O_TMPFILE	|
-		__FMODE_NONOTIFY
-		));
+	BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
+		HWEIGHT32(
+			(VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
+			__FMODE_EXEC | __FMODE_NONOTIFY));
 
 	fasync_cache = kmem_cache_create("fasync_cache",
 		sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/fs/gfs2/glock.c linux-libre-4.4.77-gnu/fs/gfs2/glock.c
--- linux-libre-4.4.76-gnu/fs/gfs2/glock.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/fs/gfs2/glock.c	2017-07-15 05:58:03.000000000 -0400
@@ -80,9 +80,9 @@ static struct rhashtable_params ht_parms
 
 static struct rhashtable gl_hash_table;
 
-void gfs2_glock_free(struct gfs2_glock *gl)
+static void gfs2_glock_dealloc(struct rcu_head *rcu)
 {
-	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+	struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu);
 
 	if (gl->gl_ops->go_flags & GLOF_ASPACE) {
 		kmem_cache_free(gfs2_glock_aspace_cachep, gl);
@@ -90,6 +90,13 @@ void gfs2_glock_free(struct gfs2_glock *
 		kfree(gl->gl_lksb.sb_lvbptr);
 		kmem_cache_free(gfs2_glock_cachep, gl);
 	}
+}
+
+void gfs2_glock_free(struct gfs2_glock *gl)
+{
+	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+
+	call_rcu(&gl->gl_rcu, gfs2_glock_dealloc);
 	if (atomic_dec_and_test(&sdp->sd_glock_disposal))
 		wake_up(&sdp->sd_glock_wait);
 }
diff -druNp --no-dereference linux-libre-4.4.76-gnu/fs/gfs2/incore.h linux-libre-4.4.77-gnu/fs/gfs2/incore.h
--- linux-libre-4.4.76-gnu/fs/gfs2/incore.h	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/fs/gfs2/incore.h	2017-07-15 05:58:03.000000000 -0400
@@ -367,6 +367,7 @@ struct gfs2_glock {
 			loff_t end;
 		} gl_vm;
 	};
+	struct rcu_head gl_rcu;
 	struct rhash_head gl_node;
 };
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/fs/open.c linux-libre-4.4.77-gnu/fs/open.c
--- linux-libre-4.4.76-gnu/fs/open.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/fs/open.c	2017-07-15 05:58:03.000000000 -0400
@@ -885,6 +885,12 @@ static inline int build_open_flags(int f
 	int lookup_flags = 0;
 	int acc_mode;
 
+	/*
+	 * Clear out all open flags we don't know about so that we don't report
+	 * them in fcntl(F_GETFD) or similar interfaces.
+	 */
+	flags &= VALID_OPEN_FLAGS;
+
 	if (flags & (O_CREAT | __O_TMPFILE))
 		op->mode = (mode & S_IALLUGO) | S_IFREG;
 	else
diff -druNp --no-dereference linux-libre-4.4.76-gnu/include/linux/fcntl.h linux-libre-4.4.77-gnu/include/linux/fcntl.h
--- linux-libre-4.4.76-gnu/include/linux/fcntl.h	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/include/linux/fcntl.h	2017-07-15 05:58:03.000000000 -0400
@@ -3,6 +3,12 @@
 
 #include <uapi/linux/fcntl.h>
 
+/* list of all valid flags for the open/openat flags argument: */
+#define VALID_OPEN_FLAGS \
+	(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \
+	 O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \
+	 FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
+	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
 
 #ifndef force_o_largefile
 #define force_o_largefile() (BITS_PER_LONG != 32)
diff -druNp --no-dereference linux-libre-4.4.76-gnu/include/linux/usb/hcd.h linux-libre-4.4.77-gnu/include/linux/usb/hcd.h
--- linux-libre-4.4.76-gnu/include/linux/usb/hcd.h	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/include/linux/usb/hcd.h	2017-07-15 05:58:03.000000000 -0400
@@ -560,9 +560,9 @@ extern void usb_ep0_reinit(struct usb_de
 	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
 
 #define EndpointRequest \
-	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
 #define EndpointOutRequest \
-	((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
+	((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
 
 /* class requests from the USB 2.0 hub spec, table 11-15 */
 /* GetBusState and SetHubDescriptor are optional, omitted */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/ipc/mqueue.c linux-libre-4.4.77-gnu/ipc/mqueue.c
--- linux-libre-4.4.76-gnu/ipc/mqueue.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/ipc/mqueue.c	2017-07-15 05:58:03.000000000 -0400
@@ -1251,8 +1251,10 @@ retry:
 
 			timeo = MAX_SCHEDULE_TIMEOUT;
 			ret = netlink_attachskb(sock, nc, &timeo, NULL);
-			if (ret == 1)
+			if (ret == 1) {
+				sock = NULL;
 				goto retry;
+			}
 			if (ret) {
 				sock = NULL;
 				nc = NULL;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/kernel/sysctl.c linux-libre-4.4.77-gnu/kernel/sysctl.c
--- linux-libre-4.4.76-gnu/kernel/sysctl.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/kernel/sysctl.c	2017-07-15 05:58:03.000000000 -0400
@@ -2067,9 +2067,12 @@ static int do_proc_douintvec_conv(bool *
 	if (write) {
 		if (*negp)
 			return -EINVAL;
+		if (*lvalp > UINT_MAX)
+			return -EINVAL;
 		*valp = *lvalp;
 	} else {
 		unsigned int val = *valp;
+		*negp = false;
 		*lvalp = (unsigned long)val;
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/kernel/trace/trace_kprobe.c linux-libre-4.4.77-gnu/kernel/trace/trace_kprobe.c
--- linux-libre-4.4.76-gnu/kernel/trace/trace_kprobe.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/kernel/trace/trace_kprobe.c	2017-07-15 05:58:03.000000000 -0400
@@ -659,30 +659,25 @@ static int create_trace_kprobe(int argc,
 		pr_info("Probe point is not specified.\n");
 		return -EINVAL;
 	}
-	if (isdigit(argv[1][0])) {
-		if (is_return) {
-			pr_info("Return probe point must be a symbol.\n");
-			return -EINVAL;
-		}
-		/* an address specified */
-		ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr);
-		if (ret) {
-			pr_info("Failed to parse address.\n");
-			return ret;
-		}
-	} else {
+
+	/* try to parse an address. if that fails, try to read the
+	 * input as a symbol. */
+	if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) {
 		/* a symbol specified */
 		symbol = argv[1];
 		/* TODO: support .init module functions */
 		ret = traceprobe_split_symbol_offset(symbol, &offset);
 		if (ret) {
-			pr_info("Failed to parse symbol.\n");
+			pr_info("Failed to parse either an address or a symbol.\n");
 			return ret;
 		}
 		if (offset && is_return) {
 			pr_info("Return probe must be used without offset.\n");
 			return -EINVAL;
 		}
+	} else if (is_return) {
+		pr_info("Return probe point must be a symbol.\n");
+		return -EINVAL;
 	}
 	argc -= 2; argv += 2;
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/Makefile linux-libre-4.4.77-gnu/Makefile
--- linux-libre-4.4.76-gnu/Makefile	2017-07-05 12:42:25.000000000 -0400
+++ linux-libre-4.4.77-gnu/Makefile	2017-07-15 13:22:20.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 76
+SUBLEVEL = 77
 EXTRAVERSION = -gnu
 NAME = Blurry Fish Butt
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/mm/vmscan.c linux-libre-4.4.77-gnu/mm/vmscan.c
--- linux-libre-4.4.76-gnu/mm/vmscan.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/mm/vmscan.c	2017-07-15 05:58:03.000000000 -0400
@@ -2529,7 +2529,7 @@ static bool shrink_zones(struct zonelist
 		if (!populated_zone(zone))
 			continue;
 
-		classzone_idx = requested_highidx;
+		classzone_idx = gfp_zone(sc->gfp_mask);
 		while (!populated_zone(zone->zone_pgdat->node_zones +
 							classzone_idx))
 			classzone_idx--;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/net/ipv4/tcp_input.c linux-libre-4.4.77-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.4.76-gnu/net/ipv4/tcp_input.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/net/ipv4/tcp_input.c	2017-07-15 05:58:03.000000000 -0400
@@ -2165,8 +2165,7 @@ static void tcp_mark_head_lost(struct so
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
-	int cnt, oldcnt;
-	int err;
+	int cnt, oldcnt, lost;
 	unsigned int mss;
 	/* Use SACK to deduce losses of new sequences sent during recovery */
 	const u32 loss_high = tcp_is_sack(tp) ?  tp->snd_nxt : tp->high_seq;
@@ -2206,9 +2205,10 @@ static void tcp_mark_head_lost(struct so
 				break;
 
 			mss = tcp_skb_mss(skb);
-			err = tcp_fragment(sk, skb, (packets - oldcnt) * mss,
-					   mss, GFP_ATOMIC);
-			if (err < 0)
+			/* If needed, chop off the prefix to mark as lost. */
+			lost = (packets - oldcnt) * mss;
+			if (lost < skb->len &&
+			    tcp_fragment(sk, skb, lost, mss, GFP_ATOMIC) < 0)
 				break;
 			cnt = packets;
 		}
diff -druNp --no-dereference linux-libre-4.4.76-gnu/security/keys/encrypted-keys/encrypted.c linux-libre-4.4.77-gnu/security/keys/encrypted-keys/encrypted.c
--- linux-libre-4.4.76-gnu/security/keys/encrypted-keys/encrypted.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/security/keys/encrypted-keys/encrypted.c	2017-07-15 05:58:03.000000000 -0400
@@ -428,7 +428,7 @@ static int init_blkcipher_desc(struct bl
 static struct key *request_master_key(struct encrypted_key_payload *epayload,
 				      const u8 **master_key, size_t *master_keylen)
 {
-	struct key *mkey = NULL;
+	struct key *mkey = ERR_PTR(-EINVAL);
 
 	if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX,
 		     KEY_TRUSTED_PREFIX_LEN)) {
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/include/linux/compiler.h linux-libre-4.4.77-gnu/tools/include/linux/compiler.h
--- linux-libre-4.4.76-gnu/tools/include/linux/compiler.h	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/include/linux/compiler.h	2017-07-15 05:58:03.000000000 -0400
@@ -115,4 +115,13 @@ static __always_inline void __write_once
 #define WRITE_ONCE(x, val) \
 	({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
 
+
+#ifndef __fallthrough
+# if defined(__GNUC__) && __GNUC__ >= 7
+#  define __fallthrough __attribute__ ((fallthrough))
+# else
+#  define __fallthrough
+# endif
+#endif
+
 #endif /* _TOOLS_LINUX_COMPILER_H */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/arch/x86/tests/intel-cqm.c linux-libre-4.4.77-gnu/tools/perf/arch/x86/tests/intel-cqm.c
--- linux-libre-4.4.76-gnu/tools/perf/arch/x86/tests/intel-cqm.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/arch/x86/tests/intel-cqm.c	2017-07-15 05:58:03.000000000 -0400
@@ -17,7 +17,7 @@ static pid_t spawn(void)
 	if (pid)
 		return pid;
 
-	while(1);
+	while(1)
 		sleep(5);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/arch/x86/util/dwarf-regs.c linux-libre-4.4.77-gnu/tools/perf/arch/x86/util/dwarf-regs.c
--- linux-libre-4.4.76-gnu/tools/perf/arch/x86/util/dwarf-regs.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/arch/x86/util/dwarf-regs.c	2017-07-15 05:58:03.000000000 -0400
@@ -63,6 +63,8 @@ struct pt_regs_offset {
 # define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)}
 #endif
 
+/* TODO: switching by dwarf address size */
+#ifndef __x86_64__
 static const struct pt_regs_offset x86_32_regoffset_table[] = {
 	REG_OFFSET_NAME_32("%ax",	eax),
 	REG_OFFSET_NAME_32("%cx",	ecx),
@@ -75,6 +77,8 @@ static const struct pt_regs_offset x86_3
 	REG_OFFSET_END,
 };
 
+#define regoffset_table x86_32_regoffset_table
+#else
 static const struct pt_regs_offset x86_64_regoffset_table[] = {
 	REG_OFFSET_NAME_64("%ax",	rax),
 	REG_OFFSET_NAME_64("%dx",	rdx),
@@ -95,11 +99,7 @@ static const struct pt_regs_offset x86_6
 	REG_OFFSET_END,
 };
 
-/* TODO: switching by dwarf address size */
-#ifdef __x86_64__
 #define regoffset_table x86_64_regoffset_table
-#else
-#define regoffset_table x86_32_regoffset_table
 #endif
 
 /* Minus 1 for the ending REG_OFFSET_END */
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/bench/numa.c linux-libre-4.4.77-gnu/tools/perf/bench/numa.c
--- linux-libre-4.4.76-gnu/tools/perf/bench/numa.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/bench/numa.c	2017-07-15 05:58:03.000000000 -0400
@@ -1570,13 +1570,13 @@ static int __bench_numa(const char *name
 		"GB/sec,", "total-speed",	"GB/sec total speed");
 
 	if (g->p.show_details >= 2) {
-		char tname[32];
+		char tname[14 + 2 * 10 + 1];
 		struct thread_data *td;
 		for (p = 0; p < g->p.nr_proc; p++) {
 			for (t = 0; t < g->p.nr_threads; t++) {
-				memset(tname, 0, 32);
+				memset(tname, 0, sizeof(tname));
 				td = g->threads + p*g->p.nr_threads + t;
-				snprintf(tname, 32, "process%d:thread%d", p, t);
+				snprintf(tname, sizeof(tname), "process%d:thread%d", p, t);
 				print_res(tname, td->speed_gbs,
 					"GB/sec",	"thread-speed", "GB/sec/thread speed");
 				print_res(tname, td->system_time_ns / 1e9,
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/builtin-script.c linux-libre-4.4.77-gnu/tools/perf/builtin-script.c
--- linux-libre-4.4.76-gnu/tools/perf/builtin-script.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/builtin-script.c	2017-07-15 05:58:03.000000000 -0400
@@ -1252,21 +1252,19 @@ static int is_directory(const char *base
 	return S_ISDIR(st.st_mode);
 }
 
-#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
-	while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) &&	\
-	       lang_next)						\
-		if ((lang_dirent.d_type == DT_DIR ||			\
-		     (lang_dirent.d_type == DT_UNKNOWN &&		\
-		      is_directory(scripts_path, &lang_dirent))) &&	\
-		    (strcmp(lang_dirent.d_name, ".")) &&		\
-		    (strcmp(lang_dirent.d_name, "..")))
+#define for_each_lang(scripts_path, scripts_dir, lang_dirent)		\
+	while ((lang_dirent = readdir(scripts_dir)) != NULL)		\
+		if ((lang_dirent->d_type == DT_DIR ||			\
+		     (lang_dirent->d_type == DT_UNKNOWN &&		\
+		      is_directory(scripts_path, lang_dirent))) &&	\
+		    (strcmp(lang_dirent->d_name, ".")) &&		\
+		    (strcmp(lang_dirent->d_name, "..")))
 
-#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
-	while (!readdir_r(lang_dir, &script_dirent, &script_next) &&	\
-	       script_next)						\
-		if (script_dirent.d_type != DT_DIR &&			\
-		    (script_dirent.d_type != DT_UNKNOWN ||		\
-		     !is_directory(lang_path, &script_dirent)))
+#define for_each_script(lang_path, lang_dir, script_dirent)		\
+	while ((script_dirent = readdir(lang_dir)) != NULL)		\
+		if (script_dirent->d_type != DT_DIR &&			\
+		    (script_dirent->d_type != DT_UNKNOWN ||		\
+		     !is_directory(lang_path, script_dirent)))
 
 
 #define RECORD_SUFFIX			"-record"
@@ -1412,7 +1410,7 @@ static int list_available_scripts(const
 				  const char *s __maybe_unused,
 				  int unset __maybe_unused)
 {
-	struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
+	struct dirent *script_dirent, *lang_dirent;
 	char scripts_path[MAXPATHLEN];
 	DIR *scripts_dir, *lang_dir;
 	char script_path[MAXPATHLEN];
@@ -1427,19 +1425,19 @@ static int list_available_scripts(const
 	if (!scripts_dir)
 		return -1;
 
-	for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
+	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
 		snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
-			 lang_dirent.d_name);
+			 lang_dirent->d_name);
 		lang_dir = opendir(lang_path);
 		if (!lang_dir)
 			continue;
 
-		for_each_script(lang_path, lang_dir, script_dirent, script_next) {
-			script_root = get_script_root(&script_dirent, REPORT_SUFFIX);
+		for_each_script(lang_path, lang_dir, script_dirent) {
+			script_root = get_script_root(script_dirent, REPORT_SUFFIX);
 			if (script_root) {
 				desc = script_desc__findnew(script_root);
 				snprintf(script_path, MAXPATHLEN, "%s/%s",
-					 lang_path, script_dirent.d_name);
+					 lang_path, script_dirent->d_name);
 				read_script_info(desc, script_path);
 				free(script_root);
 			}
@@ -1527,7 +1525,7 @@ static int check_ev_match(char *dir_name
  */
 int find_scripts(char **scripts_array, char **scripts_path_array)
 {
-	struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
+	struct dirent *script_dirent, *lang_dirent;
 	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
 	DIR *scripts_dir, *lang_dir;
 	struct perf_session *session;
@@ -1550,9 +1548,9 @@ int find_scripts(char **scripts_array, c
 		return -1;
 	}
 
-	for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
+	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
 		snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
-			 lang_dirent.d_name);
+			 lang_dirent->d_name);
 #ifdef NO_LIBPERL
 		if (strstr(lang_path, "perl"))
 			continue;
@@ -1566,16 +1564,16 @@ int find_scripts(char **scripts_array, c
 		if (!lang_dir)
 			continue;
 
-		for_each_script(lang_path, lang_dir, script_dirent, script_next) {
+		for_each_script(lang_path, lang_dir, script_dirent) {
 			/* Skip those real time scripts: xxxtop.p[yl] */
-			if (strstr(script_dirent.d_name, "top."))
+			if (strstr(script_dirent->d_name, "top."))
 				continue;
 			sprintf(scripts_path_array[i], "%s/%s", lang_path,
-				script_dirent.d_name);
-			temp = strchr(script_dirent.d_name, '.');
+				script_dirent->d_name);
+			temp = strchr(script_dirent->d_name, '.');
 			snprintf(scripts_array[i],
-				(temp - script_dirent.d_name) + 1,
-				"%s", script_dirent.d_name);
+				(temp - script_dirent->d_name) + 1,
+				"%s", script_dirent->d_name);
 
 			if (check_ev_match(lang_path,
 					scripts_array[i], session))
@@ -1593,7 +1591,7 @@ int find_scripts(char **scripts_array, c
 
 static char *get_script_path(const char *script_root, const char *suffix)
 {
-	struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
+	struct dirent *script_dirent, *lang_dirent;
 	char scripts_path[MAXPATHLEN];
 	char script_path[MAXPATHLEN];
 	DIR *scripts_dir, *lang_dir;
@@ -1606,21 +1604,21 @@ static char *get_script_path(const char
 	if (!scripts_dir)
 		return NULL;
 
-	for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
+	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
 		snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
-			 lang_dirent.d_name);
+			 lang_dirent->d_name);
 		lang_dir = opendir(lang_path);
 		if (!lang_dir)
 			continue;
 
-		for_each_script(lang_path, lang_dir, script_dirent, script_next) {
-			__script_root = get_script_root(&script_dirent, suffix);
+		for_each_script(lang_path, lang_dir, script_dirent) {
+			__script_root = get_script_root(script_dirent, suffix);
 			if (__script_root && !strcmp(script_root, __script_root)) {
 				free(__script_root);
 				closedir(lang_dir);
 				closedir(scripts_dir);
 				snprintf(script_path, MAXPATHLEN, "%s/%s",
-					 lang_path, script_dirent.d_name);
+					 lang_path, script_dirent->d_name);
 				return strdup(script_path);
 			}
 			free(__script_root);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/builtin-top.c linux-libre-4.4.77-gnu/tools/perf/builtin-top.c
--- linux-libre-4.4.76-gnu/tools/perf/builtin-top.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/builtin-top.c	2017-07-15 05:58:03.000000000 -0400
@@ -636,7 +636,7 @@ repeat:
 		case -1:
 			if (errno == EINTR)
 				continue;
-			/* Fall trhu */
+			__fallthrough;
 		default:
 			c = getc(stdin);
 			tcsetattr(0, TCSAFLUSH, &save);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/builtin-trace.c linux-libre-4.4.77-gnu/tools/perf/builtin-trace.c
--- linux-libre-4.4.76-gnu/tools/perf/builtin-trace.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/builtin-trace.c	2017-07-15 05:58:03.000000000 -0400
@@ -1617,6 +1617,7 @@ static int trace__process_event(struct t
 		color_fprintf(trace->output, PERF_COLOR_RED,
 			      "LOST %" PRIu64 " events!\n", event->lost.lost);
 		ret = machine__process_lost_event(machine, event, sample);
+		break;
 	default:
 		ret = machine__process_event(machine, event, sample);
 		break;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/tests/parse-events.c linux-libre-4.4.77-gnu/tools/perf/tests/parse-events.c
--- linux-libre-4.4.76-gnu/tools/perf/tests/parse-events.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/tests/parse-events.c	2017-07-15 05:58:03.000000000 -0400
@@ -1727,15 +1727,14 @@ static int test_pmu_events(void)
 	}
 
 	while (!ret && (ent = readdir(dir))) {
-#define MAX_NAME 100
 		struct evlist_test e;
-		char name[MAX_NAME];
+		char name[2 * NAME_MAX + 1 + 12 + 3];
 
 		if (!strcmp(ent->d_name, ".") ||
 		    !strcmp(ent->d_name, ".."))
 			continue;
 
-		snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name);
+		snprintf(name, sizeof(name), "cpu/event=%s/u", ent->d_name);
 
 		e.name  = name;
 		e.check = test__checkevent_pmu_events;
@@ -1743,11 +1742,10 @@ static int test_pmu_events(void)
 		ret = test_event(&e);
 		if (ret)
 			break;
-		snprintf(name, MAX_NAME, "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name);
+		snprintf(name, sizeof(name), "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name);
 		e.name  = name;
 		e.check = test__checkevent_pmu_events_mix;
 		ret = test_event(&e);
-#undef MAX_NAME
 	}
 
 	closedir(dir);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/ui/browsers/annotate.c linux-libre-4.4.77-gnu/tools/perf/ui/browsers/annotate.c
--- linux-libre-4.4.76-gnu/tools/perf/ui/browsers/annotate.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/ui/browsers/annotate.c	2017-07-15 05:58:03.000000000 -0400
@@ -755,11 +755,11 @@ static int annotate_browser__run(struct
 				nd = browser->curr_hot;
 			break;
 		case K_UNTAB:
-			if (nd != NULL)
+			if (nd != NULL) {
 				nd = rb_next(nd);
 				if (nd == NULL)
 					nd = rb_first(&browser->entries);
-			else
+			} else
 				nd = browser->curr_hot;
 			break;
 		case K_F1:
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/event.c linux-libre-4.4.77-gnu/tools/perf/util/event.c
--- linux-libre-4.4.76-gnu/tools/perf/util/event.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/event.c	2017-07-15 05:58:03.000000000 -0400
@@ -416,7 +416,7 @@ static int __event__synthesize_thread(un
 {
 	char filename[PATH_MAX];
 	DIR *tasks;
-	struct dirent dirent, *next;
+	struct dirent *dirent;
 	pid_t tgid, ppid;
 	int rc = 0;
 
@@ -445,11 +445,11 @@ static int __event__synthesize_thread(un
 		return 0;
 	}
 
-	while (!readdir_r(tasks, &dirent, &next) && next) {
+	while ((dirent = readdir(tasks)) != NULL) {
 		char *end;
 		pid_t _pid;
 
-		_pid = strtol(dirent.d_name, &end, 10);
+		_pid = strtol(dirent->d_name, &end, 10);
 		if (*end)
 			continue;
 
@@ -558,7 +558,7 @@ int perf_event__synthesize_threads(struc
 {
 	DIR *proc;
 	char proc_path[PATH_MAX];
-	struct dirent dirent, *next;
+	struct dirent *dirent;
 	union perf_event *comm_event, *mmap_event, *fork_event;
 	int err = -1;
 
@@ -583,9 +583,9 @@ int perf_event__synthesize_threads(struc
 	if (proc == NULL)
 		goto out_free_fork;
 
-	while (!readdir_r(proc, &dirent, &next) && next) {
+	while ((dirent = readdir(proc)) != NULL) {
 		char *end;
-		pid_t pid = strtol(dirent.d_name, &end, 10);
+		pid_t pid = strtol(dirent->d_name, &end, 10);
 
 		if (*end) /* only interested in proper numerical dirents */
 			continue;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c linux-libre-4.4.77-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
--- linux-libre-4.4.76-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c	2017-07-15 05:58:03.000000000 -0400
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <stdint.h>
 #include <inttypes.h>
+#include <linux/compiler.h>
 
 #include "../cache.h"
 #include "../util.h"
@@ -1708,6 +1709,7 @@ static int intel_pt_walk_psb(struct inte
 		switch (decoder->packet.type) {
 		case INTEL_PT_TIP_PGD:
 			decoder->continuous_period = false;
+			__fallthrough;
 		case INTEL_PT_TIP_PGE:
 		case INTEL_PT_TIP:
 			intel_pt_log("ERROR: Unexpected packet\n");
@@ -1762,6 +1764,8 @@ static int intel_pt_walk_psb(struct inte
 			decoder->pge = false;
 			decoder->continuous_period = false;
 			intel_pt_clear_tx_flags(decoder);
+			__fallthrough;
+
 		case INTEL_PT_TNT:
 			decoder->have_tma = false;
 			intel_pt_log("ERROR: Unexpected packet\n");
@@ -1802,6 +1806,7 @@ static int intel_pt_walk_to_ip(struct in
 		switch (decoder->packet.type) {
 		case INTEL_PT_TIP_PGD:
 			decoder->continuous_period = false;
+			__fallthrough;
 		case INTEL_PT_TIP_PGE:
 		case INTEL_PT_TIP:
 			decoder->pge = decoder->packet.type != INTEL_PT_TIP_PGD;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c linux-libre-4.4.77-gnu/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
--- linux-libre-4.4.76-gnu/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c	2017-07-15 05:58:03.000000000 -0400
@@ -17,6 +17,7 @@
 #include <string.h>
 #include <endian.h>
 #include <byteswap.h>
+#include <linux/compiler.h>
 
 #include "intel-pt-pkt-decoder.h"
 
@@ -488,6 +489,7 @@ int intel_pt_pkt_desc(const struct intel
 	case INTEL_PT_FUP:
 		if (!(packet->count))
 			return snprintf(buf, buf_len, "%s no ip", name);
+		__fallthrough;
 	case INTEL_PT_CYC:
 	case INTEL_PT_VMCS:
 	case INTEL_PT_MTC:
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/parse-events.c linux-libre-4.4.77-gnu/tools/perf/util/parse-events.c
--- linux-libre-4.4.76-gnu/tools/perf/util/parse-events.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/parse-events.c	2017-07-15 05:58:03.000000000 -0400
@@ -138,11 +138,11 @@ struct event_symbol event_symbols_sw[PER
 #define PERF_EVENT_TYPE(config)		__PERF_EVENT_FIELD(config, TYPE)
 #define PERF_EVENT_ID(config)		__PERF_EVENT_FIELD(config, EVENT)
 
-#define for_each_subsystem(sys_dir, sys_dirent, sys_next)	       \
-	while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)	       \
-	if (sys_dirent.d_type == DT_DIR &&				       \
-	   (strcmp(sys_dirent.d_name, ".")) &&				       \
-	   (strcmp(sys_dirent.d_name, "..")))
+#define for_each_subsystem(sys_dir, sys_dirent)			\
+	while ((sys_dirent = readdir(sys_dir)) != NULL)		\
+		if (sys_dirent->d_type == DT_DIR &&		\
+		    (strcmp(sys_dirent->d_name, ".")) &&	\
+		    (strcmp(sys_dirent->d_name, "..")))
 
 static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
 {
@@ -159,12 +159,12 @@ static int tp_event_has_id(struct dirent
 	return 0;
 }
 
-#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next)	       \
-	while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
-	if (evt_dirent.d_type == DT_DIR &&				       \
-	   (strcmp(evt_dirent.d_name, ".")) &&				       \
-	   (strcmp(evt_dirent.d_name, "..")) &&				       \
-	   (!tp_event_has_id(&sys_dirent, &evt_dirent)))
+#define for_each_event(sys_dirent, evt_dir, evt_dirent)		\
+	while ((evt_dirent = readdir(evt_dir)) != NULL)		\
+		if (evt_dirent->d_type == DT_DIR &&		\
+		    (strcmp(evt_dirent->d_name, ".")) &&	\
+		    (strcmp(evt_dirent->d_name, "..")) &&	\
+		    (!tp_event_has_id(sys_dirent, evt_dirent)))
 
 #define MAX_EVENT_LENGTH 512
 
@@ -173,7 +173,7 @@ struct tracepoint_path *tracepoint_id_to
 {
 	struct tracepoint_path *path = NULL;
 	DIR *sys_dir, *evt_dir;
-	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
+	struct dirent *sys_dirent, *evt_dirent;
 	char id_buf[24];
 	int fd;
 	u64 id;
@@ -184,18 +184,18 @@ struct tracepoint_path *tracepoint_id_to
 	if (!sys_dir)
 		return NULL;
 
-	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+	for_each_subsystem(sys_dir, sys_dirent) {
 
 		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
-			 sys_dirent.d_name);
+			 sys_dirent->d_name);
 		evt_dir = opendir(dir_path);
 		if (!evt_dir)
 			continue;
 
-		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+		for_each_event(sys_dirent, evt_dir, evt_dirent) {
 
 			snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
-				 evt_dirent.d_name);
+				 evt_dirent->d_name);
 			fd = open(evt_path, O_RDONLY);
 			if (fd < 0)
 				continue;
@@ -220,9 +220,9 @@ struct tracepoint_path *tracepoint_id_to
 					free(path);
 					return NULL;
 				}
-				strncpy(path->system, sys_dirent.d_name,
+				strncpy(path->system, sys_dirent->d_name,
 					MAX_EVENT_LENGTH);
-				strncpy(path->name, evt_dirent.d_name,
+				strncpy(path->name, evt_dirent->d_name,
 					MAX_EVENT_LENGTH);
 				return path;
 			}
@@ -1629,7 +1629,7 @@ void print_tracepoint_events(const char
 			     bool name_only)
 {
 	DIR *sys_dir, *evt_dir;
-	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
+	struct dirent *sys_dirent, *evt_dirent;
 	char evt_path[MAXPATHLEN];
 	char dir_path[MAXPATHLEN];
 	char **evt_list = NULL;
@@ -1647,20 +1647,20 @@ restart:
 			goto out_close_sys_dir;
 	}
 
-	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+	for_each_subsystem(sys_dir, sys_dirent) {
 		if (subsys_glob != NULL &&
-		    !strglobmatch(sys_dirent.d_name, subsys_glob))
+		    !strglobmatch(sys_dirent->d_name, subsys_glob))
 			continue;
 
 		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
-			 sys_dirent.d_name);
+			 sys_dirent->d_name);
 		evt_dir = opendir(dir_path);
 		if (!evt_dir)
 			continue;
 
-		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+		for_each_event(sys_dirent, evt_dir, evt_dirent) {
 			if (event_glob != NULL &&
-			    !strglobmatch(evt_dirent.d_name, event_glob))
+			    !strglobmatch(evt_dirent->d_name, event_glob))
 				continue;
 
 			if (!evt_num_known) {
@@ -1669,7 +1669,7 @@ restart:
 			}
 
 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
-				 sys_dirent.d_name, evt_dirent.d_name);
+				 sys_dirent->d_name, evt_dirent->d_name);
 
 			evt_list[evt_i] = strdup(evt_path);
 			if (evt_list[evt_i] == NULL)
@@ -1722,7 +1722,7 @@ out_close_sys_dir:
 int is_valid_tracepoint(const char *event_string)
 {
 	DIR *sys_dir, *evt_dir;
-	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
+	struct dirent *sys_dirent, *evt_dirent;
 	char evt_path[MAXPATHLEN];
 	char dir_path[MAXPATHLEN];
 
@@ -1730,17 +1730,17 @@ int is_valid_tracepoint(const char *even
 	if (!sys_dir)
 		return 0;
 
-	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+	for_each_subsystem(sys_dir, sys_dirent) {
 
 		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
-			 sys_dirent.d_name);
+			 sys_dirent->d_name);
 		evt_dir = opendir(dir_path);
 		if (!evt_dir)
 			continue;
 
-		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+		for_each_event(sys_dirent, evt_dir, evt_dirent) {
 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
-				 sys_dirent.d_name, evt_dirent.d_name);
+				 sys_dirent->d_name, evt_dirent->d_name);
 			if (!strcmp(evt_path, event_string)) {
 				closedir(evt_dir);
 				closedir(sys_dir);
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/pmu.c linux-libre-4.4.77-gnu/tools/perf/util/pmu.c
--- linux-libre-4.4.76-gnu/tools/perf/util/pmu.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/pmu.c	2017-07-15 05:58:03.000000000 -0400
@@ -153,7 +153,7 @@ static int perf_pmu__parse_unit(struct p
 	if (fd == -1)
 		return -1;
 
-		sret = read(fd, alias->unit, UNIT_MAX_LEN);
+	sret = read(fd, alias->unit, UNIT_MAX_LEN);
 	if (sret < 0)
 		goto error;
 
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/scripting-engines/Build linux-libre-4.4.77-gnu/tools/perf/util/scripting-engines/Build
--- linux-libre-4.4.76-gnu/tools/perf/util/scripting-engines/Build	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/scripting-engines/Build	2017-07-15 05:58:03.000000000 -0400
@@ -1,6 +1,6 @@
 libperf-$(CONFIG_LIBPERL)   += trace-event-perl.o
 libperf-$(CONFIG_LIBPYTHON) += trace-event-python.o
 
-CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default
+CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-nested-externs -Wno-undef -Wno-switch-default
 
 CFLAGS_trace-event-python.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/strfilter.c linux-libre-4.4.77-gnu/tools/perf/util/strfilter.c
--- linux-libre-4.4.76-gnu/tools/perf/util/strfilter.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/strfilter.c	2017-07-15 05:58:03.000000000 -0400
@@ -269,6 +269,7 @@ static int strfilter_node__sprint(struct
 		len = strfilter_node__sprint_pt(node->l, buf);
 		if (len < 0)
 			return len;
+		__fallthrough;
 	case '!':
 		if (buf) {
 			*(buf + len++) = *node->p;
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/string.c linux-libre-4.4.77-gnu/tools/perf/util/string.c
--- linux-libre-4.4.76-gnu/tools/perf/util/string.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/string.c	2017-07-15 05:58:03.000000000 -0400
@@ -21,6 +21,8 @@ s64 perf_atoll(const char *str)
 		case 'b': case 'B':
 			if (*p)
 				goto out_err;
+
+			__fallthrough;
 		case '\0':
 			return length;
 		default:
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/thread.c linux-libre-4.4.77-gnu/tools/perf/util/thread.c
--- linux-libre-4.4.76-gnu/tools/perf/util/thread.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/thread.c	2017-07-15 05:58:03.000000000 -0400
@@ -227,7 +227,7 @@ void thread__find_cpumode_addr_location(
 					struct addr_location *al)
 {
 	size_t i;
-	const u8 const cpumodes[] = {
+	const u8 cpumodes[] = {
 		PERF_RECORD_MISC_USER,
 		PERF_RECORD_MISC_KERNEL,
 		PERF_RECORD_MISC_GUEST_USER,
diff -druNp --no-dereference linux-libre-4.4.76-gnu/tools/perf/util/thread_map.c linux-libre-4.4.77-gnu/tools/perf/util/thread_map.c
--- linux-libre-4.4.76-gnu/tools/perf/util/thread_map.c	2017-07-05 08:39:21.000000000 -0400
+++ linux-libre-4.4.77-gnu/tools/perf/util/thread_map.c	2017-07-15 05:58:03.000000000 -0400
@@ -92,8 +92,8 @@ struct thread_map *thread_map__new_by_ui
 {
 	DIR *proc;
 	int max_threads = 32, items, i;
-	char path[256];
-	struct dirent dirent, *next, **namelist = NULL;
+	char path[NAME_MAX + 1 + 6];
+	struct dirent *dirent, **namelist = NULL;
 	struct thread_map *threads = thread_map__alloc(max_threads);
 
 	if (threads == NULL)
@@ -106,16 +106,16 @@ struct thread_map *thread_map__new_by_ui
 	threads->nr = 0;
 	atomic_set(&threads->refcnt, 1);
 
-	while (!readdir_r(proc, &dirent, &next) && next) {
+	while ((dirent = readdir(proc)) != NULL) {
 		char *end;
 		bool grow = false;
 		struct stat st;
-		pid_t pid = strtol(dirent.d_name, &end, 10);
+		pid_t pid = strtol(dirent->d_name, &end, 10);
 
 		if (*end) /* only interested in proper numerical dirents */
 			continue;
 
-		snprintf(path, sizeof(path), "/proc/%s", dirent.d_name);
+		snprintf(path, sizeof(path), "/proc/%s", dirent->d_name);
 
 		if (stat(path, &st) != 0)
 			continue;
