summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2013-03-16 15:07:13 -0400
committerAnthony G. Basile <blueness@gentoo.org>2013-03-16 15:07:13 -0400
commit32877177824f994f09acb21b579c9c8a7df55b3d (patch)
treeab57fcfac91d7be94baa36feb08f4c2ba721a4c3
parentGrsec/PaX: 2.9.1-{2.6.32.60,3.2.40,3.8.2}-201303142235 (diff)
downloadhardened-patchset-32877177824f994f09acb21b579c9c8a7df55b3d.tar.gz
hardened-patchset-32877177824f994f09acb21b579c9c8a7df55b3d.tar.bz2
hardened-patchset-32877177824f994f09acb21b579c9c8a7df55b3d.zip
Fix 3.8.2 -> 3.8.320130314
-rw-r--r--3.8.3/0000_README (renamed from 3.8.2/0000_README)8
-rw-r--r--3.8.3/1001_linux-3.8.2.patch (renamed from 3.8.2/1001_linux-3.8.2.patch)0
-rw-r--r--3.8.3/1002_linux-3.8.3.patch4814
-rw-r--r--3.8.3/4420_grsecurity-2.9.1-3.8.3-201303142235.patch (renamed from 3.8.2/4420_grsecurity-2.9.1-3.8.3-201303142235.patch)0
-rw-r--r--3.8.3/4425_grsec_remove_EI_PAX.patch (renamed from 3.8.2/4425_grsec_remove_EI_PAX.patch)0
-rw-r--r--3.8.3/4430_grsec-remove-localversion-grsec.patch (renamed from 3.8.2/4430_grsec-remove-localversion-grsec.patch)0
-rw-r--r--3.8.3/4435_grsec-mute-warnings.patch (renamed from 3.8.2/4435_grsec-mute-warnings.patch)0
-rw-r--r--3.8.3/4440_grsec-remove-protected-paths.patch (renamed from 3.8.2/4440_grsec-remove-protected-paths.patch)0
-rw-r--r--3.8.3/4450_grsec-kconfig-default-gids.patch (renamed from 3.8.2/4450_grsec-kconfig-default-gids.patch)0
-rw-r--r--3.8.3/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.8.2/4465_selinux-avc_audit-log-curr_ip.patch)0
-rw-r--r--3.8.3/4470_disable-compat_vdso.patch (renamed from 3.8.2/4470_disable-compat_vdso.patch)0
11 files changed, 4820 insertions, 2 deletions
diff --git a/3.8.2/0000_README b/3.8.3/0000_README
index 43053f3..072a299 100644
--- a/3.8.2/0000_README
+++ b/3.8.3/0000_README
@@ -2,9 +2,13 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1001_linux-3.8.1.patch
+Patch: 1001_linux-3.8.2.patch
From: http://www.kernel.org
-Desc: Linux 3.8.1
+Desc: Linux 3.8.2
+
+Patch: 1002_linux-3.8.3.patch
+From: http://www.kernel.org
+Desc: Linux 3.8.3
Patch: 4420_grsecurity-2.9.1-3.8.3-201303142235.patch
From: http://www.grsecurity.net
diff --git a/3.8.2/1001_linux-3.8.2.patch b/3.8.3/1001_linux-3.8.2.patch
index 0952288..0952288 100644
--- a/3.8.2/1001_linux-3.8.2.patch
+++ b/3.8.3/1001_linux-3.8.2.patch
diff --git a/3.8.3/1002_linux-3.8.3.patch b/3.8.3/1002_linux-3.8.3.patch
new file mode 100644
index 0000000..6b6c562
--- /dev/null
+++ b/3.8.3/1002_linux-3.8.3.patch
@@ -0,0 +1,4814 @@
+diff --git a/Makefile b/Makefile
+index 20d5318..8c49fc9b 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 8
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Unicycling Gorilla
+
+diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts
+index 5bb0bf3..c9c44b2 100644
+--- a/arch/arm/boot/dts/kirkwood-dns320.dts
++++ b/arch/arm/boot/dts/kirkwood-dns320.dts
+@@ -42,12 +42,10 @@
+
+ ocp@f1000000 {
+ serial@12000 {
+- clock-frequency = <166666667>;
+ status = "okay";
+ };
+
+ serial@12100 {
+- clock-frequency = <166666667>;
+ status = "okay";
+ };
+ };
+diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts
+index d430713..e4e4930 100644
+--- a/arch/arm/boot/dts/kirkwood-dns325.dts
++++ b/arch/arm/boot/dts/kirkwood-dns325.dts
+@@ -50,7 +50,6 @@
+ };
+ };
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "okay";
+ };
+ };
+diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts
+index 2e3dd34..0196cf6 100644
+--- a/arch/arm/boot/dts/kirkwood-dockstar.dts
++++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
+@@ -37,7 +37,6 @@
+ };
+ };
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts
+index f2d386c..e21ae48 100644
+--- a/arch/arm/boot/dts/kirkwood-dreamplug.dts
++++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts
+@@ -38,7 +38,6 @@
+ };
+ };
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts
+index 1b133e0..bd83b8f 100644
+--- a/arch/arm/boot/dts/kirkwood-goflexnet.dts
++++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
+@@ -73,7 +73,6 @@
+ };
+ };
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts
+index 71902da..5335b1a 100644
+--- a/arch/arm/boot/dts/kirkwood-ib62x0.dts
++++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
+@@ -51,7 +51,6 @@
+ };
+ };
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "okay";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts
+index 504f16b..12ccf74 100644
+--- a/arch/arm/boot/dts/kirkwood-iconnect.dts
++++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
+@@ -78,7 +78,6 @@
+ };
+ };
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
+index 6cae459..93c3afb 100644
+--- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
++++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
+@@ -115,7 +115,6 @@
+ };
+
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
+index 8db3123..5bbd054 100644
+--- a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
++++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
+@@ -34,7 +34,6 @@
+ };
+
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-lschlv2.dts b/arch/arm/boot/dts/kirkwood-lschlv2.dts
+index 9510c9e..9f55d95 100644
+--- a/arch/arm/boot/dts/kirkwood-lschlv2.dts
++++ b/arch/arm/boot/dts/kirkwood-lschlv2.dts
+@@ -13,7 +13,6 @@
+
+ ocp@f1000000 {
+ serial@12000 {
+- clock-frequency = <166666667>;
+ status = "okay";
+ };
+ };
+diff --git a/arch/arm/boot/dts/kirkwood-lsxhl.dts b/arch/arm/boot/dts/kirkwood-lsxhl.dts
+index 739019c..5c84c11 100644
+--- a/arch/arm/boot/dts/kirkwood-lsxhl.dts
++++ b/arch/arm/boot/dts/kirkwood-lsxhl.dts
+@@ -13,7 +13,6 @@
+
+ ocp@f1000000 {
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "okay";
+ };
+ };
+diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts
+index 262c654..07be213 100644
+--- a/arch/arm/boot/dts/kirkwood-mplcec4.dts
++++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts
+@@ -91,7 +91,6 @@
+ };
+
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
+index 77d21ab..f0245c1 100644
+--- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
++++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
+@@ -23,7 +23,6 @@
+ };
+
+ serial@12000 {
+- clock-frequency = <166666667>;
+ status = "okay";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts
+index 5509f96..28d05e4 100644
+--- a/arch/arm/boot/dts/kirkwood-nsa310.dts
++++ b/arch/arm/boot/dts/kirkwood-nsa310.dts
+@@ -18,7 +18,6 @@
+ ocp@f1000000 {
+
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
+index 49d3d74..f3cc7c4 100644
+--- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
++++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
+@@ -18,12 +18,10 @@
+
+ ocp@f1000000 {
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+ serial@12100 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood-topkick.dts b/arch/arm/boot/dts/kirkwood-topkick.dts
+index cd15452..7dd19ff 100644
+--- a/arch/arm/boot/dts/kirkwood-topkick.dts
++++ b/arch/arm/boot/dts/kirkwood-topkick.dts
+@@ -17,7 +17,6 @@
+
+ ocp@f1000000 {
+ serial@12000 {
+- clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
+index d6ab442..ad26d92 100644
+--- a/arch/arm/boot/dts/kirkwood.dtsi
++++ b/arch/arm/boot/dts/kirkwood.dtsi
+@@ -38,6 +38,7 @@
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <35>, <36>, <37>, <38>;
++ clocks = <&gate_clk 7>;
+ };
+
+ gpio1: gpio@10140 {
+@@ -49,6 +50,7 @@
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <39>, <40>, <41>;
++ clocks = <&gate_clk 7>;
+ };
+
+ serial@12000 {
+@@ -57,7 +59,6 @@
+ reg-shift = <2>;
+ interrupts = <33>;
+ clocks = <&gate_clk 7>;
+- /* set clock-frequency in board dts */
+ status = "disabled";
+ };
+
+@@ -67,7 +68,6 @@
+ reg-shift = <2>;
+ interrupts = <34>;
+ clocks = <&gate_clk 7>;
+- /* set clock-frequency in board dts */
+ status = "disabled";
+ };
+
+@@ -75,6 +75,7 @@
+ compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
+ reg = <0x10300 0x20>;
+ interrupts = <53>;
++ clocks = <&gate_clk 7>;
+ };
+
+ spi@10600 {
+diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
+index 7bf5351..a55b206 100644
+--- a/arch/arm/configs/mxs_defconfig
++++ b/arch/arm/configs/mxs_defconfig
+@@ -118,6 +118,7 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
+ CONFIG_FONTS=y
+ CONFIG_LOGO=y
+ CONFIG_USB=y
++CONFIG_USB_EHCI_HCD=y
+ CONFIG_USB_CHIPIDEA=y
+ CONFIG_USB_CHIPIDEA_HOST=y
+ CONFIG_USB_STORAGE=y
+diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
+index ab98fdd..720799f 100644
+--- a/arch/arm/include/asm/delay.h
++++ b/arch/arm/include/asm/delay.h
+@@ -24,6 +24,7 @@ extern struct arm_delay_ops {
+ void (*delay)(unsigned long);
+ void (*const_udelay)(unsigned long);
+ void (*udelay)(unsigned long);
++ bool const_clock;
+ } arm_delay_ops;
+
+ #define __delay(n) arm_delay_ops.delay(n)
+diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
+index 9f77e78..e3d5554 100644
+--- a/arch/arm/include/asm/mmu.h
++++ b/arch/arm/include/asm/mmu.h
+@@ -5,15 +5,15 @@
+
+ typedef struct {
+ #ifdef CONFIG_CPU_HAS_ASID
+- u64 id;
++ atomic64_t id;
+ #endif
+- unsigned int vmalloc_seq;
++ unsigned int vmalloc_seq;
+ } mm_context_t;
+
+ #ifdef CONFIG_CPU_HAS_ASID
+ #define ASID_BITS 8
+ #define ASID_MASK ((~0ULL) << ASID_BITS)
+-#define ASID(mm) ((mm)->context.id & ~ASID_MASK)
++#define ASID(mm) ((mm)->context.id.counter & ~ASID_MASK)
+ #else
+ #define ASID(mm) (0)
+ #endif
+@@ -26,7 +26,7 @@ typedef struct {
+ * modified for 2.6 by Hyok S. Choi <hyok.choi@samsung.com>
+ */
+ typedef struct {
+- unsigned long end_brk;
++ unsigned long end_brk;
+ } mm_context_t;
+
+ #endif
+diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
+index e1f644b..863a661 100644
+--- a/arch/arm/include/asm/mmu_context.h
++++ b/arch/arm/include/asm/mmu_context.h
+@@ -25,7 +25,7 @@ void __check_vmalloc_seq(struct mm_struct *mm);
+ #ifdef CONFIG_CPU_HAS_ASID
+
+ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
+-#define init_new_context(tsk,mm) ({ mm->context.id = 0; })
++#define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; })
+
+ #else /* !CONFIG_CPU_HAS_ASID */
+
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index 9c82f988..c094749 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -240,7 +240,8 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+- const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | L_PTE_NONE;
++ const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER |
++ L_PTE_NONE | L_PTE_VALID;
+ pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
+ return pte;
+ }
+diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
+index c985b48..cf10d18 100644
+--- a/arch/arm/kernel/asm-offsets.c
++++ b/arch/arm/kernel/asm-offsets.c
+@@ -107,7 +107,7 @@ int main(void)
+ BLANK();
+ #endif
+ #ifdef CONFIG_CPU_HAS_ASID
+- DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
++ DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter));
+ BLANK();
+ #endif
+ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 486a15a..e0eb9a1 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -184,13 +184,22 @@ __create_page_tables:
+ orr r3, r3, #3 @ PGD block type
+ mov r6, #4 @ PTRS_PER_PGD
+ mov r7, #1 << (55 - 32) @ L_PGD_SWAPPER
+-1: str r3, [r0], #4 @ set bottom PGD entry bits
++1:
++#ifdef CONFIG_CPU_ENDIAN_BE8
+ str r7, [r0], #4 @ set top PGD entry bits
++ str r3, [r0], #4 @ set bottom PGD entry bits
++#else
++ str r3, [r0], #4 @ set bottom PGD entry bits
++ str r7, [r0], #4 @ set top PGD entry bits
++#endif
+ add r3, r3, #0x1000 @ next PMD table
+ subs r6, r6, #1
+ bne 1b
+
+ add r4, r4, #0x1000 @ point to the PMD tables
++#ifdef CONFIG_CPU_ENDIAN_BE8
++ add r4, r4, #4 @ we only write the bottom word
++#endif
+ #endif
+
+ ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
+@@ -258,6 +267,11 @@ __create_page_tables:
+ addne r6, r6, #1 << SECTION_SHIFT
+ strne r6, [r3]
+
++#if defined(CONFIG_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8)
++ sub r4, r4, #4 @ Fixup page table pointer
++ @ for 64-bit descriptors
++#endif
++
+ #ifdef CONFIG_DEBUG_LL
+ #if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING)
+ /*
+@@ -276,13 +290,17 @@ __create_page_tables:
+ orr r3, r7, r3, lsl #SECTION_SHIFT
+ #ifdef CONFIG_ARM_LPAE
+ mov r7, #1 << (54 - 32) @ XN
++#ifdef CONFIG_CPU_ENDIAN_BE8
++ str r7, [r0], #4
++ str r3, [r0], #4
+ #else
+- orr r3, r3, #PMD_SECT_XN
+-#endif
+ str r3, [r0], #4
+-#ifdef CONFIG_ARM_LPAE
+ str r7, [r0], #4
+ #endif
++#else
++ orr r3, r3, #PMD_SECT_XN
++ str r3, [r0], #4
++#endif
+
+ #else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */
+ /* we don't need any serial debugging mappings */
+diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
+index 4fbc757..89ede24 100644
+--- a/arch/arm/kernel/perf_event_v7.c
++++ b/arch/arm/kernel/perf_event_v7.c
+@@ -774,7 +774,7 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ /*
+ * PMXEVTYPER: Event selection reg
+ */
+-#define ARMV7_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */
++#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
+ #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
+
+ /*
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 84f4cbf..58af91c 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -693,6 +693,9 @@ static int cpufreq_callback(struct notifier_block *nb,
+ if (freq->flags & CPUFREQ_CONST_LOOPS)
+ return NOTIFY_OK;
+
++ if (arm_delay_ops.const_clock)
++ return NOTIFY_OK;
++
+ if (!per_cpu(l_p_j_ref, cpu)) {
+ per_cpu(l_p_j_ref, cpu) =
+ per_cpu(cpu_data, cpu).loops_per_jiffy;
+diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
+index 0dc5385..6b93f6a 100644
+--- a/arch/arm/lib/delay.c
++++ b/arch/arm/lib/delay.c
+@@ -77,6 +77,7 @@ void __init register_current_timer_delay(const struct delay_timer *timer)
+ arm_delay_ops.delay = __timer_delay;
+ arm_delay_ops.const_udelay = __timer_const_udelay;
+ arm_delay_ops.udelay = __timer_udelay;
++ arm_delay_ops.const_clock = true;
+ delay_calibrated = true;
+ } else {
+ pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");
+diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
+index b820eda..db26e2e 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -749,7 +749,6 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ unsigned long instr = 0, instrptr;
+ int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
+ unsigned int type;
+- mm_segment_t fs;
+ unsigned int fault;
+ u16 tinstr = 0;
+ int isize = 4;
+@@ -760,16 +759,15 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+
+ instrptr = instruction_pointer(regs);
+
+- fs = get_fs();
+- set_fs(KERNEL_DS);
+ if (thumb_mode(regs)) {
+- fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
++ u16 *ptr = (u16 *)(instrptr & ~1);
++ fault = probe_kernel_address(ptr, tinstr);
+ if (!fault) {
+ if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
+ IS_T32(tinstr)) {
+ /* Thumb-2 32-bit */
+ u16 tinst2 = 0;
+- fault = __get_user(tinst2, (u16 *)(instrptr+2));
++ fault = probe_kernel_address(ptr + 1, tinst2);
+ instr = (tinstr << 16) | tinst2;
+ thumb2_32b = 1;
+ } else {
+@@ -778,8 +776,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ }
+ }
+ } else
+- fault = __get_user(instr, (u32 *)instrptr);
+- set_fs(fs);
++ fault = probe_kernel_address(instrptr, instr);
+
+ if (fault) {
+ type = TYPE_FAULT;
+diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
+index bc4a5e9..d07df17 100644
+--- a/arch/arm/mm/context.c
++++ b/arch/arm/mm/context.c
+@@ -149,9 +149,9 @@ static int is_reserved_asid(u64 asid)
+ return 0;
+ }
+
+-static void new_context(struct mm_struct *mm, unsigned int cpu)
++static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+ {
+- u64 asid = mm->context.id;
++ u64 asid = atomic64_read(&mm->context.id);
+ u64 generation = atomic64_read(&asid_generation);
+
+ if (asid != 0 && is_reserved_asid(asid)) {
+@@ -178,13 +178,14 @@ static void new_context(struct mm_struct *mm, unsigned int cpu)
+ cpumask_clear(mm_cpumask(mm));
+ }
+
+- mm->context.id = asid;
++ return asid;
+ }
+
+ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
+ {
+ unsigned long flags;
+ unsigned int cpu = smp_processor_id();
++ u64 asid;
+
+ if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
+ __check_vmalloc_seq(mm);
+@@ -195,20 +196,24 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
+ */
+ cpu_set_reserved_ttbr0();
+
+- if (!((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
+- && atomic64_xchg(&per_cpu(active_asids, cpu), mm->context.id))
++ asid = atomic64_read(&mm->context.id);
++ if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
++ && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
+ goto switch_mm_fastpath;
+
+ raw_spin_lock_irqsave(&cpu_asid_lock, flags);
+ /* Check that our ASID belongs to the current generation. */
+- if ((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
+- new_context(mm, cpu);
+-
+- atomic64_set(&per_cpu(active_asids, cpu), mm->context.id);
+- cpumask_set_cpu(cpu, mm_cpumask(mm));
++ asid = atomic64_read(&mm->context.id);
++ if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) {
++ asid = new_context(mm, cpu);
++ atomic64_set(&mm->context.id, asid);
++ }
+
+ if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending))
+ local_flush_tlb_all();
++
++ atomic64_set(&per_cpu(active_asids, cpu), asid);
++ cpumask_set_cpu(cpu, mm_cpumask(mm));
+ raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
+
+ switch_mm_fastpath:
+diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
+index 3b44e0d..5dfbb0b 100644
+--- a/arch/arm/vfp/vfpmodule.c
++++ b/arch/arm/vfp/vfpmodule.c
+@@ -413,7 +413,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
+ * If there isn't a second FP instruction, exit now. Note that
+ * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
+ */
+- if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
++ if ((fpexc & (FPEXC_EX | FPEXC_FP2V)) != (FPEXC_EX | FPEXC_FP2V))
+ goto exit;
+
+ /*
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+index 6da881b..8d97eb4 100644
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -156,6 +156,15 @@ early_param("smt-enabled", early_smt_enabled);
+ #define check_smt_enabled()
+ #endif /* CONFIG_SMP */
+
++/** Fix up paca fields required for the boot cpu */
++static void fixup_boot_paca(void)
++{
++ /* The boot cpu is started */
++ get_paca()->cpu_start = 1;
++ /* Allow percpu accesses to work until we setup percpu data */
++ get_paca()->data_offset = 0;
++}
++
+ /*
+ * Early initialization entry point. This is called by head.S
+ * with MMU translation disabled. We rely on the "feature" of
+@@ -185,6 +194,7 @@ void __init early_setup(unsigned long dt_ptr)
+ /* Assume we're on cpu 0 for now. Don't write to the paca yet! */
+ initialise_paca(&boot_paca, 0);
+ setup_paca(&boot_paca);
++ fixup_boot_paca();
+
+ /* Initialize lockdep early or else spinlocks will blow */
+ lockdep_init();
+@@ -205,11 +215,7 @@ void __init early_setup(unsigned long dt_ptr)
+
+ /* Now we know the logical id of our boot cpu, setup the paca. */
+ setup_paca(&paca[boot_cpuid]);
+-
+- /* Fix up paca fields required for the boot cpu */
+- get_paca()->cpu_start = 1;
+- /* Allow percpu accesses to "work" until we setup percpu data */
+- get_paca()->data_offset = 0;
++ fixup_boot_paca();
+
+ /* Probe the machine type */
+ probe_machine();
+diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
+index 88f3c22..59e3574 100644
+--- a/arch/tile/include/asm/compat.h
++++ b/arch/tile/include/asm/compat.h
+@@ -296,6 +296,9 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags,
+ long compat_sys_fallocate(int fd, int mode,
+ u32 offset_lo, u32 offset_hi,
+ u32 len_lo, u32 len_hi);
++long compat_sys_llseek(unsigned int fd, unsigned int offset_high,
++ unsigned int offset_low, loff_t __user * result,
++ unsigned int origin);
+
+ /* Assembly trampoline to avoid clobbering r0. */
+ long _compat_sys_rt_sigreturn(void);
+diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
+index 7f72401..d8e3b7e 100644
+--- a/arch/tile/kernel/compat.c
++++ b/arch/tile/kernel/compat.c
+@@ -76,6 +76,18 @@ long compat_sys_fallocate(int fd, int mode,
+ ((loff_t)len_hi << 32) | len_lo);
+ }
+
++/*
++ * Avoid bug in generic sys_llseek() that specifies offset_high and
++ * offset_low as "unsigned long", thus making it possible to pass
++ * a sign-extended high 32 bits in offset_low.
++ */
++long compat_sys_llseek(unsigned int fd, unsigned int offset_high,
++ unsigned int offset_low, loff_t __user * result,
++ unsigned int origin)
++{
++ return sys_llseek(fd, offset_high, offset_low, result, origin);
++}
++
+ /* Provide the compat syscall number to call mapping. */
+ #undef __SYSCALL
+ #define __SYSCALL(nr, call) [nr] = (call),
+@@ -83,6 +95,7 @@ long compat_sys_fallocate(int fd, int mode,
+ /* See comments in sys.c */
+ #define compat_sys_fadvise64_64 sys32_fadvise64_64
+ #define compat_sys_readahead sys32_readahead
++#define sys_llseek compat_sys_llseek
+
+ /* Call the assembly trampolines where necessary. */
+ #define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn
+diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
+index 220a360..5bedbdd 100644
+--- a/arch/x86/kernel/kvmclock.c
++++ b/arch/x86/kernel/kvmclock.c
+@@ -218,6 +218,9 @@ static void kvm_shutdown(void)
+ void __init kvmclock_init(void)
+ {
+ unsigned long mem;
++ int size;
++
++ size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS);
+
+ if (!kvm_para_available())
+ return;
+@@ -231,16 +234,14 @@ void __init kvmclock_init(void)
+ printk(KERN_INFO "kvm-clock: Using msrs %x and %x",
+ msr_kvm_system_time, msr_kvm_wall_clock);
+
+- mem = memblock_alloc(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS,
+- PAGE_SIZE);
++ mem = memblock_alloc(size, PAGE_SIZE);
+ if (!mem)
+ return;
+ hv_clock = __va(mem);
+
+ if (kvm_register_clock("boot clock")) {
+ hv_clock = NULL;
+- memblock_free(mem,
+- sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS);
++ memblock_free(mem, size);
+ return;
+ }
+ pv_time_ops.sched_clock = kvm_clock_read;
+@@ -275,7 +276,7 @@ int __init kvm_setup_vsyscall_timeinfo(void)
+ struct pvclock_vcpu_time_info *vcpu_time;
+ unsigned int size;
+
+- size = sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS;
++ size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS);
+
+ preempt_disable();
+ cpu = smp_processor_id();
+diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
+index 85c3959..2cb9470 100644
+--- a/arch/x86/kernel/pvclock.c
++++ b/arch/x86/kernel/pvclock.c
+@@ -185,7 +185,7 @@ int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i,
+
+ for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) {
+ __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx,
+- __pa_symbol(i) + (idx*PAGE_SIZE),
++ __pa(i) + (idx*PAGE_SIZE),
+ PAGE_KERNEL_VVAR);
+ }
+
+diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
+index 56ab749..94e7662 100644
+--- a/arch/x86/pci/xen.c
++++ b/arch/x86/pci/xen.c
+@@ -162,6 +162,9 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+ struct msi_desc *msidesc;
+ int *v;
+
++ if (type == PCI_CAP_ID_MSI && nvec > 1)
++ return 1;
++
+ v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL);
+ if (!v)
+ return -ENOMEM;
+@@ -220,6 +223,9 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+ struct msi_desc *msidesc;
+ struct msi_msg msg;
+
++ if (type == PCI_CAP_ID_MSI && nvec > 1)
++ return 1;
++
+ list_for_each_entry(msidesc, &dev->msi_list, list) {
+ __read_msi_msg(msidesc, &msg);
+ pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
+@@ -263,6 +269,9 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+ int ret = 0;
+ struct msi_desc *msidesc;
+
++ if (type == PCI_CAP_ID_MSI && nvec > 1)
++ return 1;
++
+ list_for_each_entry(msidesc, &dev->msi_list, list) {
+ struct physdev_map_pirq map_irq;
+ domid_t domid;
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index e014092..2262003 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -67,6 +67,7 @@
+ #include <asm/hypervisor.h>
+ #include <asm/mwait.h>
+ #include <asm/pci_x86.h>
++#include <asm/pat.h>
+
+ #ifdef CONFIG_ACPI
+ #include <linux/acpi.h>
+@@ -1417,7 +1418,14 @@ asmlinkage void __init xen_start_kernel(void)
+ */
+ acpi_numa = -1;
+ #endif
+-
++#ifdef CONFIG_X86_PAT
++ /*
++ * For right now disable the PAT. We should remove this once
++ * git commit 8eaffa67b43e99ae581622c5133e20b0f48bcef1
++ * (xen/pat: Disable PAT support for now) is reverted.
++ */
++ pat_enabled = 0;
++#endif
+ /* Don't do the full vcpu_info placement stuff until we have a
+ possible map and a non-dummy shared_info. */
+ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
+diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
+index 533de95..7d4a8d2 100644
+--- a/crypto/ablkcipher.c
++++ b/crypto/ablkcipher.c
+@@ -388,9 +388,9 @@ static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_blkcipher rblkcipher;
+
+- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher");
+- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+- alg->cra_ablkcipher.geniv ?: "<default>");
++ strncpy(rblkcipher.type, "ablkcipher", sizeof(rblkcipher.type));
++ strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<default>",
++ sizeof(rblkcipher.geniv));
+
+ rblkcipher.blocksize = alg->cra_blocksize;
+ rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
+@@ -469,9 +469,9 @@ static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_blkcipher rblkcipher;
+
+- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher");
+- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+- alg->cra_ablkcipher.geniv ?: "<built-in>");
++ strncpy(rblkcipher.type, "givcipher", sizeof(rblkcipher.type));
++ strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<built-in>",
++ sizeof(rblkcipher.geniv));
+
+ rblkcipher.blocksize = alg->cra_blocksize;
+ rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
+diff --git a/crypto/aead.c b/crypto/aead.c
+index 0b8121e..27bc487 100644
+--- a/crypto/aead.c
++++ b/crypto/aead.c
+@@ -117,9 +117,8 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
+ struct crypto_report_aead raead;
+ struct aead_alg *aead = &alg->cra_aead;
+
+- snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead");
+- snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+- aead->geniv ?: "<built-in>");
++ strncpy(raead.type, "aead", sizeof(raead.type));
++ strncpy(raead.geniv, aead->geniv ?: "<built-in>", sizeof(raead.geniv));
+
+ raead.blocksize = alg->cra_blocksize;
+ raead.maxauthsize = aead->maxauthsize;
+@@ -203,8 +202,8 @@ static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
+ struct crypto_report_aead raead;
+ struct aead_alg *aead = &alg->cra_aead;
+
+- snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead");
+- snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv);
++ strncpy(raead.type, "nivaead", sizeof(raead.type));
++ strncpy(raead.geniv, aead->geniv, sizeof(raead.geniv));
+
+ raead.blocksize = alg->cra_blocksize;
+ raead.maxauthsize = aead->maxauthsize;
+diff --git a/crypto/ahash.c b/crypto/ahash.c
+index 3887856..793a27f 100644
+--- a/crypto/ahash.c
++++ b/crypto/ahash.c
+@@ -404,7 +404,7 @@ static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_hash rhash;
+
+- snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash");
++ strncpy(rhash.type, "ahash", sizeof(rhash.type));
+
+ rhash.blocksize = alg->cra_blocksize;
+ rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize;
+diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
+index a8d85a1..c44e014 100644
+--- a/crypto/blkcipher.c
++++ b/crypto/blkcipher.c
+@@ -499,9 +499,9 @@ static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_blkcipher rblkcipher;
+
+- snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher");
+- snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+- alg->cra_blkcipher.geniv ?: "<default>");
++ strncpy(rblkcipher.type, "blkcipher", sizeof(rblkcipher.type));
++ strncpy(rblkcipher.geniv, alg->cra_blkcipher.geniv ?: "<default>",
++ sizeof(rblkcipher.geniv));
+
+ rblkcipher.blocksize = alg->cra_blocksize;
+ rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
+diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
+index 35d700a..f6d9baf 100644
+--- a/crypto/crypto_user.c
++++ b/crypto/crypto_user.c
+@@ -75,7 +75,7 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_cipher rcipher;
+
+- snprintf(rcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "cipher");
++ strncpy(rcipher.type, "cipher", sizeof(rcipher.type));
+
+ rcipher.blocksize = alg->cra_blocksize;
+ rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
+@@ -94,8 +94,7 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_comp rcomp;
+
+- snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression");
+-
++ strncpy(rcomp.type, "compression", sizeof(rcomp.type));
+ if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
+ sizeof(struct crypto_report_comp), &rcomp))
+ goto nla_put_failure;
+@@ -108,12 +107,14 @@ nla_put_failure:
+ static int crypto_report_one(struct crypto_alg *alg,
+ struct crypto_user_alg *ualg, struct sk_buff *skb)
+ {
+- memcpy(&ualg->cru_name, &alg->cra_name, sizeof(ualg->cru_name));
+- memcpy(&ualg->cru_driver_name, &alg->cra_driver_name,
+- sizeof(ualg->cru_driver_name));
+- memcpy(&ualg->cru_module_name, module_name(alg->cra_module),
+- CRYPTO_MAX_ALG_NAME);
+-
++ strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
++ strncpy(ualg->cru_driver_name, alg->cra_driver_name,
++ sizeof(ualg->cru_driver_name));
++ strncpy(ualg->cru_module_name, module_name(alg->cra_module),
++ sizeof(ualg->cru_module_name));
++
++ ualg->cru_type = 0;
++ ualg->cru_mask = 0;
+ ualg->cru_flags = alg->cra_flags;
+ ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);
+
+@@ -122,8 +123,7 @@ static int crypto_report_one(struct crypto_alg *alg,
+ if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
+ struct crypto_report_larval rl;
+
+- snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval");
+-
++ strncpy(rl.type, "larval", sizeof(rl.type));
+ if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
+ sizeof(struct crypto_report_larval), &rl))
+ goto nla_put_failure;
+diff --git a/crypto/pcompress.c b/crypto/pcompress.c
+index 04e083f..7140fe7 100644
+--- a/crypto/pcompress.c
++++ b/crypto/pcompress.c
+@@ -53,8 +53,7 @@ static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_comp rpcomp;
+
+- snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp");
+-
++ strncpy(rpcomp.type, "pcomp", sizeof(rpcomp.type));
+ if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
+ sizeof(struct crypto_report_comp), &rpcomp))
+ goto nla_put_failure;
+diff --git a/crypto/rng.c b/crypto/rng.c
+index f3b7894..e0a25c2 100644
+--- a/crypto/rng.c
++++ b/crypto/rng.c
+@@ -65,7 +65,7 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
+ {
+ struct crypto_report_rng rrng;
+
+- snprintf(rrng.type, CRYPTO_MAX_ALG_NAME, "%s", "rng");
++ strncpy(rrng.type, "rng", sizeof(rrng.type));
+
+ rrng.seedsize = alg->cra_rng.seedsize;
+
+diff --git a/crypto/shash.c b/crypto/shash.c
+index f426330f..929058a 100644
+--- a/crypto/shash.c
++++ b/crypto/shash.c
+@@ -530,7 +530,8 @@ static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
+ struct crypto_report_hash rhash;
+ struct shash_alg *salg = __crypto_shash_alg(alg);
+
+- snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash");
++ strncpy(rhash.type, "shash", sizeof(rhash.type));
++
+ rhash.blocksize = alg->cra_blocksize;
+ rhash.digestsize = salg->digestsize;
+
+diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
+index de1f319..e34a7b4 100644
+--- a/drivers/block/xen-blkback/blkback.c
++++ b/drivers/block/xen-blkback/blkback.c
+@@ -881,6 +881,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
+ goto fail_response;
+ }
+
++ preq.dev = req->u.rw.handle;
+ preq.sector_number = req->u.rw.sector_number;
+ preq.nr_sects = 0;
+
+diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
+index 1bafb40..69ae597 100644
+--- a/drivers/char/hw_random/core.c
++++ b/drivers/char/hw_random/core.c
+@@ -40,6 +40,7 @@
+ #include <linux/init.h>
+ #include <linux/miscdevice.h>
+ #include <linux/delay.h>
++#include <linux/slab.h>
+ #include <asm/uaccess.h>
+
+
+@@ -52,8 +53,12 @@ static struct hwrng *current_rng;
+ static LIST_HEAD(rng_list);
+ static DEFINE_MUTEX(rng_mutex);
+ static int data_avail;
+-static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
+- __cacheline_aligned;
++static u8 *rng_buffer;
++
++static size_t rng_buffer_size(void)
++{
++ return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
++}
+
+ static inline int hwrng_init(struct hwrng *rng)
+ {
+@@ -116,7 +121,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
+
+ if (!data_avail) {
+ bytes_read = rng_get_data(current_rng, rng_buffer,
+- sizeof(rng_buffer),
++ rng_buffer_size(),
+ !(filp->f_flags & O_NONBLOCK));
+ if (bytes_read < 0) {
+ err = bytes_read;
+@@ -307,6 +312,14 @@ int hwrng_register(struct hwrng *rng)
+
+ mutex_lock(&rng_mutex);
+
++ /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
++ err = -ENOMEM;
++ if (!rng_buffer) {
++ rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
++ if (!rng_buffer)
++ goto out_unlock;
++ }
++
+ /* Must not register two RNGs with the same name. */
+ err = -EEXIST;
+ list_for_each_entry(tmp, &rng_list, list) {
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 85e81ec..57d4b15 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -852,6 +852,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ int reserved)
+ {
+ unsigned long flags;
++ int wakeup_write = 0;
+
+ /* Hold lock while accounting */
+ spin_lock_irqsave(&r->lock, flags);
+@@ -873,10 +874,8 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ else
+ r->entropy_count = reserved;
+
+- if (r->entropy_count < random_write_wakeup_thresh) {
+- wake_up_interruptible(&random_write_wait);
+- kill_fasync(&fasync, SIGIO, POLL_OUT);
+- }
++ if (r->entropy_count < random_write_wakeup_thresh)
++ wakeup_write = 1;
+ }
+
+ DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
+@@ -884,6 +883,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+
+ spin_unlock_irqrestore(&r->lock, flags);
+
++ if (wakeup_write) {
++ wake_up_interruptible(&random_write_wait);
++ kill_fasync(&fasync, SIGIO, POLL_OUT);
++ }
++
+ return nbytes;
+ }
+
+diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
+index fce2000..1110478 100644
+--- a/drivers/connector/cn_proc.c
++++ b/drivers/connector/cn_proc.c
+@@ -313,6 +313,12 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
+ (task_active_pid_ns(current) != &init_pid_ns))
+ return;
+
++ /* Can only change if privileged. */
++ if (!capable(CAP_NET_ADMIN)) {
++ err = EPERM;
++ goto out;
++ }
++
+ mc_op = (enum proc_cn_mcast_op *)msg->data;
+ switch (*mc_op) {
+ case PROC_CN_MCAST_LISTEN:
+@@ -325,6 +331,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
+ err = EINVAL;
+ break;
+ }
++
++out:
+ cn_proc_ack(err, msg->seq, msg->ack);
+ }
+
+diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
+index 982f1f5..4cd392d 100644
+--- a/drivers/firmware/dmi_scan.c
++++ b/drivers/firmware/dmi_scan.c
+@@ -442,7 +442,6 @@ static int __init dmi_present(const char __iomem *p)
+ static int __init smbios_present(const char __iomem *p)
+ {
+ u8 buf[32];
+- int offset = 0;
+
+ memcpy_fromio(buf, p, 32);
+ if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
+@@ -461,9 +460,9 @@ static int __init smbios_present(const char __iomem *p)
+ dmi_ver = 0x0206;
+ break;
+ }
+- offset = 16;
++ return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16);
+ }
+- return dmi_present(buf + offset);
++ return 1;
+ }
+
+ void __init dmi_scan_machine(void)
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index bcb201c..2a2e145 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -406,10 +406,11 @@ static efi_status_t
+ get_var_data(struct efivars *efivars, struct efi_variable *var)
+ {
+ efi_status_t status;
++ unsigned long flags;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irqsave(&efivars->lock, flags);
+ status = get_var_data_locked(efivars, var);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irqrestore(&efivars->lock, flags);
+
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
+@@ -418,6 +419,44 @@ get_var_data(struct efivars *efivars, struct efi_variable *var)
+ return status;
+ }
+
++static efi_status_t
++check_var_size_locked(struct efivars *efivars, u32 attributes,
++ unsigned long size)
++{
++ u64 storage_size, remaining_size, max_size;
++ efi_status_t status;
++ const struct efivar_operations *fops = efivars->ops;
++
++ if (!efivars->ops->query_variable_info)
++ return EFI_UNSUPPORTED;
++
++ status = fops->query_variable_info(attributes, &storage_size,
++ &remaining_size, &max_size);
++
++ if (status != EFI_SUCCESS)
++ return status;
++
++ if (!storage_size || size > remaining_size || size > max_size ||
++ (remaining_size - size) < (storage_size / 2))
++ return EFI_OUT_OF_RESOURCES;
++
++ return status;
++}
++
++
++static efi_status_t
++check_var_size(struct efivars *efivars, u32 attributes, unsigned long size)
++{
++ efi_status_t status;
++ unsigned long flags;
++
++ spin_lock_irqsave(&efivars->lock, flags);
++ status = check_var_size_locked(efivars, attributes, size);
++ spin_unlock_irqrestore(&efivars->lock, flags);
++
++ return status;
++}
++
+ static ssize_t
+ efivar_guid_read(struct efivar_entry *entry, char *buf)
+ {
+@@ -538,14 +577,19 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
+ return -EINVAL;
+ }
+
+- spin_lock(&efivars->lock);
+- status = efivars->ops->set_variable(new_var->VariableName,
+- &new_var->VendorGuid,
+- new_var->Attributes,
+- new_var->DataSize,
+- new_var->Data);
++ spin_lock_irq(&efivars->lock);
++
++ status = check_var_size_locked(efivars, new_var->Attributes,
++ new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+
+- spin_unlock(&efivars->lock);
++ if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
++ status = efivars->ops->set_variable(new_var->VariableName,
++ &new_var->VendorGuid,
++ new_var->Attributes,
++ new_var->DataSize,
++ new_var->Data);
++
++ spin_unlock_irq(&efivars->lock);
+
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
+@@ -694,8 +738,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ u32 attributes;
+ struct inode *inode = file->f_mapping->host;
+ unsigned long datasize = count - sizeof(attributes);
+- unsigned long newdatasize;
+- u64 storage_size, remaining_size, max_size;
++ unsigned long newdatasize, varsize;
+ ssize_t bytes = 0;
+
+ if (count < sizeof(attributes))
+@@ -714,28 +757,18 @@ static ssize_t efivarfs_file_write(struct file *file,
+ * amounts of memory. Pick a default size of 64K if
+ * QueryVariableInfo() isn't supported by the firmware.
+ */
+- spin_lock(&efivars->lock);
+
+- if (!efivars->ops->query_variable_info)
+- status = EFI_UNSUPPORTED;
+- else {
+- const struct efivar_operations *fops = efivars->ops;
+- status = fops->query_variable_info(attributes, &storage_size,
+- &remaining_size, &max_size);
+- }
+-
+- spin_unlock(&efivars->lock);
++ varsize = datasize + utf16_strsize(var->var.VariableName, 1024);
++ status = check_var_size(efivars, attributes, varsize);
+
+ if (status != EFI_SUCCESS) {
+ if (status != EFI_UNSUPPORTED)
+ return efi_status_to_err(status);
+
+- remaining_size = 65536;
++ if (datasize > 65536)
++ return -ENOSPC;
+ }
+
+- if (datasize > remaining_size)
+- return -ENOSPC;
+-
+ data = kmalloc(datasize, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+@@ -755,7 +788,20 @@ static ssize_t efivarfs_file_write(struct file *file,
+ * set_variable call, and removal of the variable from the efivars
+ * list (in the case of an authenticated delete).
+ */
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
++
++ /*
++ * Ensure that the available space hasn't shrunk below the safe level
++ */
++
++ status = check_var_size_locked(efivars, attributes, varsize);
++
++ if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) {
++ spin_unlock_irq(&efivars->lock);
++ kfree(data);
++
++ return efi_status_to_err(status);
++ }
+
+ status = efivars->ops->set_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+@@ -763,7 +809,7 @@ static ssize_t efivarfs_file_write(struct file *file,
+ data);
+
+ if (status != EFI_SUCCESS) {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ kfree(data);
+
+ return efi_status_to_err(status);
+@@ -784,21 +830,21 @@ static ssize_t efivarfs_file_write(struct file *file,
+ NULL);
+
+ if (status == EFI_BUFFER_TOO_SMALL) {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ mutex_lock(&inode->i_mutex);
+ i_size_write(inode, newdatasize + sizeof(attributes));
+ mutex_unlock(&inode->i_mutex);
+
+ } else if (status == EFI_NOT_FOUND) {
+ list_del(&var->list);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ efivar_unregister(var);
+ drop_nlink(inode);
+ d_delete(file->f_dentry);
+ dput(file->f_dentry);
+
+ } else {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ pr_warn("efivarfs: inconsistent EFI variable implementation? "
+ "status = %lx\n", status);
+ }
+@@ -820,11 +866,11 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ void *data;
+ ssize_t size = 0;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ status = efivars->ops->get_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+ &attributes, &datasize, NULL);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ if (status != EFI_BUFFER_TOO_SMALL)
+ return efi_status_to_err(status);
+@@ -834,12 +880,12 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
+ if (!data)
+ return -ENOMEM;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ status = efivars->ops->get_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+ &attributes, &datasize,
+ (data + sizeof(attributes)));
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ if (status != EFI_SUCCESS) {
+ size = efi_status_to_err(status);
+@@ -921,8 +967,8 @@ static bool efivarfs_valid_name(const char *str, int len)
+ if (len < GUID_LEN + 2)
+ return false;
+
+- /* GUID should be right after the first '-' */
+- if (s - 1 != strchr(str, '-'))
++ /* GUID must be preceded by a '-' */
++ if (*(s - 1) != '-')
+ return false;
+
+ /*
+@@ -1005,9 +1051,9 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+ goto out;
+
+ kobject_uevent(&var->kobj, KOBJ_ADD);
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ list_add(&var->list, &efivars->list);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ d_instantiate(dentry, inode);
+ dget(dentry);
+ out:
+@@ -1024,7 +1070,7 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
+ struct efivars *efivars = var->efivars;
+ efi_status_t status;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+
+ status = efivars->ops->set_variable(var->var.VariableName,
+ &var->var.VendorGuid,
+@@ -1032,14 +1078,14 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
+
+ if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) {
+ list_del(&var->list);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ efivar_unregister(var);
+ drop_nlink(dentry->d_inode);
+ dput(dentry);
+ return 0;
+ }
+
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EINVAL;
+ };
+
+@@ -1110,15 +1156,22 @@ static struct dentry_operations efivarfs_d_ops = {
+
+ static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
+ {
++ struct dentry *d;
+ struct qstr q;
++ int err;
+
+ q.name = name;
+ q.len = strlen(name);
+
+- if (efivarfs_d_hash(NULL, NULL, &q))
+- return NULL;
++ err = efivarfs_d_hash(NULL, NULL, &q);
++ if (err)
++ return ERR_PTR(err);
+
+- return d_alloc(parent, &q);
++ d = d_alloc(parent, &q);
++ if (d)
++ return d;
++
++ return ERR_PTR(-ENOMEM);
+ }
+
+ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+@@ -1128,6 +1181,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ struct efivar_entry *entry, *n;
+ struct efivars *efivars = &__efivars;
+ char *name;
++ int err = -ENOMEM;
+
+ efivarfs_sb = sb;
+
+@@ -1178,19 +1232,21 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ goto fail_name;
+
+ dentry = efivarfs_alloc_dentry(root, name);
+- if (!dentry)
++ if (IS_ERR(dentry)) {
++ err = PTR_ERR(dentry);
+ goto fail_inode;
++ }
+
+ /* copied by the above to local storage in the dentry. */
+ kfree(name);
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ efivars->ops->get_variable(entry->var.VariableName,
+ &entry->var.VendorGuid,
+ &entry->var.Attributes,
+ &size,
+ NULL);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ mutex_lock(&inode->i_mutex);
+ inode->i_private = entry;
+@@ -1206,7 +1262,7 @@ fail_inode:
+ fail_name:
+ kfree(name);
+ fail:
+- return -ENOMEM;
++ return err;
+ }
+
+ static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
+@@ -1253,7 +1309,7 @@ static int efi_pstore_open(struct pstore_info *psi)
+ {
+ struct efivars *efivars = psi->data;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ efivars->walk_entry = list_first_entry(&efivars->list,
+ struct efivar_entry, list);
+ return 0;
+@@ -1263,7 +1319,7 @@ static int efi_pstore_close(struct pstore_info *psi)
+ {
+ struct efivars *efivars = psi->data;
+
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return 0;
+ }
+
+@@ -1337,22 +1393,22 @@ static int efi_pstore_write(enum pstore_type_id type,
+ efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
+ struct efivars *efivars = psi->data;
+ int i, ret = 0;
+- u64 storage_space, remaining_space, max_variable_size;
+ efi_status_t status = EFI_NOT_FOUND;
++ unsigned long flags;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irqsave(&efivars->lock, flags);
+
+ /*
+ * Check if there is a space enough to log.
+ * size: a size of logging data
+ * DUMP_NAME_LEN * 2: a maximum size of variable name
+ */
+- status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
+- &storage_space,
+- &remaining_space,
+- &max_variable_size);
+- if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
+- spin_unlock(&efivars->lock);
++
++ status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
++ size + DUMP_NAME_LEN * 2);
++
++ if (status) {
++ spin_unlock_irqrestore(&efivars->lock, flags);
+ *id = part;
+ return -ENOSPC;
+ }
+@@ -1366,7 +1422,7 @@ static int efi_pstore_write(enum pstore_type_id type,
+ efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES,
+ size, psi->buf);
+
+- spin_unlock(&efivars->lock);
++ spin_unlock_irqrestore(&efivars->lock, flags);
+
+ if (size)
+ ret = efivar_create_sysfs_entry(efivars,
+@@ -1393,7 +1449,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
+ sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
+ time.tv_sec);
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+
+ for (i = 0; i < DUMP_NAME_LEN; i++)
+ efi_name[i] = name[i];
+@@ -1437,7 +1493,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
+ if (found)
+ list_del(&found->list);
+
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ if (found)
+ efivar_unregister(found);
+@@ -1507,7 +1563,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
+ return -EINVAL;
+ }
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+
+ /*
+ * Does this variable already exist?
+@@ -1525,10 +1581,18 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
+ }
+ }
+ if (found) {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EINVAL;
+ }
+
++ status = check_var_size_locked(efivars, new_var->Attributes,
++ new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
++
++ if (status && status != EFI_UNSUPPORTED) {
++ spin_unlock_irq(&efivars->lock);
++ return efi_status_to_err(status);
++ }
++
+ /* now *really* create the variable via EFI */
+ status = efivars->ops->set_variable(new_var->VariableName,
+ &new_var->VendorGuid,
+@@ -1539,10 +1603,10 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
+ status);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EIO;
+ }
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ /* Create the entry in sysfs. Locking is not required here */
+ status = efivar_create_sysfs_entry(efivars,
+@@ -1570,7 +1634,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+
+ /*
+ * Does this variable already exist?
+@@ -1588,7 +1652,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
+ }
+ }
+ if (!found) {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EINVAL;
+ }
+ /* force the Attributes/DataSize to 0 to ensure deletion */
+@@ -1604,12 +1668,12 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
+ status);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EIO;
+ }
+ list_del(&search_efivar->list);
+ /* We need to release this lock before unregistering. */
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ efivar_unregister(search_efivar);
+
+ /* It's dead Jim.... */
+@@ -1724,9 +1788,9 @@ efivar_create_sysfs_entry(struct efivars *efivars,
+ kfree(short_name);
+ short_name = NULL;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ list_add(&new_efivar->list, &efivars->list);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ return 0;
+ }
+@@ -1795,9 +1859,9 @@ void unregister_efivars(struct efivars *efivars)
+ struct efivar_entry *entry, *n;
+
+ list_for_each_entry_safe(entry, n, &efivars->list, list) {
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ list_del(&entry->list);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ efivar_unregister(entry);
+ }
+ if (efivars->new_var)
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index 6819d63..456663c 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -41,6 +41,7 @@
+ #include <linux/io.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_device.h>
++#include <linux/clk.h>
+ #include <linux/pinctrl/consumer.h>
+
+ /*
+@@ -495,6 +496,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
+ struct resource *res;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
++ struct clk *clk;
+ unsigned int ngpios;
+ int soc_variant;
+ int i, cpu, id;
+@@ -528,6 +530,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
+ return id;
+ }
+
++ clk = devm_clk_get(&pdev->dev, NULL);
++ /* Not all SoCs require a clock.*/
++ if (!IS_ERR(clk))
++ clk_prepare_enable(clk);
++
+ mvchip->soc_variant = soc_variant;
+ mvchip->chip.label = dev_name(&pdev->dev);
+ mvchip->chip.dev = &pdev->dev;
+diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
+index 99daa89..5206f24 100644
+--- a/drivers/gpu/drm/i915/i915_dma.c
++++ b/drivers/gpu/drm/i915/i915_dma.c
+@@ -1297,19 +1297,21 @@ static int i915_load_modeset_init(struct drm_device *dev)
+ if (ret)
+ goto cleanup_vga_switcheroo;
+
++ ret = drm_irq_install(dev);
++ if (ret)
++ goto cleanup_gem_stolen;
++
++ /* Important: The output setup functions called by modeset_init need
++ * working irqs for e.g. gmbus and dp aux transfers. */
+ intel_modeset_init(dev);
+
+ ret = i915_gem_init(dev);
+ if (ret)
+- goto cleanup_gem_stolen;
+-
+- intel_modeset_gem_init(dev);
++ goto cleanup_irq;
+
+ INIT_WORK(&dev_priv->console_resume_work, intel_console_resume);
+
+- ret = drm_irq_install(dev);
+- if (ret)
+- goto cleanup_gem;
++ intel_modeset_gem_init(dev);
+
+ /* Always safe in the mode setting case. */
+ /* FIXME: do pre/post-mode set stuff in core KMS code */
+@@ -1317,7 +1319,10 @@ static int i915_load_modeset_init(struct drm_device *dev)
+
+ ret = intel_fbdev_init(dev);
+ if (ret)
+- goto cleanup_irq;
++ goto cleanup_gem;
++
++ /* Only enable hotplug handling once the fbdev is fully set up. */
++ dev_priv->enable_hotplug_processing = true;
+
+ drm_kms_helper_poll_init(dev);
+
+@@ -1326,13 +1331,13 @@ static int i915_load_modeset_init(struct drm_device *dev)
+
+ return 0;
+
+-cleanup_irq:
+- drm_irq_uninstall(dev);
+ cleanup_gem:
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_cleanup_ringbuffer(dev);
+ mutex_unlock(&dev->struct_mutex);
+ i915_gem_cleanup_aliasing_ppgtt(dev);
++cleanup_irq:
++ drm_irq_uninstall(dev);
+ cleanup_gem_stolen:
+ i915_gem_cleanup_stolen(dev);
+ cleanup_vga_switcheroo:
+diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
+index 1172658..fb6454c 100644
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -377,15 +377,15 @@ static const struct pci_device_id pciidlist[] = { /* aka */
+ INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
+ INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
+ INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
+- INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */
++ INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */
++ INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */
+ INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
+- INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */
+- INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */
++ INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */
++ INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */
+ INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
+- INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */
+- INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */
++ INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */
++ INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
+ INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
+- INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */
+ INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
+ INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
+ INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
+@@ -486,6 +486,7 @@ static int i915_drm_freeze(struct drm_device *dev)
+ intel_modeset_disable(dev);
+
+ drm_irq_uninstall(dev);
++ dev_priv->enable_hotplug_processing = false;
+ }
+
+ i915_save_state(dev);
+@@ -562,9 +563,19 @@ static int __i915_drm_thaw(struct drm_device *dev)
+ error = i915_gem_init_hw(dev);
+ mutex_unlock(&dev->struct_mutex);
+
++ /* We need working interrupts for modeset enabling ... */
++ drm_irq_install(dev);
++
+ intel_modeset_init_hw(dev);
+ intel_modeset_setup_hw_state(dev, false);
+- drm_irq_install(dev);
++
++ /*
++ * ... but also need to make sure that hotplug processing
++ * doesn't cause havoc. Like in the driver load code we don't
++ * bother with the tiny race here where we might loose hotplug
++ * notifications.
++ * */
++ dev_priv->enable_hotplug_processing = true;
+ }
+
+ intel_opregion_init(dev);
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index 7339a4b..66ad64f 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -672,6 +672,7 @@ typedef struct drm_i915_private {
+
+ u32 hotplug_supported_mask;
+ struct work_struct hotplug_work;
++ bool enable_hotplug_processing;
+
+ int num_pipe;
+ int num_pch_pll;
+diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
+index fe84338..3c00403 100644
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -287,6 +287,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
+ struct drm_mode_config *mode_config = &dev->mode_config;
+ struct intel_encoder *encoder;
+
++ /* HPD irq before everything is fully set up. */
++ if (!dev_priv->enable_hotplug_processing)
++ return;
++
+ mutex_lock(&mode_config->mutex);
+ DRM_DEBUG_KMS("running encoder hotplug functions\n");
+
+diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
+index 06b1786..b52ed09 100644
+--- a/drivers/gpu/drm/i915/intel_crt.c
++++ b/drivers/gpu/drm/i915/intel_crt.c
+@@ -88,7 +88,7 @@ static void intel_disable_crt(struct intel_encoder *encoder)
+ u32 temp;
+
+ temp = I915_READ(crt->adpa_reg);
+- temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
++ temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
+ temp &= ~ADPA_DAC_ENABLE;
+ I915_WRITE(crt->adpa_reg, temp);
+ }
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 3280cff..dde0ded 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2572,7 +2572,7 @@ static void gen6_enable_rps(struct drm_device *dev)
+ I915_WRITE(GEN6_RC_SLEEP, 0);
+ I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
+ I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
+- I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
++ I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
+ I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
+
+ /* Check if we are enabling RC6 */
+diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
+index 3e403bd..78edadc 100644
+--- a/drivers/gpu/drm/radeon/radeon_combios.c
++++ b/drivers/gpu/drm/radeon/radeon_combios.c
+@@ -970,6 +970,15 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
+ found = 1;
+ }
+
++ /* quirks */
++ /* Radeon 9100 (R200) */
++ if ((dev->pdev->device == 0x514D) &&
++ (dev->pdev->subsystem_vendor == 0x174B) &&
++ (dev->pdev->subsystem_device == 0x7149)) {
++ /* vbios value is bad, use the default */
++ found = 0;
++ }
++
+ if (!found) /* fallback to defaults */
+ radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
+
+diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+index 90374dd..48f80cd 100644
+--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+@@ -400,6 +400,9 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block)
+ {
+ unsigned long irqflags;
+
++ if (!rdev->ddev->irq_enabled)
++ return;
++
+ spin_lock_irqsave(&rdev->irq.lock, irqflags);
+ rdev->irq.afmt[block] = true;
+ radeon_irq_set(rdev);
+@@ -419,6 +422,9 @@ void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block)
+ {
+ unsigned long irqflags;
+
++ if (!rdev->ddev->irq_enabled)
++ return;
++
+ spin_lock_irqsave(&rdev->irq.lock, irqflags);
+ rdev->irq.afmt[block] = false;
+ radeon_irq_set(rdev);
+@@ -438,6 +444,9 @@ void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
+ unsigned long irqflags;
+ int i;
+
++ if (!rdev->ddev->irq_enabled)
++ return;
++
+ spin_lock_irqsave(&rdev->irq.lock, irqflags);
+ for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
+ rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i));
+@@ -458,6 +467,9 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
+ unsigned long irqflags;
+ int i;
+
++ if (!rdev->ddev->irq_enabled)
++ return;
++
+ spin_lock_irqsave(&rdev->irq.lock, irqflags);
+ for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
+ rdev->irq.hpd[i] &= !(hpd_mask & (1 << i));
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 9500f2f..8758f38c 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -459,19 +459,25 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
+ struct dj_report *dj_report)
+ {
+ struct hid_device *hdev = djrcv_dev->hdev;
+- int sent_bytes;
++ struct hid_report *report;
++ struct hid_report_enum *output_report_enum;
++ u8 *data = (u8 *)(&dj_report->device_index);
++ int i;
+
+- if (!hdev->hid_output_raw_report) {
+- dev_err(&hdev->dev, "%s:"
+- "hid_output_raw_report is null\n", __func__);
++ output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
++ report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
++
++ if (!report) {
++ dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__);
+ return -ENODEV;
+ }
+
+- sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report,
+- sizeof(struct dj_report),
+- HID_OUTPUT_REPORT);
++ for (i = 0; i < report->field[0]->report_count; i++)
++ report->field[0]->value[i] = data[i];
++
++ usbhid_submit_report(hdev, report, USB_DIR_OUT);
+
+- return (sent_bytes < 0) ? sent_bytes : 0;
++ return 0;
+ }
+
+ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
+diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
+index 9652a2c..a58de38 100644
+--- a/drivers/hwmon/pmbus/ltc2978.c
++++ b/drivers/hwmon/pmbus/ltc2978.c
+@@ -62,7 +62,7 @@ struct ltc2978_data {
+ int temp_min, temp_max;
+ int vout_min[8], vout_max[8];
+ int iout_max[2];
+- int temp2_max[2];
++ int temp2_max;
+ struct pmbus_driver_info info;
+ };
+
+@@ -204,10 +204,9 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
+ ret = pmbus_read_word_data(client, page,
+ LTC3880_MFR_TEMPERATURE2_PEAK);
+ if (ret >= 0) {
+- if (lin11_to_val(ret)
+- > lin11_to_val(data->temp2_max[page]))
+- data->temp2_max[page] = ret;
+- ret = data->temp2_max[page];
++ if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
++ data->temp2_max = ret;
++ ret = data->temp2_max;
+ }
+ break;
+ case PMBUS_VIRT_READ_VIN_MIN:
+@@ -248,11 +247,11 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
+
+ switch (reg) {
+ case PMBUS_VIRT_RESET_IOUT_HISTORY:
+- data->iout_max[page] = 0x7fff;
++ data->iout_max[page] = 0x7c00;
+ ret = ltc2978_clear_peaks(client, page, data->id);
+ break;
+ case PMBUS_VIRT_RESET_TEMP2_HISTORY:
+- data->temp2_max[page] = 0x7fff;
++ data->temp2_max = 0x7c00;
+ ret = ltc2978_clear_peaks(client, page, data->id);
+ break;
+ case PMBUS_VIRT_RESET_VOUT_HISTORY:
+@@ -262,12 +261,12 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
+ break;
+ case PMBUS_VIRT_RESET_VIN_HISTORY:
+ data->vin_min = 0x7bff;
+- data->vin_max = 0;
++ data->vin_max = 0x7c00;
+ ret = ltc2978_clear_peaks(client, page, data->id);
+ break;
+ case PMBUS_VIRT_RESET_TEMP_HISTORY:
+ data->temp_min = 0x7bff;
+- data->temp_max = 0x7fff;
++ data->temp_max = 0x7c00;
+ ret = ltc2978_clear_peaks(client, page, data->id);
+ break;
+ default:
+@@ -321,12 +320,13 @@ static int ltc2978_probe(struct i2c_client *client,
+ info = &data->info;
+ info->write_word_data = ltc2978_write_word_data;
+
+- data->vout_min[0] = 0xffff;
+ data->vin_min = 0x7bff;
++ data->vin_max = 0x7c00;
+ data->temp_min = 0x7bff;
+- data->temp_max = 0x7fff;
++ data->temp_max = 0x7c00;
++ data->temp2_max = 0x7c00;
+
+- switch (id->driver_data) {
++ switch (data->id) {
+ case ltc2978:
+ info->read_word_data = ltc2978_read_word_data;
+ info->pages = 8;
+@@ -336,7 +336,6 @@ static int ltc2978_probe(struct i2c_client *client,
+ for (i = 1; i < 8; i++) {
+ info->func[i] = PMBUS_HAVE_VOUT
+ | PMBUS_HAVE_STATUS_VOUT;
+- data->vout_min[i] = 0xffff;
+ }
+ break;
+ case ltc3880:
+@@ -352,11 +351,14 @@ static int ltc2978_probe(struct i2c_client *client,
+ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
+ | PMBUS_HAVE_POUT
+ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+- data->vout_min[1] = 0xffff;
++ data->iout_max[0] = 0x7c00;
++ data->iout_max[1] = 0x7c00;
+ break;
+ default:
+ return -ENODEV;
+ }
++ for (i = 0; i < info->pages; i++)
++ data->vout_min[i] = 0xffff;
+
+ return pmbus_do_probe(client, id, info);
+ }
+diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
+index 1c85d39..8047fed 100644
+--- a/drivers/hwmon/sht15.c
++++ b/drivers/hwmon/sht15.c
+@@ -926,7 +926,13 @@ static int sht15_probe(struct platform_device *pdev)
+ if (voltage)
+ data->supply_uV = voltage;
+
+- regulator_enable(data->reg);
++ ret = regulator_enable(data->reg);
++ if (ret != 0) {
++ dev_err(&pdev->dev,
++ "failed to enable regulator: %d\n", ret);
++ return ret;
++ }
++
+ /*
+ * Setup a notifier block to update this if another device
+ * causes the voltage to change
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index f7369f9..2ae151e 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -1234,20 +1234,6 @@ static int crypt_decode_key(u8 *key, char *hex, unsigned int size)
+ return 0;
+ }
+
+-/*
+- * Encode key into its hex representation
+- */
+-static void crypt_encode_key(char *hex, u8 *key, unsigned int size)
+-{
+- unsigned int i;
+-
+- for (i = 0; i < size; i++) {
+- sprintf(hex, "%02x", *key);
+- hex += 2;
+- key++;
+- }
+-}
+-
+ static void crypt_free_tfms(struct crypt_config *cc)
+ {
+ unsigned i;
+@@ -1717,11 +1703,11 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
+ return DM_MAPIO_SUBMITTED;
+ }
+
+-static int crypt_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void crypt_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ struct crypt_config *cc = ti->private;
+- unsigned int sz = 0;
++ unsigned i, sz = 0;
+
+ switch (type) {
+ case STATUSTYPE_INFO:
+@@ -1731,17 +1717,11 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
+ case STATUSTYPE_TABLE:
+ DMEMIT("%s ", cc->cipher_string);
+
+- if (cc->key_size > 0) {
+- if ((maxlen - sz) < ((cc->key_size << 1) + 1))
+- return -ENOMEM;
+-
+- crypt_encode_key(result + sz, cc->key, cc->key_size);
+- sz += cc->key_size << 1;
+- } else {
+- if (sz >= maxlen)
+- return -ENOMEM;
+- result[sz++] = '-';
+- }
++ if (cc->key_size > 0)
++ for (i = 0; i < cc->key_size; i++)
++ DMEMIT("%02x", cc->key[i]);
++ else
++ DMEMIT("-");
+
+ DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
+ cc->dev->name, (unsigned long long)cc->start);
+@@ -1751,7 +1731,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
+
+ break;
+ }
+- return 0;
+ }
+
+ static void crypt_postsuspend(struct dm_target *ti)
+@@ -1845,7 +1824,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
+
+ static struct target_type crypt_target = {
+ .name = "crypt",
+- .version = {1, 12, 0},
++ .version = {1, 12, 1},
+ .module = THIS_MODULE,
+ .ctr = crypt_ctr,
+ .dtr = crypt_dtr,
+diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
+index cc1bd04..c0d03b0 100644
+--- a/drivers/md/dm-delay.c
++++ b/drivers/md/dm-delay.c
+@@ -293,8 +293,8 @@ static int delay_map(struct dm_target *ti, struct bio *bio)
+ return delay_bio(dc, dc->read_delay, bio);
+ }
+
+-static int delay_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void delay_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ struct delay_c *dc = ti->private;
+ int sz = 0;
+@@ -314,8 +314,6 @@ static int delay_status(struct dm_target *ti, status_type_t type,
+ dc->write_delay);
+ break;
+ }
+-
+- return 0;
+ }
+
+ static int delay_iterate_devices(struct dm_target *ti,
+@@ -337,7 +335,7 @@ out:
+
+ static struct target_type delay_target = {
+ .name = "delay",
+- .version = {1, 2, 0},
++ .version = {1, 2, 1},
+ .module = THIS_MODULE,
+ .ctr = delay_ctr,
+ .dtr = delay_dtr,
+diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
+index 9721f2f..5d6c04c 100644
+--- a/drivers/md/dm-flakey.c
++++ b/drivers/md/dm-flakey.c
+@@ -337,8 +337,8 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)
+ return error;
+ }
+
+-static int flakey_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void flakey_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ unsigned sz = 0;
+ struct flakey_c *fc = ti->private;
+@@ -368,7 +368,6 @@ static int flakey_status(struct dm_target *ti, status_type_t type,
+
+ break;
+ }
+- return 0;
+ }
+
+ static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg)
+@@ -411,7 +410,7 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_
+
+ static struct target_type flakey_target = {
+ .name = "flakey",
+- .version = {1, 3, 0},
++ .version = {1, 3, 1},
+ .module = THIS_MODULE,
+ .ctr = flakey_ctr,
+ .dtr = flakey_dtr,
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 0666b5d..eee353d 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1067,6 +1067,7 @@ static void retrieve_status(struct dm_table *table,
+ num_targets = dm_table_get_num_targets(table);
+ for (i = 0; i < num_targets; i++) {
+ struct dm_target *ti = dm_table_get_target(table, i);
++ size_t l;
+
+ remaining = len - (outptr - outbuf);
+ if (remaining <= sizeof(struct dm_target_spec)) {
+@@ -1093,14 +1094,17 @@ static void retrieve_status(struct dm_table *table,
+ if (ti->type->status) {
+ if (param->flags & DM_NOFLUSH_FLAG)
+ status_flags |= DM_STATUS_NOFLUSH_FLAG;
+- if (ti->type->status(ti, type, status_flags, outptr, remaining)) {
+- param->flags |= DM_BUFFER_FULL_FLAG;
+- break;
+- }
++ ti->type->status(ti, type, status_flags, outptr, remaining);
+ } else
+ outptr[0] = '\0';
+
+- outptr += strlen(outptr) + 1;
++ l = strlen(outptr) + 1;
++ if (l == remaining) {
++ param->flags |= DM_BUFFER_FULL_FLAG;
++ break;
++ }
++
++ outptr += l;
+ used = param->data_start + (outptr - outbuf);
+
+ outptr = align_ptr(outptr);
+diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
+index 328cad5..5be301c 100644
+--- a/drivers/md/dm-linear.c
++++ b/drivers/md/dm-linear.c
+@@ -95,8 +95,8 @@ static int linear_map(struct dm_target *ti, struct bio *bio)
+ return DM_MAPIO_REMAPPED;
+ }
+
+-static int linear_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void linear_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ struct linear_c *lc = (struct linear_c *) ti->private;
+
+@@ -110,7 +110,6 @@ static int linear_status(struct dm_target *ti, status_type_t type,
+ (unsigned long long)lc->start);
+ break;
+ }
+- return 0;
+ }
+
+ static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
+@@ -155,7 +154,7 @@ static int linear_iterate_devices(struct dm_target *ti,
+
+ static struct target_type linear_target = {
+ .name = "linear",
+- .version = {1, 2, 0},
++ .version = {1, 2, 1},
+ .module = THIS_MODULE,
+ .ctr = linear_ctr,
+ .dtr = linear_dtr,
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index 573bd04..d267bb5 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -1378,8 +1378,8 @@ static void multipath_resume(struct dm_target *ti)
+ * [priority selector-name num_ps_args [ps_args]*
+ * num_paths num_selector_args [path_dev [selector_args]* ]+ ]+
+ */
+-static int multipath_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void multipath_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ int sz = 0;
+ unsigned long flags;
+@@ -1485,8 +1485,6 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
+ }
+
+ spin_unlock_irqrestore(&m->lock, flags);
+-
+- return 0;
+ }
+
+ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
+@@ -1695,7 +1693,7 @@ out:
+ *---------------------------------------------------------------*/
+ static struct target_type multipath_target = {
+ .name = "multipath",
+- .version = {1, 5, 0},
++ .version = {1, 5, 1},
+ .module = THIS_MODULE,
+ .ctr = multipath_ctr,
+ .dtr = multipath_dtr,
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 9e58dbd..5a578d8 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -1201,8 +1201,8 @@ static int raid_map(struct dm_target *ti, struct bio *bio)
+ return DM_MAPIO_SUBMITTED;
+ }
+
+-static int raid_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void raid_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ struct raid_set *rs = ti->private;
+ unsigned raid_param_cnt = 1; /* at least 1 for chunksize */
+@@ -1344,8 +1344,6 @@ static int raid_status(struct dm_target *ti, status_type_t type,
+ DMEMIT(" -");
+ }
+ }
+-
+- return 0;
+ }
+
+ static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data)
+@@ -1405,7 +1403,7 @@ static void raid_resume(struct dm_target *ti)
+
+ static struct target_type raid_target = {
+ .name = "raid",
+- .version = {1, 4, 1},
++ .version = {1, 4, 2},
+ .module = THIS_MODULE,
+ .ctr = raid_ctr,
+ .dtr = raid_dtr,
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index fa51918..7f24190 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -1347,8 +1347,8 @@ static char device_status_char(struct mirror *m)
+ }
+
+
+-static int mirror_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void mirror_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ unsigned int m, sz = 0;
+ struct mirror_set *ms = (struct mirror_set *) ti->private;
+@@ -1383,8 +1383,6 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
+ if (ms->features & DM_RAID1_HANDLE_ERRORS)
+ DMEMIT(" 1 handle_errors");
+ }
+-
+- return 0;
+ }
+
+ static int mirror_iterate_devices(struct dm_target *ti,
+@@ -1403,7 +1401,7 @@ static int mirror_iterate_devices(struct dm_target *ti,
+
+ static struct target_type mirror_target = {
+ .name = "mirror",
+- .version = {1, 13, 1},
++ .version = {1, 13, 2},
+ .module = THIS_MODULE,
+ .ctr = mirror_ctr,
+ .dtr = mirror_dtr,
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index 59fc18a..df74f9f 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -1837,8 +1837,8 @@ static void snapshot_merge_resume(struct dm_target *ti)
+ start_merge(s);
+ }
+
+-static int snapshot_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void snapshot_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ unsigned sz = 0;
+ struct dm_snapshot *snap = ti->private;
+@@ -1884,8 +1884,6 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
+ maxlen - sz);
+ break;
+ }
+-
+- return 0;
+ }
+
+ static int snapshot_iterate_devices(struct dm_target *ti,
+@@ -2139,8 +2137,8 @@ static void origin_resume(struct dm_target *ti)
+ ti->max_io_len = get_origin_minimum_chunksize(dev->bdev);
+ }
+
+-static int origin_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void origin_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ struct dm_dev *dev = ti->private;
+
+@@ -2153,8 +2151,6 @@ static int origin_status(struct dm_target *ti, status_type_t type,
+ snprintf(result, maxlen, "%s", dev->name);
+ break;
+ }
+-
+- return 0;
+ }
+
+ static int origin_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+@@ -2181,7 +2177,7 @@ static int origin_iterate_devices(struct dm_target *ti,
+
+ static struct target_type origin_target = {
+ .name = "snapshot-origin",
+- .version = {1, 8, 0},
++ .version = {1, 8, 1},
+ .module = THIS_MODULE,
+ .ctr = origin_ctr,
+ .dtr = origin_dtr,
+@@ -2194,7 +2190,7 @@ static struct target_type origin_target = {
+
+ static struct target_type snapshot_target = {
+ .name = "snapshot",
+- .version = {1, 11, 0},
++ .version = {1, 11, 1},
+ .module = THIS_MODULE,
+ .ctr = snapshot_ctr,
+ .dtr = snapshot_dtr,
+@@ -2307,3 +2303,5 @@ module_exit(dm_snapshot_exit);
+ MODULE_DESCRIPTION(DM_NAME " snapshot target");
+ MODULE_AUTHOR("Joe Thornber");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS("dm-snapshot-origin");
++MODULE_ALIAS("dm-snapshot-merge");
+diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
+index c89cde8..aaecefa 100644
+--- a/drivers/md/dm-stripe.c
++++ b/drivers/md/dm-stripe.c
+@@ -312,8 +312,8 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
+ *
+ */
+
+-static int stripe_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void stripe_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ struct stripe_c *sc = (struct stripe_c *) ti->private;
+ char buffer[sc->stripes + 1];
+@@ -340,7 +340,6 @@ static int stripe_status(struct dm_target *ti, status_type_t type,
+ (unsigned long long)sc->stripe[i].physical_start);
+ break;
+ }
+- return 0;
+ }
+
+ static int stripe_end_io(struct dm_target *ti, struct bio *bio, int error)
+@@ -428,7 +427,7 @@ static int stripe_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+
+ static struct target_type stripe_target = {
+ .name = "striped",
+- .version = {1, 5, 0},
++ .version = {1, 5, 1},
+ .module = THIS_MODULE,
+ .ctr = stripe_ctr,
+ .dtr = stripe_dtr,
+diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
+index 5409607..7a66d73 100644
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -2299,8 +2299,8 @@ static void emit_flags(struct pool_features *pf, char *result,
+ * <transaction id> <used metadata sectors>/<total metadata sectors>
+ * <used data sectors>/<total data sectors> <held metadata root>
+ */
+-static int pool_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void pool_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ int r;
+ unsigned sz = 0;
+@@ -2326,32 +2326,41 @@ static int pool_status(struct dm_target *ti, status_type_t type,
+ if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti))
+ (void) commit_or_fallback(pool);
+
+- r = dm_pool_get_metadata_transaction_id(pool->pmd,
+- &transaction_id);
+- if (r)
+- return r;
++ r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id);
++ if (r) {
++ DMERR("dm_pool_get_metadata_transaction_id returned %d", r);
++ goto err;
++ }
+
+- r = dm_pool_get_free_metadata_block_count(pool->pmd,
+- &nr_free_blocks_metadata);
+- if (r)
+- return r;
++ r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free_blocks_metadata);
++ if (r) {
++ DMERR("dm_pool_get_free_metadata_block_count returned %d", r);
++ goto err;
++ }
+
+ r = dm_pool_get_metadata_dev_size(pool->pmd, &nr_blocks_metadata);
+- if (r)
+- return r;
++ if (r) {
++ DMERR("dm_pool_get_metadata_dev_size returned %d", r);
++ goto err;
++ }
+
+- r = dm_pool_get_free_block_count(pool->pmd,
+- &nr_free_blocks_data);
+- if (r)
+- return r;
++ r = dm_pool_get_free_block_count(pool->pmd, &nr_free_blocks_data);
++ if (r) {
++ DMERR("dm_pool_get_free_block_count returned %d", r);
++ goto err;
++ }
+
+ r = dm_pool_get_data_dev_size(pool->pmd, &nr_blocks_data);
+- if (r)
+- return r;
++ if (r) {
++ DMERR("dm_pool_get_data_dev_size returned %d", r);
++ goto err;
++ }
+
+ r = dm_pool_get_metadata_snap(pool->pmd, &held_root);
+- if (r)
+- return r;
++ if (r) {
++ DMERR("dm_pool_get_metadata_snap returned %d", r);
++ goto err;
++ }
+
+ DMEMIT("%llu %llu/%llu %llu/%llu ",
+ (unsigned long long)transaction_id,
+@@ -2388,8 +2397,10 @@ static int pool_status(struct dm_target *ti, status_type_t type,
+ emit_flags(&pt->requested_pf, result, sz, maxlen);
+ break;
+ }
++ return;
+
+- return 0;
++err:
++ DMEMIT("Error");
+ }
+
+ static int pool_iterate_devices(struct dm_target *ti,
+@@ -2468,7 +2479,7 @@ static struct target_type pool_target = {
+ .name = "thin-pool",
+ .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
+ DM_TARGET_IMMUTABLE,
+- .version = {1, 6, 0},
++ .version = {1, 6, 1},
+ .module = THIS_MODULE,
+ .ctr = pool_ctr,
+ .dtr = pool_dtr,
+@@ -2676,8 +2687,8 @@ static void thin_postsuspend(struct dm_target *ti)
+ /*
+ * <nr mapped sectors> <highest mapped sector>
+ */
+-static int thin_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void thin_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ int r;
+ ssize_t sz = 0;
+@@ -2687,7 +2698,7 @@ static int thin_status(struct dm_target *ti, status_type_t type,
+
+ if (get_pool_mode(tc->pool) == PM_FAIL) {
+ DMEMIT("Fail");
+- return 0;
++ return;
+ }
+
+ if (!tc->td)
+@@ -2696,12 +2707,16 @@ static int thin_status(struct dm_target *ti, status_type_t type,
+ switch (type) {
+ case STATUSTYPE_INFO:
+ r = dm_thin_get_mapped_count(tc->td, &mapped);
+- if (r)
+- return r;
++ if (r) {
++ DMERR("dm_thin_get_mapped_count returned %d", r);
++ goto err;
++ }
+
+ r = dm_thin_get_highest_mapped_block(tc->td, &highest);
+- if (r < 0)
+- return r;
++ if (r < 0) {
++ DMERR("dm_thin_get_highest_mapped_block returned %d", r);
++ goto err;
++ }
+
+ DMEMIT("%llu ", mapped * tc->pool->sectors_per_block);
+ if (r)
+@@ -2721,7 +2736,10 @@ static int thin_status(struct dm_target *ti, status_type_t type,
+ }
+ }
+
+- return 0;
++ return;
++
++err:
++ DMEMIT("Error");
+ }
+
+ static int thin_iterate_devices(struct dm_target *ti,
+@@ -2748,7 +2766,7 @@ static int thin_iterate_devices(struct dm_target *ti,
+
+ static struct target_type thin_target = {
+ .name = "thin",
+- .version = {1, 7, 0},
++ .version = {1, 7, 1},
+ .module = THIS_MODULE,
+ .ctr = thin_ctr,
+ .dtr = thin_dtr,
+diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c
+index 52cde98..6ad5383 100644
+--- a/drivers/md/dm-verity.c
++++ b/drivers/md/dm-verity.c
+@@ -508,8 +508,8 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
+ /*
+ * Status: V (valid) or C (corruption found)
+ */
+-static int verity_status(struct dm_target *ti, status_type_t type,
+- unsigned status_flags, char *result, unsigned maxlen)
++static void verity_status(struct dm_target *ti, status_type_t type,
++ unsigned status_flags, char *result, unsigned maxlen)
+ {
+ struct dm_verity *v = ti->private;
+ unsigned sz = 0;
+@@ -540,8 +540,6 @@ static int verity_status(struct dm_target *ti, status_type_t type,
+ DMEMIT("%02x", v->salt[x]);
+ break;
+ }
+-
+- return 0;
+ }
+
+ static int verity_ioctl(struct dm_target *ti, unsigned cmd,
+@@ -860,7 +858,7 @@ bad:
+
+ static struct target_type verity_target = {
+ .name = "verity",
+- .version = {1, 1, 0},
++ .version = {1, 1, 1},
+ .module = THIS_MODULE,
+ .ctr = verity_ctr,
+ .dtr = verity_dtr,
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 314a0e2..0d8f086 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1973,15 +1973,27 @@ static void __bind_mempools(struct mapped_device *md, struct dm_table *t)
+ {
+ struct dm_md_mempools *p = dm_table_get_md_mempools(t);
+
+- if (md->io_pool && (md->tio_pool || dm_table_get_type(t) == DM_TYPE_BIO_BASED) && md->bs) {
+- /*
+- * The md already has necessary mempools. Reload just the
+- * bioset because front_pad may have changed because
+- * a different table was loaded.
+- */
+- bioset_free(md->bs);
+- md->bs = p->bs;
+- p->bs = NULL;
++ if (md->io_pool && md->bs) {
++ /* The md already has necessary mempools. */
++ if (dm_table_get_type(t) == DM_TYPE_BIO_BASED) {
++ /*
++ * Reload bioset because front_pad may have changed
++ * because a different table was loaded.
++ */
++ bioset_free(md->bs);
++ md->bs = p->bs;
++ p->bs = NULL;
++ } else if (dm_table_get_type(t) == DM_TYPE_REQUEST_BASED) {
++ BUG_ON(!md->tio_pool);
++ /*
++ * There's no need to reload with request-based dm
++ * because the size of front_pad doesn't change.
++ * Note for future: If you are to reload bioset,
++ * prep-ed requests in the queue may refer
++ * to bio from the old bioset, so you must walk
++ * through the queue to unprep.
++ */
++ }
+ goto out;
+ }
+
+@@ -2421,7 +2433,7 @@ static void dm_queue_flush(struct mapped_device *md)
+ */
+ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
+ {
+- struct dm_table *live_map, *map = ERR_PTR(-EINVAL);
++ struct dm_table *live_map = NULL, *map = ERR_PTR(-EINVAL);
+ struct queue_limits limits;
+ int r;
+
+@@ -2444,10 +2456,12 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
+ dm_table_put(live_map);
+ }
+
+- r = dm_calculate_queue_limits(table, &limits);
+- if (r) {
+- map = ERR_PTR(r);
+- goto out;
++ if (!live_map) {
++ r = dm_calculate_queue_limits(table, &limits);
++ if (r) {
++ map = ERR_PTR(r);
++ goto out;
++ }
+ }
+
+ map = __bind(md, table, &limits);
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 3db3d1b..f363135 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -307,6 +307,10 @@ static void md_make_request(struct request_queue *q, struct bio *bio)
+ bio_io_error(bio);
+ return;
+ }
++ if (mddev->ro == 1 && unlikely(rw == WRITE)) {
++ bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
++ return;
++ }
+ smp_rmb(); /* Ensure implications of 'active' are visible */
+ rcu_read_lock();
+ if (mddev->suspended) {
+@@ -2994,6 +2998,9 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len)
+ } else if (!sectors)
+ sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) -
+ rdev->data_offset;
++ if (!my_mddev->pers->resize)
++ /* Cannot change size for RAID0 or Linear etc */
++ return -EINVAL;
+ }
+ if (sectors < my_mddev->dev_sectors)
+ return -EINVAL; /* component must fit device */
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 24b3597..d9babda 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -289,7 +289,7 @@ abort:
+ kfree(conf->strip_zone);
+ kfree(conf->devlist);
+ kfree(conf);
+- *private_conf = NULL;
++ *private_conf = ERR_PTR(err);
+ return err;
+ }
+
+@@ -411,7 +411,8 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks
+ "%s does not support generic reshape\n", __func__);
+
+ rdev_for_each(rdev, mddev)
+- array_sectors += rdev->sectors;
++ array_sectors += (rdev->sectors &
++ ~(sector_t)(mddev->chunk_sectors-1));
+
+ return array_sectors;
+ }
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index d5bddfc..75b1f89 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -967,6 +967,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
+ bio_list_merge(&conf->pending_bio_list, &plug->pending);
+ conf->pending_count += plug->pending_cnt;
+ spin_unlock_irq(&conf->device_lock);
++ wake_up(&conf->wait_barrier);
+ md_wakeup_thread(mddev->thread);
+ kfree(plug);
+ return;
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 64d4824..8d925dc 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1073,6 +1073,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
+ bio_list_merge(&conf->pending_bio_list, &plug->pending);
+ conf->pending_count += plug->pending_cnt;
+ spin_unlock_irq(&conf->device_lock);
++ wake_up(&conf->wait_barrier);
+ md_wakeup_thread(mddev->thread);
+ kfree(plug);
+ return;
+diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c
+index f5ddb82..64a779c 100644
+--- a/drivers/memstick/host/rtsx_pci_ms.c
++++ b/drivers/memstick/host/rtsx_pci_ms.c
+@@ -426,6 +426,9 @@ static void rtsx_pci_ms_request(struct memstick_host *msh)
+
+ dev_dbg(ms_dev(host), "--> %s\n", __func__);
+
++ if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD))
++ return;
++
+ schedule_work(&host->handle_req);
+ }
+
+@@ -441,6 +444,10 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh,
+ dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
+ __func__, param, value);
+
++ err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD);
++ if (err)
++ return err;
++
+ switch (param) {
+ case MEMSTICK_POWER:
+ if (value == MEMSTICK_POWER_ON)
+diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
+index 9fc5700..1e2d120 100644
+--- a/drivers/mfd/rtsx_pcr.c
++++ b/drivers/mfd/rtsx_pcr.c
+@@ -713,6 +713,25 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)
+ }
+ EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
+
++int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card)
++{
++ unsigned int cd_mask[] = {
++ [RTSX_SD_CARD] = SD_EXIST,
++ [RTSX_MS_CARD] = MS_EXIST
++ };
++
++ if (!pcr->ms_pmos) {
++ /* When using single PMOS, accessing card is not permitted
++ * if the existing card is not the designated one.
++ */
++ if (pcr->card_exist & (~cd_mask[card]))
++ return -EIO;
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(rtsx_pci_card_exclusive_check);
++
+ int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+ {
+ if (pcr->ops->switch_output_voltage)
+@@ -758,7 +777,7 @@ static void rtsx_pci_card_detect(struct work_struct *work)
+ struct delayed_work *dwork;
+ struct rtsx_pcr *pcr;
+ unsigned long flags;
+- unsigned int card_detect = 0;
++ unsigned int card_detect = 0, card_inserted, card_removed;
+ u32 irq_status;
+
+ dwork = to_delayed_work(work);
+@@ -766,25 +785,35 @@ static void rtsx_pci_card_detect(struct work_struct *work)
+
+ dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
+
++ mutex_lock(&pcr->pcr_mutex);
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ irq_status = rtsx_pci_readl(pcr, RTSX_BIPR);
+ dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status);
+
+- if (pcr->card_inserted || pcr->card_removed) {
++ irq_status &= CARD_EXIST;
++ card_inserted = pcr->card_inserted & irq_status;
++ card_removed = pcr->card_removed;
++ pcr->card_inserted = 0;
++ pcr->card_removed = 0;
++
++ spin_unlock_irqrestore(&pcr->lock, flags);
++
++ if (card_inserted || card_removed) {
+ dev_dbg(&(pcr->pci->dev),
+ "card_inserted: 0x%x, card_removed: 0x%x\n",
+- pcr->card_inserted, pcr->card_removed);
++ card_inserted, card_removed);
+
+ if (pcr->ops->cd_deglitch)
+- pcr->card_inserted = pcr->ops->cd_deglitch(pcr);
++ card_inserted = pcr->ops->cd_deglitch(pcr);
++
++ card_detect = card_inserted | card_removed;
+
+- card_detect = pcr->card_inserted | pcr->card_removed;
+- pcr->card_inserted = 0;
+- pcr->card_removed = 0;
++ pcr->card_exist |= card_inserted;
++ pcr->card_exist &= ~card_removed;
+ }
+
+- spin_unlock_irqrestore(&pcr->lock, flags);
++ mutex_unlock(&pcr->pcr_mutex);
+
+ if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event)
+ pcr->slots[RTSX_SD_CARD].card_event(
+@@ -836,10 +865,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
+ }
+ }
+
+- if (pcr->card_inserted || pcr->card_removed)
+- schedule_delayed_work(&pcr->carddet_work,
+- msecs_to_jiffies(200));
+-
+ if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
+ if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
+ pcr->trans_result = TRANS_RESULT_FAIL;
+@@ -852,6 +877,10 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
+ }
+ }
+
++ if (pcr->card_inserted || pcr->card_removed)
++ schedule_delayed_work(&pcr->carddet_work,
++ msecs_to_jiffies(200));
++
+ spin_unlock(&pcr->lock);
+ return IRQ_HANDLED;
+ }
+@@ -974,6 +1003,14 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
+ return err;
+ }
+
++ /* No CD interrupt if probing driver with card inserted.
++ * So we need to initialize pcr->card_exist here.
++ */
++ if (pcr->ops->cd_deglitch)
++ pcr->card_exist = pcr->ops->cd_deglitch(pcr);
++ else
++ pcr->card_exist = rtsx_pci_readl(pcr, RTSX_BIPR) & CARD_EXIST;
++
+ return 0;
+ }
+
+diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
+index f74b5ad..468c923 100644
+--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
++++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
+@@ -678,12 +678,19 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ struct mmc_command *cmd = mrq->cmd;
+ struct mmc_data *data = mrq->data;
+ unsigned int data_size = 0;
++ int err;
+
+ if (host->eject) {
+ cmd->error = -ENOMEDIUM;
+ goto finish;
+ }
+
++ err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
++ if (err) {
++ cmd->error = err;
++ goto finish;
++ }
++
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+@@ -901,6 +908,9 @@ static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ if (host->eject)
+ return;
+
++ if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD))
++ return;
++
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+@@ -1073,6 +1083,10 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
+ if (host->eject)
+ return -ENOMEDIUM;
+
++ err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
++ if (err)
++ return err;
++
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+@@ -1122,6 +1136,10 @@ static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+ if (host->eject)
+ return -ENOMEDIUM;
+
++ err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD);
++ if (err)
++ return err;
++
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index bdb0869..f0b38fa 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -1843,6 +1843,8 @@ static void tg3_link_report(struct tg3 *tp)
+
+ tg3_ump_link_report(tp);
+ }
++
++ tp->link_up = netif_carrier_ok(tp->dev);
+ }
+
+ static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
+@@ -2496,12 +2498,6 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
+ return err;
+ }
+
+-static void tg3_carrier_on(struct tg3 *tp)
+-{
+- netif_carrier_on(tp->dev);
+- tp->link_up = true;
+-}
+-
+ static void tg3_carrier_off(struct tg3 *tp)
+ {
+ netif_carrier_off(tp->dev);
+@@ -2527,7 +2523,7 @@ static int tg3_phy_reset(struct tg3 *tp)
+ return -EBUSY;
+
+ if (netif_running(tp->dev) && tp->link_up) {
+- tg3_carrier_off(tp);
++ netif_carrier_off(tp->dev);
+ tg3_link_report(tp);
+ }
+
+@@ -4225,9 +4221,9 @@ static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up)
+ {
+ if (curr_link_up != tp->link_up) {
+ if (curr_link_up) {
+- tg3_carrier_on(tp);
++ netif_carrier_on(tp->dev);
+ } else {
+- tg3_carrier_off(tp);
++ netif_carrier_off(tp->dev);
+ if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
+ tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
+ }
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index 643c883..1f93880 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -5549,7 +5549,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
+ */
+ e1000e_release_hw_control(adapter);
+
+- pci_disable_device(pdev);
++ pci_clear_master(pdev);
+
+ return 0;
+ }
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index 9b73670..6214181 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -1340,6 +1340,8 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev)
+ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
+ if (ret < 0)
+ netdev_warn(dev->net, "Error reading PM_CTRL\n");
++ else
++ ret = 0;
+
+ return ret;
+ }
+@@ -1392,6 +1394,8 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev)
+ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
+ if (ret < 0)
+ netdev_warn(dev->net, "Error writing PM_CTRL\n");
++ else
++ ret = 0;
+
+ return ret;
+ }
+@@ -1413,6 +1417,8 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev)
+ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
+ if (ret < 0)
+ netdev_warn(dev->net, "Error writing PM_CTRL\n");
++ else
++ ret = 0;
+
+ return ret;
+ }
+diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
+index 5f845be..050ca4a 100644
+--- a/drivers/net/wireless/ath/ath9k/common.h
++++ b/drivers/net/wireless/ath/ath9k/common.h
+@@ -27,7 +27,7 @@
+ #define WME_MAX_BA WME_BA_BMP_SIZE
+ #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
+
+-#define ATH_RSSI_DUMMY_MARKER 0x127
++#define ATH_RSSI_DUMMY_MARKER 127
+ #define ATH_RSSI_LPF_LEN 10
+ #define RSSI_LPF_THRESHOLD -20
+ #define ATH_RSSI_EP_MULTIPLIER (1<<7)
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
+index 96bfb18..d3b099d 100644
+--- a/drivers/net/wireless/ath/ath9k/htc.h
++++ b/drivers/net/wireless/ath/ath9k/htc.h
+@@ -22,6 +22,7 @@
+ #include <linux/firmware.h>
+ #include <linux/skbuff.h>
+ #include <linux/netdevice.h>
++#include <linux/etherdevice.h>
+ #include <linux/leds.h>
+ #include <linux/slab.h>
+ #include <net/mac80211.h>
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+index b6a5a08..8788621 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+@@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
+
+ last_rssi = priv->rx.last_rssi;
+
+- if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+- rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
+- ATH_RSSI_EP_MULTIPLIER);
++ if (ieee80211_is_beacon(hdr->frame_control) &&
++ !is_zero_ether_addr(common->curbssid) &&
++ ether_addr_equal(hdr->addr3, common->curbssid)) {
++ s8 rssi = rxbuf->rxstatus.rs_rssi;
+
+- if (rxbuf->rxstatus.rs_rssi < 0)
+- rxbuf->rxstatus.rs_rssi = 0;
++ if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
++ rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
+
+- if (ieee80211_is_beacon(fc))
+- priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
++ if (rssi < 0)
++ rssi = 0;
++
++ priv->ah->stats.avgbrssi = rssi;
++ }
+
+ rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
+ rx_status->band = hw->conf.channel->band;
+diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
+index 7cb7870..e26f92d 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1480,7 +1480,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
+ reset_type = ATH9K_RESET_POWER_ON;
+ else
+ reset_type = ATH9K_RESET_COLD;
+- }
++ } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) ||
++ (REG_READ(ah, AR_CR) & AR_CR_RXE))
++ reset_type = ATH9K_RESET_COLD;
+
+ if (!ath9k_hw_set_reset_reg(ah, reset_type))
+ return false;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+index dc7e26b..c85eb37 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
++++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
+ TRACE_EVENT(iwlwifi_dev_hcmd,
+ TP_PROTO(const struct device *dev,
+ struct iwl_host_cmd *cmd, u16 total_size,
+- const void *hdr, size_t hdr_len),
+- TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
++ struct iwl_cmd_header *hdr),
++ TP_ARGS(dev, cmd, total_size, hdr),
+ TP_STRUCT__entry(
+ DEV_ENTRY
+ __dynamic_array(u8, hcmd, total_size)
+ __field(u32, flags)
+ ),
+ TP_fast_assign(
+- int i, offset = hdr_len;
++ int i, offset = sizeof(*hdr);
+
+ DEV_ASSIGN;
+ __entry->flags = cmd->flags;
+- memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
++ memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
+
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ if (!cmd->len[i])
+ continue;
+- if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
+- continue;
+ memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
+ cmd->data[i], cmd->len[i]);
+ offset += cmd->len[i];
+diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
+index d91d2e8..bc5e9ec 100644
+--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
++++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
+@@ -182,6 +182,15 @@ struct iwl_queue {
+ #define TFD_TX_CMD_SLOTS 256
+ #define TFD_CMD_SLOTS 32
+
++/*
++ * The FH will write back to the first TB only, so we need
++ * to copy some data into the buffer regardless of whether
++ * it should be mapped or not. This indicates how much to
++ * copy, even for HCMDs it must be big enough to fit the
++ * DRAM scratch from the TX cmd, at least 16 bytes.
++ */
++#define IWL_HCMD_MIN_COPY_SIZE 16
++
+ struct iwl_pcie_txq_entry {
+ struct iwl_device_cmd *cmd;
+ struct iwl_device_cmd *copy_cmd;
+diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
+index 6c5b867..c6cd922 100644
+--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
+@@ -1131,10 +1131,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ void *dup_buf = NULL;
+ dma_addr_t phys_addr;
+ int idx;
+- u16 copy_size, cmd_size;
++ u16 copy_size, cmd_size, dma_size;
+ bool had_nocopy = false;
+ int i;
+ u32 cmd_pos;
++ const u8 *cmddata[IWL_MAX_CMD_TFDS];
++ u16 cmdlen[IWL_MAX_CMD_TFDS];
+
+ copy_size = sizeof(out_cmd->hdr);
+ cmd_size = sizeof(out_cmd->hdr);
+@@ -1143,8 +1145,23 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
+
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
++ cmddata[i] = cmd->data[i];
++ cmdlen[i] = cmd->len[i];
++
+ if (!cmd->len[i])
+ continue;
++
++ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
++ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
++ int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
++
++ if (copy > cmdlen[i])
++ copy = cmdlen[i];
++ cmdlen[i] -= copy;
++ cmddata[i] += copy;
++ copy_size += copy;
++ }
++
+ if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
+ had_nocopy = true;
+ if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
+@@ -1164,7 +1181,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ goto free_dup_buf;
+ }
+
+- dup_buf = kmemdup(cmd->data[i], cmd->len[i],
++ dup_buf = kmemdup(cmddata[i], cmdlen[i],
+ GFP_ATOMIC);
+ if (!dup_buf)
+ return -ENOMEM;
+@@ -1174,7 +1191,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ idx = -EINVAL;
+ goto free_dup_buf;
+ }
+- copy_size += cmd->len[i];
++ copy_size += cmdlen[i];
+ }
+ cmd_size += cmd->len[i];
+ }
+@@ -1221,14 +1238,31 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+
+ /* and copy the data that needs to be copied */
+ cmd_pos = offsetof(struct iwl_device_cmd, payload);
++ copy_size = sizeof(out_cmd->hdr);
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+- if (!cmd->len[i])
++ int copy = 0;
++
++ if (!cmd->len)
+ continue;
+- if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+- IWL_HCMD_DFL_DUP))
+- break;
+- memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
+- cmd_pos += cmd->len[i];
++
++ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
++ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
++ copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
++
++ if (copy > cmd->len[i])
++ copy = cmd->len[i];
++ }
++
++ /* copy everything if not nocopy/dup */
++ if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
++ IWL_HCMD_DFL_DUP)))
++ copy = cmd->len[i];
++
++ if (copy) {
++ memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
++ cmd_pos += copy;
++ copy_size += copy;
++ }
+ }
+
+ WARN_ON_ONCE(txq->entries[idx].copy_cmd);
+@@ -1254,7 +1288,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
+ cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
+
+- phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
++ /*
++ * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
++ * still map at least that many bytes for the hardware to write back to.
++ * We have enough space, so that's not a problem.
++ */
++ dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE);
++
++ phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size,
+ DMA_BIDIRECTIONAL);
+ if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
+ idx = -ENOMEM;
+@@ -1262,14 +1303,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ }
+
+ dma_unmap_addr_set(out_meta, mapping, phys_addr);
+- dma_unmap_len_set(out_meta, len, copy_size);
++ dma_unmap_len_set(out_meta, len, dma_size);
+
+ iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
+
++ /* map the remaining (adjusted) nocopy/dup fragments */
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+- const void *data = cmd->data[i];
++ const void *data = cmddata[i];
+
+- if (!cmd->len[i])
++ if (!cmdlen[i])
+ continue;
+ if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+ IWL_HCMD_DFL_DUP)))
+@@ -1277,7 +1319,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
+ data = dup_buf;
+ phys_addr = dma_map_single(trans->dev, (void *)data,
+- cmd->len[i], DMA_BIDIRECTIONAL);
++ cmdlen[i], DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(trans->dev, phys_addr)) {
+ iwl_pcie_tfd_unmap(trans, out_meta,
+ &txq->tfds[q->write_ptr],
+@@ -1286,7 +1328,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+ goto out;
+ }
+
+- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);
++ iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
+ }
+
+ out_meta->flags = cmd->flags;
+@@ -1296,8 +1338,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
+
+ txq->need_update = 1;
+
+- trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,
+- &out_cmd->hdr, copy_size);
++ trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
+
+ /* start timer if queue currently empty */
+ if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
+diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
+index 739309e..4557833 100644
+--- a/drivers/net/wireless/libertas/if_sdio.c
++++ b/drivers/net/wireless/libertas/if_sdio.c
+@@ -825,6 +825,11 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
+
+ sdio_release_host(func);
+
++ /* Set fw_ready before queuing any commands so that
++ * lbs_thread won't block from sending them to firmware.
++ */
++ priv->fw_ready = 1;
++
+ /*
+ * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
+ */
+@@ -839,7 +844,6 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
+ netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
+ }
+
+- priv->fw_ready = 1;
+ wake_up(&card->pwron_waitq);
+
+ if (!card->started) {
+diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
+index b879e13..0bbea88 100644
+--- a/drivers/net/wireless/mwifiex/pcie.c
++++ b/drivers/net/wireless/mwifiex/pcie.c
+@@ -291,7 +291,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
+ i++;
+ usleep_range(10, 20);
+ /* 50ms max wait */
+- if (i == 50000)
++ if (i == 5000)
+ break;
+ }
+
+diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
+index afed701..684ce75 100644
+--- a/drivers/platform/x86/acer-wmi.c
++++ b/drivers/platform/x86/acer-wmi.c
+@@ -1204,6 +1204,9 @@ static acpi_status WMID_set_capabilities(void)
+ devices = *((u32 *) obj->buffer.pointer);
+ } else if (obj->type == ACPI_TYPE_INTEGER) {
+ devices = (u32) obj->integer.value;
++ } else {
++ kfree(out.pointer);
++ return AE_ERROR;
+ }
+ } else {
+ kfree(out.pointer);
+diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
+index b8ad71f..0fe987f 100644
+--- a/drivers/platform/x86/sony-laptop.c
++++ b/drivers/platform/x86/sony-laptop.c
+@@ -1534,7 +1534,7 @@ static int sony_nc_rfkill_set(void *data, bool blocked)
+ int argument = sony_rfkill_address[(long) data] + 0x100;
+
+ if (!blocked)
+- argument |= 0x030000;
++ argument |= 0x070000;
+
+ return sony_call_snc_handle(sony_rfkill_handle, argument, &result);
+ }
+diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
+index 57233c8..8f87fec 100644
+--- a/drivers/rtc/rtc-mv.c
++++ b/drivers/rtc/rtc-mv.c
+@@ -14,6 +14,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+ #include <linux/delay.h>
++#include <linux/clk.h>
+ #include <linux/gfp.h>
+ #include <linux/module.h>
+
+@@ -41,6 +42,7 @@ struct rtc_plat_data {
+ struct rtc_device *rtc;
+ void __iomem *ioaddr;
+ int irq;
++ struct clk *clk;
+ };
+
+ static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
+@@ -221,6 +223,7 @@ static int mv_rtc_probe(struct platform_device *pdev)
+ struct rtc_plat_data *pdata;
+ resource_size_t size;
+ u32 rtc_time;
++ int ret = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+@@ -239,11 +242,17 @@ static int mv_rtc_probe(struct platform_device *pdev)
+ if (!pdata->ioaddr)
+ return -ENOMEM;
+
++ pdata->clk = devm_clk_get(&pdev->dev, NULL);
++ /* Not all SoCs require a clock.*/
++ if (!IS_ERR(pdata->clk))
++ clk_prepare_enable(pdata->clk);
++
+ /* make sure the 24 hours mode is enabled */
+ rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
+ if (rtc_time & RTC_HOURS_12H_MODE) {
+ dev_err(&pdev->dev, "24 Hours mode not supported.\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto out;
+ }
+
+ /* make sure it is actually functional */
+@@ -252,7 +261,8 @@ static int mv_rtc_probe(struct platform_device *pdev)
+ rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
+ if (rtc_time == 0x01000000) {
+ dev_err(&pdev->dev, "internal RTC not ticking\n");
+- return -ENODEV;
++ ret = -ENODEV;
++ goto out;
+ }
+ }
+
+@@ -268,8 +278,10 @@ static int mv_rtc_probe(struct platform_device *pdev)
+ } else
+ pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ &mv_rtc_ops, THIS_MODULE);
+- if (IS_ERR(pdata->rtc))
+- return PTR_ERR(pdata->rtc);
++ if (IS_ERR(pdata->rtc)) {
++ ret = PTR_ERR(pdata->rtc);
++ goto out;
++ }
+
+ if (pdata->irq >= 0) {
+ writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
+@@ -282,6 +294,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
+ }
+
+ return 0;
++out:
++ if (!IS_ERR(pdata->clk))
++ clk_disable_unprepare(pdata->clk);
++
++ return ret;
+ }
+
+ static int __exit mv_rtc_remove(struct platform_device *pdev)
+@@ -292,6 +309,9 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
+ device_init_wakeup(&pdev->dev, 0);
+
+ rtc_device_unregister(pdata->rtc);
++ if (!IS_ERR(pdata->clk))
++ clk_disable_unprepare(pdata->clk);
++
+ return 0;
+ }
+
+diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
+index 865c64f..fed486bf 100644
+--- a/drivers/scsi/dc395x.c
++++ b/drivers/scsi/dc395x.c
+@@ -3747,13 +3747,13 @@ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb,
+ dcb->max_command = 1;
+ dcb->target_id = target;
+ dcb->target_lun = lun;
++ dcb->dev_mode = eeprom->target[target].cfg0;
+ #ifndef DC395x_NO_DISCONNECT
+ dcb->identify_msg =
+ IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun);
+ #else
+ dcb->identify_msg = IDENTIFY(0, lun);
+ #endif
+- dcb->dev_mode = eeprom->target[target].cfg0;
+ dcb->inquiry7 = 0;
+ dcb->sync_mode = 0;
+ dcb->min_nego_period = clock_period[period_index];
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 0144078..9f4e560 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -467,6 +467,7 @@ static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
+ if (!bounce_sgl)
+ return NULL;
+
++ sg_init_table(bounce_sgl, num_pages);
+ for (i = 0; i < num_pages; i++) {
+ page_buf = alloc_page(GFP_ATOMIC);
+ if (!page_buf)
+diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
+index 339f97f..42a2bf7 100644
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -3570,6 +3570,10 @@ check_rsp_state:
+ spin_lock_bh(&cmd->istate_lock);
+ cmd->i_state = ISTATE_SENT_STATUS;
+ spin_unlock_bh(&cmd->istate_lock);
++
++ if (atomic_read(&conn->check_immediate_queue))
++ return 1;
++
+ continue;
+ } else if (ret == 2) {
+ /* Still must send status,
+@@ -3659,7 +3663,7 @@ check_rsp_state:
+ }
+
+ if (atomic_read(&conn->check_immediate_queue))
+- break;
++ return 1;
+ }
+
+ return 0;
+@@ -3703,12 +3707,15 @@ restart:
+ signal_pending(current))
+ goto transport_err;
+
++get_immediate:
+ ret = handle_immediate_queue(conn);
+ if (ret < 0)
+ goto transport_err;
+
+ ret = handle_response_queue(conn);
+- if (ret == -EAGAIN)
++ if (ret == 1)
++ goto get_immediate;
++ else if (ret == -EAGAIN)
+ goto restart;
+ else if (ret < 0)
+ goto transport_err;
+diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
+index 2bcfd79..55b9530 100644
+--- a/drivers/target/target_core_pscsi.c
++++ b/drivers/target/target_core_pscsi.c
+@@ -940,7 +940,6 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
+ bio = NULL;
+ }
+
+- page++;
+ len -= bytes;
+ data_len -= bytes;
+ off = 0;
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index cbf7168..2a89588 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2538,70 +2538,35 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
+ if ((portstatus & USB_PORT_STAT_RESET))
+ goto delay;
+
+- /*
+- * Some buggy devices require a warm reset to be issued even
+- * when the port appears not to be connected.
++ if (hub_port_warm_reset_required(hub, portstatus))
++ return -ENOTCONN;
++
++ /* Device went away? */
++ if (!(portstatus & USB_PORT_STAT_CONNECTION))
++ return -ENOTCONN;
++
++ /* bomb out completely if the connection bounced. A USB 3.0
++ * connection may bounce if multiple warm resets were issued,
++ * but the device may have successfully re-connected. Ignore it.
+ */
+- if (!warm) {
+- /*
+- * Some buggy devices can cause an NEC host controller
+- * to transition to the "Error" state after a hot port
+- * reset. This will show up as the port state in
+- * "Inactive", and the port may also report a
+- * disconnect. Forcing a warm port reset seems to make
+- * the device work.
+- *
+- * See https://bugzilla.kernel.org/show_bug.cgi?id=41752
+- */
+- if (hub_port_warm_reset_required(hub, portstatus)) {
+- int ret;
+-
+- if ((portchange & USB_PORT_STAT_C_CONNECTION))
+- clear_port_feature(hub->hdev, port1,
+- USB_PORT_FEAT_C_CONNECTION);
+- if (portchange & USB_PORT_STAT_C_LINK_STATE)
+- clear_port_feature(hub->hdev, port1,
+- USB_PORT_FEAT_C_PORT_LINK_STATE);
+- if (portchange & USB_PORT_STAT_C_RESET)
+- clear_port_feature(hub->hdev, port1,
+- USB_PORT_FEAT_C_RESET);
+- dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
+- port1);
+- ret = hub_port_reset(hub, port1,
+- udev, HUB_BH_RESET_TIME,
+- true);
+- if ((portchange & USB_PORT_STAT_C_CONNECTION))
+- clear_port_feature(hub->hdev, port1,
+- USB_PORT_FEAT_C_CONNECTION);
+- return ret;
+- }
+- /* Device went away? */
+- if (!(portstatus & USB_PORT_STAT_CONNECTION))
+- return -ENOTCONN;
+-
+- /* bomb out completely if the connection bounced */
+- if ((portchange & USB_PORT_STAT_C_CONNECTION))
+- return -ENOTCONN;
+-
+- if ((portstatus & USB_PORT_STAT_ENABLE)) {
+- if (hub_is_wusb(hub))
+- udev->speed = USB_SPEED_WIRELESS;
+- else if (hub_is_superspeed(hub->hdev))
+- udev->speed = USB_SPEED_SUPER;
+- else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+- udev->speed = USB_SPEED_HIGH;
+- else if (portstatus & USB_PORT_STAT_LOW_SPEED)
+- udev->speed = USB_SPEED_LOW;
+- else
+- udev->speed = USB_SPEED_FULL;
++ if (!hub_is_superspeed(hub->hdev) &&
++ (portchange & USB_PORT_STAT_C_CONNECTION))
++ return -ENOTCONN;
++
++ if ((portstatus & USB_PORT_STAT_ENABLE)) {
++ if (!udev)
+ return 0;
+- }
+- } else {
+- if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
+- hub_port_warm_reset_required(hub,
+- portstatus))
+- return -ENOTCONN;
+
++ if (hub_is_wusb(hub))
++ udev->speed = USB_SPEED_WIRELESS;
++ else if (hub_is_superspeed(hub->hdev))
++ udev->speed = USB_SPEED_SUPER;
++ else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
++ udev->speed = USB_SPEED_HIGH;
++ else if (portstatus & USB_PORT_STAT_LOW_SPEED)
++ udev->speed = USB_SPEED_LOW;
++ else
++ udev->speed = USB_SPEED_FULL;
+ return 0;
+ }
+
+@@ -2619,16 +2584,16 @@ delay:
+ }
+
+ static void hub_port_finish_reset(struct usb_hub *hub, int port1,
+- struct usb_device *udev, int *status, bool warm)
++ struct usb_device *udev, int *status)
+ {
+ switch (*status) {
+ case 0:
+- if (!warm) {
+- struct usb_hcd *hcd;
+- /* TRSTRCY = 10 ms; plus some extra */
+- msleep(10 + 40);
++ /* TRSTRCY = 10 ms; plus some extra */
++ msleep(10 + 40);
++ if (udev) {
++ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
++
+ update_devnum(udev, 0);
+- hcd = bus_to_hcd(udev->bus);
+ /* The xHC may think the device is already reset,
+ * so ignore the status.
+ */
+@@ -2640,14 +2605,15 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1,
+ case -ENODEV:
+ clear_port_feature(hub->hdev,
+ port1, USB_PORT_FEAT_C_RESET);
+- /* FIXME need disconnect() for NOTATTACHED device */
+ if (hub_is_superspeed(hub->hdev)) {
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_BH_PORT_RESET);
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_PORT_LINK_STATE);
++ clear_port_feature(hub->hdev, port1,
++ USB_PORT_FEAT_C_CONNECTION);
+ }
+- if (!warm)
++ if (udev)
+ usb_set_device_state(udev, *status
+ ? USB_STATE_NOTATTACHED
+ : USB_STATE_DEFAULT);
+@@ -2660,18 +2626,30 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
+ struct usb_device *udev, unsigned int delay, bool warm)
+ {
+ int i, status;
++ u16 portchange, portstatus;
+
+- if (!warm) {
+- /* Block EHCI CF initialization during the port reset.
+- * Some companion controllers don't like it when they mix.
+- */
+- down_read(&ehci_cf_port_reset_rwsem);
+- } else {
+- if (!hub_is_superspeed(hub->hdev)) {
++ if (!hub_is_superspeed(hub->hdev)) {
++ if (warm) {
+ dev_err(hub->intfdev, "only USB3 hub support "
+ "warm reset\n");
+ return -EINVAL;
+ }
++ /* Block EHCI CF initialization during the port reset.
++ * Some companion controllers don't like it when they mix.
++ */
++ down_read(&ehci_cf_port_reset_rwsem);
++ } else if (!warm) {
++ /*
++ * If the caller hasn't explicitly requested a warm reset,
++ * double check and see if one is needed.
++ */
++ status = hub_port_status(hub, port1,
++ &portstatus, &portchange);
++ if (status < 0)
++ goto done;
++
++ if (hub_port_warm_reset_required(hub, portstatus))
++ warm = true;
+ }
+
+ /* Reset the port */
+@@ -2692,10 +2670,33 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
+ status);
+ }
+
+- /* return on disconnect or reset */
++ /* Check for disconnect or reset */
+ if (status == 0 || status == -ENOTCONN || status == -ENODEV) {
+- hub_port_finish_reset(hub, port1, udev, &status, warm);
+- goto done;
++ hub_port_finish_reset(hub, port1, udev, &status);
++
++ if (!hub_is_superspeed(hub->hdev))
++ goto done;
++
++ /*
++ * If a USB 3.0 device migrates from reset to an error
++ * state, re-issue the warm reset.
++ */
++ if (hub_port_status(hub, port1,
++ &portstatus, &portchange) < 0)
++ goto done;
++
++ if (!hub_port_warm_reset_required(hub, portstatus))
++ goto done;
++
++ /*
++ * If the port is in SS.Inactive or Compliance Mode, the
++ * hot or warm reset failed. Try another warm reset.
++ */
++ if (!warm) {
++ dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
++ port1);
++ warm = true;
++ }
+ }
+
+ dev_dbg (hub->intfdev,
+@@ -2709,7 +2710,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
+ port1);
+
+ done:
+- if (!warm)
++ if (!hub_is_superspeed(hub->hdev))
+ up_read(&ehci_cf_port_reset_rwsem);
+
+ return status;
+@@ -4740,12 +4741,21 @@ static void hub_events(void)
+ */
+ if (hub_port_warm_reset_required(hub, portstatus)) {
+ int status;
++ struct usb_device *udev =
++ hub->ports[i - 1]->child;
+
+ dev_dbg(hub_dev, "warm reset port %d\n", i);
+- status = hub_port_reset(hub, i, NULL,
+- HUB_BH_RESET_TIME, true);
+- if (status < 0)
+- hub_port_disable(hub, i, 1);
++ if (!udev) {
++ status = hub_port_reset(hub, i,
++ NULL, HUB_BH_RESET_TIME,
++ true);
++ if (status < 0)
++ hub_port_disable(hub, i, 1);
++ } else {
++ usb_lock_device(udev);
++ status = usb_reset_device(udev);
++ usb_unlock_device(udev);
++ }
+ connect_change = 0;
+ }
+
+diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c
+index f904071..20dbdcb 100644
+--- a/drivers/usb/host/ehci-timer.c
++++ b/drivers/usb/host/ehci-timer.c
+@@ -113,15 +113,14 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
+
+ if (want != actual) {
+
+- /* Poll again later */
+- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
+- ++ehci->ASS_poll_count;
+- return;
++ /* Poll again later, but give up after about 20 ms */
++ if (ehci->ASS_poll_count++ < 20) {
++ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
++ return;
++ }
++ ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n",
++ want, actual);
+ }
+-
+- if (ehci->ASS_poll_count > 20)
+- ehci_dbg(ehci, "ASS poll count reached %d\n",
+- ehci->ASS_poll_count);
+ ehci->ASS_poll_count = 0;
+
+ /* The status is up-to-date; restart or stop the schedule as needed */
+@@ -160,14 +159,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
+
+ if (want != actual) {
+
+- /* Poll again later */
+- ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
+- return;
++ /* Poll again later, but give up after about 20 ms */
++ if (ehci->PSS_poll_count++ < 20) {
++ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
++ return;
++ }
++ ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
++ want, actual);
+ }
+-
+- if (ehci->PSS_poll_count > 20)
+- ehci_dbg(ehci, "PSS poll count reached %d\n",
+- ehci->PSS_poll_count);
+ ehci->PSS_poll_count = 0;
+
+ /* The status is up-to-date; restart or stop the schedule as needed */
+diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
+index 85b363a..d39dfa4 100644
+--- a/drivers/w1/masters/w1-gpio.c
++++ b/drivers/w1/masters/w1-gpio.c
+@@ -72,7 +72,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int __init w1_gpio_probe(struct platform_device *pdev)
++static int w1_gpio_probe(struct platform_device *pdev)
+ {
+ struct w1_bus_master *master;
+ struct w1_gpio_platform_data *pdata;
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index 7f809fd..19fa73a 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -79,6 +79,7 @@ config DA9052_WATCHDOG
+ config DA9055_WATCHDOG
+ tristate "Dialog Semiconductor DA9055 Watchdog"
+ depends on MFD_DA9055
++ select WATCHDOG_CORE
+ help
+ If you say yes here you get support for watchdog on the Dialog
+ Semiconductor DA9055 PMIC.
+diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
+index 2b0e000..e3b8f75 100644
+--- a/drivers/watchdog/sp5100_tco.c
++++ b/drivers/watchdog/sp5100_tco.c
+@@ -361,7 +361,7 @@ static unsigned char sp5100_tco_setupdevice(void)
+ {
+ struct pci_dev *dev = NULL;
+ const char *dev_name = NULL;
+- u32 val;
++ u32 val, tmp_val;
+ u32 index_reg, data_reg, base_addr;
+
+ /* Match the PCI device */
+@@ -497,30 +497,19 @@ static unsigned char sp5100_tco_setupdevice(void)
+ pr_debug("Got 0x%04x from resource tree\n", val);
+ }
+
+- /* Restore to the low three bits, if chipset is SB8x0(or later) */
+- if (sp5100_tco_pci->revision >= 0x40) {
+- u8 reserved_bit;
+- reserved_bit = inb(base_addr) & 0x7;
+- val |= (u32)reserved_bit;
+- }
++ /* Restore to the low three bits */
++ outb(base_addr+0, index_reg);
++ tmp_val = val | (inb(data_reg) & 0x7);
+
+ /* Re-programming the watchdog timer base address */
+ outb(base_addr+0, index_reg);
+- /* Low three bits of BASE are reserved */
+- outb((val >> 0) & 0xf8, data_reg);
++ outb((tmp_val >> 0) & 0xff, data_reg);
+ outb(base_addr+1, index_reg);
+- outb((val >> 8) & 0xff, data_reg);
++ outb((tmp_val >> 8) & 0xff, data_reg);
+ outb(base_addr+2, index_reg);
+- outb((val >> 16) & 0xff, data_reg);
++ outb((tmp_val >> 16) & 0xff, data_reg);
+ outb(base_addr+3, index_reg);
+- outb((val >> 24) & 0xff, data_reg);
+-
+- /*
+- * Clear unnecessary the low three bits,
+- * if chipset is SB8x0(or later)
+- */
+- if (sp5100_tco_pci->revision >= 0x40)
+- val &= ~0x7;
++ outb((tmp_val >> 24) & 0xff, data_reg);
+
+ if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
+ dev_name)) {
+diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
+index bcf3ba4..61786be 100644
+--- a/drivers/xen/xenbus/xenbus_client.c
++++ b/drivers/xen/xenbus/xenbus_client.c
+@@ -30,6 +30,7 @@
+ * IN THE SOFTWARE.
+ */
+
++#include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/types.h>
+ #include <linux/spinlock.h>
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index cc93b23..659ea81 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -265,6 +265,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans,
+ return 1;
+ }
+
++ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
+ btrfs_delalloc_release_metadata(inode, end + 1 - start);
+ btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0);
+ return 0;
+@@ -2469,6 +2470,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
+ */
+ set_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
+ &BTRFS_I(inode)->runtime_flags);
++ atomic_inc(&root->orphan_inodes);
+
+ /* if we have links, this was a truncate, lets do that */
+ if (inode->i_nlink) {
+@@ -2491,6 +2493,8 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
+ goto out;
+
+ ret = btrfs_truncate(inode);
++ if (ret)
++ btrfs_orphan_del(NULL, inode);
+ } else {
+ nr_unlink++;
+ }
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 9027bb1..b6818ee 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -3281,6 +3281,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
+ int ret;
+ bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
+
++insert:
+ INIT_LIST_HEAD(&ordered_sums);
+ btrfs_init_map_token(&token);
+ key.objectid = btrfs_ino(inode);
+@@ -3296,6 +3297,23 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
+ leaf = path->nodes[0];
+ fi = btrfs_item_ptr(leaf, path->slots[0],
+ struct btrfs_file_extent_item);
++
++ /*
++ * If we are overwriting an inline extent with a real one then we need
++ * to just delete the inline extent as it may not be large enough to
++ * have the entire file_extent_item.
++ */
++ if (ret && btrfs_token_file_extent_type(leaf, fi, &token) ==
++ BTRFS_FILE_EXTENT_INLINE) {
++ ret = btrfs_del_item(trans, log, path);
++ btrfs_release_path(path);
++ if (ret) {
++ path->really_keep_locks = 0;
++ return ret;
++ }
++ goto insert;
++ }
++
+ btrfs_set_token_file_extent_generation(leaf, fi, em->generation,
+ &token);
+ if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) {
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 5cbb7f4..ac8ff8d 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -647,6 +647,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
+ new_device->writeable = 0;
+ new_device->in_fs_metadata = 0;
+ new_device->can_discard = 0;
++ spin_lock_init(&new_device->io_lock);
+ list_replace_rcu(&device->dev_list, &new_device->dev_list);
+
+ call_rcu(&device->rcu, free_device);
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index de7f916..e328339 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -558,6 +558,11 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
+ dentry = ERR_PTR(-ENOENT);
+ break;
+ }
++ if (!S_ISDIR(dir->i_mode)) {
++ dput(dentry);
++ dentry = ERR_PTR(-ENOTDIR);
++ break;
++ }
+
+ /* skip separators */
+ while (*s == sep)
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index c9c7aa7..bceffe7 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -744,4 +744,5 @@ struct smb_version_values smb30_values = {
+ .cap_unix = 0,
+ .cap_nt_find = SMB2_NT_FIND,
+ .cap_large_files = SMB2_LARGE_FILES,
++ .oplock_read = SMB2_OPLOCK_LEVEL_II,
+ };
+diff --git a/fs/compat.c b/fs/compat.c
+index 015e1e1..a06dcbc 100644
+--- a/fs/compat.c
++++ b/fs/compat.c
+@@ -558,6 +558,10 @@ ssize_t compat_rw_copy_check_uvector(int type,
+ }
+ *ret_pointer = iov;
+
++ ret = -EFAULT;
++ if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
++ goto out;
++
+ /*
+ * Single unix specification:
+ * We should -EINVAL if an element length is not >= 0 and fitting an
+@@ -1080,17 +1084,12 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
+ if (!file->f_op)
+ goto out;
+
+- ret = -EFAULT;
+- if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+- goto out;
+-
+- tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,
++ ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
+ UIO_FASTIOV, iovstack, &iov);
+- if (tot_len == 0) {
+- ret = 0;
++ if (ret <= 0)
+ goto out;
+- }
+
++ tot_len = ret;
+ ret = rw_verify_area(type, file, pos, tot_len);
+ if (ret < 0)
+ goto out;
+diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
+index 2f2e0da..92e68b3 100644
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -635,7 +635,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
+ brelse(bitmap_bh);
+ printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu"
+ ", computed = %llu, %llu\n",
+- EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)),
++ EXT4_NUM_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)),
+ desc_count, bitmap_count);
+ return bitmap_count;
+ #else
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 061727a..28bbf9b 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3444,7 +3444,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ win = offs;
+
+ ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical -
+- EXT4_B2C(sbi, win);
++ EXT4_NUM_B2C(sbi, win);
+ BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
+ BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
+ }
+@@ -4590,7 +4590,7 @@ do_more:
+ EXT4_BLOCKS_PER_GROUP(sb);
+ count -= overflow;
+ }
+- count_clusters = EXT4_B2C(sbi, count);
++ count_clusters = EXT4_NUM_B2C(sbi, count);
+ bitmap_bh = ext4_read_block_bitmap(sb, block_group);
+ if (!bitmap_bh) {
+ err = -EIO;
+@@ -4832,11 +4832,11 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
+ ext4_group_desc_csum_set(sb, block_group, desc);
+ ext4_unlock_group(sb, block_group);
+ percpu_counter_add(&sbi->s_freeclusters_counter,
+- EXT4_B2C(sbi, blocks_freed));
++ EXT4_NUM_B2C(sbi, blocks_freed));
+
+ if (sbi->s_log_groups_per_flex) {
+ ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
+- atomic_add(EXT4_B2C(sbi, blocks_freed),
++ atomic_add(EXT4_NUM_B2C(sbi, blocks_freed),
+ &sbi->s_flex_groups[flex_group].free_clusters);
+ }
+
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 02824dc..1aab70d 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1247,7 +1247,7 @@ static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb,
+
+ ext4_inode_table_set(sb, gdp, group_data->inode_table);
+ ext4_free_group_clusters_set(sb, gdp,
+- EXT4_B2C(sbi, group_data->free_blocks_count));
++ EXT4_NUM_B2C(sbi, group_data->free_blocks_count));
+ ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
+ if (ext4_has_group_desc_csum(sb))
+ ext4_itable_unused_set(sb, gdp,
+@@ -1349,7 +1349,7 @@ static void ext4_update_super(struct super_block *sb,
+
+ /* Update the free space counts */
+ percpu_counter_add(&sbi->s_freeclusters_counter,
+- EXT4_B2C(sbi, free_blocks));
++ EXT4_NUM_B2C(sbi, free_blocks));
+ percpu_counter_add(&sbi->s_freeinodes_counter,
+ EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
+
+@@ -1360,7 +1360,7 @@ static void ext4_update_super(struct super_block *sb,
+ sbi->s_log_groups_per_flex) {
+ ext4_group_t flex_group;
+ flex_group = ext4_flex_group(sbi, group_data[0].group);
+- atomic_add(EXT4_B2C(sbi, free_blocks),
++ atomic_add(EXT4_NUM_B2C(sbi, free_blocks),
+ &sbi->s_flex_groups[flex_group].free_clusters);
+ atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
+ &sbi->s_flex_groups[flex_group].free_inodes);
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 0465f36..5fa223d 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super_block *sb)
+ }
+ /* Add the journal blocks as well */
+ if (sbi->s_journal)
+- overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen);
++ overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
+
+ sbi->s_overhead = overhead;
+ smp_wmb();
+diff --git a/fs/namei.c b/fs/namei.c
+index 43a97ee..ec97aef 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -693,8 +693,6 @@ void nd_jump_link(struct nameidata *nd, struct path *path)
+ nd->path = *path;
+ nd->inode = nd->path.dentry->d_inode;
+ nd->flags |= LOOKUP_JUMPED;
+-
+- BUG_ON(nd->inode->i_op->follow_link);
+ }
+
+ static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
+diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
+index 194c484..49eeb04 100644
+--- a/fs/nfs/nfs4filelayout.c
++++ b/fs/nfs/nfs4filelayout.c
+@@ -99,7 +99,8 @@ static void filelayout_reset_write(struct nfs_write_data *data)
+
+ task->tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
+ &hdr->pages,
+- hdr->completion_ops);
++ hdr->completion_ops,
++ hdr->dreq);
+ }
+ }
+
+@@ -119,7 +120,8 @@ static void filelayout_reset_read(struct nfs_read_data *data)
+
+ task->tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
+ &hdr->pages,
+- hdr->completion_ops);
++ hdr->completion_ops,
++ hdr->dreq);
+ }
+ }
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index efda60d..3cb5e77 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6087,11 +6087,13 @@ static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
+ static void nfs4_layoutget_release(void *calldata)
+ {
+ struct nfs4_layoutget *lgp = calldata;
+- struct nfs_server *server = NFS_SERVER(lgp->args.inode);
++ struct inode *inode = lgp->args.inode;
++ struct nfs_server *server = NFS_SERVER(inode);
+ size_t max_pages = max_response_pages(server);
+
+ dprintk("--> %s\n", __func__);
+ nfs4_free_pages(lgp->args.layout.pages, max_pages);
++ pnfs_put_layout_hdr(NFS_I(inode)->layout);
+ put_nfs_open_context(lgp->args.ctx);
+ kfree(calldata);
+ dprintk("<-- %s\n", __func__);
+@@ -6106,7 +6108,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
+ struct pnfs_layout_segment *
+ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
+ {
+- struct nfs_server *server = NFS_SERVER(lgp->args.inode);
++ struct inode *inode = lgp->args.inode;
++ struct nfs_server *server = NFS_SERVER(inode);
+ size_t max_pages = max_response_pages(server);
+ struct rpc_task *task;
+ struct rpc_message msg = {
+@@ -6136,6 +6139,10 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
+ lgp->res.layoutp = &lgp->args.layout;
+ lgp->res.seq_res.sr_slot = NULL;
+ nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
++
++ /* nfs4_layoutget_release calls pnfs_put_layout_hdr */
++ pnfs_get_layout_hdr(NFS_I(inode)->layout);
++
+ task = rpc_run_task(&task_setup_data);
+ if (IS_ERR(task))
+ return ERR_CAST(task);
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index 6be70f6..97767c8 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -1422,13 +1422,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
+
+ int pnfs_write_done_resend_to_mds(struct inode *inode,
+ struct list_head *head,
+- const struct nfs_pgio_completion_ops *compl_ops)
++ const struct nfs_pgio_completion_ops *compl_ops,
++ struct nfs_direct_req *dreq)
+ {
+ struct nfs_pageio_descriptor pgio;
+ LIST_HEAD(failed);
+
+ /* Resend all requests through the MDS */
+ nfs_pageio_init_write(&pgio, inode, FLUSH_STABLE, compl_ops);
++ pgio.pg_dreq = dreq;
+ while (!list_empty(head)) {
+ struct nfs_page *req = nfs_list_entry(head->next);
+
+@@ -1463,7 +1465,8 @@ static void pnfs_ld_handle_write_error(struct nfs_write_data *data)
+ if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
+ data->task.tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
+ &hdr->pages,
+- hdr->completion_ops);
++ hdr->completion_ops,
++ hdr->dreq);
+ }
+
+ /*
+@@ -1578,13 +1581,15 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
+
+ int pnfs_read_done_resend_to_mds(struct inode *inode,
+ struct list_head *head,
+- const struct nfs_pgio_completion_ops *compl_ops)
++ const struct nfs_pgio_completion_ops *compl_ops,
++ struct nfs_direct_req *dreq)
+ {
+ struct nfs_pageio_descriptor pgio;
+ LIST_HEAD(failed);
+
+ /* Resend all requests through the MDS */
+ nfs_pageio_init_read(&pgio, inode, compl_ops);
++ pgio.pg_dreq = dreq;
+ while (!list_empty(head)) {
+ struct nfs_page *req = nfs_list_entry(head->next);
+
+@@ -1615,7 +1620,8 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
+ if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
+ data->task.tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
+ &hdr->pages,
+- hdr->completion_ops);
++ hdr->completion_ops,
++ hdr->dreq);
+ }
+
+ /*
+diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
+index 97cb358..94ba804 100644
+--- a/fs/nfs/pnfs.h
++++ b/fs/nfs/pnfs.h
+@@ -230,9 +230,11 @@ struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
+
+ void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp);
+ int pnfs_read_done_resend_to_mds(struct inode *inode, struct list_head *head,
+- const struct nfs_pgio_completion_ops *compl_ops);
++ const struct nfs_pgio_completion_ops *compl_ops,
++ struct nfs_direct_req *dreq);
+ int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head,
+- const struct nfs_pgio_completion_ops *compl_ops);
++ const struct nfs_pgio_completion_ops *compl_ops,
++ struct nfs_direct_req *dreq);
+ struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
+
+ /* nfs4_deviceid_flags */
+diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
+index 3f79c77..6edc807 100644
+--- a/fs/nfs/unlink.c
++++ b/fs/nfs/unlink.c
+@@ -336,20 +336,14 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
+ struct inode *old_dir = data->old_dir;
+ struct inode *new_dir = data->new_dir;
+ struct dentry *old_dentry = data->old_dentry;
+- struct dentry *new_dentry = data->new_dentry;
+
+ if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
+ rpc_restart_call_prepare(task);
+ return;
+ }
+
+- if (task->tk_status != 0) {
++ if (task->tk_status != 0)
+ nfs_cancel_async_unlink(old_dentry);
+- return;
+- }
+-
+- d_drop(old_dentry);
+- d_drop(new_dentry);
+ }
+
+ /**
+@@ -550,6 +544,18 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
+ error = rpc_wait_for_completion_task(task);
+ if (error == 0)
+ error = task->tk_status;
++ switch (error) {
++ case 0:
++ /* The rename succeeded */
++ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
++ d_move(dentry, sdentry);
++ break;
++ case -ERESTARTSYS:
++ /* The result of the rename is unknown. Play it safe by
++ * forcing a new lookup */
++ d_drop(dentry);
++ d_drop(sdentry);
++ }
+ rpc_put_task(task);
+ out_dput:
+ dput(sdentry);
+diff --git a/fs/pipe.c b/fs/pipe.c
+index bd3479d..8e2e73f 100644
+--- a/fs/pipe.c
++++ b/fs/pipe.c
+@@ -863,6 +863,9 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
+ {
+ int ret = -ENOENT;
+
++ if (!(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
++ return -EINVAL;
++
+ mutex_lock(&inode->i_mutex);
+
+ if (inode->i_pipe) {
+diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
+index b7a4719..66b51c0 100644
+--- a/fs/proc/namespaces.c
++++ b/fs/proc/namespaces.c
+@@ -118,7 +118,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
+ struct super_block *sb = inode->i_sb;
+ struct proc_inode *ei = PROC_I(inode);
+ struct task_struct *task;
+- struct dentry *ns_dentry;
++ struct path ns_path;
+ void *error = ERR_PTR(-EACCES);
+
+ task = get_proc_task(inode);
+@@ -128,14 +128,14 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
+ if (!ptrace_may_access(task, PTRACE_MODE_READ))
+ goto out_put_task;
+
+- ns_dentry = proc_ns_get_dentry(sb, task, ei->ns_ops);
+- if (IS_ERR(ns_dentry)) {
+- error = ERR_CAST(ns_dentry);
++ ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns_ops);
++ if (IS_ERR(ns_path.dentry)) {
++ error = ERR_CAST(ns_path.dentry);
+ goto out_put_task;
+ }
+
+- dput(nd->path.dentry);
+- nd->path.dentry = ns_dentry;
++ ns_path.mnt = mntget(nd->path.mnt);
++ nd_jump_link(nd, &ns_path);
+ error = NULL;
+
+ out_put_task:
+diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
+index bf6afa2..a5cda3e 100644
+--- a/include/linux/device-mapper.h
++++ b/include/linux/device-mapper.h
+@@ -68,8 +68,8 @@ typedef void (*dm_postsuspend_fn) (struct dm_target *ti);
+ typedef int (*dm_preresume_fn) (struct dm_target *ti);
+ typedef void (*dm_resume_fn) (struct dm_target *ti);
+
+-typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
+- unsigned status_flags, char *result, unsigned maxlen);
++typedef void (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
++ unsigned status_flags, char *result, unsigned maxlen);
+
+ typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
+
+diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
+index 4b117a3..acf4d31 100644
+--- a/include/linux/mfd/rtsx_pci.h
++++ b/include/linux/mfd/rtsx_pci.h
+@@ -735,6 +735,7 @@ struct rtsx_pcr {
+
+ unsigned int card_inserted;
+ unsigned int card_removed;
++ unsigned int card_exist;
+
+ struct delayed_work carddet_work;
+ struct delayed_work idle_work;
+@@ -799,6 +800,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
+ u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
+ int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card);
+ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card);
++int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card);
+ int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage);
+ unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr);
+ void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr);
+diff --git a/ipc/msg.c b/ipc/msg.c
+index 950572f..31cd1bf 100644
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -820,15 +820,17 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
+ struct msg_msg *copy = NULL;
+ unsigned long copy_number = 0;
+
++ ns = current->nsproxy->ipc_ns;
++
+ if (msqid < 0 || (long) bufsz < 0)
+ return -EINVAL;
+ if (msgflg & MSG_COPY) {
+- copy = prepare_copy(buf, bufsz, msgflg, &msgtyp, &copy_number);
++ copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax),
++ msgflg, &msgtyp, &copy_number);
+ if (IS_ERR(copy))
+ return PTR_ERR(copy);
+ }
+ mode = convert_mode(&msgtyp, msgflg);
+- ns = current->nsproxy->ipc_ns;
+
+ msq = msg_lock_check(ns, msqid);
+ if (IS_ERR(msq)) {
+diff --git a/ipc/msgutil.c b/ipc/msgutil.c
+index ebfcbfa..5df8e4b 100644
+--- a/ipc/msgutil.c
++++ b/ipc/msgutil.c
+@@ -117,9 +117,6 @@ struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
+ if (alen > DATALEN_MSG)
+ alen = DATALEN_MSG;
+
+- dst->next = NULL;
+- dst->security = NULL;
+-
+ memcpy(dst + 1, src + 1, alen);
+
+ len -= alen;
+diff --git a/kernel/fork.c b/kernel/fork.c
+index c535f33..5630e52 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -1141,6 +1141,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
+ if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
+ return ERR_PTR(-EINVAL);
+
++ if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
++ return ERR_PTR(-EINVAL);
++
+ /*
+ * Thread groups must share signals as well, and detached threads
+ * can only be started up within the thread group.
+@@ -1801,7 +1804,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
+ * If unsharing a user namespace must also unshare the thread.
+ */
+ if (unshare_flags & CLONE_NEWUSER)
+- unshare_flags |= CLONE_THREAD;
++ unshare_flags |= CLONE_THREAD | CLONE_FS;
+ /*
+ * If unsharing a pid namespace must also unshare the thread.
+ */
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index d58e552..e78feff 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -564,14 +564,19 @@ void tick_nohz_idle_enter(void)
+ */
+ void tick_nohz_irq_exit(void)
+ {
++ unsigned long flags;
+ struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
+
+ if (!ts->inidle)
+ return;
+
+- /* Cancel the timer because CPU already waken up from the C-states*/
++ local_irq_save(flags);
++
++ /* Cancel the timer because CPU already waken up from the C-states */
+ menu_hrtimer_cancel();
+ __tick_nohz_idle_enter(ts);
++
++ local_irq_restore(flags);
+ }
+
+ /**
+diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
+index 5d89335..2747967 100644
+--- a/kernel/trace/Kconfig
++++ b/kernel/trace/Kconfig
+@@ -416,24 +416,28 @@ config PROBE_EVENTS
+ def_bool n
+
+ config DYNAMIC_FTRACE
+- bool "enable/disable ftrace tracepoints dynamically"
++ bool "enable/disable function tracing dynamically"
+ depends on FUNCTION_TRACER
+ depends on HAVE_DYNAMIC_FTRACE
+ default y
+ help
+- This option will modify all the calls to ftrace dynamically
+- (will patch them out of the binary image and replace them
+- with a No-Op instruction) as they are called. A table is
+- created to dynamically enable them again.
++ This option will modify all the calls to function tracing
++ dynamically (will patch them out of the binary image and
++ replace them with a No-Op instruction) on boot up. During
++ compile time, a table is made of all the locations that ftrace
++ can function trace, and this table is linked into the kernel
++ image. When this is enabled, functions can be individually
++ enabled, and the functions not enabled will not affect
++ performance of the system.
++
++ See the files in /sys/kernel/debug/tracing:
++ available_filter_functions
++ set_ftrace_filter
++ set_ftrace_notrace
+
+ This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
+ otherwise has native performance as long as no tracing is active.
+
+- The changes to the code are done by a kernel thread that
+- wakes up once a second and checks to see if any ftrace calls
+- were made. If so, it runs stop_machine (stops all CPUS)
+- and modifies the code to jump over the call to ftrace.
+-
+ config FUNCTION_PROFILER
+ bool "Kernel function profiler"
+ depends on FUNCTION_TRACER
+diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
+index 2b042c4..dbfe36a7 100644
+--- a/kernel/user_namespace.c
++++ b/kernel/user_namespace.c
+@@ -21,6 +21,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/ctype.h>
+ #include <linux/projid.h>
++#include <linux/fs_struct.h>
+
+ static struct kmem_cache *user_ns_cachep __read_mostly;
+
+@@ -803,6 +804,9 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
+ if (atomic_read(&current->mm->mm_users) > 1)
+ return -EINVAL;
+
++ if (current->fs->users != 1)
++ return -EINVAL;
++
+ if (!ns_capable(user_ns, CAP_SYS_ADMIN))
+ return -EPERM;
+
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index e2df1c1..3df6d12 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -2386,8 +2386,8 @@ restart:
+ *mpol_new = *n->policy;
+ atomic_set(&mpol_new->refcnt, 1);
+ sp_node_init(n_new, n->end, end, mpol_new);
+- sp_insert(sp, n_new);
+ n->end = start;
++ sp_insert(sp, n_new);
+ n_new = NULL;
+ mpol_new = NULL;
+ break;
+diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
+index 926b466..fd26d04 100644
+--- a/mm/process_vm_access.c
++++ b/mm/process_vm_access.c
+@@ -429,12 +429,6 @@ compat_process_vm_rw(compat_pid_t pid,
+ if (flags != 0)
+ return -EINVAL;
+
+- if (!access_ok(VERIFY_READ, lvec, liovcnt * sizeof(*lvec)))
+- goto out;
+-
+- if (!access_ok(VERIFY_READ, rvec, riovcnt * sizeof(*rvec)))
+- goto out;
+-
+ if (vm_write)
+ rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,
+ UIO_FASTIOV, iovstack_l,
+@@ -459,8 +453,6 @@ free_iovecs:
+ kfree(iov_r);
+ if (iov_l != iovstack_l)
+ kfree(iov_l);
+-
+-out:
+ return rc;
+ }
+
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index f651da6..76c3d0a 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -1234,7 +1234,7 @@ static inline int __init lowpan_netlink_init(void)
+ return rtnl_link_register(&lowpan_link_ops);
+ }
+
+-static inline void __init lowpan_netlink_fini(void)
++static inline void lowpan_netlink_fini(void)
+ {
+ rtnl_link_unregister(&lowpan_link_ops);
+ }
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index f75ba1a..9979bf8 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -4072,6 +4072,17 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
+ {
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
++ /*
++ * Make sure some work items will not run after this,
++ * they will not do anything but might not have been
++ * cancelled when disconnecting.
++ */
++ cancel_work_sync(&ifmgd->monitor_work);
++ cancel_work_sync(&ifmgd->beacon_connection_loss_work);
++ cancel_work_sync(&ifmgd->request_smps_work);
++ cancel_work_sync(&ifmgd->csa_connection_drop_work);
++ cancel_work_sync(&ifmgd->chswitch_work);
++
+ mutex_lock(&ifmgd->mtx);
+ if (ifmgd->assoc_data)
+ ieee80211_destroy_assoc_data(sdata, false);
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index 33811db..ab02588 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -485,13 +485,17 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_tasks);
+ * xprt_wait_for_buffer_space - wait for transport output buffer to clear
+ * @task: task to be put to sleep
+ * @action: function pointer to be executed after wait
++ *
++ * Note that we only set the timer for the case of RPC_IS_SOFT(), since
++ * we don't in general want to force a socket disconnection due to
++ * an incomplete RPC call transmission.
+ */
+ void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
+ {
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+
+- task->tk_timeout = req->rq_timeout;
++ task->tk_timeout = RPC_IS_SOFT(task) ? req->rq_timeout : 0;
+ rpc_sleep_on(&xprt->pending, task, action);
+ }
+ EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
+diff --git a/security/keys/compat.c b/security/keys/compat.c
+index 1c26176..d65fa7f 100644
+--- a/security/keys/compat.c
++++ b/security/keys/compat.c
+@@ -40,12 +40,12 @@ static long compat_keyctl_instantiate_key_iov(
+ ARRAY_SIZE(iovstack),
+ iovstack, &iov);
+ if (ret < 0)
+- return ret;
++ goto err;
+ if (ret == 0)
+ goto no_payload_free;
+
+ ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
+-
++err:
+ if (iov != iovstack)
+ kfree(iov);
+ return ret;
+diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
+index 58dfe08..42defae 100644
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -57,7 +57,7 @@ int install_user_keyrings(void)
+
+ kenter("%p{%u}", user, uid);
+
+- if (user->uid_keyring) {
++ if (user->uid_keyring && user->session_keyring) {
+ kleave(" = 0 [exist]");
+ return 0;
+ }
+@@ -839,7 +839,7 @@ void key_change_session_keyring(struct callback_head *twork)
+ new-> sgid = old-> sgid;
+ new->fsgid = old->fsgid;
+ new->user = get_uid(old->user);
+- new->user_ns = get_user_ns(new->user_ns);
++ new->user_ns = get_user_ns(old->user_ns);
+ new->group_info = get_group_info(old->group_info);
+
+ new->securebits = old->securebits;
+diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
+index 8575861..0097f36 100644
+--- a/sound/core/vmaster.c
++++ b/sound/core/vmaster.c
+@@ -213,7 +213,10 @@ static int slave_put(struct snd_kcontrol *kcontrol,
+ }
+ if (!changed)
+ return 0;
+- return slave_put_val(slave, ucontrol);
++ err = slave_put_val(slave, ucontrol);
++ if (err < 0)
++ return err;
++ return 1;
+ }
+
+ static int slave_tlv_cmd(struct snd_kcontrol *kcontrol,
+diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
+index 2ffdc35..806407a 100644
+--- a/sound/pci/ice1712/ice1712.c
++++ b/sound/pci/ice1712/ice1712.c
+@@ -2594,6 +2594,8 @@ static int snd_ice1712_create(struct snd_card *card,
+ snd_ice1712_proc_init(ice);
+ synchronize_irq(pci->irq);
+
++ card->private_data = ice;
++
+ err = pci_request_regions(pci, "ICE1712");
+ if (err < 0) {
+ kfree(ice);
diff --git a/3.8.2/4420_grsecurity-2.9.1-3.8.3-201303142235.patch b/3.8.3/4420_grsecurity-2.9.1-3.8.3-201303142235.patch
index ef25e2b..ef25e2b 100644
--- a/3.8.2/4420_grsecurity-2.9.1-3.8.3-201303142235.patch
+++ b/3.8.3/4420_grsecurity-2.9.1-3.8.3-201303142235.patch
diff --git a/3.8.2/4425_grsec_remove_EI_PAX.patch b/3.8.3/4425_grsec_remove_EI_PAX.patch
index 97e6951..97e6951 100644
--- a/3.8.2/4425_grsec_remove_EI_PAX.patch
+++ b/3.8.3/4425_grsec_remove_EI_PAX.patch
diff --git a/3.8.2/4430_grsec-remove-localversion-grsec.patch b/3.8.3/4430_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/3.8.2/4430_grsec-remove-localversion-grsec.patch
+++ b/3.8.3/4430_grsec-remove-localversion-grsec.patch
diff --git a/3.8.2/4435_grsec-mute-warnings.patch b/3.8.3/4435_grsec-mute-warnings.patch
index e1a7a3c..e1a7a3c 100644
--- a/3.8.2/4435_grsec-mute-warnings.patch
+++ b/3.8.3/4435_grsec-mute-warnings.patch
diff --git a/3.8.2/4440_grsec-remove-protected-paths.patch b/3.8.3/4440_grsec-remove-protected-paths.patch
index 637934a..637934a 100644
--- a/3.8.2/4440_grsec-remove-protected-paths.patch
+++ b/3.8.3/4440_grsec-remove-protected-paths.patch
diff --git a/3.8.2/4450_grsec-kconfig-default-gids.patch b/3.8.3/4450_grsec-kconfig-default-gids.patch
index 3dfdc8f..3dfdc8f 100644
--- a/3.8.2/4450_grsec-kconfig-default-gids.patch
+++ b/3.8.3/4450_grsec-kconfig-default-gids.patch
diff --git a/3.8.2/4465_selinux-avc_audit-log-curr_ip.patch b/3.8.3/4465_selinux-avc_audit-log-curr_ip.patch
index 5b614b1..5b614b1 100644
--- a/3.8.2/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/3.8.3/4465_selinux-avc_audit-log-curr_ip.patch
diff --git a/3.8.2/4470_disable-compat_vdso.patch b/3.8.3/4470_disable-compat_vdso.patch
index 1037ba9..1037ba9 100644
--- a/3.8.2/4470_disable-compat_vdso.patch
+++ b/3.8.3/4470_disable-compat_vdso.patch