diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm/include/asm/assembler.h linux-libre-4.4.106-gnu/arch/arm/include/asm/assembler.h
--- linux-libre-4.4.105-gnu/arch/arm/include/asm/assembler.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm/include/asm/assembler.h	2017-12-16 04:33:57.000000000 -0500
@@ -512,4 +512,22 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 #endif
 	.endm
 
+	.macro	bug, msg, line
+#ifdef CONFIG_THUMB2_KERNEL
+1:	.inst	0xde02
+#else
+1:	.inst	0xe7f001f2
+#endif
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+	.pushsection .rodata.str, "aMS", %progbits, 1
+2:	.asciz	"\msg"
+	.popsection
+	.pushsection __bug_table, "aw"
+	.align	2
+	.word	1b, 2b
+	.hword	\line
+	.popsection
+#endif
+	.endm
+
 #endif /* __ASM_ASSEMBLER_H__ */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm/include/asm/kvm_arm.h linux-libre-4.4.106-gnu/arch/arm/include/asm/kvm_arm.h
--- linux-libre-4.4.105-gnu/arch/arm/include/asm/kvm_arm.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm/include/asm/kvm_arm.h	2017-12-16 04:33:57.000000000 -0500
@@ -161,8 +161,7 @@
 #else
 #define VTTBR_X		(5 - KVM_T0SZ)
 #endif
-#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
-#define VTTBR_BADDR_MASK  (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_BADDR_MASK  (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_X)
 #define VTTBR_VMID_SHIFT  (48LLU)
 #define VTTBR_VMID_MASK	  (0xffLLU << VTTBR_VMID_SHIFT)
 
@@ -209,6 +208,7 @@
 #define HSR_EC_IABT_HYP	(0x21)
 #define HSR_EC_DABT	(0x24)
 #define HSR_EC_DABT_HYP	(0x25)
+#define HSR_EC_MAX	(0x3f)
 
 #define HSR_WFI_IS_WFE		(1U << 0)
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm/kernel/entry-header.S linux-libre-4.4.106-gnu/arch/arm/kernel/entry-header.S
--- linux-libre-4.4.105-gnu/arch/arm/kernel/entry-header.S	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm/kernel/entry-header.S	2017-12-16 04:33:57.000000000 -0500
@@ -295,6 +295,8 @@
 	mov	r2, sp
 	ldr	r1, [r2, #\offset + S_PSR]	@ get calling cpsr
 	ldr	lr, [r2, #\offset + S_PC]!	@ get pc
+	tst	r1, #PSR_I_BIT | 0x0f
+	bne	1f
 	msr	spsr_cxsf, r1			@ save in spsr_svc
 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
 	@ We must avoid clrex due to Cortex-A15 erratum #830321
@@ -309,6 +311,7 @@
 						@ after ldm {}^
 	add	sp, sp, #\offset + S_FRAME_SIZE
 	movs	pc, lr				@ return & move spsr_svc into cpsr
+1:	bug	"Returning to usermode but unexpected PSR bits set?", \@
 #elif defined(CONFIG_CPU_V7M)
 	@ V7M restore.
 	@ Note that we don't need to do clrex here as clearing the local
@@ -324,6 +327,8 @@
 	ldr	r1, [sp, #\offset + S_PSR]	@ get calling cpsr
 	ldr	lr, [sp, #\offset + S_PC]	@ get pc
 	add	sp, sp, #\offset + S_SP
+	tst	r1, #PSR_I_BIT | 0x0f
+	bne	1f
 	msr	spsr_cxsf, r1			@ save in spsr_svc
 
 	@ We must avoid clrex due to Cortex-A15 erratum #830321
@@ -336,6 +341,7 @@
 	.endif
 	add	sp, sp, #S_FRAME_SIZE - S_SP
 	movs	pc, lr				@ return & move spsr_svc into cpsr
+1:	bug	"Returning to usermode but unexpected PSR bits set?", \@
 #endif	/* !CONFIG_THUMB2_KERNEL */
 	.endm
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm/kvm/handle_exit.c linux-libre-4.4.106-gnu/arch/arm/kvm/handle_exit.c
--- linux-libre-4.4.105-gnu/arch/arm/kvm/handle_exit.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm/kvm/handle_exit.c	2017-12-16 04:33:57.000000000 -0500
@@ -100,7 +100,19 @@ static int kvm_handle_wfx(struct kvm_vcp
 	return 1;
 }
 
+static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	u32 hsr = kvm_vcpu_get_hsr(vcpu);
+
+	kvm_pr_unimpl("Unknown exception class: hsr: %#08x\n",
+		      hsr);
+
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
+	[0 ... HSR_EC_MAX]	= kvm_handle_unknown_ec,
 	[HSR_EC_WFI]		= kvm_handle_wfx,
 	[HSR_EC_CP15_32]	= kvm_handle_cp15_32,
 	[HSR_EC_CP15_64]	= kvm_handle_cp15_64,
@@ -122,13 +134,6 @@ static exit_handle_fn kvm_get_exit_handl
 {
 	u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu);
 
-	if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) ||
-	    !arm_exit_handlers[hsr_ec]) {
-		kvm_err("Unknown exception class: hsr: %#08x\n",
-			(unsigned int)kvm_vcpu_get_hsr(vcpu));
-		BUG();
-	}
-
 	return arm_exit_handlers[hsr_ec];
 }
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm/mach-omap2/gpmc-onenand.c linux-libre-4.4.106-gnu/arch/arm/mach-omap2/gpmc-onenand.c
--- linux-libre-4.4.105-gnu/arch/arm/mach-omap2/gpmc-onenand.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm/mach-omap2/gpmc-onenand.c	2017-12-16 04:33:57.000000000 -0500
@@ -367,7 +367,7 @@ static int gpmc_onenand_setup(void __iom
 	return ret;
 }
 
-void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+int gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
 {
 	int err;
 	struct device *dev = &gpmc_onenand_device.dev;
@@ -393,15 +393,17 @@ void gpmc_onenand_init(struct omap_onena
 	if (err < 0) {
 		dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
 			gpmc_onenand_data->cs, err);
-		return;
+		return err;
 	}
 
 	gpmc_onenand_resource.end = gpmc_onenand_resource.start +
 							ONENAND_IO_SIZE - 1;
 
-	if (platform_device_register(&gpmc_onenand_device) < 0) {
+	err = platform_device_register(&gpmc_onenand_device);
+	if (err) {
 		dev_err(dev, "Unable to register OneNAND device\n");
 		gpmc_cs_free(gpmc_onenand_data->cs);
-		return;
 	}
+
+	return err;
 }
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c linux-libre-4.4.106-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
--- linux-libre-4.4.105-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	2017-12-16 04:33:57.000000000 -0500
@@ -3885,16 +3885,20 @@ static struct omap_hwmod_ocp_if *omap3xx
  * Return: 0 if device named @dev_name is not likely to be accessible,
  * or 1 if it is likely to be accessible.
  */
-static int __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus,
-						       const char *dev_name)
+static bool __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus,
+							const char *dev_name)
 {
+	struct device_node *node;
+	bool available;
+
 	if (!bus)
-		return (omap_type() == OMAP2_DEVICE_TYPE_GP) ? 1 : 0;
+		return omap_type() == OMAP2_DEVICE_TYPE_GP;
 
-	if (of_device_is_available(of_find_node_by_name(bus, dev_name)))
-		return 1;
+	node = of_get_child_by_name(bus, dev_name);
+	available = of_device_is_available(node);
+	of_node_put(node);
 
-	return 0;
+	return available;
 }
 
 int __init omap3xxx_hwmod_init(void)
@@ -3963,15 +3967,20 @@ int __init omap3xxx_hwmod_init(void)
 
 	if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) {
 		r = omap_hwmod_register_links(h_sham);
-		if (r < 0)
+		if (r < 0) {
+			of_node_put(bus);
 			return r;
+		}
 	}
 
 	if (h_aes && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "aes")) {
 		r = omap_hwmod_register_links(h_aes);
-		if (r < 0)
+		if (r < 0) {
+			of_node_put(bus);
 			return r;
+		}
 	}
+	of_node_put(bus);
 
 	/*
 	 * Register hwmod links specific to certain ES levels of a
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm64/include/asm/kvm_arm.h linux-libre-4.4.106-gnu/arch/arm64/include/asm/kvm_arm.h
--- linux-libre-4.4.105-gnu/arch/arm64/include/asm/kvm_arm.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm64/include/asm/kvm_arm.h	2017-12-16 04:33:57.000000000 -0500
@@ -164,8 +164,7 @@
 #define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
 #endif
 
-#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
-#define VTTBR_BADDR_MASK  (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_BADDR_MASK  (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_X)
 #define VTTBR_VMID_SHIFT  (UL(48))
 #define VTTBR_VMID_MASK	  (UL(0xFF) << VTTBR_VMID_SHIFT)
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm64/kernel/process.c linux-libre-4.4.106-gnu/arch/arm64/kernel/process.c
--- linux-libre-4.4.105-gnu/arch/arm64/kernel/process.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm64/kernel/process.c	2017-12-16 04:33:57.000000000 -0500
@@ -251,6 +251,15 @@ int copy_thread(unsigned long clone_flag
 
 	memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
 
+	/*
+	 * In case p was allocated the same task_struct pointer as some
+	 * other recently-exited task, make sure p is disassociated from
+	 * any cpu that may have run that now-exited task recently.
+	 * Otherwise we could erroneously skip reloading the FPSIMD
+	 * registers for p.
+	 */
+	fpsimd_flush_task_state(p);
+
 	if (likely(!(p->flags & PF_KTHREAD))) {
 		*childregs = *current_pt_regs();
 		childregs->regs[0] = 0;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/arm64/kvm/handle_exit.c linux-libre-4.4.106-gnu/arch/arm64/kvm/handle_exit.c
--- linux-libre-4.4.105-gnu/arch/arm64/kvm/handle_exit.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/arm64/kvm/handle_exit.c	2017-12-16 04:33:57.000000000 -0500
@@ -121,7 +121,19 @@ static int kvm_handle_guest_debug(struct
 	return ret;
 }
 
+static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	u32 hsr = kvm_vcpu_get_hsr(vcpu);
+
+	kvm_pr_unimpl("Unknown exception class: hsr: %#08x -- %s\n",
+		      hsr, esr_get_class_string(hsr));
+
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]	= kvm_handle_unknown_ec,
 	[ESR_ELx_EC_WFx]	= kvm_handle_wfx,
 	[ESR_ELx_EC_CP15_32]	= kvm_handle_cp15_32,
 	[ESR_ELx_EC_CP15_64]	= kvm_handle_cp15_64,
@@ -147,13 +159,6 @@ static exit_handle_fn kvm_get_exit_handl
 	u32 hsr = kvm_vcpu_get_hsr(vcpu);
 	u8 hsr_ec = hsr >> ESR_ELx_EC_SHIFT;
 
-	if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) ||
-	    !arm_exit_handlers[hsr_ec]) {
-		kvm_err("Unknown exception class: hsr: %#08x -- %s\n",
-			hsr, esr_get_class_string(hsr));
-		BUG();
-	}
-
 	return arm_exit_handlers[hsr_ec];
 }
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/powerpc/platforms/powernv/pci-ioda.c linux-libre-4.4.106-gnu/arch/powerpc/platforms/powernv/pci-ioda.c
--- linux-libre-4.4.105-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2017-12-16 04:33:57.000000000 -0500
@@ -2270,6 +2270,9 @@ static long pnv_pci_ioda2_table_alloc_pa
 	level_shift = entries_shift + 3;
 	level_shift = max_t(unsigned, level_shift, PAGE_SHIFT);
 
+	if ((level_shift - 3) * levels + page_shift >= 60)
+		return -EINVAL;
+
 	/* Allocate TCE table */
 	addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
 			levels, tce_table_size, &offset, &total_allocated);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/powerpc/sysdev/axonram.c linux-libre-4.4.106-gnu/arch/powerpc/sysdev/axonram.c
--- linux-libre-4.4.105-gnu/arch/powerpc/sysdev/axonram.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/powerpc/sysdev/axonram.c	2017-12-16 04:33:57.000000000 -0500
@@ -276,7 +276,9 @@ failed:
 			if (bank->disk->major > 0)
 				unregister_blkdev(bank->disk->major,
 						bank->disk->disk_name);
-			del_gendisk(bank->disk);
+			if (bank->disk->flags & GENHD_FL_UP)
+				del_gendisk(bank->disk);
+			put_disk(bank->disk);
 		}
 		device->dev.platform_data = NULL;
 		if (bank->io_addr != 0)
@@ -301,6 +303,7 @@ axon_ram_remove(struct platform_device *
 	device_remove_file(&device->dev, &dev_attr_ecc);
 	free_irq(bank->irq_id, device);
 	del_gendisk(bank->disk);
+	put_disk(bank->disk);
 	iounmap((void __iomem *) bank->io_addr);
 	kfree(bank);
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/s390/include/asm/asm-prototypes.h linux-libre-4.4.106-gnu/arch/s390/include/asm/asm-prototypes.h
--- linux-libre-4.4.105-gnu/arch/s390/include/asm/asm-prototypes.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/s390/include/asm/asm-prototypes.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-#ifndef _ASM_S390_PROTOTYPES_H
-
-#include <linux/kvm_host.h>
-#include <linux/ftrace.h>
-#include <asm/fpu/api.h>
-#include <asm-generic/asm-prototypes.h>
-
-#endif /* _ASM_S390_PROTOTYPES_H */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/s390/include/asm/switch_to.h linux-libre-4.4.106-gnu/arch/s390/include/asm/switch_to.h
--- linux-libre-4.4.105-gnu/arch/s390/include/asm/switch_to.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/s390/include/asm/switch_to.h	2017-12-16 04:33:57.000000000 -0500
@@ -29,17 +29,16 @@ static inline void restore_access_regs(u
 }
 
 #define switch_to(prev,next,last) do {					\
-	if (prev->mm) {							\
-		save_fpu_regs();					\
-		save_access_regs(&prev->thread.acrs[0]);		\
-		save_ri_cb(prev->thread.ri_cb);				\
-	}								\
+	/* save_fpu_regs() sets the CIF_FPU flag, which enforces	\
+	 * a restore of the floating point / vector registers as	\
+	 * soon as the next task returns to user space			\
+	 */								\
+	save_fpu_regs();						\
+	save_access_regs(&prev->thread.acrs[0]);			\
+	save_ri_cb(prev->thread.ri_cb);					\
 	update_cr_regs(next);						\
-	if (next->mm) {							\
-		set_cpu_flag(CIF_FPU);					\
-		restore_access_regs(&next->thread.acrs[0]);		\
-		restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb);	\
-	}								\
+	restore_access_regs(&next->thread.acrs[0]);			\
+	restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb);		\
 	prev = __switch_to(prev,next);					\
 } while (0)
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/s390/kernel/syscalls.S linux-libre-4.4.106-gnu/arch/s390/kernel/syscalls.S
--- linux-libre-4.4.105-gnu/arch/s390/kernel/syscalls.S	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/s390/kernel/syscalls.S	2017-12-16 04:33:57.000000000 -0500
@@ -369,10 +369,10 @@ SYSCALL(sys_recvmmsg,compat_sys_recvmmsg
 SYSCALL(sys_sendmmsg,compat_sys_sendmmsg)
 SYSCALL(sys_socket,sys_socket)
 SYSCALL(sys_socketpair,compat_sys_socketpair)		/* 360 */
-SYSCALL(sys_bind,sys_bind)
-SYSCALL(sys_connect,sys_connect)
+SYSCALL(sys_bind,compat_sys_bind)
+SYSCALL(sys_connect,compat_sys_connect)
 SYSCALL(sys_listen,sys_listen)
-SYSCALL(sys_accept4,sys_accept4)
+SYSCALL(sys_accept4,compat_sys_accept4)
 SYSCALL(sys_getsockopt,compat_sys_getsockopt)		/* 365 */
 SYSCALL(sys_setsockopt,compat_sys_setsockopt)
 SYSCALL(sys_getsockname,compat_sys_getsockname)
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/sparc/mm/init_64.c linux-libre-4.4.106-gnu/arch/sparc/mm/init_64.c
--- linux-libre-4.4.105-gnu/arch/sparc/mm/init_64.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/sparc/mm/init_64.c	2017-12-16 04:33:57.000000000 -0500
@@ -2402,10 +2402,17 @@ void __init mem_init(void)
 {
 	high_memory = __va(last_valid_pfn << PAGE_SHIFT);
 
-	register_page_bootmem_info();
 	free_all_bootmem();
 
 	/*
+	 * Must be done after boot memory is put on freelist, because here we
+	 * might set fields in deferred struct pages that have not yet been
+	 * initialized, and free_all_bootmem() initializes all the reserved
+	 * deferred pages for us.
+	 */
+	register_page_bootmem_info();
+
+	/*
 	 * Set up the zero page, mark it reserved, so that page count
 	 * is not manipulated when freeing the page from user ptes.
 	 */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/include/asm/efi.h linux-libre-4.4.106-gnu/arch/x86/include/asm/efi.h
--- linux-libre-4.4.105-gnu/arch/x86/include/asm/efi.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/include/asm/efi.h	2017-12-16 04:33:57.000000000 -0500
@@ -3,7 +3,6 @@
 
 #include <asm/fpu/api.h>
 #include <asm/pgtable.h>
-#include <asm/tlb.h>
 
 /*
  * We map the EFI regions needed for runtime services non-contiguously,
@@ -65,17 +64,6 @@ extern u64 asmlinkage efi_call(void *fp,
 
 #define efi_call_phys(f, args...)		efi_call((f), args)
 
-/*
- * Scratch space used for switching the pagetable in the EFI stub
- */
-struct efi_scratch {
-	u64	r15;
-	u64	prev_cr3;
-	pgd_t	*efi_pgt;
-	bool	use_pgd;
-	u64	phys_stack;
-} __packed;
-
 #define efi_call_virt(f, ...)						\
 ({									\
 	efi_status_t __s;						\
@@ -83,20 +71,7 @@ struct efi_scratch {
 	efi_sync_low_kernel_mappings();					\
 	preempt_disable();						\
 	__kernel_fpu_begin();						\
-									\
-	if (efi_scratch.use_pgd) {					\
-		efi_scratch.prev_cr3 = read_cr3();			\
-		write_cr3((unsigned long)efi_scratch.efi_pgt);		\
-		__flush_tlb_all();					\
-	}								\
-									\
 	__s = efi_call((void *)efi.systab->runtime->f, __VA_ARGS__);	\
-									\
-	if (efi_scratch.use_pgd) {					\
-		write_cr3(efi_scratch.prev_cr3);			\
-		__flush_tlb_all();					\
-	}								\
-									\
 	__kernel_fpu_end();						\
 	preempt_enable();						\
 	__s;								\
@@ -136,7 +111,6 @@ extern void __init efi_memory_uc(u64 add
 extern void __init efi_map_region(efi_memory_desc_t *md);
 extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
 extern void efi_sync_low_kernel_mappings(void);
-extern int __init efi_alloc_page_tables(void);
 extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages);
 extern void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages);
 extern void __init old_map_region(efi_memory_desc_t *md);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/kernel/hpet.c linux-libre-4.4.106-gnu/arch/x86/kernel/hpet.c
--- linux-libre-4.4.105-gnu/arch/x86/kernel/hpet.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/kernel/hpet.c	2017-12-16 04:33:57.000000000 -0500
@@ -353,7 +353,7 @@ static int hpet_resume(struct clock_even
 
 		irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
 		irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
-		disable_irq(hdev->irq);
+		disable_hardirq(hdev->irq);
 		irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
 		enable_irq(hdev->irq);
 	}
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/kvm/vmx.c linux-libre-4.4.106-gnu/arch/x86/kvm/vmx.c
--- linux-libre-4.4.105-gnu/arch/x86/kvm/vmx.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/kvm/vmx.c	2017-12-16 04:33:57.000000000 -0500
@@ -6182,12 +6182,7 @@ static __init int hardware_setup(void)
 	memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
 	memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
 
-	/*
-	 * Allow direct access to the PC debug port (it is often used for I/O
-	 * delays, but the vmexits simply slow things down).
-	 */
 	memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE);
-	clear_bit(0x80, vmx_io_bitmap_a);
 
 	memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
 
@@ -6929,9 +6924,8 @@ static int handle_vmoff(struct kvm_vcpu
 static int handle_vmclear(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	u32 zero = 0;
 	gpa_t vmptr;
-	struct vmcs12 *vmcs12;
-	struct page *page;
 
 	if (!nested_vmx_check_permission(vcpu))
 		return 1;
@@ -6942,22 +6936,9 @@ static int handle_vmclear(struct kvm_vcp
 	if (vmptr == vmx->nested.current_vmptr)
 		nested_release_vmcs12(vmx);
 
-	page = nested_get_page(vcpu, vmptr);
-	if (page == NULL) {
-		/*
-		 * For accurate processor emulation, VMCLEAR beyond available
-		 * physical memory should do nothing at all. However, it is
-		 * possible that a nested vmx bug, not a guest hypervisor bug,
-		 * resulted in this case, so let's shut down before doing any
-		 * more damage:
-		 */
-		kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
-		return 1;
-	}
-	vmcs12 = kmap(page);
-	vmcs12->launch_state = 0;
-	kunmap(page);
-	nested_release_page(page);
+	kvm_vcpu_write_guest(vcpu,
+			vmptr + offsetof(struct vmcs12, launch_state),
+			&zero, sizeof(zero));
 
 	nested_free_vmcs02(vmx, vmptr);
 
@@ -10574,8 +10555,10 @@ static void nested_vmx_vmexit(struct kvm
  */
 static void vmx_leave_nested(struct kvm_vcpu *vcpu)
 {
-	if (is_guest_mode(vcpu))
+	if (is_guest_mode(vcpu)) {
+		to_vmx(vcpu)->nested.nested_run_pending = 0;
 		nested_vmx_vmexit(vcpu, -1, 0, 0);
+	}
 	free_nested(to_vmx(vcpu));
 }
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/mm/pageattr.c linux-libre-4.4.106-gnu/arch/x86/mm/pageattr.c
--- linux-libre-4.4.105-gnu/arch/x86/mm/pageattr.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/mm/pageattr.c	2017-12-16 04:33:57.000000000 -0500
@@ -911,10 +911,15 @@ static void populate_pte(struct cpa_data
 	pte = pte_offset_kernel(pmd, start);
 
 	while (num_pages-- && start < end) {
-		set_pte(pte, pfn_pte(cpa->pfn, pgprot));
+
+		/* deal with the NX bit */
+		if (!(pgprot_val(pgprot) & _PAGE_NX))
+			cpa->pfn &= ~_PAGE_NX;
+
+		set_pte(pte, pfn_pte(cpa->pfn >> PAGE_SHIFT, pgprot));
 
 		start	 += PAGE_SIZE;
-		cpa->pfn++;
+		cpa->pfn += PAGE_SIZE;
 		pte++;
 	}
 }
@@ -970,11 +975,11 @@ static int populate_pmd(struct cpa_data
 
 		pmd = pmd_offset(pud, start);
 
-		set_pmd(pmd, __pmd(cpa->pfn << PAGE_SHIFT | _PAGE_PSE |
+		set_pmd(pmd, __pmd(cpa->pfn | _PAGE_PSE |
 				   massage_pgprot(pmd_pgprot)));
 
 		start	  += PMD_SIZE;
-		cpa->pfn  += PMD_SIZE >> PAGE_SHIFT;
+		cpa->pfn  += PMD_SIZE;
 		cur_pages += PMD_SIZE >> PAGE_SHIFT;
 	}
 
@@ -1043,11 +1048,11 @@ static int populate_pud(struct cpa_data
 	 * Map everything starting from the Gb boundary, possibly with 1G pages
 	 */
 	while (end - start >= PUD_SIZE) {
-		set_pud(pud, __pud(cpa->pfn << PAGE_SHIFT | _PAGE_PSE |
+		set_pud(pud, __pud(cpa->pfn | _PAGE_PSE |
 				   massage_pgprot(pud_pgprot)));
 
 		start	  += PUD_SIZE;
-		cpa->pfn  += PUD_SIZE >> PAGE_SHIFT;
+		cpa->pfn  += PUD_SIZE;
 		cur_pages += PUD_SIZE >> PAGE_SHIFT;
 		pud++;
 	}
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/pci/broadcom_bus.c linux-libre-4.4.106-gnu/arch/x86/pci/broadcom_bus.c
--- linux-libre-4.4.105-gnu/arch/x86/pci/broadcom_bus.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/pci/broadcom_bus.c	2017-12-16 04:33:57.000000000 -0500
@@ -97,7 +97,7 @@ static int __init broadcom_postcore_init
 	 * We should get host bridge information from ACPI unless the BIOS
 	 * doesn't support it.
 	 */
-	if (acpi_os_get_root_pointer())
+	if (!acpi_disabled && acpi_os_get_root_pointer())
 		return 0;
 #endif
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi_32.c linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi_32.c
--- linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi_32.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi_32.c	2017-12-16 04:33:57.000000000 -0500
@@ -38,11 +38,6 @@
  * say 0 - 3G.
  */
 
-int __init efi_alloc_page_tables(void)
-{
-	return 0;
-}
-
 void efi_sync_low_kernel_mappings(void) {}
 void __init efi_dump_pagetable(void) {}
 int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi_64.c linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi_64.c
--- linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi_64.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi_64.c	2017-12-16 04:33:57.000000000 -0500
@@ -40,7 +40,6 @@
 #include <asm/fixmap.h>
 #include <asm/realmode.h>
 #include <asm/time.h>
-#include <asm/pgalloc.h>
 
 /*
  * We allocate runtime services regions bottom-up, starting from -4G, i.e.
@@ -48,7 +47,16 @@
  */
 static u64 efi_va = EFI_VA_START;
 
-struct efi_scratch efi_scratch;
+/*
+ * Scratch space used for switching the pagetable in the EFI stub
+ */
+struct efi_scratch {
+	u64 r15;
+	u64 prev_cr3;
+	pgd_t *efi_pgt;
+	bool use_pgd;
+	u64 phys_stack;
+} __packed;
 
 static void __init early_code_mapping_set_exec(int executable)
 {
@@ -75,11 +83,8 @@ pgd_t * __init efi_call_phys_prolog(void
 	int pgd;
 	int n_pgds;
 
-	if (!efi_enabled(EFI_OLD_MEMMAP)) {
-		save_pgd = (pgd_t *)read_cr3();
-		write_cr3((unsigned long)efi_scratch.efi_pgt);
-		goto out;
-	}
+	if (!efi_enabled(EFI_OLD_MEMMAP))
+		return NULL;
 
 	early_code_mapping_set_exec(1);
 
@@ -91,7 +96,6 @@ pgd_t * __init efi_call_phys_prolog(void
 		vaddress = (unsigned long)__va(pgd * PGDIR_SIZE);
 		set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
 	}
-out:
 	__flush_tlb_all();
 
 	return save_pgd;
@@ -105,11 +109,8 @@ void __init efi_call_phys_epilog(pgd_t *
 	int pgd_idx;
 	int nr_pgds;
 
-	if (!efi_enabled(EFI_OLD_MEMMAP)) {
-		write_cr3((unsigned long)save_pgd);
-		__flush_tlb_all();
+	if (!save_pgd)
 		return;
-	}
 
 	nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
 
@@ -122,97 +123,27 @@ void __init efi_call_phys_epilog(pgd_t *
 	early_code_mapping_set_exec(0);
 }
 
-static pgd_t *efi_pgd;
-
-/*
- * We need our own copy of the higher levels of the page tables
- * because we want to avoid inserting EFI region mappings (EFI_VA_END
- * to EFI_VA_START) into the standard kernel page tables. Everything
- * else can be shared, see efi_sync_low_kernel_mappings().
- */
-int __init efi_alloc_page_tables(void)
-{
-	pgd_t *pgd;
-	pud_t *pud;
-	gfp_t gfp_mask;
-
-	if (efi_enabled(EFI_OLD_MEMMAP))
-		return 0;
-
-	gfp_mask = GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO;
-	efi_pgd = (pgd_t *)__get_free_page(gfp_mask);
-	if (!efi_pgd)
-		return -ENOMEM;
-
-	pgd = efi_pgd + pgd_index(EFI_VA_END);
-
-	pud = pud_alloc_one(NULL, 0);
-	if (!pud) {
-		free_page((unsigned long)efi_pgd);
-		return -ENOMEM;
-	}
-
-	pgd_populate(NULL, pgd, pud);
-
-	return 0;
-}
-
 /*
  * Add low kernel mappings for passing arguments to EFI functions.
  */
 void efi_sync_low_kernel_mappings(void)
 {
-	unsigned num_entries;
-	pgd_t *pgd_k, *pgd_efi;
-	pud_t *pud_k, *pud_efi;
+	unsigned num_pgds;
+	pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
 
 	if (efi_enabled(EFI_OLD_MEMMAP))
 		return;
 
-	/*
-	 * We can share all PGD entries apart from the one entry that
-	 * covers the EFI runtime mapping space.
-	 *
-	 * Make sure the EFI runtime region mappings are guaranteed to
-	 * only span a single PGD entry and that the entry also maps
-	 * other important kernel regions.
-	 */
-	BUILD_BUG_ON(pgd_index(EFI_VA_END) != pgd_index(MODULES_END));
-	BUILD_BUG_ON((EFI_VA_START & PGDIR_MASK) !=
-			(EFI_VA_END & PGDIR_MASK));
-
-	pgd_efi = efi_pgd + pgd_index(PAGE_OFFSET);
-	pgd_k = pgd_offset_k(PAGE_OFFSET);
-
-	num_entries = pgd_index(EFI_VA_END) - pgd_index(PAGE_OFFSET);
-	memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries);
-
-	/*
-	 * We share all the PUD entries apart from those that map the
-	 * EFI regions. Copy around them.
-	 */
-	BUILD_BUG_ON((EFI_VA_START & ~PUD_MASK) != 0);
-	BUILD_BUG_ON((EFI_VA_END & ~PUD_MASK) != 0);
-
-	pgd_efi = efi_pgd + pgd_index(EFI_VA_END);
-	pud_efi = pud_offset(pgd_efi, 0);
-
-	pgd_k = pgd_offset_k(EFI_VA_END);
-	pud_k = pud_offset(pgd_k, 0);
-
-	num_entries = pud_index(EFI_VA_END);
-	memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries);
-
-	pud_efi = pud_offset(pgd_efi, EFI_VA_START);
-	pud_k = pud_offset(pgd_k, EFI_VA_START);
+	num_pgds = pgd_index(MODULES_END - 1) - pgd_index(PAGE_OFFSET);
 
-	num_entries = PTRS_PER_PUD - pud_index(EFI_VA_START);
-	memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries);
+	memcpy(pgd + pgd_index(PAGE_OFFSET),
+		init_mm.pgd + pgd_index(PAGE_OFFSET),
+		sizeof(pgd_t) * num_pgds);
 }
 
 int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
 {
-	unsigned long pfn, text;
+	unsigned long text;
 	struct page *page;
 	unsigned npages;
 	pgd_t *pgd;
@@ -220,8 +151,8 @@ int __init efi_setup_page_tables(unsigne
 	if (efi_enabled(EFI_OLD_MEMMAP))
 		return 0;
 
-	efi_scratch.efi_pgt = (pgd_t *)__pa(efi_pgd);
-	pgd = efi_pgd;
+	efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd;
+	pgd = __va(efi_scratch.efi_pgt);
 
 	/*
 	 * It can happen that the physical address of new_memmap lands in memory
@@ -229,8 +160,7 @@ int __init efi_setup_page_tables(unsigne
 	 * and ident-map those pages containing the map before calling
 	 * phys_efi_set_virtual_address_map().
 	 */
-	pfn = pa_memmap >> PAGE_SHIFT;
-	if (kernel_map_pages_in_pgd(pgd, pfn, pa_memmap, num_pages, _PAGE_NX)) {
+	if (kernel_map_pages_in_pgd(pgd, pa_memmap, pa_memmap, num_pages, _PAGE_NX)) {
 		pr_err("Error ident-mapping new memmap (0x%lx)!\n", pa_memmap);
 		return 1;
 	}
@@ -255,9 +185,8 @@ int __init efi_setup_page_tables(unsigne
 
 	npages = (_end - _text) >> PAGE_SHIFT;
 	text = __pa(_text);
-	pfn = text >> PAGE_SHIFT;
 
-	if (kernel_map_pages_in_pgd(pgd, pfn, text, npages, 0)) {
+	if (kernel_map_pages_in_pgd(pgd, text >> PAGE_SHIFT, text, npages, 0)) {
 		pr_err("Failed to map kernel text 1:1\n");
 		return 1;
 	}
@@ -267,20 +196,20 @@ int __init efi_setup_page_tables(unsigne
 
 void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages)
 {
-	kernel_unmap_pages_in_pgd(efi_pgd, pa_memmap, num_pages);
+	pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
+
+	kernel_unmap_pages_in_pgd(pgd, pa_memmap, num_pages);
 }
 
 static void __init __map_region(efi_memory_desc_t *md, u64 va)
 {
-	unsigned long flags = 0;
-	unsigned long pfn;
-	pgd_t *pgd = efi_pgd;
+	pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
+	unsigned long pf = 0;
 
 	if (!(md->attribute & EFI_MEMORY_WB))
-		flags |= _PAGE_PCD;
+		pf |= _PAGE_PCD;
 
-	pfn = md->phys_addr >> PAGE_SHIFT;
-	if (kernel_map_pages_in_pgd(pgd, pfn, va, md->num_pages, flags))
+	if (kernel_map_pages_in_pgd(pgd, md->phys_addr, va, md->num_pages, pf))
 		pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n",
 			   md->phys_addr, va);
 }
@@ -383,7 +312,9 @@ void __init efi_runtime_mkexec(void)
 void __init efi_dump_pagetable(void)
 {
 #ifdef CONFIG_EFI_PGT_DUMP
-	ptdump_walk_pgd_level(NULL, efi_pgd);
+	pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
+
+	ptdump_walk_pgd_level(NULL, pgd);
 #endif
 }
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi.c linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi.c
--- linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi.c	2017-12-16 04:33:57.000000000 -0500
@@ -869,7 +869,7 @@ static void __init kexec_enter_virtual_m
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, we look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor into the
- * efi_pgd page table.
+ * ->trampoline_pgd page table using a top-down VA allocation scheme.
  *
  * The old method which used to update that memory descriptor with the
  * virtual address obtained from ioremap() is still supported when the
@@ -879,8 +879,8 @@ static void __init kexec_enter_virtual_m
  *
  * The new method does a pagetable switch in a preemption-safe manner
  * so that we're in a different address space when calling a runtime
- * function. For function arguments passing we do copy the PUDs of the
- * kernel page table into efi_pgd prior to each call.
+ * function. For function arguments passing we do copy the PGDs of the
+ * kernel page table into ->trampoline_pgd prior to each call.
  *
  * Specially for kexec boot, efi runtime maps in previous kernel should
  * be passed in via setup_data. In that case runtime ranges will be mapped
@@ -895,12 +895,6 @@ static void __init __efi_enter_virtual_m
 
 	efi.systab = NULL;
 
-	if (efi_alloc_page_tables()) {
-		pr_err("Failed to allocate EFI page tables\n");
-		clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
-		return;
-	}
-
 	efi_merge_regions();
 	new_memmap = efi_map_regions(&count, &pg_shift);
 	if (!new_memmap) {
@@ -960,11 +954,28 @@ static void __init __efi_enter_virtual_m
 	efi_runtime_mkexec();
 
 	/*
-	 * We mapped the descriptor array into the EFI pagetable above
-	 * but we're not unmapping it here because if we're running in
-	 * EFI mixed mode we need all of memory to be accessible when
-	 * we pass parameters to the EFI runtime services in the
-	 * thunking code.
+	 * We mapped the descriptor array into the EFI pagetable above but we're
+	 * not unmapping it here. Here's why:
+	 *
+	 * We're copying select PGDs from the kernel page table to the EFI page
+	 * table and when we do so and make changes to those PGDs like unmapping
+	 * stuff from them, those changes appear in the kernel page table and we
+	 * go boom.
+	 *
+	 * From setup_real_mode():
+	 *
+	 * ...
+	 * trampoline_pgd[0] = init_level4_pgt[pgd_index(__PAGE_OFFSET)].pgd;
+	 *
+	 * In this particular case, our allocation is in PGD 0 of the EFI page
+	 * table but we've copied that PGD from PGD[272] of the EFI page table:
+	 *
+	 *	pgd_index(__PAGE_OFFSET = 0xffff880000000000) = 272
+	 *
+	 * where the direct memory mapping in kernel space is.
+	 *
+	 * new_memmap's VA comes from that direct mapping and thus clearing it,
+	 * it would get cleared in the kernel page table too.
 	 *
 	 * efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift);
 	 */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi_stub_64.S linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi_stub_64.S
--- linux-libre-4.4.105-gnu/arch/x86/platform/efi/efi_stub_64.S	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/arch/x86/platform/efi/efi_stub_64.S	2017-12-16 04:33:57.000000000 -0500
@@ -38,6 +38,41 @@
 	mov %rsi, %cr0;			\
 	mov (%rsp), %rsp
 
+	/* stolen from gcc */
+	.macro FLUSH_TLB_ALL
+	movq %r15, efi_scratch(%rip)
+	movq %r14, efi_scratch+8(%rip)
+	movq %cr4, %r15
+	movq %r15, %r14
+	andb $0x7f, %r14b
+	movq %r14, %cr4
+	movq %r15, %cr4
+	movq efi_scratch+8(%rip), %r14
+	movq efi_scratch(%rip), %r15
+	.endm
+
+	.macro SWITCH_PGT
+	cmpb $0, efi_scratch+24(%rip)
+	je 1f
+	movq %r15, efi_scratch(%rip)		# r15
+	# save previous CR3
+	movq %cr3, %r15
+	movq %r15, efi_scratch+8(%rip)		# prev_cr3
+	movq efi_scratch+16(%rip), %r15		# EFI pgt
+	movq %r15, %cr3
+	1:
+	.endm
+
+	.macro RESTORE_PGT
+	cmpb $0, efi_scratch+24(%rip)
+	je 2f
+	movq efi_scratch+8(%rip), %r15
+	movq %r15, %cr3
+	movq efi_scratch(%rip), %r15
+	FLUSH_TLB_ALL
+	2:
+	.endm
+
 ENTRY(efi_call)
 	SAVE_XMM
 	mov (%rsp), %rax
@@ -48,8 +83,16 @@ ENTRY(efi_call)
 	mov %r8, %r9
 	mov %rcx, %r8
 	mov %rsi, %rcx
+	SWITCH_PGT
 	call *%rdi
+	RESTORE_PGT
 	addq $48, %rsp
 	RESTORE_XMM
 	ret
 ENDPROC(efi_call)
+
+	.data
+ENTRY(efi_scratch)
+	.fill 3,8,0
+	.byte 0
+	.quad 0
diff -druNp --no-dereference linux-libre-4.4.105-gnu/block/bio.c linux-libre-4.4.106-gnu/block/bio.c
--- linux-libre-4.4.105-gnu/block/bio.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/block/bio.c	2017-12-16 04:33:57.000000000 -0500
@@ -1268,6 +1268,7 @@ struct bio *bio_map_user_iov(struct requ
 	int ret, offset;
 	struct iov_iter i;
 	struct iovec iov;
+	struct bio_vec *bvec;
 
 	iov_for_each(iov, i, *iter) {
 		unsigned long uaddr = (unsigned long) iov.iov_base;
@@ -1312,7 +1313,12 @@ struct bio *bio_map_user_iov(struct requ
 		ret = get_user_pages_fast(uaddr, local_nr_pages,
 				(iter->type & WRITE) != WRITE,
 				&pages[cur_page]);
-		if (ret < local_nr_pages) {
+		if (unlikely(ret < local_nr_pages)) {
+			for (j = cur_page; j < page_limit; j++) {
+				if (!pages[j])
+					break;
+				put_page(pages[j]);
+			}
 			ret = -EFAULT;
 			goto out_unmap;
 		}
@@ -1374,10 +1380,8 @@ struct bio *bio_map_user_iov(struct requ
 	return bio;
 
  out_unmap:
-	for (j = 0; j < nr_pages; j++) {
-		if (!pages[j])
-			break;
-		page_cache_release(pages[j]);
+	bio_for_each_segment_all(bvec, bio, j) {
+		put_page(bvec->bv_page);
 	}
  out:
 	kfree(pages);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/block/blk-core.c linux-libre-4.4.106-gnu/block/blk-core.c
--- linux-libre-4.4.105-gnu/block/blk-core.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/block/blk-core.c	2017-12-16 04:33:57.000000000 -0500
@@ -526,8 +526,8 @@ void blk_set_queue_dying(struct request_
 
 		blk_queue_for_each_rl(rl, q) {
 			if (rl->rq_pool) {
-				wake_up(&rl->wait[BLK_RW_SYNC]);
-				wake_up(&rl->wait[BLK_RW_ASYNC]);
+				wake_up_all(&rl->wait[BLK_RW_SYNC]);
+				wake_up_all(&rl->wait[BLK_RW_ASYNC]);
 			}
 		}
 	}
diff -druNp --no-dereference linux-libre-4.4.105-gnu/crypto/asymmetric_keys/x509_cert_parser.c linux-libre-4.4.106-gnu/crypto/asymmetric_keys/x509_cert_parser.c
--- linux-libre-4.4.105-gnu/crypto/asymmetric_keys/x509_cert_parser.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/crypto/asymmetric_keys/x509_cert_parser.c	2017-12-16 04:33:57.000000000 -0500
@@ -399,6 +399,8 @@ int x509_extract_key_data(void *context,
 	ctx->cert->pub->pkey_algo = PKEY_ALGO_RSA;
 
 	/* Discard the BIT STRING metadata */
+	if (vlen < 1 || *(const u8 *)value != 0)
+		return -EBADMSG;
 	ctx->key = value + 1;
 	ctx->key_size = vlen - 1;
 	return 0;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/ata/libata-sff.c linux-libre-4.4.106-gnu/drivers/ata/libata-sff.c
--- linux-libre-4.4.105-gnu/drivers/ata/libata-sff.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/ata/libata-sff.c	2017-12-16 04:33:57.000000000 -0500
@@ -1480,7 +1480,6 @@ unsigned int ata_sff_qc_issue(struct ata
 		break;
 
 	default:
-		WARN_ON_ONCE(1);
 		return AC_ERR_SYSTEM;
 	}
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/atm/horizon.c linux-libre-4.4.106-gnu/drivers/atm/horizon.c
--- linux-libre-4.4.105-gnu/drivers/atm/horizon.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/atm/horizon.c	2017-12-16 04:33:57.000000000 -0500
@@ -2804,7 +2804,7 @@ out:
 	return err;
 
 out_free_irq:
-	free_irq(dev->irq, dev);
+	free_irq(irq, dev);
 out_free:
 	kfree(dev);
 out_release:
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/base/isa.c linux-libre-4.4.106-gnu/drivers/base/isa.c
--- linux-libre-4.4.105-gnu/drivers/base/isa.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/base/isa.c	2017-12-16 04:33:57.000000000 -0500
@@ -39,7 +39,7 @@ static int isa_bus_probe(struct device *
 {
 	struct isa_driver *isa_driver = dev->platform_data;
 
-	if (isa_driver->probe)
+	if (isa_driver && isa_driver->probe)
 		return isa_driver->probe(dev, to_isa_dev(dev)->id);
 
 	return 0;
@@ -49,7 +49,7 @@ static int isa_bus_remove(struct device
 {
 	struct isa_driver *isa_driver = dev->platform_data;
 
-	if (isa_driver->remove)
+	if (isa_driver && isa_driver->remove)
 		return isa_driver->remove(dev, to_isa_dev(dev)->id);
 
 	return 0;
@@ -59,7 +59,7 @@ static void isa_bus_shutdown(struct devi
 {
 	struct isa_driver *isa_driver = dev->platform_data;
 
-	if (isa_driver->shutdown)
+	if (isa_driver && isa_driver->shutdown)
 		isa_driver->shutdown(dev, to_isa_dev(dev)->id);
 }
 
@@ -67,7 +67,7 @@ static int isa_bus_suspend(struct device
 {
 	struct isa_driver *isa_driver = dev->platform_data;
 
-	if (isa_driver->suspend)
+	if (isa_driver && isa_driver->suspend)
 		return isa_driver->suspend(dev, to_isa_dev(dev)->id, state);
 
 	return 0;
@@ -77,7 +77,7 @@ static int isa_bus_resume(struct device
 {
 	struct isa_driver *isa_driver = dev->platform_data;
 
-	if (isa_driver->resume)
+	if (isa_driver && isa_driver->resume)
 		return isa_driver->resume(dev, to_isa_dev(dev)->id);
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/block/zram/zram_drv.c linux-libre-4.4.106-gnu/drivers/block/zram/zram_drv.c
--- linux-libre-4.4.105-gnu/drivers/block/zram/zram_drv.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/block/zram/zram_drv.c	2017-12-16 04:33:57.000000000 -0500
@@ -1247,6 +1247,8 @@ static int zram_add(void)
 	blk_queue_io_min(zram->disk->queue, PAGE_SIZE);
 	blk_queue_io_opt(zram->disk->queue, PAGE_SIZE);
 	zram->disk->queue->limits.discard_granularity = PAGE_SIZE;
+	zram->disk->queue->limits.max_sectors = SECTORS_PER_PAGE;
+	zram->disk->queue->limits.chunk_sectors = 0;
 	blk_queue_max_discard_sectors(zram->disk->queue, UINT_MAX);
 	/*
 	 * zram_bio_discard() will clear all logical blocks if logical block
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/char/ipmi/ipmi_si_intf.c linux-libre-4.4.106-gnu/drivers/char/ipmi/ipmi_si_intf.c
--- linux-libre-4.4.105-gnu/drivers/char/ipmi/ipmi_si_intf.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/char/ipmi/ipmi_si_intf.c	2017-12-16 04:33:57.000000000 -0500
@@ -239,6 +239,9 @@ struct smi_info {
 	/* The timer for this si. */
 	struct timer_list   si_timer;
 
+	/* This flag is set, if the timer can be set */
+	bool		    timer_can_start;
+
 	/* This flag is set, if the timer is running (timer_pending() isn't enough) */
 	bool		    timer_running;
 
@@ -414,6 +417,8 @@ static enum si_sm_result start_next_msg(
 
 static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
 {
+	if (!smi_info->timer_can_start)
+		return;
 	smi_info->last_timeout_jiffies = jiffies;
 	mod_timer(&smi_info->si_timer, new_val);
 	smi_info->timer_running = true;
@@ -433,21 +438,18 @@ static void start_new_msg(struct smi_inf
 	smi_info->handlers->start_transaction(smi_info->si_sm, msg, size);
 }
 
-static void start_check_enables(struct smi_info *smi_info, bool start_timer)
+static void start_check_enables(struct smi_info *smi_info)
 {
 	unsigned char msg[2];
 
 	msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
 	msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
 
-	if (start_timer)
-		start_new_msg(smi_info, msg, 2);
-	else
-		smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+	start_new_msg(smi_info, msg, 2);
 	smi_info->si_state = SI_CHECKING_ENABLES;
 }
 
-static void start_clear_flags(struct smi_info *smi_info, bool start_timer)
+static void start_clear_flags(struct smi_info *smi_info)
 {
 	unsigned char msg[3];
 
@@ -456,10 +458,7 @@ static void start_clear_flags(struct smi
 	msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
 	msg[2] = WDT_PRE_TIMEOUT_INT;
 
-	if (start_timer)
-		start_new_msg(smi_info, msg, 3);
-	else
-		smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
+	start_new_msg(smi_info, msg, 3);
 	smi_info->si_state = SI_CLEARING_FLAGS;
 }
 
@@ -494,11 +493,11 @@ static void start_getting_events(struct
  * Note that we cannot just use disable_irq(), since the interrupt may
  * be shared.
  */
-static inline bool disable_si_irq(struct smi_info *smi_info, bool start_timer)
+static inline bool disable_si_irq(struct smi_info *smi_info)
 {
 	if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
 		smi_info->interrupt_disabled = true;
-		start_check_enables(smi_info, start_timer);
+		start_check_enables(smi_info);
 		return true;
 	}
 	return false;
@@ -508,7 +507,7 @@ static inline bool enable_si_irq(struct
 {
 	if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
 		smi_info->interrupt_disabled = false;
-		start_check_enables(smi_info, true);
+		start_check_enables(smi_info);
 		return true;
 	}
 	return false;
@@ -526,7 +525,7 @@ static struct ipmi_smi_msg *alloc_msg_ha
 
 	msg = ipmi_alloc_smi_msg();
 	if (!msg) {
-		if (!disable_si_irq(smi_info, true))
+		if (!disable_si_irq(smi_info))
 			smi_info->si_state = SI_NORMAL;
 	} else if (enable_si_irq(smi_info)) {
 		ipmi_free_smi_msg(msg);
@@ -542,7 +541,7 @@ static void handle_flags(struct smi_info
 		/* Watchdog pre-timeout */
 		smi_inc_stat(smi_info, watchdog_pretimeouts);
 
-		start_clear_flags(smi_info, true);
+		start_clear_flags(smi_info);
 		smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
 		if (smi_info->intf)
 			ipmi_smi_watchdog_pretimeout(smi_info->intf);
@@ -925,7 +924,7 @@ static enum si_sm_result smi_event_handl
 		 * disable and messages disabled.
 		 */
 		if (smi_info->supports_event_msg_buff || smi_info->irq) {
-			start_check_enables(smi_info, true);
+			start_check_enables(smi_info);
 		} else {
 			smi_info->curr_msg = alloc_msg_handle_irq(smi_info);
 			if (!smi_info->curr_msg)
@@ -1232,6 +1231,7 @@ static int smi_start_processing(void
 
 	/* Set up the timer that drives the interface. */
 	setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
+	new_smi->timer_can_start = true;
 	smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
 
 	/* Try to claim any interrupts. */
@@ -3434,10 +3434,12 @@ static void check_for_broken_irqs(struct
 	check_set_rcv_irq(smi_info);
 }
 
-static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
+static inline void stop_timer_and_thread(struct smi_info *smi_info)
 {
 	if (smi_info->thread != NULL)
 		kthread_stop(smi_info->thread);
+
+	smi_info->timer_can_start = false;
 	if (smi_info->timer_running)
 		del_timer_sync(&smi_info->si_timer);
 }
@@ -3635,7 +3637,7 @@ static int try_smi_init(struct smi_info
 	 * Start clearing the flags before we enable interrupts or the
 	 * timer to avoid racing with the timer.
 	 */
-	start_clear_flags(new_smi, false);
+	start_clear_flags(new_smi);
 
 	/*
 	 * IRQ is defined to be set when non-zero.  req_events will
@@ -3713,7 +3715,7 @@ static int try_smi_init(struct smi_info
 	return 0;
 
  out_err_stop_timer:
-	wait_for_timer_and_thread(new_smi);
+	stop_timer_and_thread(new_smi);
 
  out_err:
 	new_smi->interrupt_disabled = true;
@@ -3919,7 +3921,7 @@ static void cleanup_one_si(struct smi_in
 	 */
 	if (to_clean->irq_cleanup)
 		to_clean->irq_cleanup(to_clean);
-	wait_for_timer_and_thread(to_clean);
+	stop_timer_and_thread(to_clean);
 
 	/*
 	 * Timeouts are stopped, now make sure the interrupts are off
@@ -3930,7 +3932,7 @@ static void cleanup_one_si(struct smi_in
 		poll(to_clean);
 		schedule_timeout_uninterruptible(1);
 	}
-	disable_si_irq(to_clean, false);
+	disable_si_irq(to_clean);
 	while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
 		poll(to_clean);
 		schedule_timeout_uninterruptible(1);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/crypto/s5p-sss.c linux-libre-4.4.106-gnu/drivers/crypto/s5p-sss.c
--- linux-libre-4.4.105-gnu/drivers/crypto/s5p-sss.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/crypto/s5p-sss.c	2017-12-16 04:33:57.000000000 -0500
@@ -664,8 +664,9 @@ static int s5p_aes_probe(struct platform
 		dev_warn(dev, "feed control interrupt is not available.\n");
 		goto err_irq;
 	}
-	err = devm_request_irq(dev, pdata->irq_fc, s5p_aes_interrupt,
-			       IRQF_SHARED, pdev->name, pdev);
+	err = devm_request_threaded_irq(dev, pdata->irq_fc, NULL,
+					s5p_aes_interrupt, IRQF_ONESHOT,
+					pdev->name, pdev);
 	if (err < 0) {
 		dev_warn(dev, "feed control interrupt is not available.\n");
 		goto err_irq;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/edac/i5000_edac.c linux-libre-4.4.106-gnu/drivers/edac/i5000_edac.c
--- linux-libre-4.4.105-gnu/drivers/edac/i5000_edac.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/edac/i5000_edac.c	2017-12-16 04:33:57.000000000 -0500
@@ -227,7 +227,7 @@
 #define			NREC_RDWR(x)		(((x)>>11) & 1)
 #define			NREC_RANK(x)		(((x)>>8) & 0x7)
 #define		NRECMEMB		0xC0
-#define			NREC_CAS(x)		(((x)>>16) & 0xFFFFFF)
+#define			NREC_CAS(x)		(((x)>>16) & 0xFFF)
 #define			NREC_RAS(x)		((x) & 0x7FFF)
 #define		NRECFGLOG		0xC4
 #define		NREEECFBDA		0xC8
@@ -371,7 +371,7 @@ struct i5000_error_info {
 	/* These registers are input ONLY if there was a
 	 * Non-Recoverable Error */
 	u16 nrecmema;		/* Non-Recoverable Mem log A */
-	u16 nrecmemb;		/* Non-Recoverable Mem log B */
+	u32 nrecmemb;		/* Non-Recoverable Mem log B */
 
 };
 
@@ -407,7 +407,7 @@ static void i5000_get_error_info(struct
 				NERR_FAT_FBD, &info->nerr_fat_fbd);
 		pci_read_config_word(pvt->branchmap_werrors,
 				NRECMEMA, &info->nrecmema);
-		pci_read_config_word(pvt->branchmap_werrors,
+		pci_read_config_dword(pvt->branchmap_werrors,
 				NRECMEMB, &info->nrecmemb);
 
 		/* Clear the error bits, by writing them back */
@@ -1293,7 +1293,7 @@ static int i5000_init_csrows(struct mem_
 			dimm->mtype = MEM_FB_DDR2;
 
 			/* ask what device type on this row */
-			if (MTR_DRAM_WIDTH(mtr))
+			if (MTR_DRAM_WIDTH(mtr) == 8)
 				dimm->dtype = DEV_X8;
 			else
 				dimm->dtype = DEV_X4;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/edac/i5400_edac.c linux-libre-4.4.106-gnu/drivers/edac/i5400_edac.c
--- linux-libre-4.4.105-gnu/drivers/edac/i5400_edac.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/edac/i5400_edac.c	2017-12-16 04:33:57.000000000 -0500
@@ -368,7 +368,7 @@ struct i5400_error_info {
 
 	/* These registers are input ONLY if there was a Non-Rec Error */
 	u16 nrecmema;		/* Non-Recoverable Mem log A */
-	u16 nrecmemb;		/* Non-Recoverable Mem log B */
+	u32 nrecmemb;		/* Non-Recoverable Mem log B */
 
 };
 
@@ -458,7 +458,7 @@ static void i5400_get_error_info(struct
 				NERR_FAT_FBD, &info->nerr_fat_fbd);
 		pci_read_config_word(pvt->branchmap_werrors,
 				NRECMEMA, &info->nrecmema);
-		pci_read_config_word(pvt->branchmap_werrors,
+		pci_read_config_dword(pvt->branchmap_werrors,
 				NRECMEMB, &info->nrecmemb);
 
 		/* Clear the error bits, by writing them back */
@@ -1207,13 +1207,14 @@ static int i5400_init_dimms(struct mem_c
 
 			dimm->nr_pages = size_mb << 8;
 			dimm->grain = 8;
-			dimm->dtype = MTR_DRAM_WIDTH(mtr) ? DEV_X8 : DEV_X4;
+			dimm->dtype = MTR_DRAM_WIDTH(mtr) == 8 ?
+				      DEV_X8 : DEV_X4;
 			dimm->mtype = MEM_FB_DDR2;
 			/*
 			 * The eccc mechanism is SDDC (aka SECC), with
 			 * is similar to Chipkill.
 			 */
-			dimm->edac_mode = MTR_DRAM_WIDTH(mtr) ?
+			dimm->edac_mode = MTR_DRAM_WIDTH(mtr) == 8 ?
 					  EDAC_S8ECD8ED : EDAC_S4ECD4ED;
 			ndimms++;
 		}
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/firmware/efi/efi.c linux-libre-4.4.106-gnu/drivers/firmware/efi/efi.c
--- linux-libre-4.4.105-gnu/drivers/firmware/efi/efi.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/firmware/efi/efi.c	2017-12-16 04:33:57.000000000 -0500
@@ -113,8 +113,7 @@ static ssize_t systab_show(struct kobjec
 	return str - buf;
 }
 
-static struct kobj_attribute efi_attr_systab =
-			__ATTR(systab, 0400, systab_show, NULL);
+static struct kobj_attribute efi_attr_systab = __ATTR_RO_MODE(systab, 0400);
 
 #define EFI_FIELD(var) efi.var
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/firmware/efi/esrt.c linux-libre-4.4.106-gnu/drivers/firmware/efi/esrt.c
--- linux-libre-4.4.105-gnu/drivers/firmware/efi/esrt.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/firmware/efi/esrt.c	2017-12-16 04:33:57.000000000 -0500
@@ -105,7 +105,7 @@ static const struct sysfs_ops esre_attr_
 };
 
 /* Generic ESRT Entry ("ESRE") support. */
-static ssize_t esre_fw_class_show(struct esre_entry *entry, char *buf)
+static ssize_t fw_class_show(struct esre_entry *entry, char *buf)
 {
 	char *str = buf;
 
@@ -116,18 +116,16 @@ static ssize_t esre_fw_class_show(struct
 	return str - buf;
 }
 
-static struct esre_attribute esre_fw_class = __ATTR(fw_class, 0400,
-	esre_fw_class_show, NULL);
+static struct esre_attribute esre_fw_class = __ATTR_RO_MODE(fw_class, 0400);
 
 #define esre_attr_decl(name, size, fmt) \
-static ssize_t esre_##name##_show(struct esre_entry *entry, char *buf) \
+static ssize_t name##_show(struct esre_entry *entry, char *buf) \
 { \
 	return sprintf(buf, fmt "\n", \
 		       le##size##_to_cpu(entry->esre.esre1->name)); \
 } \
 \
-static struct esre_attribute esre_##name = __ATTR(name, 0400, \
-	esre_##name##_show, NULL)
+static struct esre_attribute esre_##name = __ATTR_RO_MODE(name, 0400)
 
 esre_attr_decl(fw_type, 32, "%u");
 esre_attr_decl(fw_version, 32, "%u");
@@ -195,14 +193,13 @@ static int esre_create_sysfs_entry(void
 
 /* support for displaying ESRT fields at the top level */
 #define esrt_attr_decl(name, size, fmt) \
-static ssize_t esrt_##name##_show(struct kobject *kobj, \
+static ssize_t name##_show(struct kobject *kobj, \
 				  struct kobj_attribute *attr, char *buf)\
 { \
 	return sprintf(buf, fmt "\n", le##size##_to_cpu(esrt->name)); \
 } \
 \
-static struct kobj_attribute esrt_##name = __ATTR(name, 0400, \
-	esrt_##name##_show, NULL)
+static struct kobj_attribute esrt_##name = __ATTR_RO_MODE(name, 0400)
 
 esrt_attr_decl(fw_resource_count, 32, "%u");
 esrt_attr_decl(fw_resource_count_max, 32, "%u");
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/firmware/efi/runtime-map.c linux-libre-4.4.106-gnu/drivers/firmware/efi/runtime-map.c
--- linux-libre-4.4.105-gnu/drivers/firmware/efi/runtime-map.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/firmware/efi/runtime-map.c	2017-12-16 04:33:57.000000000 -0500
@@ -67,11 +67,11 @@ static ssize_t map_attr_show(struct kobj
 	return map_attr->show(entry, buf);
 }
 
-static struct map_attribute map_type_attr = __ATTR_RO(type);
-static struct map_attribute map_phys_addr_attr   = __ATTR_RO(phys_addr);
-static struct map_attribute map_virt_addr_attr  = __ATTR_RO(virt_addr);
-static struct map_attribute map_num_pages_attr  = __ATTR_RO(num_pages);
-static struct map_attribute map_attribute_attr  = __ATTR_RO(attribute);
+static struct map_attribute map_type_attr = __ATTR_RO_MODE(type, 0400);
+static struct map_attribute map_phys_addr_attr = __ATTR_RO_MODE(phys_addr, 0400);
+static struct map_attribute map_virt_addr_attr = __ATTR_RO_MODE(virt_addr, 0400);
+static struct map_attribute map_num_pages_attr = __ATTR_RO_MODE(num_pages, 0400);
+static struct map_attribute map_attribute_attr = __ATTR_RO_MODE(attribute, 0400);
 
 /*
  * These are default attributes that are added for every memmap entry.
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/gpio/gpio-altera.c linux-libre-4.4.106-gnu/drivers/gpio/gpio-altera.c
--- linux-libre-4.4.105-gnu/drivers/gpio/gpio-altera.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/gpio/gpio-altera.c	2017-12-16 04:33:57.000000000 -0500
@@ -94,21 +94,18 @@ static int altera_gpio_irq_set_type(stru
 
 	altera_gc = to_altera(irq_data_get_irq_chip_data(d));
 
-	if (type == IRQ_TYPE_NONE)
-		return 0;
-	if (type == IRQ_TYPE_LEVEL_HIGH &&
-		altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH)
-		return 0;
-	if (type == IRQ_TYPE_EDGE_RISING &&
-		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_RISING)
-		return 0;
-	if (type == IRQ_TYPE_EDGE_FALLING &&
-		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_FALLING)
+	if (type == IRQ_TYPE_NONE) {
+		irq_set_handler_locked(d, handle_bad_irq);
 		return 0;
-	if (type == IRQ_TYPE_EDGE_BOTH &&
-		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_BOTH)
+	}
+	if (type == altera_gc->interrupt_trigger) {
+		if (type == IRQ_TYPE_LEVEL_HIGH)
+			irq_set_handler_locked(d, handle_level_irq);
+		else
+			irq_set_handler_locked(d, handle_simple_irq);
 		return 0;
-
+	}
+	irq_set_handler_locked(d, handle_bad_irq);
 	return -EINVAL;
 }
 
@@ -234,7 +231,6 @@ static void altera_gpio_irq_edge_handler
 	chained_irq_exit(chip, desc);
 }
 
-
 static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc)
 {
 	struct altera_gpio_chip *altera_gc;
@@ -314,7 +310,7 @@ static int altera_gpio_probe(struct plat
 	altera_gc->interrupt_trigger = reg;
 
 	ret = gpiochip_irqchip_add(&altera_gc->mmchip.gc, &altera_irq_chip, 0,
-		handle_simple_irq, IRQ_TYPE_NONE);
+		handle_bad_irq, IRQ_TYPE_NONE);
 
 	if (ret) {
 		dev_info(&pdev->dev, "could not add irqchip\n");
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c linux-libre-4.4.106-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
--- linux-libre-4.4.105-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2017-12-16 04:33:57.000000000 -0500
@@ -1760,8 +1760,11 @@ int amdgpu_resume_kms(struct drm_device
 	}
 
 	r = amdgpu_late_init(adev);
-	if (r)
+	if (r) {
+		if (fbcon)
+			console_unlock();
 		return r;
+	}
 
 	/* pin cursors */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/gpu/drm/armada/Makefile linux-libre-4.4.106-gnu/drivers/gpu/drm/armada/Makefile
--- linux-libre-4.4.105-gnu/drivers/gpu/drm/armada/Makefile	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/gpu/drm/armada/Makefile	2017-12-16 04:33:57.000000000 -0500
@@ -4,5 +4,3 @@ armada-y	+= armada_510.o
 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
 
 obj-$(CONFIG_DRM_ARMADA) := armada.o
-
-CFLAGS_armada_trace.o := -I$(src)
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c linux-libre-4.4.106-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c
--- linux-libre-4.4.105-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c	2017-12-16 04:33:57.000000000 -0500
@@ -245,6 +245,15 @@ struct exynos_drm_gem *exynos_drm_gem_cr
 	if (IS_ERR(exynos_gem))
 		return exynos_gem;
 
+	if (!is_drm_iommu_supported(dev) && (flags & EXYNOS_BO_NONCONTIG)) {
+		/*
+		 * when no IOMMU is available, all allocated buffers are
+		 * contiguous anyway, so drop EXYNOS_BO_NONCONTIG flag
+		 */
+		flags &= ~EXYNOS_BO_NONCONTIG;
+		DRM_WARN("Non-contiguous allocation is not supported without IOMMU, falling back to contiguous buffer\n");
+	}
+
 	/* set memory type and cache attribute from user side. */
 	exynos_gem->flags = flags;
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/hid/hid-chicony.c linux-libre-4.4.106-gnu/drivers/hid/hid-chicony.c
--- linux-libre-4.4.105-gnu/drivers/hid/hid-chicony.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/hid/hid-chicony.c	2017-12-16 04:33:57.000000000 -0500
@@ -86,6 +86,7 @@ static const struct hid_device_id ch_dev
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, ch_devices);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/hid/hid-core.c linux-libre-4.4.106-gnu/drivers/hid/hid-core.c
--- linux-libre-4.4.105-gnu/drivers/hid/hid-core.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/hid/hid-core.c	2017-12-16 04:33:57.000000000 -0500
@@ -1867,6 +1867,7 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_ZEN_AIO_KBD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/hid/hid-ids.h linux-libre-4.4.106-gnu/drivers/hid/hid-ids.h
--- linux-libre-4.4.105-gnu/drivers/hid/hid-ids.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/hid/hid-ids.h	2017-12-16 04:33:57.000000000 -0500
@@ -523,6 +523,7 @@
 
 #define USB_VENDOR_ID_JESS		0x0c45
 #define USB_DEVICE_ID_JESS_YUREX	0x1010
+#define USB_DEVICE_ID_JESS_ZEN_AIO_KBD	0x5112
 
 #define USB_VENDOR_ID_JESS2		0x0f30
 #define USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD 0x0111
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/hid/Kconfig linux-libre-4.4.106-gnu/drivers/hid/Kconfig
--- linux-libre-4.4.105-gnu/drivers/hid/Kconfig	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/hid/Kconfig	2017-12-16 04:33:57.000000000 -0500
@@ -165,11 +165,11 @@ config HID_CHERRY
 	Support for Cherry Cymotion keyboard.
 
 config HID_CHICONY
-	tristate "Chicony Tactical pad"
+	tristate "Chicony devices"
 	depends on HID
 	default !EXPERT
 	---help---
-	Support for Chicony Tactical pad.
+	Support for Chicony Tactical pad and special keys on Chicony keyboards.
 
 config HID_CORSAIR
 	tristate "Corsair devices"
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/i2c/busses/i2c-riic.c linux-libre-4.4.106-gnu/drivers/i2c/busses/i2c-riic.c
--- linux-libre-4.4.105-gnu/drivers/i2c/busses/i2c-riic.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/i2c/busses/i2c-riic.c	2017-12-16 04:33:57.000000000 -0500
@@ -218,8 +218,12 @@ static irqreturn_t riic_tend_isr(int irq
 	}
 
 	if (riic->is_last || riic->err) {
-		riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER);
+		riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER);
 		writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
+	} else {
+		/* Transfer is complete, but do not send STOP */
+		riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER);
+		complete(&riic->msg_done);
 	}
 
 	return IRQ_HANDLED;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/infiniband/hw/mlx4/qp.c linux-libre-4.4.106-gnu/drivers/infiniband/hw/mlx4/qp.c
--- linux-libre-4.4.105-gnu/drivers/infiniband/hw/mlx4/qp.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/infiniband/hw/mlx4/qp.c	2017-12-16 04:33:57.000000000 -0500
@@ -1564,7 +1564,7 @@ static int __mlx4_ib_modify_qp(struct ib
 			context->mtu_msgmax = (IB_MTU_4096 << 5) |
 					      ilog2(dev->dev->caps.max_gso_sz);
 		else
-			context->mtu_msgmax = (IB_MTU_4096 << 5) | 12;
+			context->mtu_msgmax = (IB_MTU_4096 << 5) | 13;
 	} else if (attr_mask & IB_QP_PATH_MTU) {
 		if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) {
 			pr_err("path MTU (%u) is invalid\n",
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-4.4.106-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-4.4.105-gnu/drivers/infiniband/hw/mlx5/main.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/infiniband/hw/mlx5/main.c	2017-12-16 04:33:57.000000000 -0500
@@ -1123,6 +1123,8 @@ static int create_umr_res(struct mlx5_ib
 	qp->real_qp    = qp;
 	qp->uobject    = NULL;
 	qp->qp_type    = MLX5_IB_QPT_REG_UMR;
+	qp->send_cq    = init_attr->send_cq;
+	qp->recv_cq    = init_attr->recv_cq;
 
 	attr->qp_state = IB_QPS_INIT;
 	attr->port_num = 1;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/iommu/intel-iommu.c linux-libre-4.4.106-gnu/drivers/iommu/intel-iommu.c
--- linux-libre-4.4.105-gnu/drivers/iommu/intel-iommu.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/iommu/intel-iommu.c	2017-12-16 04:33:57.000000000 -0500
@@ -2201,10 +2201,12 @@ static int __domain_mapping(struct dmar_
 		uint64_t tmp;
 
 		if (!sg_res) {
+			unsigned int pgoff = sg->offset & ~PAGE_MASK;
+
 			sg_res = aligned_nrpages(sg->offset, sg->length);
-			sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
+			sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
 			sg->dma_length = sg->length;
-			pteval = page_to_phys(sg_page(sg)) | prot;
+			pteval = (sg_phys(sg) - pgoff) | prot;
 			phys_pfn = pteval >> VTD_PAGE_SHIFT;
 		}
 
@@ -3757,7 +3759,7 @@ static int intel_nontranslate_map_sg(str
 
 	for_each_sg(sglist, sg, nelems, i) {
 		BUG_ON(!sg_page(sg));
-		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
+		sg->dma_address = sg_phys(sg);
 		sg->dma_length = sg->length;
 	}
 	return nelems;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/irqchip/irq-crossbar.c linux-libre-4.4.106-gnu/drivers/irqchip/irq-crossbar.c
--- linux-libre-4.4.105-gnu/drivers/irqchip/irq-crossbar.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/irqchip/irq-crossbar.c	2017-12-16 04:33:57.000000000 -0500
@@ -199,7 +199,7 @@ static const struct irq_domain_ops cross
 static int __init crossbar_of_init(struct device_node *node)
 {
 	int i, size, reserved = 0;
-	u32 max = 0, entry;
+	u32 max = 0, entry, reg_size;
 	const __be32 *irqsr;
 	int ret = -ENOMEM;
 
@@ -276,9 +276,9 @@ static int __init crossbar_of_init(struc
 	if (!cb->register_offsets)
 		goto err_irq_map;
 
-	of_property_read_u32(node, "ti,reg-size", &size);
+	of_property_read_u32(node, "ti,reg-size", &reg_size);
 
-	switch (size) {
+	switch (reg_size) {
 	case 1:
 		cb->write = crossbar_writeb;
 		break;
@@ -304,7 +304,7 @@ static int __init crossbar_of_init(struc
 			continue;
 
 		cb->register_offsets[i] = reserved;
-		reserved += size;
+		reserved += reg_size;
 	}
 
 	of_property_read_u32(node, "ti,irqs-safe-map", &cb->safe_map);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/media/usb/dvb-usb/dibusb-common.c linux-libre-4.4.106-gnu/drivers/media/usb/dvb-usb/dibusb-common.c
--- linux-libre-4.4.105-gnu/drivers/media/usb/dvb-usb/dibusb-common.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/media/usb/dvb-usb/dibusb-common.c	2017-12-16 04:33:57.000000000 -0500
@@ -179,8 +179,20 @@ EXPORT_SYMBOL(dibusb_i2c_algo);
 
 int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
 {
-	u8 wbuf[1] = { offs };
-	return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
+	u8 *buf;
+	int rc;
+
+	buf = kmalloc(2, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	buf[0] = offs;
+
+	rc = dibusb_i2c_msg(d, 0x50, &buf[0], 1, &buf[1], 1);
+	*val = buf[1];
+	kfree(buf);
+
+	return rc;
 }
 EXPORT_SYMBOL(dibusb_read_eeprom_byte);
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/memory/omap-gpmc.c linux-libre-4.4.106-gnu/drivers/memory/omap-gpmc.c
--- linux-libre-4.4.105-gnu/drivers/memory/omap-gpmc.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/memory/omap-gpmc.c	2017-12-16 04:33:57.000000000 -0500
@@ -1890,9 +1890,7 @@ static int gpmc_probe_onenand_child(stru
 	if (!of_property_read_u32(child, "dma-channel", &val))
 		gpmc_onenand_data->dma_channel = val;
 
-	gpmc_onenand_init(gpmc_onenand_data);
-
-	return 0;
+	return gpmc_onenand_init(gpmc_onenand_data);
 }
 #else
 static int gpmc_probe_onenand_child(struct platform_device *pdev,
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/can/ti_hecc.c linux-libre-4.4.106-gnu/drivers/net/can/ti_hecc.c
--- linux-libre-4.4.105-gnu/drivers/net/can/ti_hecc.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/can/ti_hecc.c	2017-12-16 04:33:57.000000000 -0500
@@ -652,6 +652,9 @@ static int ti_hecc_rx_poll(struct napi_s
 		mbx_mask = hecc_read(priv, HECC_CANMIM);
 		mbx_mask |= HECC_TX_MBOX_MASK;
 		hecc_write(priv, HECC_CANMIM, mbx_mask);
+	} else {
+		/* repoll is done only if whole budget is used */
+		num_pkts = quota;
 	}
 
 	return num_pkts;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/can/usb/ems_usb.c linux-libre-4.4.106-gnu/drivers/net/can/usb/ems_usb.c
--- linux-libre-4.4.105-gnu/drivers/net/can/usb/ems_usb.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/can/usb/ems_usb.c	2017-12-16 04:33:57.000000000 -0500
@@ -290,6 +290,8 @@ static void ems_usb_read_interrupt_callb
 
 	case -ECONNRESET: /* unlink */
 	case -ENOENT:
+	case -EPIPE:
+	case -EPROTO:
 	case -ESHUTDOWN:
 		return;
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/can/usb/esd_usb2.c linux-libre-4.4.106-gnu/drivers/net/can/usb/esd_usb2.c
--- linux-libre-4.4.105-gnu/drivers/net/can/usb/esd_usb2.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/can/usb/esd_usb2.c	2017-12-16 04:33:57.000000000 -0500
@@ -393,6 +393,8 @@ static void esd_usb2_read_bulk_callback(
 		break;
 
 	case -ENOENT:
+	case -EPIPE:
+	case -EPROTO:
 	case -ESHUTDOWN:
 		return;
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/can/usb/kvaser_usb.c linux-libre-4.4.106-gnu/drivers/net/can/usb/kvaser_usb.c
--- linux-libre-4.4.105-gnu/drivers/net/can/usb/kvaser_usb.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/can/usb/kvaser_usb.c	2017-12-16 04:33:57.000000000 -0500
@@ -603,8 +603,8 @@ static int kvaser_usb_wait_msg(const str
 			}
 
 			if (pos + tmp->len > actual_len) {
-				dev_err(dev->udev->dev.parent,
-					"Format error\n");
+				dev_err_ratelimited(dev->udev->dev.parent,
+						    "Format error\n");
 				break;
 			}
 
@@ -809,6 +809,7 @@ static int kvaser_usb_simple_msg_async(s
 	if (err) {
 		netdev_err(netdev, "Error transmitting URB\n");
 		usb_unanchor_urb(urb);
+		kfree(buf);
 		usb_free_urb(urb);
 		return err;
 	}
@@ -1321,6 +1322,8 @@ static void kvaser_usb_read_bulk_callbac
 	case 0:
 		break;
 	case -ENOENT:
+	case -EPIPE:
+	case -EPROTO:
 	case -ESHUTDOWN:
 		return;
 	default:
@@ -1329,7 +1332,7 @@ static void kvaser_usb_read_bulk_callbac
 		goto resubmit_urb;
 	}
 
-	while (pos <= urb->actual_length - MSG_HEADER_LEN) {
+	while (pos <= (int)(urb->actual_length - MSG_HEADER_LEN)) {
 		msg = urb->transfer_buffer + pos;
 
 		/* The Kvaser firmware can only read and write messages that
@@ -1348,7 +1351,8 @@ static void kvaser_usb_read_bulk_callbac
 		}
 
 		if (pos + msg->len > urb->actual_length) {
-			dev_err(dev->udev->dev.parent, "Format error\n");
+			dev_err_ratelimited(dev->udev->dev.parent,
+					    "Format error\n");
 			break;
 		}
 
@@ -1767,6 +1771,7 @@ static netdev_tx_t kvaser_usb_start_xmit
 		spin_unlock_irqrestore(&priv->tx_contexts_lock, flags);
 
 		usb_unanchor_urb(urb);
+		kfree(buf);
 
 		stats->tx_dropped++;
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/can/usb/usb_8dev.c linux-libre-4.4.106-gnu/drivers/net/can/usb/usb_8dev.c
--- linux-libre-4.4.105-gnu/drivers/net/can/usb/usb_8dev.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/can/usb/usb_8dev.c	2017-12-16 04:33:57.000000000 -0500
@@ -524,6 +524,8 @@ static void usb_8dev_read_bulk_callback(
 		break;
 
 	case -ENOENT:
+	case -EPIPE:
+	case -EPROTO:
 	case -ESHUTDOWN:
 		return;
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
--- linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2017-12-09 22:02:22.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2017-12-16 10:32:02.000000000 -0500
@@ -13582,7 +13582,7 @@ static int bnx2x_ptp_adjfreq(struct ptp_
 	if (!netif_running(bp->dev)) {
 		DP(BNX2X_MSG_PTP,
 		   "PTP adjfreq called while the interface is down\n");
-		return -EFAULT;
+		return -ENETDOWN;
 	}
 
 	if (ppb < 0) {
@@ -13641,6 +13641,12 @@ static int bnx2x_ptp_adjtime(struct ptp_
 {
 	struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info);
 
+	if (!netif_running(bp->dev)) {
+		DP(BNX2X_MSG_PTP,
+		   "PTP adjtime called while the interface is down\n");
+		return -ENETDOWN;
+	}
+
 	DP(BNX2X_MSG_PTP, "PTP adjtime called, delta = %llx\n", delta);
 
 	timecounter_adjtime(&bp->timecounter, delta);
@@ -13653,6 +13659,12 @@ static int bnx2x_ptp_gettime(struct ptp_
 	struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info);
 	u64 ns;
 
+	if (!netif_running(bp->dev)) {
+		DP(BNX2X_MSG_PTP,
+		   "PTP gettime called while the interface is down\n");
+		return -ENETDOWN;
+	}
+
 	ns = timecounter_read(&bp->timecounter);
 
 	DP(BNX2X_MSG_PTP, "PTP gettime called, ns = %llu\n", ns);
@@ -13668,6 +13680,12 @@ static int bnx2x_ptp_settime(struct ptp_
 	struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info);
 	u64 ns;
 
+	if (!netif_running(bp->dev)) {
+		DP(BNX2X_MSG_PTP,
+		   "PTP settime called while the interface is down\n");
+		return -ENETDOWN;
+	}
+
 	ns = timespec64_to_ns(ts);
 
 	DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
--- linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c	2017-12-16 04:33:57.000000000 -0500
@@ -434,7 +434,9 @@ static int bnx2x_vf_mac_vlan_config(stru
 
 	/* Add/Remove the filter */
 	rc = bnx2x_config_vlan_mac(bp, &ramrod);
-	if (rc && rc != -EEXIST) {
+	if (rc == -EEXIST)
+		return 0;
+	if (rc) {
 		BNX2X_ERR("Failed to %s %s\n",
 			  filter->add ? "add" : "delete",
 			  (filter->type == BNX2X_VF_FILTER_VLAN_MAC) ?
@@ -444,6 +446,8 @@ static int bnx2x_vf_mac_vlan_config(stru
 		return rc;
 	}
 
+	filter->applied = true;
+
 	return 0;
 }
 
@@ -471,6 +475,8 @@ int bnx2x_vf_mac_vlan_config_list(struct
 		BNX2X_ERR("Managed only %d/%d filters - rolling back\n",
 			  i, filters->count + 1);
 		while (--i >= 0) {
+			if (!filters->filters[i].applied)
+				continue;
 			filters->filters[i].add = !filters->filters[i].add;
 			bnx2x_vf_mac_vlan_config(bp, vf, qid,
 						 &filters->filters[i],
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
--- linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h	2017-12-16 04:33:57.000000000 -0500
@@ -114,6 +114,7 @@ struct bnx2x_vf_mac_vlan_filter {
 	(BNX2X_VF_FILTER_MAC | BNX2X_VF_FILTER_VLAN) /*shortcut*/
 
 	bool add;
+	bool applied;
 	u8 *mac;
 	u16 vid;
 };
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
--- linux-libre-4.4.105-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c	2017-12-16 04:33:57.000000000 -0500
@@ -868,7 +868,7 @@ int bnx2x_vfpf_set_mcast(struct net_devi
 	struct bnx2x *bp = netdev_priv(dev);
 	struct vfpf_set_q_filters_tlv *req = &bp->vf2pf_mbox->req.set_q_filters;
 	struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp;
-	int rc, i = 0;
+	int rc = 0, i = 0;
 	struct netdev_hw_addr *ha;
 
 	if (bp->state != BNX2X_STATE_OPEN) {
@@ -883,6 +883,15 @@ int bnx2x_vfpf_set_mcast(struct net_devi
 	/* Get Rx mode requested */
 	DP(NETIF_MSG_IFUP, "dev->flags = %x\n", dev->flags);
 
+	/* We support PFVF_MAX_MULTICAST_PER_VF mcast addresses tops */
+	if (netdev_mc_count(dev) > PFVF_MAX_MULTICAST_PER_VF) {
+		DP(NETIF_MSG_IFUP,
+		   "VF supports not more than %d multicast MAC addresses\n",
+		   PFVF_MAX_MULTICAST_PER_VF);
+		rc = -EINVAL;
+		goto out;
+	}
+
 	netdev_for_each_mc_addr(ha, dev) {
 		DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
 		   bnx2x_mc_addr(ha));
@@ -890,16 +899,6 @@ int bnx2x_vfpf_set_mcast(struct net_devi
 		i++;
 	}
 
-	/* We support four PFVF_MAX_MULTICAST_PER_VF mcast
-	  * addresses tops
-	  */
-	if (i >= PFVF_MAX_MULTICAST_PER_VF) {
-		DP(NETIF_MSG_IFUP,
-		   "VF supports not more than %d multicast MAC addresses\n",
-		   PFVF_MAX_MULTICAST_PER_VF);
-		return -EINVAL;
-	}
-
 	req->n_multicast = i;
 	req->flags |= VFPF_SET_Q_FILTERS_MULTICAST_CHANGED;
 	req->vf_qid = 0;
@@ -924,7 +923,7 @@ int bnx2x_vfpf_set_mcast(struct net_devi
 out:
 	bnx2x_vfpf_finalize(bp, &req->first_tlv);
 
-	return 0;
+	return rc;
 }
 
 /* request pf to add a vlan for the vf */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/ipvlan/ipvlan_core.c linux-libre-4.4.106-gnu/drivers/net/ipvlan/ipvlan_core.c
--- linux-libre-4.4.105-gnu/drivers/net/ipvlan/ipvlan_core.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/ipvlan/ipvlan_core.c	2017-12-16 04:33:57.000000000 -0500
@@ -388,7 +388,7 @@ static int ipvlan_process_v6_outbound(st
 	struct dst_entry *dst;
 	int err, ret = NET_XMIT_DROP;
 	struct flowi6 fl6 = {
-		.flowi6_iif = dev->ifindex,
+		.flowi6_oif = dev->ifindex,
 		.daddr = ip6h->daddr,
 		.saddr = ip6h->saddr,
 		.flowi6_flags = FLOWI_FLAG_ANYSRC,
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/phy/spi_ks8995.c linux-libre-4.4.106-gnu/drivers/net/phy/spi_ks8995.c
--- linux-libre-4.4.105-gnu/drivers/net/phy/spi_ks8995.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/phy/spi_ks8995.c	2017-12-16 04:33:57.000000000 -0500
@@ -310,6 +310,7 @@ static int ks8995_probe(struct spi_devic
 	if (err)
 		return err;
 
+	sysfs_attr_init(&ks->regs_attr.attr);
 	err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr);
 	if (err) {
 		dev_err(&spi->dev, "unable to create sysfs file, err=%d\n",
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/net/wireless/mac80211_hwsim.c linux-libre-4.4.106-gnu/drivers/net/wireless/mac80211_hwsim.c
--- linux-libre-4.4.105-gnu/drivers/net/wireless/mac80211_hwsim.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/net/wireless/mac80211_hwsim.c	2017-12-16 04:33:57.000000000 -0500
@@ -2885,6 +2885,7 @@ static int hwsim_new_radio_nl(struct sk_
 {
 	struct hwsim_new_radio_params param = { 0 };
 	const char *hwname = NULL;
+	int ret;
 
 	param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
 	param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE];
@@ -2924,7 +2925,9 @@ static int hwsim_new_radio_nl(struct sk_
 		param.regd = hwsim_world_regdom_custom[idx];
 	}
 
-	return mac80211_hwsim_new_radio(info, &param);
+	ret = mac80211_hwsim_new_radio(info, &param);
+	kfree(hwname);
+	return ret;
 }
 
 static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/scsi/lpfc/lpfc_els.c linux-libre-4.4.106-gnu/drivers/scsi/lpfc/lpfc_els.c
--- linux-libre-4.4.105-gnu/drivers/scsi/lpfc/lpfc_els.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/scsi/lpfc/lpfc_els.c	2017-12-16 04:33:57.000000000 -0500
@@ -7887,11 +7887,17 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba
 			spin_lock_irq(shost->host_lock);
 			vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
 			spin_unlock_irq(shost->host_lock);
-			if (vport->port_type == LPFC_PHYSICAL_PORT
-				&& !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG))
-				lpfc_issue_init_vfi(vport);
-			else
+			if (mb->mbxStatus == MBX_NOT_FINISHED)
+				break;
+			if ((vport->port_type == LPFC_PHYSICAL_PORT) &&
+			    !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) {
+				if (phba->sli_rev == LPFC_SLI_REV4)
+					lpfc_issue_init_vfi(vport);
+				else
+					lpfc_initial_flogi(vport);
+			} else {
 				lpfc_initial_fdisc(vport);
+			}
 			break;
 		}
 	} else {
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/scsi/storvsc_drv.c linux-libre-4.4.106-gnu/drivers/scsi/storvsc_drv.c
--- linux-libre-4.4.105-gnu/drivers/scsi/storvsc_drv.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/scsi/storvsc_drv.c	2017-12-16 04:33:57.000000000 -0500
@@ -379,8 +379,6 @@ MODULE_PARM_DESC(vcpus_per_sub_channel,
  */
 static int storvsc_timeout = 180;
 
-static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
-
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -1241,6 +1239,22 @@ static int storvsc_do_io(struct hv_devic
 	return ret;
 }
 
+static int storvsc_device_alloc(struct scsi_device *sdevice)
+{
+	/*
+	 * Set blist flag to permit the reading of the VPD pages even when
+	 * the target may claim SPC-2 compliance. MSFT targets currently
+	 * claim SPC-2 compliance while they implement post SPC-2 features.
+	 * With this flag we can correctly handle WRITE_SAME_16 issues.
+	 *
+	 * Hypervisor reports SCSI_UNKNOWN type for DVD ROM device but
+	 * still supports REPORT LUN.
+	 */
+	sdevice->sdev_bflags = BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES;
+
+	return 0;
+}
+
 static int storvsc_device_configure(struct scsi_device *sdevice)
 {
 
@@ -1256,14 +1270,6 @@ static int storvsc_device_configure(stru
 	sdevice->no_write_same = 1;
 
 	/*
-	 * Add blist flags to permit the reading of the VPD pages even when
-	 * the target may claim SPC-2 compliance. MSFT targets currently
-	 * claim SPC-2 compliance while they implement post SPC-2 features.
-	 * With this patch we can correctly handle WRITE_SAME_16 issues.
-	 */
-	sdevice->sdev_bflags |= msft_blist_flags;
-
-	/*
 	 * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
 	 * if the device is a MSFT virtual device.  If the host is
 	 * WIN10 or newer, allow write_same.
@@ -1529,6 +1535,7 @@ static struct scsi_host_template scsi_dr
 	.eh_host_reset_handler =	storvsc_host_reset_handler,
 	.proc_name =		"storvsc_host",
 	.eh_timed_out =		storvsc_eh_timed_out,
+	.slave_alloc =		storvsc_device_alloc,
 	.slave_configure =	storvsc_device_configure,
 	.cmd_per_lun =		255,
 	.this_id =		-1,
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/spi/Kconfig linux-libre-4.4.106-gnu/drivers/spi/Kconfig
--- linux-libre-4.4.105-gnu/drivers/spi/Kconfig	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/spi/Kconfig	2017-12-16 04:33:57.000000000 -0500
@@ -315,7 +315,6 @@ config SPI_FSL_SPI
 config SPI_FSL_DSPI
 	tristate "Freescale DSPI controller"
 	select REGMAP_MMIO
-	depends on HAS_DMA
 	depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST
 	help
 	  This enables support for the Freescale DSPI controller in master
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/usb/gadget/configfs.c linux-libre-4.4.106-gnu/drivers/usb/gadget/configfs.c
--- linux-libre-4.4.105-gnu/drivers/usb/gadget/configfs.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/usb/gadget/configfs.c	2017-12-16 04:33:57.000000000 -0500
@@ -270,6 +270,7 @@ static ssize_t gadget_dev_desc_UDC_store
 		ret = unregister_gadget(gi);
 		if (ret)
 			goto err;
+		kfree(name);
 	} else {
 		if (gi->udc_name) {
 			ret = -EBUSY;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/usb/gadget/function/f_fs.c linux-libre-4.4.106-gnu/drivers/usb/gadget/function/f_fs.c
--- linux-libre-4.4.105-gnu/drivers/usb/gadget/function/f_fs.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/usb/gadget/function/f_fs.c	2017-12-16 04:33:57.000000000 -0500
@@ -791,7 +791,7 @@ static ssize_t ffs_epfile_io(struct file
 		}
 
 		if (io_data->aio) {
-			req = usb_ep_alloc_request(ep->ep, GFP_KERNEL);
+			req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC);
 			if (unlikely(!req))
 				goto error_lock;
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/usb/gadget/legacy/inode.c linux-libre-4.4.106-gnu/drivers/usb/gadget/legacy/inode.c
--- linux-libre-4.4.105-gnu/drivers/usb/gadget/legacy/inode.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/usb/gadget/legacy/inode.c	2017-12-16 04:33:57.000000000 -0500
@@ -1837,8 +1837,10 @@ dev_config (struct file *fd, const char
 
 	spin_lock_irq (&dev->lock);
 	value = -EINVAL;
-	if (dev->buf)
+	if (dev->buf) {
+		kfree(kbuf);
 		goto fail;
+	}
 	dev->buf = kbuf;
 
 	/* full or low speed config */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/drivers/virtio/virtio.c linux-libre-4.4.106-gnu/drivers/virtio/virtio.c
--- linux-libre-4.4.105-gnu/drivers/virtio/virtio.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/drivers/virtio/virtio.c	2017-12-16 04:33:57.000000000 -0500
@@ -323,6 +323,8 @@ int register_virtio_device(struct virtio
 	/* device_register() causes the bus infrastructure to look for a
 	 * matching driver. */
 	err = device_register(&dev->dev);
+	if (err)
+		ida_simple_remove(&virtio_index_ida, dev->index);
 out:
 	if (err)
 		add_status(dev, VIRTIO_CONFIG_S_FAILED);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/fs/afs/cmservice.c linux-libre-4.4.106-gnu/fs/afs/cmservice.c
--- linux-libre-4.4.105-gnu/fs/afs/cmservice.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/fs/afs/cmservice.c	2017-12-16 04:33:57.000000000 -0500
@@ -115,6 +115,9 @@ bool afs_cm_incoming_call(struct afs_cal
 	case CBProbe:
 		call->type = &afs_SRXCBProbe;
 		return true;
+	case CBProbeUuid:
+		call->type = &afs_SRXCBProbeUuid;
+		return true;
 	case CBTellMeAboutYourself:
 		call->type = &afs_SRXCBTellMeAboutYourself;
 		return true;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/fs/nfs/dir.c linux-libre-4.4.106-gnu/fs/nfs/dir.c
--- linux-libre-4.4.105-gnu/fs/nfs/dir.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/fs/nfs/dir.c	2017-12-16 04:33:57.000000000 -0500
@@ -2051,7 +2051,7 @@ out:
 		if (new_inode != NULL)
 			nfs_drop_nlink(new_inode);
 		d_move(old_dentry, new_dentry);
-		nfs_set_verifier(new_dentry,
+		nfs_set_verifier(old_dentry,
 					nfs_save_change_attribute(new_dir));
 	} else if (error == -ENOENT)
 		nfs_dentry_handle_enoent(old_dentry);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/include/drm/drmP.h linux-libre-4.4.106-gnu/include/drm/drmP.h
--- linux-libre-4.4.105-gnu/include/drm/drmP.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/include/drm/drmP.h	2017-12-16 04:33:57.000000000 -0500
@@ -158,6 +158,26 @@ void drm_err(const char *format, ...);
 /** \name Macros to make printk easier */
 /*@{*/
 
+#define _DRM_PRINTK(once, level, fmt, ...)				\
+	do {								\
+		printk##once(KERN_##level "[" DRM_NAME "] " fmt,	\
+			     ##__VA_ARGS__);				\
+	} while (0)
+
+#define DRM_INFO(fmt, ...)						\
+	_DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__)
+#define DRM_NOTE(fmt, ...)						\
+	_DRM_PRINTK(, NOTICE, fmt, ##__VA_ARGS__)
+#define DRM_WARN(fmt, ...)						\
+	_DRM_PRINTK(, WARNING, fmt, ##__VA_ARGS__)
+
+#define DRM_INFO_ONCE(fmt, ...)						\
+	_DRM_PRINTK(_once, INFO, fmt, ##__VA_ARGS__)
+#define DRM_NOTE_ONCE(fmt, ...)						\
+	_DRM_PRINTK(_once, NOTICE, fmt, ##__VA_ARGS__)
+#define DRM_WARN_ONCE(fmt, ...)						\
+	_DRM_PRINTK(_once, WARNING, fmt, ##__VA_ARGS__)
+
 /**
  * Error output.
  *
@@ -183,12 +203,6 @@ void drm_err(const char *format, ...);
 		drm_err(fmt, ##__VA_ARGS__);				\
 })
 
-#define DRM_INFO(fmt, ...)				\
-	printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__)
-
-#define DRM_INFO_ONCE(fmt, ...)				\
-	printk_once(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__)
-
 /**
  * Debug output.
  *
diff -druNp --no-dereference linux-libre-4.4.105-gnu/include/linux/genalloc.h linux-libre-4.4.106-gnu/include/linux/genalloc.h
--- linux-libre-4.4.105-gnu/include/linux/genalloc.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/include/linux/genalloc.h	2017-12-16 04:33:57.000000000 -0500
@@ -31,6 +31,7 @@
 #define __GENALLOC_H__
 
 #include <linux/spinlock_types.h>
+#include <linux/atomic.h>
 
 struct device;
 struct device_node;
@@ -68,7 +69,7 @@ struct gen_pool {
  */
 struct gen_pool_chunk {
 	struct list_head next_chunk;	/* next chunk in pool */
-	atomic_t avail;
+	atomic_long_t avail;
 	phys_addr_t phys_addr;		/* physical starting address of memory chunk */
 	unsigned long start_addr;	/* start address of memory chunk */
 	unsigned long end_addr;		/* end address of memory chunk (inclusive) */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/include/linux/mmu_notifier.h linux-libre-4.4.106-gnu/include/linux/mmu_notifier.h
--- linux-libre-4.4.105-gnu/include/linux/mmu_notifier.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/include/linux/mmu_notifier.h	2017-12-16 04:33:57.000000000 -0500
@@ -381,18 +381,6 @@ static inline void mmu_notifier_mm_destr
 	___pmd;								\
 })
 
-#define pmdp_huge_get_and_clear_notify(__mm, __haddr, __pmd)		\
-({									\
-	unsigned long ___haddr = __haddr & HPAGE_PMD_MASK;		\
-	pmd_t ___pmd;							\
-									\
-	___pmd = pmdp_huge_get_and_clear(__mm, __haddr, __pmd);		\
-	mmu_notifier_invalidate_range(__mm, ___haddr,			\
-				      ___haddr + HPAGE_PMD_SIZE);	\
-									\
-	___pmd;								\
-})
-
 /*
  * set_pte_at_notify() sets the pte _after_ running the notifier.
  * This is safe to start by updating the secondary MMUs, because the primary MMU
@@ -475,7 +463,6 @@ static inline void mmu_notifier_mm_destr
 #define pmdp_clear_young_notify pmdp_test_and_clear_young
 #define	ptep_clear_flush_notify ptep_clear_flush
 #define pmdp_huge_clear_flush_notify pmdp_huge_clear_flush
-#define pmdp_huge_get_and_clear_notify pmdp_huge_get_and_clear
 #define set_pte_at_notify set_pte_at
 
 #endif /* CONFIG_MMU_NOTIFIER */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/include/linux/omap-gpmc.h linux-libre-4.4.106-gnu/include/linux/omap-gpmc.h
--- linux-libre-4.4.105-gnu/include/linux/omap-gpmc.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/include/linux/omap-gpmc.h	2017-12-16 04:33:57.000000000 -0500
@@ -191,10 +191,11 @@ static inline int gpmc_nand_init(struct
 #endif
 
 #if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
-extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
+extern int gpmc_onenand_init(struct omap_onenand_platform_data *d);
 #else
 #define board_onenand_data	NULL
-static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
+static inline int gpmc_onenand_init(struct omap_onenand_platform_data *d)
 {
+	return 0;
 }
 #endif
diff -druNp --no-dereference linux-libre-4.4.105-gnu/include/linux/sysfs.h linux-libre-4.4.106-gnu/include/linux/sysfs.h
--- linux-libre-4.4.105-gnu/include/linux/sysfs.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/include/linux/sysfs.h	2017-12-16 04:33:57.000000000 -0500
@@ -116,6 +116,12 @@ struct attribute_group {
 	.show	= _name##_show,						\
 }
 
+#define __ATTR_RO_MODE(_name, _mode) {					\
+	.attr	= { .name = __stringify(_name),				\
+		    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },		\
+	.show	= _name##_show,						\
+}
+
 #define __ATTR_WO(_name) {						\
 	.attr	= { .name = __stringify(_name), .mode = S_IWUSR },	\
 	.store	= _name##_store,					\
diff -druNp --no-dereference linux-libre-4.4.105-gnu/include/scsi/libsas.h linux-libre-4.4.106-gnu/include/scsi/libsas.h
--- linux-libre-4.4.105-gnu/include/scsi/libsas.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/include/scsi/libsas.h	2017-12-16 04:33:57.000000000 -0500
@@ -165,11 +165,11 @@ struct expander_device {
 
 struct sata_device {
 	unsigned int class;
-	struct smp_resp        rps_resp; /* report_phy_sata_resp */
 	u8     port_no;        /* port number, if this is a PM (Port) */
 
 	struct ata_port *ap;
 	struct ata_host ata_host;
+	struct smp_resp rps_resp ____cacheline_aligned; /* report_phy_sata_resp */
 	u8     fis[ATA_RESP_FIS_SIZE];
 };
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/kernel/audit.c linux-libre-4.4.106-gnu/kernel/audit.c
--- linux-libre-4.4.105-gnu/kernel/audit.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/kernel/audit.c	2017-12-16 04:33:57.000000000 -0500
@@ -80,13 +80,13 @@ static int	audit_initialized;
 #define AUDIT_OFF	0
 #define AUDIT_ON	1
 #define AUDIT_LOCKED	2
-u32		audit_enabled;
-u32		audit_ever_enabled;
+u32		audit_enabled = AUDIT_OFF;
+u32		audit_ever_enabled = !!AUDIT_OFF;
 
 EXPORT_SYMBOL_GPL(audit_enabled);
 
 /* Default state when kernel boots without any parameters. */
-static u32	audit_default;
+static u32	audit_default = AUDIT_OFF;
 
 /* If auditing cannot proceed, audit_failure selects what happens. */
 static u32	audit_failure = AUDIT_FAIL_PRINTK;
@@ -1179,8 +1179,6 @@ static int __init audit_init(void)
 	skb_queue_head_init(&audit_skb_queue);
 	skb_queue_head_init(&audit_skb_hold_queue);
 	audit_initialized = AUDIT_INITIALIZED;
-	audit_enabled = audit_default;
-	audit_ever_enabled |= !!audit_default;
 
 	audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
 
@@ -1197,6 +1195,8 @@ static int __init audit_enable(char *str
 	audit_default = !!simple_strtol(str, NULL, 0);
 	if (!audit_default)
 		audit_initialized = AUDIT_DISABLED;
+	audit_enabled = audit_default;
+	audit_ever_enabled = !!audit_enabled;
 
 	pr_info("%s\n", audit_default ?
 		"enabled (after initialization)" : "disabled (until reboot)");
diff -druNp --no-dereference linux-libre-4.4.105-gnu/kernel/debug/kdb/kdb_io.c linux-libre-4.4.106-gnu/kernel/debug/kdb/kdb_io.c
--- linux-libre-4.4.105-gnu/kernel/debug/kdb/kdb_io.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/kernel/debug/kdb/kdb_io.c	2017-12-16 04:33:57.000000000 -0500
@@ -349,7 +349,7 @@ poll_again:
 			}
 			kdb_printf("\n");
 			for (i = 0; i < count; i++) {
-				if (kallsyms_symbol_next(p_tmp, i) < 0)
+				if (WARN_ON(!kallsyms_symbol_next(p_tmp, i)))
 					break;
 				kdb_printf("%s ", p_tmp);
 				*(p_tmp + len) = '\0';
diff -druNp --no-dereference linux-libre-4.4.105-gnu/kernel/jump_label.c linux-libre-4.4.106-gnu/kernel/jump_label.c
--- linux-libre-4.4.105-gnu/kernel/jump_label.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/kernel/jump_label.c	2017-12-16 04:33:57.000000000 -0500
@@ -553,7 +553,7 @@ static __init int jump_label_test(void)
 
 	return 0;
 }
-late_initcall(jump_label_test);
+early_initcall(jump_label_test);
 #endif /* STATIC_KEYS_SELFTEST */
 
 #endif /* HAVE_JUMP_LABEL */
diff -druNp --no-dereference linux-libre-4.4.105-gnu/kernel/workqueue.c linux-libre-4.4.106-gnu/kernel/workqueue.c
--- linux-libre-4.4.105-gnu/kernel/workqueue.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/kernel/workqueue.c	2017-12-16 04:33:57.000000000 -0500
@@ -1479,6 +1479,7 @@ static void __queue_delayed_work(int cpu
 	struct timer_list *timer = &dwork->timer;
 	struct work_struct *work = &dwork->work;
 
+	WARN_ON_ONCE(!wq);
 	WARN_ON_ONCE(timer->function != delayed_work_timer_fn ||
 		     timer->data != (unsigned long)dwork);
 	WARN_ON_ONCE(timer_pending(timer));
diff -druNp --no-dereference linux-libre-4.4.105-gnu/lib/asn1_decoder.c linux-libre-4.4.106-gnu/lib/asn1_decoder.c
--- linux-libre-4.4.105-gnu/lib/asn1_decoder.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/lib/asn1_decoder.c	2017-12-16 04:33:57.000000000 -0500
@@ -312,42 +312,47 @@ next_op:
 
 	/* Decide how to handle the operation */
 	switch (op) {
-	case ASN1_OP_MATCH_ANY_ACT:
-	case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
-	case ASN1_OP_COND_MATCH_ANY_ACT:
-	case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:
-		ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len);
-		if (ret < 0)
-			return ret;
-		goto skip_data;
-
-	case ASN1_OP_MATCH_ACT:
-	case ASN1_OP_MATCH_ACT_OR_SKIP:
-	case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
-		ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len);
-		if (ret < 0)
-			return ret;
-		goto skip_data;
-
 	case ASN1_OP_MATCH:
 	case ASN1_OP_MATCH_OR_SKIP:
+	case ASN1_OP_MATCH_ACT:
+	case ASN1_OP_MATCH_ACT_OR_SKIP:
 	case ASN1_OP_MATCH_ANY:
 	case ASN1_OP_MATCH_ANY_OR_SKIP:
+	case ASN1_OP_MATCH_ANY_ACT:
+	case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
 	case ASN1_OP_COND_MATCH_OR_SKIP:
+	case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
 	case ASN1_OP_COND_MATCH_ANY:
 	case ASN1_OP_COND_MATCH_ANY_OR_SKIP:
-	skip_data:
+	case ASN1_OP_COND_MATCH_ANY_ACT:
+	case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:
+
 		if (!(flags & FLAG_CONS)) {
 			if (flags & FLAG_INDEFINITE_LENGTH) {
+				size_t tmp = dp;
+
 				ret = asn1_find_indefinite_length(
-					data, datalen, &dp, &len, &errmsg);
+					data, datalen, &tmp, &len, &errmsg);
 				if (ret < 0)
 					goto error;
-			} else {
-				dp += len;
 			}
 			pr_debug("- LEAF: %zu\n", len);
 		}
+
+		if (op & ASN1_OP_MATCH__ACT) {
+			unsigned char act;
+
+			if (op & ASN1_OP_MATCH__ANY)
+				act = machine[pc + 1];
+			else
+				act = machine[pc + 2];
+			ret = actions[act](context, hdr, tag, data + dp, len);
+			if (ret < 0)
+				return ret;
+		}
+
+		if (!(flags & FLAG_CONS))
+			dp += len;
 		pc += asn1_op_lengths[op];
 		goto next_op;
 
@@ -433,6 +438,8 @@ next_op:
 			else
 				act = machine[pc + 1];
 			ret = actions[act](context, hdr, 0, data + tdp, len);
+			if (ret < 0)
+				return ret;
 		}
 		pc += asn1_op_lengths[op];
 		goto next_op;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/lib/dynamic_debug.c linux-libre-4.4.106-gnu/lib/dynamic_debug.c
--- linux-libre-4.4.105-gnu/lib/dynamic_debug.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/lib/dynamic_debug.c	2017-12-16 04:33:57.000000000 -0500
@@ -353,6 +353,10 @@ static int ddebug_parse_query(char *word
 				if (parse_lineno(last, &query->last_lineno) < 0)
 					return -EINVAL;
 
+				/* special case for last lineno not specified */
+				if (query->last_lineno == 0)
+					query->last_lineno = UINT_MAX;
+
 				if (query->last_lineno < query->first_lineno) {
 					pr_err("last-line:%d < 1st-line:%d\n",
 						query->last_lineno,
diff -druNp --no-dereference linux-libre-4.4.105-gnu/lib/genalloc.c linux-libre-4.4.106-gnu/lib/genalloc.c
--- linux-libre-4.4.105-gnu/lib/genalloc.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/lib/genalloc.c	2017-12-16 04:33:57.000000000 -0500
@@ -194,7 +194,7 @@ int gen_pool_add_virt(struct gen_pool *p
 	chunk->phys_addr = phys;
 	chunk->start_addr = virt;
 	chunk->end_addr = virt + size - 1;
-	atomic_set(&chunk->avail, size);
+	atomic_long_set(&chunk->avail, size);
 
 	spin_lock(&pool->lock);
 	list_add_rcu(&chunk->next_chunk, &pool->chunks);
@@ -285,7 +285,7 @@ unsigned long gen_pool_alloc(struct gen_
 	nbits = (size + (1UL << order) - 1) >> order;
 	rcu_read_lock();
 	list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) {
-		if (size > atomic_read(&chunk->avail))
+		if (size > atomic_long_read(&chunk->avail))
 			continue;
 
 		start_bit = 0;
@@ -305,7 +305,7 @@ retry:
 
 		addr = chunk->start_addr + ((unsigned long)start_bit << order);
 		size = nbits << order;
-		atomic_sub(size, &chunk->avail);
+		atomic_long_sub(size, &chunk->avail);
 		break;
 	}
 	rcu_read_unlock();
@@ -371,7 +371,7 @@ void gen_pool_free(struct gen_pool *pool
 			remain = bitmap_clear_ll(chunk->bits, start_bit, nbits);
 			BUG_ON(remain);
 			size = nbits << order;
-			atomic_add(size, &chunk->avail);
+			atomic_long_add(size, &chunk->avail);
 			rcu_read_unlock();
 			return;
 		}
@@ -445,7 +445,7 @@ size_t gen_pool_avail(struct gen_pool *p
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk)
-		avail += atomic_read(&chunk->avail);
+		avail += atomic_long_read(&chunk->avail);
 	rcu_read_unlock();
 	return avail;
 }
diff -druNp --no-dereference linux-libre-4.4.105-gnu/Makefile linux-libre-4.4.106-gnu/Makefile
--- linux-libre-4.4.105-gnu/Makefile	2017-12-09 21:45:21.000000000 -0500
+++ linux-libre-4.4.106-gnu/Makefile	2017-12-16 10:22:21.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 105
+SUBLEVEL = 106
 EXTRAVERSION = -gnu
 NAME = Blurry Fish Butt
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/mm/huge_memory.c linux-libre-4.4.106-gnu/mm/huge_memory.c
--- linux-libre-4.4.105-gnu/mm/huge_memory.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/mm/huge_memory.c	2017-12-16 04:33:57.000000000 -0500
@@ -1566,35 +1566,69 @@ int change_huge_pmd(struct vm_area_struc
 {
 	struct mm_struct *mm = vma->vm_mm;
 	spinlock_t *ptl;
+	pmd_t entry;
+	bool preserve_write;
+
 	int ret = 0;
 
-	if (__pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
-		pmd_t entry;
-		bool preserve_write = prot_numa && pmd_write(*pmd);
-		ret = 1;
+	if (__pmd_trans_huge_lock(pmd, vma, &ptl) != 1)
+		return 0;
 
-		/*
-		 * Avoid trapping faults against the zero page. The read-only
-		 * data is likely to be read-cached on the local CPU and
-		 * local/remote hits to the zero page are not interesting.
-		 */
-		if (prot_numa && is_huge_zero_pmd(*pmd)) {
-			spin_unlock(ptl);
-			return ret;
-		}
+	preserve_write = prot_numa && pmd_write(*pmd);
+	ret = 1;
 
-		if (!prot_numa || !pmd_protnone(*pmd)) {
-			entry = pmdp_huge_get_and_clear_notify(mm, addr, pmd);
-			entry = pmd_modify(entry, newprot);
-			if (preserve_write)
-				entry = pmd_mkwrite(entry);
-			ret = HPAGE_PMD_NR;
-			set_pmd_at(mm, addr, pmd, entry);
-			BUG_ON(!preserve_write && pmd_write(entry));
-		}
-		spin_unlock(ptl);
-	}
+	/*
+	 * Avoid trapping faults against the zero page. The read-only
+	 * data is likely to be read-cached on the local CPU and
+	 * local/remote hits to the zero page are not interesting.
+	 */
+	if (prot_numa && is_huge_zero_pmd(*pmd))
+		goto unlock;
+
+	if (prot_numa && pmd_protnone(*pmd))
+		goto unlock;
 
+	/*
+	 * In case prot_numa, we are under down_read(mmap_sem). It's critical
+	 * to not clear pmd intermittently to avoid race with MADV_DONTNEED
+	 * which is also under down_read(mmap_sem):
+	 *
+	 *	CPU0:				CPU1:
+	 *				change_huge_pmd(prot_numa=1)
+	 *				 pmdp_huge_get_and_clear_notify()
+	 * madvise_dontneed()
+	 *  zap_pmd_range()
+	 *   pmd_trans_huge(*pmd) == 0 (without ptl)
+	 *   // skip the pmd
+	 *				 set_pmd_at();
+	 *				 // pmd is re-established
+	 *
+	 * The race makes MADV_DONTNEED miss the huge pmd and don't clear it
+	 * which may break userspace.
+	 *
+	 * pmdp_invalidate() is required to make sure we don't miss
+	 * dirty/young flags set by hardware.
+	 */
+	entry = *pmd;
+	pmdp_invalidate(vma, addr, pmd);
+
+	/*
+	 * Recover dirty/young flags.  It relies on pmdp_invalidate to not
+	 * corrupt them.
+	 */
+	if (pmd_dirty(*pmd))
+		entry = pmd_mkdirty(entry);
+	if (pmd_young(*pmd))
+		entry = pmd_mkyoung(entry);
+
+	entry = pmd_modify(entry, newprot);
+	if (preserve_write)
+		entry = pmd_mkwrite(entry);
+	ret = HPAGE_PMD_NR;
+	set_pmd_at(mm, addr, pmd, entry);
+	BUG_ON(!preserve_write && pmd_write(entry));
+unlock:
+	spin_unlock(ptl);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c linux-libre-4.4.106-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
--- linux-libre-4.4.105-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c	2017-12-16 04:33:57.000000000 -0500
@@ -158,6 +158,10 @@ static unsigned int ipv4_conntrack_local
 	if (skb->len < sizeof(struct iphdr) ||
 	    ip_hdrlen(skb) < sizeof(struct iphdr))
 		return NF_ACCEPT;
+
+	if (ip_is_fragment(ip_hdr(skb))) /* IP_NODEFRAG setsockopt set */
+		return NF_ACCEPT;
+
 	return nf_conntrack_in(state->net, PF_INET, state->hook, skb);
 }
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c linux-libre-4.4.106-gnu/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
--- linux-libre-4.4.105-gnu/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c	2017-12-16 04:33:57.000000000 -0500
@@ -268,11 +268,6 @@ nf_nat_ipv4_fn(void *priv, struct sk_buf
 	/* maniptype == SRC for postrouting. */
 	enum nf_nat_manip_type maniptype = HOOK2MANIP(state->hook);
 
-	/* We never see fragments: conntrack defrags on pre-routing
-	 * and local-out, and nf_nat_out protects post-routing.
-	 */
-	NF_CT_ASSERT(!ip_is_fragment(ip_hdr(skb)));
-
 	ct = nf_ct_get(skb, &ctinfo);
 	/* Can't track?  It's not due to stress, or conntrack would
 	 * have dropped it.  Hence it's the user's responsibilty to
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/ipv4/route.c linux-libre-4.4.106-gnu/net/ipv4/route.c
--- linux-libre-4.4.105-gnu/net/ipv4/route.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/ipv4/route.c	2017-12-16 04:33:57.000000000 -0500
@@ -624,9 +624,12 @@ static void update_or_create_fnhe(struct
 	struct fnhe_hash_bucket *hash;
 	struct fib_nh_exception *fnhe;
 	struct rtable *rt;
+	u32 genid, hval;
 	unsigned int i;
 	int depth;
-	u32 hval = fnhe_hashfun(daddr);
+
+	genid = fnhe_genid(dev_net(nh->nh_dev));
+	hval = fnhe_hashfun(daddr);
 
 	spin_lock_bh(&fnhe_lock);
 
@@ -649,12 +652,13 @@ static void update_or_create_fnhe(struct
 	}
 
 	if (fnhe) {
+		if (fnhe->fnhe_genid != genid)
+			fnhe->fnhe_genid = genid;
 		if (gw)
 			fnhe->fnhe_gw = gw;
-		if (pmtu) {
+		if (pmtu)
 			fnhe->fnhe_pmtu = pmtu;
-			fnhe->fnhe_expires = max(1UL, expires);
-		}
+		fnhe->fnhe_expires = max(1UL, expires);
 		/* Update all cached dsts too */
 		rt = rcu_dereference(fnhe->fnhe_rth_input);
 		if (rt)
@@ -673,7 +677,7 @@ static void update_or_create_fnhe(struct
 			fnhe->fnhe_next = hash->chain;
 			rcu_assign_pointer(hash->chain, fnhe);
 		}
-		fnhe->fnhe_genid = fnhe_genid(dev_net(nh->nh_dev));
+		fnhe->fnhe_genid = genid;
 		fnhe->fnhe_daddr = daddr;
 		fnhe->fnhe_gw = gw;
 		fnhe->fnhe_pmtu = pmtu;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/ipv6/af_inet6.c linux-libre-4.4.106-gnu/net/ipv6/af_inet6.c
--- linux-libre-4.4.105-gnu/net/ipv6/af_inet6.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/ipv6/af_inet6.c	2017-12-16 04:33:57.000000000 -0500
@@ -893,12 +893,12 @@ static int __init inet6_init(void)
 	err = register_pernet_subsys(&inet6_net_ops);
 	if (err)
 		goto register_pernet_fail;
-	err = icmpv6_init();
-	if (err)
-		goto icmp_fail;
 	err = ip6_mr_init();
 	if (err)
 		goto ipmr_fail;
+	err = icmpv6_init();
+	if (err)
+		goto icmp_fail;
 	err = ndisc_init();
 	if (err)
 		goto ndisc_fail;
@@ -1016,10 +1016,10 @@ igmp_fail:
 	ndisc_cleanup();
 ndisc_fail:
 	ip6_mr_cleanup();
-ipmr_fail:
-	icmpv6_cleanup();
 icmp_fail:
 	unregister_pernet_subsys(&inet6_net_ops);
+ipmr_fail:
+	icmpv6_cleanup();
 register_pernet_fail:
 	sock_unregister(PF_INET6);
 	rtnl_unregister_all(PF_INET6);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/ipv6/ip6_vti.c linux-libre-4.4.106-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.4.105-gnu/net/ipv6/ip6_vti.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/ipv6/ip6_vti.c	2017-12-16 04:33:57.000000000 -0500
@@ -474,11 +474,15 @@ vti6_xmit(struct sk_buff *skb, struct ne
 	if (!skb->ignore_df && skb->len > mtu) {
 		skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu);
 
-		if (skb->protocol == htons(ETH_P_IPV6))
+		if (skb->protocol == htons(ETH_P_IPV6)) {
+			if (mtu < IPV6_MIN_MTU)
+				mtu = IPV6_MIN_MTU;
+
 			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
-		else
+		} else {
 			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
 				  htonl(mtu));
+		}
 
 		return -EMSGSIZE;
 	}
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/ipv6/sit.c linux-libre-4.4.106-gnu/net/ipv6/sit.c
--- linux-libre-4.4.105-gnu/net/ipv6/sit.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/ipv6/sit.c	2017-12-16 04:33:57.000000000 -0500
@@ -1093,6 +1093,7 @@ static void ipip6_tunnel_update(struct i
 	ipip6_tunnel_link(sitn, t);
 	t->parms.iph.ttl = p->iph.ttl;
 	t->parms.iph.tos = p->iph.tos;
+	t->parms.iph.frag_off = p->iph.frag_off;
 	if (t->parms.link != p->link) {
 		t->parms.link = p->link;
 		ipip6_tunnel_bind_dev(t->dev);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/packet/af_packet.c linux-libre-4.4.106-gnu/net/packet/af_packet.c
--- linux-libre-4.4.105-gnu/net/packet/af_packet.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/packet/af_packet.c	2017-12-16 04:33:57.000000000 -0500
@@ -1665,7 +1665,6 @@ static int fanout_add(struct sock *sk, u
 		atomic_long_set(&rollover->num, 0);
 		atomic_long_set(&rollover->num_huge, 0);
 		atomic_long_set(&rollover->num_failed, 0);
-		po->rollover = rollover;
 	}
 
 	match = NULL;
@@ -1710,6 +1709,8 @@ static int fanout_add(struct sock *sk, u
 		if (atomic_read(&match->sk_ref) < PACKET_FANOUT_MAX) {
 			__dev_remove_pack(&po->prot_hook);
 			po->fanout = match;
+			po->rollover = rollover;
+			rollover = NULL;
 			atomic_inc(&match->sk_ref);
 			__fanout_link(sk, po);
 			err = 0;
@@ -1723,10 +1724,7 @@ static int fanout_add(struct sock *sk, u
 	}
 
 out:
-	if (err && rollover) {
-		kfree_rcu(rollover, rcu);
-		po->rollover = NULL;
-	}
+	kfree(rollover);
 	mutex_unlock(&fanout_mutex);
 	return err;
 }
@@ -1750,11 +1748,6 @@ static struct packet_fanout *fanout_rele
 			list_del(&f->list);
 		else
 			f = NULL;
-
-		if (po->rollover) {
-			kfree_rcu(po->rollover, rcu);
-			po->rollover = NULL;
-		}
 	}
 	mutex_unlock(&fanout_mutex);
 
@@ -2914,6 +2907,7 @@ static int packet_release(struct socket
 	synchronize_net();
 
 	if (f) {
+		kfree(po->rollover);
 		fanout_release_data(f);
 		kfree(f);
 	}
@@ -2982,6 +2976,10 @@ static int packet_do_bind(struct sock *s
 	if (need_rehook) {
 		if (po->running) {
 			rcu_read_unlock();
+			/* prevents packet_notifier() from calling
+			 * register_prot_hook()
+			 */
+			po->num = 0;
 			__unregister_prot_hook(sk, true);
 			rcu_read_lock();
 			dev_curr = po->prot_hook.dev;
@@ -2990,6 +2988,7 @@ static int packet_do_bind(struct sock *s
 								 dev->ifindex);
 		}
 
+		BUG_ON(po->running);
 		po->num = proto;
 		po->prot_hook.type = proto;
 
@@ -3771,7 +3770,6 @@ static int packet_getsockopt(struct sock
 	void *data = &val;
 	union tpacket_stats_u st;
 	struct tpacket_rollover_stats rstats;
-	struct packet_rollover *rollover;
 
 	if (level != SOL_PACKET)
 		return -ENOPROTOOPT;
@@ -3850,18 +3848,13 @@ static int packet_getsockopt(struct sock
 		       0);
 		break;
 	case PACKET_ROLLOVER_STATS:
-		rcu_read_lock();
-		rollover = rcu_dereference(po->rollover);
-		if (rollover) {
-			rstats.tp_all = atomic_long_read(&rollover->num);
-			rstats.tp_huge = atomic_long_read(&rollover->num_huge);
-			rstats.tp_failed = atomic_long_read(&rollover->num_failed);
-			data = &rstats;
-			lv = sizeof(rstats);
-		}
-		rcu_read_unlock();
-		if (!rollover)
+		if (!po->rollover)
 			return -EINVAL;
+		rstats.tp_all = atomic_long_read(&po->rollover->num);
+		rstats.tp_huge = atomic_long_read(&po->rollover->num_huge);
+		rstats.tp_failed = atomic_long_read(&po->rollover->num_failed);
+		data = &rstats;
+		lv = sizeof(rstats);
 		break;
 	case PACKET_TX_HAS_OFF:
 		val = po->tp_tx_has_off;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/packet/internal.h linux-libre-4.4.106-gnu/net/packet/internal.h
--- linux-libre-4.4.105-gnu/net/packet/internal.h	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/packet/internal.h	2017-12-16 04:33:57.000000000 -0500
@@ -92,7 +92,6 @@ struct packet_fanout {
 
 struct packet_rollover {
 	int			sock;
-	struct rcu_head		rcu;
 	atomic_long_t		num;
 	atomic_long_t		num_huge;
 	atomic_long_t		num_failed;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/rds/rdma.c linux-libre-4.4.106-gnu/net/rds/rdma.c
--- linux-libre-4.4.105-gnu/net/rds/rdma.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/rds/rdma.c	2017-12-16 04:33:57.000000000 -0500
@@ -184,7 +184,7 @@ static int __rds_rdma_map(struct rds_soc
 	long i;
 	int ret;
 
-	if (rs->rs_bound_addr == 0) {
+	if (rs->rs_bound_addr == 0 || !rs->rs_transport) {
 		ret = -ENOTCONN; /* XXX not a great errno */
 		goto out;
 	}
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/sctp/socket.c linux-libre-4.4.106-gnu/net/sctp/socket.c
--- linux-libre-4.4.105-gnu/net/sctp/socket.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/sctp/socket.c	2017-12-16 04:33:57.000000000 -0500
@@ -82,8 +82,8 @@
 /* Forward declarations for internal helper functions. */
 static int sctp_writeable(struct sock *sk);
 static void sctp_wfree(struct sk_buff *skb);
-static int sctp_wait_for_sndbuf(struct sctp_association *, long *timeo_p,
-				size_t msg_len);
+static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
+				size_t msg_len, struct sock **orig_sk);
 static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p);
 static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p);
 static int sctp_wait_for_accept(struct sock *sk, long timeo);
@@ -1953,9 +1953,16 @@ static int sctp_sendmsg(struct sock *sk,
 
 	timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
 	if (!sctp_wspace(asoc)) {
-		err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
-		if (err)
+		/* sk can be changed by peel off when waiting for buf. */
+		err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len, &sk);
+		if (err) {
+			if (err == -ESRCH) {
+				/* asoc is already dead. */
+				new_asoc = NULL;
+				err = -EPIPE;
+			}
 			goto out_free;
+		}
 	}
 
 	/* If an address is passed with the sendto/sendmsg call, it is used
@@ -4460,12 +4467,6 @@ int sctp_do_peeloff(struct sock *sk, sct
 	if (!asoc)
 		return -EINVAL;
 
-	/* If there is a thread waiting on more sndbuf space for
-	 * sending on this asoc, it cannot be peeled.
-	 */
-	if (waitqueue_active(&asoc->wait))
-		return -EBUSY;
-
 	/* An association cannot be branched off from an already peeled-off
 	 * socket, nor is this supported for tcp style sockets.
 	 */
@@ -6975,7 +6976,7 @@ void sctp_sock_rfree(struct sk_buff *skb
 
 /* Helper function to wait for space in the sndbuf.  */
 static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
-				size_t msg_len)
+				size_t msg_len, struct sock **orig_sk)
 {
 	struct sock *sk = asoc->base.sk;
 	int err = 0;
@@ -6992,10 +6993,11 @@ static int sctp_wait_for_sndbuf(struct s
 	for (;;) {
 		prepare_to_wait_exclusive(&asoc->wait, &wait,
 					  TASK_INTERRUPTIBLE);
+		if (asoc->base.dead)
+			goto do_dead;
 		if (!*timeo_p)
 			goto do_nonblock;
-		if (sk->sk_err || asoc->state >= SCTP_STATE_SHUTDOWN_PENDING ||
-		    asoc->base.dead)
+		if (sk->sk_err || asoc->state >= SCTP_STATE_SHUTDOWN_PENDING)
 			goto do_error;
 		if (signal_pending(current))
 			goto do_interrupted;
@@ -7008,11 +7010,17 @@ static int sctp_wait_for_sndbuf(struct s
 		release_sock(sk);
 		current_timeo = schedule_timeout(current_timeo);
 		lock_sock(sk);
+		if (sk != asoc->base.sk) {
+			release_sock(sk);
+			sk = asoc->base.sk;
+			lock_sock(sk);
+		}
 
 		*timeo_p = current_timeo;
 	}
 
 out:
+	*orig_sk = sk;
 	finish_wait(&asoc->wait, &wait);
 
 	/* Release the association's refcnt.  */
@@ -7020,6 +7028,10 @@ out:
 
 	return err;
 
+do_dead:
+	err = -ESRCH;
+	goto out;
+
 do_error:
 	err = -EPIPE;
 	goto out;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/sunrpc/sched.c linux-libre-4.4.106-gnu/net/sunrpc/sched.c
--- linux-libre-4.4.105-gnu/net/sunrpc/sched.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/sunrpc/sched.c	2017-12-16 04:33:57.000000000 -0500
@@ -273,10 +273,9 @@ static inline void rpc_task_set_debuginf
 
 static void rpc_set_active(struct rpc_task *task)
 {
-	trace_rpc_task_begin(task->tk_client, task, NULL);
-
 	rpc_task_set_debuginfo(task);
 	set_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
+	trace_rpc_task_begin(task->tk_client, task, NULL);
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/tipc/server.c linux-libre-4.4.106-gnu/net/tipc/server.c
--- linux-libre-4.4.105-gnu/net/tipc/server.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/tipc/server.c	2017-12-16 04:33:57.000000000 -0500
@@ -311,6 +311,7 @@ static int tipc_accept_from_sock(struct
 	newcon->usr_data = s->tipc_conn_new(newcon->conid);
 	if (!newcon->usr_data) {
 		sock_release(newsock);
+		conn_put(newcon);
 		return -ENOMEM;
 	}
 
diff -druNp --no-dereference linux-libre-4.4.105-gnu/net/xfrm/xfrm_policy.c linux-libre-4.4.106-gnu/net/xfrm/xfrm_policy.c
--- linux-libre-4.4.105-gnu/net/xfrm/xfrm_policy.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/net/xfrm/xfrm_policy.c	2017-12-16 04:33:57.000000000 -0500
@@ -1361,6 +1361,7 @@ static struct xfrm_policy *clone_policy(
 		newp->xfrm_nr = old->xfrm_nr;
 		newp->index = old->index;
 		newp->type = old->type;
+		newp->family = old->family;
 		memcpy(newp->xfrm_vec, old->xfrm_vec,
 		       newp->xfrm_nr*sizeof(struct xfrm_tmpl));
 		write_lock_bh(&net->xfrm.xfrm_policy_lock);
diff -druNp --no-dereference linux-libre-4.4.105-gnu/scripts/module-common.lds linux-libre-4.4.106-gnu/scripts/module-common.lds
--- linux-libre-4.4.105-gnu/scripts/module-common.lds	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/scripts/module-common.lds	2017-12-16 04:33:57.000000000 -0500
@@ -19,4 +19,6 @@ SECTIONS {
 
 	. = ALIGN(8);
 	.init_array		0 : { *(SORT(.init_array.*)) *(.init_array) }
+
+	__jump_table		0 : ALIGN(8) { KEEP(*(__jump_table)) }
 }
diff -druNp --no-dereference linux-libre-4.4.105-gnu/scripts/package/Makefile linux-libre-4.4.106-gnu/scripts/package/Makefile
--- linux-libre-4.4.105-gnu/scripts/package/Makefile	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/scripts/package/Makefile	2017-12-16 04:33:57.000000000 -0500
@@ -39,10 +39,9 @@ if test "$(objtree)" != "$(srctree)"; th
 	false; \
 fi ; \
 $(srctree)/scripts/setlocalversion --save-scmversion; \
-ln -sf $(srctree) $(2); \
 tar -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \
-	$(addprefix $(2)/,$(TAR_CONTENT) $(3)); \
-rm -f $(2) $(objtree)/.scmversion
+	--transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3); \
+rm -f $(objtree)/.scmversion
 
 # rpm-pkg
 # ---------------------------------------------------------------------------
diff -druNp --no-dereference linux-libre-4.4.105-gnu/sound/core/pcm.c linux-libre-4.4.106-gnu/sound/core/pcm.c
--- linux-libre-4.4.105-gnu/sound/core/pcm.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/sound/core/pcm.c	2017-12-16 04:33:57.000000000 -0500
@@ -149,7 +149,9 @@ static int snd_pcm_control_ioctl(struct
 				err = -ENXIO;
 				goto _error;
 			}
+			mutex_lock(&pcm->open_mutex);
 			err = snd_pcm_info_user(substream, info);
+			mutex_unlock(&pcm->open_mutex);
 		_error:
 			mutex_unlock(&register_mutex);
 			return err;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/sound/core/seq/seq_timer.c linux-libre-4.4.106-gnu/sound/core/seq/seq_timer.c
--- linux-libre-4.4.105-gnu/sound/core/seq/seq_timer.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/sound/core/seq/seq_timer.c	2017-12-16 04:33:57.000000000 -0500
@@ -355,7 +355,7 @@ static int initialize_timer(struct snd_s
 	unsigned long freq;
 
 	t = tmr->timeri->timer;
-	if (snd_BUG_ON(!t))
+	if (!t)
 		return -EINVAL;
 
 	freq = tmr->preferred_resolution;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/sound/usb/mixer.c linux-libre-4.4.106-gnu/sound/usb/mixer.c
--- linux-libre-4.4.105-gnu/sound/usb/mixer.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/sound/usb/mixer.c	2017-12-16 04:33:57.000000000 -0500
@@ -203,6 +203,10 @@ static int snd_usb_copy_string_desc(stru
 				    int index, char *buf, int maxlen)
 {
 	int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
+
+	if (len < 0)
+		return 0;
+
 	buf[len] = 0;
 	return len;
 }
@@ -2102,13 +2106,14 @@ static int parse_audio_selector_unit(str
 	if (len)
 		;
 	else if (nameid)
-		snd_usb_copy_string_desc(state, nameid, kctl->id.name,
+		len = snd_usb_copy_string_desc(state, nameid, kctl->id.name,
 					 sizeof(kctl->id.name));
-	else {
+	else
 		len = get_term_name(state, &state->oterm,
 				    kctl->id.name, sizeof(kctl->id.name), 0);
-		if (!len)
-			strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
+
+	if (!len) {
+		strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
 
 		if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
 			append_ctl_name(kctl, " Clock Source");
diff -druNp --no-dereference linux-libre-4.4.105-gnu/tools/hv/hv_kvp_daemon.c linux-libre-4.4.106-gnu/tools/hv/hv_kvp_daemon.c
--- linux-libre-4.4.105-gnu/tools/hv/hv_kvp_daemon.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/tools/hv/hv_kvp_daemon.c	2017-12-16 04:33:57.000000000 -0500
@@ -193,11 +193,14 @@ static void kvp_update_mem_state(int poo
 	for (;;) {
 		readp = &record[records_read];
 		records_read += fread(readp, sizeof(struct kvp_record),
-					ENTRIES_PER_BLOCK * num_blocks,
-					filep);
+				ENTRIES_PER_BLOCK * num_blocks - records_read,
+				filep);
 
 		if (ferror(filep)) {
-			syslog(LOG_ERR, "Failed to read file, pool: %d", pool);
+			syslog(LOG_ERR,
+				"Failed to read file, pool: %d; error: %d %s",
+				 pool, errno, strerror(errno));
+			kvp_release_lock(pool);
 			exit(EXIT_FAILURE);
 		}
 
@@ -210,6 +213,7 @@ static void kvp_update_mem_state(int poo
 
 			if (record == NULL) {
 				syslog(LOG_ERR, "malloc failed");
+				kvp_release_lock(pool);
 				exit(EXIT_FAILURE);
 			}
 			continue;
@@ -224,15 +228,11 @@ static void kvp_update_mem_state(int poo
 	fclose(filep);
 	kvp_release_lock(pool);
 }
+
 static int kvp_file_init(void)
 {
 	int  fd;
-	FILE *filep;
-	size_t records_read;
 	char *fname;
-	struct kvp_record *record;
-	struct kvp_record *readp;
-	int num_blocks;
 	int i;
 	int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
 
@@ -246,61 +246,19 @@ static int kvp_file_init(void)
 
 	for (i = 0; i < KVP_POOL_COUNT; i++) {
 		fname = kvp_file_info[i].fname;
-		records_read = 0;
-		num_blocks = 1;
 		sprintf(fname, "%s/.kvp_pool_%d", KVP_CONFIG_LOC, i);
 		fd = open(fname, O_RDWR | O_CREAT | O_CLOEXEC, 0644 /* rw-r--r-- */);
 
 		if (fd == -1)
 			return 1;
 
-
-		filep = fopen(fname, "re");
-		if (!filep) {
-			close(fd);
-			return 1;
-		}
-
-		record = malloc(alloc_unit * num_blocks);
-		if (record == NULL) {
-			fclose(filep);
-			close(fd);
-			return 1;
-		}
-		for (;;) {
-			readp = &record[records_read];
-			records_read += fread(readp, sizeof(struct kvp_record),
-					ENTRIES_PER_BLOCK,
-					filep);
-
-			if (ferror(filep)) {
-				syslog(LOG_ERR, "Failed to read file, pool: %d",
-				       i);
-				exit(EXIT_FAILURE);
-			}
-
-			if (!feof(filep)) {
-				/*
-				 * We have more data to read.
-				 */
-				num_blocks++;
-				record = realloc(record, alloc_unit *
-						num_blocks);
-				if (record == NULL) {
-					fclose(filep);
-					close(fd);
-					return 1;
-				}
-				continue;
-			}
-			break;
-		}
 		kvp_file_info[i].fd = fd;
-		kvp_file_info[i].num_blocks = num_blocks;
-		kvp_file_info[i].records = record;
-		kvp_file_info[i].num_records = records_read;
-		fclose(filep);
-
+		kvp_file_info[i].num_blocks = 1;
+		kvp_file_info[i].records = malloc(alloc_unit);
+		if (kvp_file_info[i].records == NULL)
+			return 1;
+		kvp_file_info[i].num_records = 0;
+		kvp_update_mem_state(i);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.4.105-gnu/tools/testing/selftests/powerpc/harness.c linux-libre-4.4.106-gnu/tools/testing/selftests/powerpc/harness.c
--- linux-libre-4.4.105-gnu/tools/testing/selftests/powerpc/harness.c	2017-12-09 12:42:44.000000000 -0500
+++ linux-libre-4.4.106-gnu/tools/testing/selftests/powerpc/harness.c	2017-12-16 04:33:57.000000000 -0500
@@ -109,9 +109,11 @@ int test_harness(int (test_function)(voi
 
 	rc = run_test(test_function, name);
 
-	if (rc == MAGIC_SKIP_RETURN_VALUE)
+	if (rc == MAGIC_SKIP_RETURN_VALUE) {
 		test_skip(name);
-	else
+		/* so that skipped test is not marked as failed */
+		rc = 0;
+	} else
 		test_finish(name, rc);
 
 	return rc;
