commit: f8c7c0cb868106263d4b863504609171d27c8d11 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Wed Jul 22 10:12:58 2015 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Wed Jul 22 10:12:58 2015 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f8c7c0cb
Linux patch 3.18.19 0000_README | 4 + 1018_linux-3.18.19.patch | 1822 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1826 insertions(+) diff --git a/0000_README b/0000_README index 4092093..61cb27a 100644 --- a/0000_README +++ b/0000_README @@ -115,6 +115,10 @@ Patch: 1017_linux-3.18.18.patch From: http://www.kernel.org Desc: Linux 3.18.18 +Patch: 1018_linux-3.18.19.patch +From: http://www.kernel.org +Desc: Linux 3.18.19 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1018_linux-3.18.19.patch b/1018_linux-3.18.19.patch new file mode 100644 index 0000000..67377c5 --- /dev/null +++ b/1018_linux-3.18.19.patch @@ -0,0 +1,1822 @@ +diff --git a/Makefile b/Makefile +index 35faaf8fb651..eab97c3d462d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 18 +-SUBLEVEL = 18 ++SUBLEVEL = 19 + EXTRAVERSION = + NAME = Diseased Newt + +diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S +index 01dcb0e752d9..d66d608f7ce7 100644 +--- a/arch/arm/kvm/interrupts.S ++++ b/arch/arm/kvm/interrupts.S +@@ -159,13 +159,9 @@ __kvm_vcpu_return: + @ Don't trap coprocessor accesses for host kernel + set_hstr vmexit + set_hdcr vmexit +- set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)) ++ set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)), after_vfp_restore + + #ifdef CONFIG_VFPv3 +- @ Save floating point registers we if let guest use them. +- tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) +- bne after_vfp_restore +- + @ Switch VFP/NEON hardware state to the host's + add r7, vcpu, #VCPU_VFP_GUEST + store_vfp_state r7 +@@ -177,6 +173,8 @@ after_vfp_restore: + @ Restore FPEXC_EN which we clobbered on entry + pop {r2} + VFPFMXR FPEXC, r2 ++#else ++after_vfp_restore: + #endif + + @ Reset Hyp-role +@@ -472,7 +470,7 @@ switch_to_guest_vfp: + push {r3-r7} + + @ NEON/VFP used. Turn on VFP access. +- set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11)) ++ set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11)) + + @ Switch VFP/NEON hardware state to the guest's + add r7, r0, #VCPU_VFP_HOST +diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S +index 14d488388480..f6f14812d106 100644 +--- a/arch/arm/kvm/interrupts_head.S ++++ b/arch/arm/kvm/interrupts_head.S +@@ -599,8 +599,13 @@ ARM_BE8(rev r6, r6 ) + .endm + + /* Configures the HCPTR (Hyp Coprocessor Trap Register) on entry/return +- * (hardware reset value is 0). Keep previous value in r2. */ +-.macro set_hcptr operation, mask ++ * (hardware reset value is 0). Keep previous value in r2. ++ * An ISB is emited on vmexit/vmtrap, but executed on vmexit only if ++ * VFP wasn't already enabled (always executed on vmtrap). ++ * If a label is specified with vmexit, it is branched to if VFP wasn't ++ * enabled. ++ */ ++.macro set_hcptr operation, mask, label = none + mrc p15, 4, r2, c1, c1, 2 + ldr r3, =\mask + .if \operation == vmentry +@@ -609,6 +614,17 @@ ARM_BE8(rev r6, r6 ) + bic r3, r2, r3 @ Don't trap defined coproc-accesses + .endif + mcr p15, 4, r3, c1, c1, 2 ++ .if \operation != vmentry ++ .if \operation == vmexit ++ tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) ++ beq 1f ++ .endif ++ isb ++ .if \label != none ++ b \label ++ .endif ++1: ++ .endif + .endm + + /* Configures the HDCR (Hyp Debug Configuration Register) on entry/return +diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c +index 2daef619d053..5474a76803f0 100644 +--- a/arch/arm/mach-imx/clk-imx6q.c ++++ b/arch/arm/mach-imx/clk-imx6q.c +@@ -439,7 +439,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) + clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); + clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); + clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); +- clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); ++ clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); + clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); + clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); + clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); +diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h +index 7fd3e27e3ccc..8afb863f5a9e 100644 +--- a/arch/arm64/include/asm/kvm_arm.h ++++ b/arch/arm64/include/asm/kvm_arm.h +@@ -18,6 +18,7 @@ + #ifndef __ARM64_KVM_ARM_H__ + #define __ARM64_KVM_ARM_H__ + ++#include <asm/memory.h> + #include <asm/types.h> + + /* Hyp Configuration Register (HCR) bits */ +@@ -160,9 +161,9 @@ + #endif + + #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) +-#define VTTBR_BADDR_MASK (((1LLU << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) +-#define VTTBR_VMID_SHIFT (48LLU) +-#define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT) ++#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) ++#define VTTBR_VMID_SHIFT (UL(48)) ++#define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT) + + /* Hyp System Trap Register */ + #define HSTR_EL2_TTEE (1 << 16) +@@ -185,13 +186,13 @@ + + /* Exception Syndrome Register (ESR) bits */ + #define ESR_EL2_EC_SHIFT (26) +-#define ESR_EL2_EC (0x3fU << ESR_EL2_EC_SHIFT) +-#define ESR_EL2_IL (1U << 25) ++#define ESR_EL2_EC (UL(0x3f) << ESR_EL2_EC_SHIFT) ++#define ESR_EL2_IL (UL(1) << 25) + #define ESR_EL2_ISS (ESR_EL2_IL - 1) + #define ESR_EL2_ISV_SHIFT (24) +-#define ESR_EL2_ISV (1U << ESR_EL2_ISV_SHIFT) ++#define ESR_EL2_ISV (UL(1) << ESR_EL2_ISV_SHIFT) + #define ESR_EL2_SAS_SHIFT (22) +-#define ESR_EL2_SAS (3U << ESR_EL2_SAS_SHIFT) ++#define ESR_EL2_SAS (UL(3) << ESR_EL2_SAS_SHIFT) + #define ESR_EL2_SSE (1 << 21) + #define ESR_EL2_SRT_SHIFT (16) + #define ESR_EL2_SRT_MASK (0x1f << ESR_EL2_SRT_SHIFT) +@@ -205,16 +206,16 @@ + #define ESR_EL2_FSC_TYPE (0x3c) + + #define ESR_EL2_CV_SHIFT (24) +-#define ESR_EL2_CV (1U << ESR_EL2_CV_SHIFT) ++#define ESR_EL2_CV (UL(1) << ESR_EL2_CV_SHIFT) + #define ESR_EL2_COND_SHIFT (20) +-#define ESR_EL2_COND (0xfU << ESR_EL2_COND_SHIFT) ++#define ESR_EL2_COND (UL(0xf) << ESR_EL2_COND_SHIFT) + + + #define FSC_FAULT (0x04) + #define FSC_PERM (0x0c) + + /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ +-#define HPFAR_MASK (~0xFUL) ++#define HPFAR_MASK (~UL(0xf)) + + #define ESR_EL2_EC_UNKNOWN (0x00) + #define ESR_EL2_EC_WFI (0x01) +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 3635fff7b32d..c9148e268512 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -173,7 +173,7 @@ config SBUS + + config NEED_DMA_MAP_STATE + def_bool y +- depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG ++ depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG || SWIOTLB + + config NEED_SG_DMA_LENGTH + def_bool y +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 6c0709ff2f38..306d152336cd 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -571,7 +571,7 @@ struct kvm_arch { + struct kvm_pic *vpic; + struct kvm_ioapic *vioapic; + struct kvm_pit *vpit; +- int vapics_in_nmi_mode; ++ atomic_t vapics_in_nmi_mode; + struct mutex apic_map_lock; + struct kvm_apic_map *apic_map; + +diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c +index ec9df6f9cd47..5e109a31f62b 100644 +--- a/arch/x86/kernel/cpu/microcode/intel_early.c ++++ b/arch/x86/kernel/cpu/microcode/intel_early.c +@@ -321,7 +321,7 @@ get_matching_model_microcode(int cpu, unsigned long start, + unsigned int mc_saved_count = mc_saved_data->mc_saved_count; + int i; + +- while (leftover) { ++ while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) { + mc_header = (struct microcode_header_intel *)ucode_ptr; + + mc_size = get_totalsize(mc_header); +diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c +index 498b6d967138..df11583a9041 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel.c ++++ b/arch/x86/kernel/cpu/perf_event_intel.c +@@ -2604,13 +2604,13 @@ __init int intel_pmu_init(void) + * counter, so do not extend mask to generic counters + */ + for_each_event_constraint(c, x86_pmu.event_constraints) { +- if (c->cmask != FIXED_EVENT_FLAGS +- || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) { +- continue; ++ if (c->cmask == FIXED_EVENT_FLAGS ++ && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) { ++ c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; + } +- +- c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; +- c->weight += x86_pmu.num_counters; ++ c->idxmsk64 &= ++ ~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed)); ++ c->weight = hweight64(c->idxmsk64); + } + } + +diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S +index 344b63f18d14..3dddb89ba320 100644 +--- a/arch/x86/kernel/entry_32.S ++++ b/arch/x86/kernel/entry_32.S +@@ -982,6 +982,9 @@ ENTRY(xen_hypervisor_callback) + ENTRY(xen_do_upcall) + 1: mov %esp, %eax + call xen_evtchn_do_upcall ++#ifndef CONFIG_PREEMPT ++ call xen_maybe_preempt_hcall ++#endif + jmp ret_from_intr + CFI_ENDPROC + ENDPROC(xen_hypervisor_callback) +diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S +index f1dc27f457f1..e36d9815ef56 100644 +--- a/arch/x86/kernel/entry_64.S ++++ b/arch/x86/kernel/entry_64.S +@@ -1173,6 +1173,9 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) + popq %rsp + CFI_DEF_CFA_REGISTER rsp + decl PER_CPU_VAR(irq_count) ++#ifndef CONFIG_PREEMPT ++ call xen_maybe_preempt_hcall ++#endif + jmp error_exit + CFI_ENDPROC + END(xen_do_hypervisor_callback) +diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S +index 30a2aa3782fa..e7be5290fe1f 100644 +--- a/arch/x86/kernel/head_32.S ++++ b/arch/x86/kernel/head_32.S +@@ -61,9 +61,16 @@ + #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) + #endif + +-/* Number of possible pages in the lowmem region */ +-LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) +- ++/* ++ * Number of possible pages in the lowmem region. ++ * ++ * We shift 2 by 31 instead of 1 by 32 to the left in order to avoid a ++ * gas warning about overflowing shift count when gas has been compiled ++ * with only a host target support using a 32-bit type for internal ++ * representation. ++ */ ++LOWMEM_PAGES = (((2<<31) - __PAGE_OFFSET) >> PAGE_SHIFT) ++ + /* Enough space to fit pagetables for the low memory linear map */ + MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT + +diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c +index 93d2c04c6f8f..f2e281cf8c19 100644 +--- a/arch/x86/kernel/kprobes/core.c ++++ b/arch/x86/kernel/kprobes/core.c +@@ -330,13 +330,16 @@ int __copy_instruction(u8 *dest, u8 *src) + { + struct insn insn; + kprobe_opcode_t buf[MAX_INSN_SIZE]; ++ int length; + + kernel_insn_init(&insn, (void *)recover_probed_instruction(buf, (unsigned long)src)); + insn_get_length(&insn); ++ length = insn.length; ++ + /* Another subsystem puts a breakpoint, failed to recover */ + if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) + return 0; +- memcpy(dest, insn.kaddr, insn.length); ++ memcpy(dest, insn.kaddr, length); + + #ifdef CONFIG_X86_64 + if (insn_rip_relative(&insn)) { +@@ -366,7 +369,7 @@ int __copy_instruction(u8 *dest, u8 *src) + *(s32 *) disp = (s32) newdisp; + } + #endif +- return insn.length; ++ return length; + } + + static int arch_copy_kprobe(struct kprobe *p) +diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c +index 298781d4cfb4..1406ffde3e35 100644 +--- a/arch/x86/kvm/i8254.c ++++ b/arch/x86/kvm/i8254.c +@@ -305,7 +305,7 @@ static void pit_do_work(struct kthread_work *work) + * LVT0 to NMI delivery. Other PIC interrupts are just sent to + * VCPU0, and only if its LVT0 is in EXTINT mode. + */ +- if (kvm->arch.vapics_in_nmi_mode > 0) ++ if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0) + kvm_for_each_vcpu(i, vcpu, kvm) + kvm_apic_nmi_wd_deliver(vcpu); + } +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index b8345dd41b25..de8e50040124 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -1112,10 +1112,10 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) + if (!nmi_wd_enabled) { + apic_debug("Receive NMI setting on APIC_LVT0 " + "for cpu %d\n", apic->vcpu->vcpu_id); +- apic->vcpu->kvm->arch.vapics_in_nmi_mode++; ++ atomic_inc(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); + } + } else if (nmi_wd_enabled) +- apic->vcpu->kvm->arch.vapics_in_nmi_mode--; ++ atomic_dec(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); + } + + static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) +@@ -1687,6 +1687,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, + + apic_update_ppr(apic); + hrtimer_cancel(&apic->lapic_timer.timer); ++ apic_manage_nmi_watchdog(apic, kvm_apic_get_reg(apic, APIC_LVT0)); + update_divide_count(apic); + start_apic_timer(apic); + apic->irr_pending = true; +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index 170e7d49ba65..b83bff87408f 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -511,8 +511,10 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) + { + struct vcpu_svm *svm = to_svm(vcpu); + +- if (svm->vmcb->control.next_rip != 0) ++ if (svm->vmcb->control.next_rip != 0) { ++ WARN_ON(!static_cpu_has(X86_FEATURE_NRIPS)); + svm->next_rip = svm->vmcb->control.next_rip; ++ } + + if (!svm->next_rip) { + if (emulate_instruction(vcpu, EMULTYPE_SKIP) != +@@ -4306,7 +4308,9 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, + break; + } + +- vmcb->control.next_rip = info->next_rip; ++ /* TODO: Advertise NRIPS to guest hypervisor unconditionally */ ++ if (static_cpu_has(X86_FEATURE_NRIPS)) ++ vmcb->control.next_rip = info->next_rip; + vmcb->control.exit_code = icpt_info.exit_code; + vmexit = nested_svm_exit_handled(svm); + +diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c +index a46c4af2ac98..15697c630139 100644 +--- a/drivers/edac/sb_edac.c ++++ b/drivers/edac/sb_edac.c +@@ -910,7 +910,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci) + u32 reg; + u64 limit, prv = 0; + u64 tmp_mb; +- u32 mb, kb; ++ u32 gb, mb; + u32 rir_way; + + /* +@@ -920,15 +920,17 @@ static void get_memory_layout(const struct mem_ctl_info *mci) + pvt->tolm = pvt->info.get_tolm(pvt); + tmp_mb = (1 + pvt->tolm) >> 20; + +- mb = div_u64_rem(tmp_mb, 1000, &kb); +- edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tolm); ++ gb = div_u64_rem(tmp_mb, 1024, &mb); ++ edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", ++ gb, (mb*1000)/1024, (u64)pvt->tolm); + + /* Address range is already 45:25 */ + pvt->tohm = pvt->info.get_tohm(pvt); + tmp_mb = (1 + pvt->tohm) >> 20; + +- mb = div_u64_rem(tmp_mb, 1000, &kb); +- edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tohm); ++ gb = div_u64_rem(tmp_mb, 1024, &mb); ++ edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", ++ gb, (mb*1000)/1024, (u64)pvt->tohm); + + /* + * Step 2) Get SAD range and SAD Interleave list +@@ -950,11 +952,11 @@ static void get_memory_layout(const struct mem_ctl_info *mci) + break; + + tmp_mb = (limit + 1) >> 20; +- mb = div_u64_rem(tmp_mb, 1000, &kb); ++ gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n", + n_sads, + get_dram_attr(reg), +- mb, kb, ++ gb, (mb*1000)/1024, + ((u64)tmp_mb) << 20L, + INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]", + reg); +@@ -985,9 +987,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci) + break; + tmp_mb = (limit + 1) >> 20; + +- mb = div_u64_rem(tmp_mb, 1000, &kb); ++ gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n", +- n_tads, mb, kb, ++ n_tads, gb, (mb*1000)/1024, + ((u64)tmp_mb) << 20L, + (u32)TAD_SOCK(reg), + (u32)TAD_CH(reg), +@@ -1010,10 +1012,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) + tad_ch_nilv_offset[j], + ®); + tmp_mb = TAD_OFFSET(reg) >> 20; +- mb = div_u64_rem(tmp_mb, 1000, &kb); ++ gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n", + i, j, +- mb, kb, ++ gb, (mb*1000)/1024, + ((u64)tmp_mb) << 20L, + reg); + } +@@ -1035,10 +1037,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) + + tmp_mb = pvt->info.rir_limit(reg) >> 20; + rir_way = 1 << RIR_WAY(reg); +- mb = div_u64_rem(tmp_mb, 1000, &kb); ++ gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", + i, j, +- mb, kb, ++ gb, (mb*1000)/1024, + ((u64)tmp_mb) << 20L, + rir_way, + reg); +@@ -1049,10 +1051,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) + ®); + tmp_mb = RIR_OFFSET(reg) << 6; + +- mb = div_u64_rem(tmp_mb, 1000, &kb); ++ gb = div_u64_rem(tmp_mb, 1024, &mb); + edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n", + i, j, k, +- mb, kb, ++ gb, (mb*1000)/1024, + ((u64)tmp_mb) << 20L, + (u32)RIR_RNK_TGT(reg), + reg); +@@ -1090,7 +1092,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, + u8 ch_way, sck_way, pkg, sad_ha = 0; + u32 tad_offset; + u32 rir_way; +- u32 mb, kb; ++ u32 mb, gb; + u64 ch_addr, offset, limit = 0, prv = 0; + + +@@ -1359,10 +1361,10 @@ static int get_memory_error_data(struct mem_ctl_info *mci, + continue; + + limit = pvt->info.rir_limit(reg); +- mb = div_u64_rem(limit >> 20, 1000, &kb); ++ gb = div_u64_rem(limit >> 20, 1024, &mb); + edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", + n_rir, +- mb, kb, ++ gb, (mb*1000)/1024, + limit, + 1 << RIR_WAY(reg)); + if (ch_addr <= limit) +diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c +index f599357e8392..826ef3df2dc7 100644 +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -149,6 +149,7 @@ static const struct min_max_quirk min_max_pnpid_table[] = { + }, + { + (const char * const []){"LEN2000", NULL}, ++ {ANY_BOARD_ID, ANY_BOARD_ID}, + 1024, 5113, 2021, 4832 + }, + { +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index 505a9adac2d5..fab0ea1a46d1 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -1870,9 +1870,15 @@ static void free_pt_##LVL (unsigned long __pt) \ + pt = (u64 *)__pt; \ + \ + for (i = 0; i < 512; ++i) { \ ++ /* PTE present? */ \ + if (!IOMMU_PTE_PRESENT(pt[i])) \ + continue; \ + \ ++ /* Large PTE? */ \ ++ if (PM_PTE_LEVEL(pt[i]) == 0 || \ ++ PM_PTE_LEVEL(pt[i]) == 7) \ ++ continue; \ ++ \ + p = (unsigned long)IOMMU_PTE_PAGE(pt[i]); \ + FN(p); \ + } \ +diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c +index 573b53b38af4..bb686e15102c 100644 +--- a/drivers/net/can/dev.c ++++ b/drivers/net/can/dev.c +@@ -360,6 +360,9 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) + struct can_frame *cf = (struct can_frame *)skb->data; + u8 dlc = cf->can_dlc; + ++ if (!(skb->tstamp.tv64)) ++ __net_timestamp(skb); ++ + netif_rx(priv->echo_skb[idx]); + priv->echo_skb[idx] = NULL; + +@@ -496,6 +499,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) + if (unlikely(!skb)) + return NULL; + ++ __net_timestamp(skb); + skb->protocol = htons(ETH_P_CAN); + skb->pkt_type = PACKET_BROADCAST; + skb->ip_summed = CHECKSUM_UNNECESSARY; +@@ -524,6 +528,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, + if (unlikely(!skb)) + return NULL; + ++ __net_timestamp(skb); + skb->protocol = htons(ETH_P_CANFD); + skb->pkt_type = PACKET_BROADCAST; + skb->ip_summed = CHECKSUM_UNNECESSARY; +diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c +index acb5b92ace92..cb6b4723af4a 100644 +--- a/drivers/net/can/slcan.c ++++ b/drivers/net/can/slcan.c +@@ -210,6 +210,7 @@ static void slc_bump(struct slcan *sl) + if (!skb) + return; + ++ __net_timestamp(skb); + skb->dev = sl->dev; + skb->protocol = htons(ETH_P_CAN); + skb->pkt_type = PACKET_BROADCAST; +diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c +index 4e94057ef5cf..30e4627a0c01 100644 +--- a/drivers/net/can/vcan.c ++++ b/drivers/net/can/vcan.c +@@ -81,6 +81,9 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev) + skb->dev = dev; + skb->ip_summed = CHECKSUM_UNNECESSARY; + ++ if (!(skb->tstamp.tv64)) ++ __net_timestamp(skb); ++ + netif_rx_ni(skb); + } + +diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c +index bda52f18e967..397e6b8b9656 100644 +--- a/drivers/s390/kvm/virtio_ccw.c ++++ b/drivers/s390/kvm/virtio_ccw.c +@@ -64,6 +64,7 @@ struct virtio_ccw_device { + bool is_thinint; + bool going_away; + bool device_lost; ++ unsigned int config_ready; + void *airq_info; + }; + +@@ -758,8 +759,11 @@ static void virtio_ccw_get_config(struct virtio_device *vdev, + if (ret) + goto out_free; + +- memcpy(vcdev->config, config_area, sizeof(vcdev->config)); +- memcpy(buf, &vcdev->config[offset], len); ++ memcpy(vcdev->config, config_area, offset + len); ++ if (buf) ++ memcpy(buf, &vcdev->config[offset], len); ++ if (vcdev->config_ready < offset + len) ++ vcdev->config_ready = offset + len; + + out_free: + kfree(config_area); +@@ -782,6 +786,9 @@ static void virtio_ccw_set_config(struct virtio_device *vdev, + if (!config_area) + goto out_free; + ++ /* Make sure we don't overwrite fields. */ ++ if (vcdev->config_ready < offset) ++ virtio_ccw_get_config(vdev, 0, NULL, offset); + memcpy(&vcdev->config[offset], buf, len); + /* Write the config area to the host. */ + memcpy(config_area, vcdev->config, sizeof(vcdev->config)); +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index 11300f7b49cb..daaed7c79e4f 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -311,8 +311,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) + if (rs485conf->flags & SER_RS485_ENABLED) { + dev_dbg(port->dev, "Setting UART to RS485\n"); + atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; +- if ((rs485conf->delay_rts_after_send) > 0) +- UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); ++ UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); + mode |= ATMEL_US_USMODE_RS485; + } else { + dev_dbg(port->dev, "Setting UART to RS232\n"); +@@ -2016,9 +2015,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, + mode &= ~ATMEL_US_USMODE; + + if (atmel_port->rs485.flags & SER_RS485_ENABLED) { +- if ((atmel_port->rs485.delay_rts_after_send) > 0) +- UART_PUT_TTGR(port, +- atmel_port->rs485.delay_rts_after_send); ++ UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_after_send); + mode |= ATMEL_US_USMODE_RS485; + } + +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index 63314ede7ba6..ab9b7ac63407 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -3400,6 +3400,7 @@ done: + static void ffs_closed(struct ffs_data *ffs) + { + struct ffs_dev *ffs_obj; ++ struct f_fs_opts *opts; + + ENTER(); + ffs_dev_lock(); +@@ -3413,8 +3414,13 @@ static void ffs_closed(struct ffs_data *ffs) + if (ffs_obj->ffs_closed_callback) + ffs_obj->ffs_closed_callback(ffs); + +- if (!ffs_obj->opts || ffs_obj->opts->no_configfs +- || !ffs_obj->opts->func_inst.group.cg_item.ci_parent) ++ if (ffs_obj->opts) ++ opts = ffs_obj->opts; ++ else ++ goto done; ++ ++ if (opts->no_configfs || !opts->func_inst.group.cg_item.ci_parent ++ || !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount)) + goto done; + + unregister_gadget_item(ffs_obj->opts-> +diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile +index 2140398a2a8c..2ccd3592d41f 100644 +--- a/drivers/xen/Makefile ++++ b/drivers/xen/Makefile +@@ -2,7 +2,7 @@ ifeq ($(filter y, $(CONFIG_ARM) $(CONFIG_ARM64)),) + obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o + endif + obj-$(CONFIG_X86) += fallback.o +-obj-y += grant-table.o features.o balloon.o manage.o ++obj-y += grant-table.o features.o balloon.o manage.o preempt.o + obj-y += events/ + obj-y += xenbus/ + +diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c +new file mode 100644 +index 000000000000..a1800c150839 +--- /dev/null ++++ b/drivers/xen/preempt.c +@@ -0,0 +1,44 @@ ++/* ++ * Preemptible hypercalls ++ * ++ * Copyright (C) 2014 Citrix Systems R&D ltd. ++ * ++ * This source code is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ */ ++ ++#include <linux/sched.h> ++#include <xen/xen-ops.h> ++ ++#ifndef CONFIG_PREEMPT ++ ++/* ++ * Some hypercalls issued by the toolstack can take many 10s of ++ * seconds. Allow tasks running hypercalls via the privcmd driver to ++ * be voluntarily preempted even if full kernel preemption is ++ * disabled. ++ * ++ * Such preemptible hypercalls are bracketed by ++ * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end() ++ * calls. ++ */ ++ ++DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); ++EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); ++ ++asmlinkage __visible void xen_maybe_preempt_hcall(void) ++{ ++ if (unlikely(__this_cpu_read(xen_in_preemptible_hcall) ++ && should_resched())) { ++ /* ++ * Clear flag as we may be rescheduled on a different ++ * cpu. ++ */ ++ __this_cpu_write(xen_in_preemptible_hcall, false); ++ _cond_resched(); ++ __this_cpu_write(xen_in_preemptible_hcall, true); ++ } ++} ++#endif /* CONFIG_PREEMPT */ +diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c +index 569a13b9e856..59ac71c4a043 100644 +--- a/drivers/xen/privcmd.c ++++ b/drivers/xen/privcmd.c +@@ -56,10 +56,12 @@ static long privcmd_ioctl_hypercall(void __user *udata) + if (copy_from_user(&hypercall, udata, sizeof(hypercall))) + return -EFAULT; + ++ xen_preemptible_hcall_begin(); + ret = privcmd_call(hypercall.op, + hypercall.arg[0], hypercall.arg[1], + hypercall.arg[2], hypercall.arg[3], + hypercall.arg[4]); ++ xen_preemptible_hcall_end(); + + return ret; + } +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index c81ce0c7c1a9..f54511dd287e 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -2920,7 +2920,7 @@ done: + */ + if (!p->leave_spinning) + btrfs_set_path_blocking(p); +- if (ret < 0) ++ if (ret < 0 && !p->skip_release_on_error) + btrfs_release_path(p); + return ret; + } +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index fe69edda11fb..ba5aec76e6f8 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -607,6 +607,7 @@ struct btrfs_path { + unsigned int leave_spinning:1; + unsigned int search_commit_root:1; + unsigned int need_commit_sem:1; ++ unsigned int skip_release_on_error:1; + }; + + /* +@@ -3686,6 +3687,10 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, + int verify_dir_item(struct btrfs_root *root, + struct extent_buffer *leaf, + struct btrfs_dir_item *dir_item); ++struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, ++ struct btrfs_path *path, ++ const char *name, ++ int name_len); + + /* orphan.c */ + int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, +diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c +index fc8df866e919..1752625fb4dd 100644 +--- a/fs/btrfs/dir-item.c ++++ b/fs/btrfs/dir-item.c +@@ -21,10 +21,6 @@ + #include "hash.h" + #include "transaction.h" + +-static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, +- struct btrfs_path *path, +- const char *name, int name_len); +- + /* + * insert a name into a directory, doing overflow properly if there is a hash + * collision. data_size indicates how big the item inserted should be. On +@@ -383,9 +379,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, + * this walks through all the entries in a dir item and finds one + * for a specific name. + */ +-static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, +- struct btrfs_path *path, +- const char *name, int name_len) ++struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, ++ struct btrfs_path *path, ++ const char *name, int name_len) + { + struct btrfs_dir_item *dir_item; + unsigned long name_ptr; +diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c +index 00eacd83ce3d..01bad724b5f7 100644 +--- a/fs/btrfs/xattr.c ++++ b/fs/btrfs/xattr.c +@@ -29,6 +29,7 @@ + #include "xattr.h" + #include "disk-io.h" + #include "props.h" ++#include "locking.h" + + + ssize_t __btrfs_getxattr(struct inode *inode, const char *name, +@@ -91,7 +92,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans, + struct inode *inode, const char *name, + const void *value, size_t size, int flags) + { +- struct btrfs_dir_item *di; ++ struct btrfs_dir_item *di = NULL; + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_path *path; + size_t name_len = strlen(name); +@@ -103,84 +104,119 @@ static int do_setxattr(struct btrfs_trans_handle *trans, + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; ++ path->skip_release_on_error = 1; ++ ++ if (!value) { ++ di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), ++ name, name_len, -1); ++ if (!di && (flags & XATTR_REPLACE)) ++ ret = -ENODATA; ++ else if (di) ++ ret = btrfs_delete_one_dir_name(trans, root, path, di); ++ goto out; ++ } + ++ /* ++ * For a replace we can't just do the insert blindly. ++ * Do a lookup first (read-only btrfs_search_slot), and return if xattr ++ * doesn't exist. If it exists, fall down below to the insert/replace ++ * path - we can't race with a concurrent xattr delete, because the VFS ++ * locks the inode's i_mutex before calling setxattr or removexattr. ++ */ + if (flags & XATTR_REPLACE) { +- di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, +- name_len, -1); +- if (IS_ERR(di)) { +- ret = PTR_ERR(di); +- goto out; +- } else if (!di) { ++ ASSERT(mutex_is_locked(&inode->i_mutex)); ++ di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), ++ name, name_len, 0); ++ if (!di) { + ret = -ENODATA; + goto out; + } +- ret = btrfs_delete_one_dir_name(trans, root, path, di); +- if (ret) +- goto out; + btrfs_release_path(path); ++ di = NULL; ++ } + ++ ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), ++ name, name_len, value, size); ++ if (ret == -EOVERFLOW) { + /* +- * remove the attribute ++ * We have an existing item in a leaf, split_leaf couldn't ++ * expand it. That item might have or not a dir_item that ++ * matches our target xattr, so lets check. + */ +- if (!value) +- goto out; +- } else { +- di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), +- name, name_len, 0); +- if (IS_ERR(di)) { +- ret = PTR_ERR(di); ++ ret = 0; ++ btrfs_assert_tree_locked(path->nodes[0]); ++ di = btrfs_match_dir_item_name(root, path, name, name_len); ++ if (!di && !(flags & XATTR_REPLACE)) { ++ ret = -ENOSPC; + goto out; + } +- if (!di && !value) +- goto out; +- btrfs_release_path(path); ++ } else if (ret == -EEXIST) { ++ ret = 0; ++ di = btrfs_match_dir_item_name(root, path, name, name_len); ++ ASSERT(di); /* logic error */ ++ } else if (ret) { ++ goto out; + } + +-again: +- ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), +- name, name_len, value, size); +- /* +- * If we're setting an xattr to a new value but the new value is say +- * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting +- * back from split_leaf. This is because it thinks we'll be extending +- * the existing item size, but we're asking for enough space to add the +- * item itself. So if we get EOVERFLOW just set ret to EEXIST and let +- * the rest of the function figure it out. +- */ +- if (ret == -EOVERFLOW) ++ if (di && (flags & XATTR_CREATE)) { + ret = -EEXIST; ++ goto out; ++ } + +- if (ret == -EEXIST) { +- if (flags & XATTR_CREATE) +- goto out; ++ if (di) { + /* +- * We can't use the path we already have since we won't have the +- * proper locking for a delete, so release the path and +- * re-lookup to delete the thing. ++ * We're doing a replace, and it must be atomic, that is, at ++ * any point in time we have either the old or the new xattr ++ * value in the tree. We don't want readers (getxattr and ++ * listxattrs) to miss a value, this is specially important ++ * for ACLs. + */ +- btrfs_release_path(path); +- di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), +- name, name_len, -1); +- if (IS_ERR(di)) { +- ret = PTR_ERR(di); +- goto out; +- } else if (!di) { +- /* Shouldn't happen but just in case... */ +- btrfs_release_path(path); +- goto again; ++ const int slot = path->slots[0]; ++ struct extent_buffer *leaf = path->nodes[0]; ++ const u16 old_data_len = btrfs_dir_data_len(leaf, di); ++ const u32 item_size = btrfs_item_size_nr(leaf, slot); ++ const u32 data_size = sizeof(*di) + name_len + size; ++ struct btrfs_item *item; ++ unsigned long data_ptr; ++ char *ptr; ++ ++ if (size > old_data_len) { ++ if (btrfs_leaf_free_space(root, leaf) < ++ (size - old_data_len)) { ++ ret = -ENOSPC; ++ goto out; ++ } + } + +- ret = btrfs_delete_one_dir_name(trans, root, path, di); +- if (ret) +- goto out; ++ if (old_data_len + name_len + sizeof(*di) == item_size) { ++ /* No other xattrs packed in the same leaf item. */ ++ if (size > old_data_len) ++ btrfs_extend_item(root, path, ++ size - old_data_len); ++ else if (size < old_data_len) ++ btrfs_truncate_item(root, path, data_size, 1); ++ } else { ++ /* There are other xattrs packed in the same item. */ ++ ret = btrfs_delete_one_dir_name(trans, root, path, di); ++ if (ret) ++ goto out; ++ btrfs_extend_item(root, path, data_size); ++ } + ++ item = btrfs_item_nr(slot); ++ ptr = btrfs_item_ptr(leaf, slot, char); ++ ptr += btrfs_item_size(leaf, item) - data_size; ++ di = (struct btrfs_dir_item *)ptr; ++ btrfs_set_dir_data_len(leaf, di, size); ++ data_ptr = ((unsigned long)(di + 1)) + name_len; ++ write_extent_buffer(leaf, value, data_ptr, size); ++ btrfs_mark_buffer_dirty(leaf); ++ } else { + /* +- * We have a value to set, so go back and try to insert it now. ++ * Insert, and we had space for the xattr, so path->slots[0] is ++ * where our xattr dir_item is and btrfs_insert_xattr_item() ++ * filled it. + */ +- if (value) { +- btrfs_release_path(path); +- goto again; +- } + } + out: + btrfs_free_path(path); +diff --git a/fs/dcache.c b/fs/dcache.c +index e0750b8f51aa..d0539a4a1ab1 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -2893,17 +2893,6 @@ restart: + vfsmnt = &mnt->mnt; + continue; + } +- /* +- * Filesystems needing to implement special "root names" +- * should do so with ->d_dname() +- */ +- if (IS_ROOT(dentry) && +- (dentry->d_name.len != 1 || +- dentry->d_name.name[0] != '/')) { +- WARN(1, "Root dentry has weird name <%.*s>\n", +- (int) dentry->d_name.len, +- dentry->d_name.name); +- } + if (!error) + error = is_mounted(vfsmnt) ? 1 : 2; + break; +diff --git a/fs/inode.c b/fs/inode.c +index 26753ba7b6d6..56d1d2b4bf31 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1631,8 +1631,8 @@ int file_remove_suid(struct file *file) + error = security_inode_killpriv(dentry); + if (!error && killsuid) + error = __remove_suid(dentry, killsuid); +- if (!error && (inode->i_sb->s_flags & MS_NOSEC)) +- inode->i_flags |= S_NOSEC; ++ if (!error) ++ inode_has_no_xattr(inode); + + return error; + } +diff --git a/fs/namespace.c b/fs/namespace.c +index a19d05c4ebe5..da23ad8a2c85 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -2297,6 +2297,8 @@ unlock: + return err; + } + ++static bool fs_fully_visible(struct file_system_type *fs_type, int *new_mnt_flags); ++ + /* + * create a new mount for userspace and request it to be added into the + * namespace's tree +@@ -2328,6 +2330,10 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, + flags |= MS_NODEV; + mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV; + } ++ if (type->fs_flags & FS_USERNS_VISIBLE) { ++ if (!fs_fully_visible(type, &mnt_flags)) ++ return -EPERM; ++ } + } + + mnt = vfs_kern_mount(type, flags, name, data); +@@ -3125,9 +3131,10 @@ bool current_chrooted(void) + return chrooted; + } + +-bool fs_fully_visible(struct file_system_type *type) ++static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags) + { + struct mnt_namespace *ns = current->nsproxy->mnt_ns; ++ int new_flags = *new_mnt_flags; + struct mount *mnt; + bool visible = false; + +@@ -3146,16 +3153,37 @@ bool fs_fully_visible(struct file_system_type *type) + if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) + continue; + +- /* This mount is not fully visible if there are any child mounts +- * that cover anything except for empty directories. ++ /* Verify the mount flags are equal to or more permissive ++ * than the proposed new mount. ++ */ ++ if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) && ++ !(new_flags & MNT_READONLY)) ++ continue; ++ if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) && ++ !(new_flags & MNT_NODEV)) ++ continue; ++ if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) && ++ ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK))) ++ continue; ++ ++ /* This mount is not fully visible if there are any ++ * locked child mounts that cover anything except for ++ * empty directories. + */ + list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) { + struct inode *inode = child->mnt_mountpoint->d_inode; ++ /* Only worry about locked mounts */ ++ if (!(mnt->mnt.mnt_flags & MNT_LOCKED)) ++ continue; + if (!S_ISDIR(inode->i_mode)) + goto next; + if (inode->i_nlink > 2) + goto next; + } ++ /* Preserve the locked attributes */ ++ *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \ ++ MNT_LOCK_NODEV | \ ++ MNT_LOCK_ATIME); + visible = true; + goto found; + next: ; +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index b13edc0865f7..c9ff4a176a25 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5356,7 +5356,6 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, + atomic_inc(&lsp->ls_count); + /* Ensure we don't close file until we're done freeing locks! */ + p->ctx = get_nfs_open_context(ctx); +- get_file(fl->fl_file); + memcpy(&p->fl, fl, sizeof(p->fl)); + p->server = NFS_SERVER(inode); + return p; +@@ -5368,7 +5367,6 @@ static void nfs4_locku_release_calldata(void *data) + nfs_free_seqid(calldata->arg.seqid); + nfs4_put_lock_state(calldata->lsp); + put_nfs_open_context(calldata->ctx); +- fput(calldata->fl.fl_file); + kfree(calldata); + } + +diff --git a/fs/proc/root.c b/fs/proc/root.c +index 094e44d4a6be..9e772f1a5386 100644 +--- a/fs/proc/root.c ++++ b/fs/proc/root.c +@@ -112,9 +112,6 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, + ns = task_active_pid_ns(current); + options = data; + +- if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type)) +- return ERR_PTR(-EPERM); +- + /* Does the mounter have privilege over the pid namespace? */ + if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN)) + return ERR_PTR(-EPERM); +@@ -159,7 +156,7 @@ static struct file_system_type proc_fs_type = { + .name = "proc", + .mount = proc_mount, + .kill_sb = proc_kill_sb, +- .fs_flags = FS_USERNS_MOUNT, ++ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT, + }; + + void __init proc_root_init(void) +diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c +index 8a49486bf30c..1c6ac6fcee9f 100644 +--- a/fs/sysfs/mount.c ++++ b/fs/sysfs/mount.c +@@ -31,9 +31,6 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, + bool new_sb; + + if (!(flags & MS_KERNMOUNT)) { +- if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type)) +- return ERR_PTR(-EPERM); +- + if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET)) + return ERR_PTR(-EPERM); + } +@@ -58,7 +55,7 @@ static struct file_system_type sysfs_fs_type = { + .name = "sysfs", + .mount = sysfs_mount, + .kill_sb = sysfs_kill_sb, +- .fs_flags = FS_USERNS_MOUNT, ++ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT, + }; + + int __init sysfs_init(void) +diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c +index 2c1036080d52..a7106eda5024 100644 +--- a/fs/ufs/balloc.c ++++ b/fs/ufs/balloc.c +@@ -51,8 +51,8 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) + + if (ufs_fragnum(fragment) + count > uspi->s_fpg) + ufs_error (sb, "ufs_free_fragments", "internal error"); +- +- lock_ufs(sb); ++ ++ mutex_lock(&UFS_SB(sb)->s_lock); + + cgno = ufs_dtog(uspi, fragment); + bit = ufs_dtogd(uspi, fragment); +@@ -115,13 +115,13 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) + if (sb->s_flags & MS_SYNCHRONOUS) + ubh_sync_block(UCPI_UBH(ucpi)); + ufs_mark_sb_dirty(sb); +- +- unlock_ufs(sb); ++ ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT\n"); + return; + + failed: +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT (FAILED)\n"); + return; + } +@@ -151,7 +151,7 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count) + goto failed; + } + +- lock_ufs(sb); ++ mutex_lock(&UFS_SB(sb)->s_lock); + + do_more: + overflow = 0; +@@ -211,12 +211,12 @@ do_more: + } + + ufs_mark_sb_dirty(sb); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT\n"); + return; + + failed_unlock: +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + failed: + UFSD("EXIT (FAILED)\n"); + return; +@@ -357,7 +357,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, + usb1 = ubh_get_usb_first(uspi); + *err = -ENOSPC; + +- lock_ufs(sb); ++ mutex_lock(&UFS_SB(sb)->s_lock); + tmp = ufs_data_ptr_to_cpu(sb, p); + + if (count + ufs_fragnum(fragment) > uspi->s_fpb) { +@@ -378,19 +378,19 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, + "fragment %llu, tmp %llu\n", + (unsigned long long)fragment, + (unsigned long long)tmp); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + return INVBLOCK; + } + if (fragment < UFS_I(inode)->i_lastfrag) { + UFSD("EXIT (ALREADY ALLOCATED)\n"); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + return 0; + } + } + else { + if (tmp) { + UFSD("EXIT (ALREADY ALLOCATED)\n"); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + return 0; + } + } +@@ -399,7 +399,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, + * There is not enough space for user on the device + */ + if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT (FAILED)\n"); + return 0; + } +@@ -424,7 +424,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, + ufs_clear_frags(inode, result + oldcount, + newcount - oldcount, locked_page != NULL); + } +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT, result %llu\n", (unsigned long long)result); + return result; + } +@@ -439,7 +439,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, + fragment + count); + ufs_clear_frags(inode, result + oldcount, newcount - oldcount, + locked_page != NULL); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT, result %llu\n", (unsigned long long)result); + return result; + } +@@ -477,7 +477,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, + *err = 0; + UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, + fragment + count); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + if (newcount < request) + ufs_free_fragments (inode, result + newcount, request - newcount); + ufs_free_fragments (inode, tmp, oldcount); +@@ -485,7 +485,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, + return result; + } + +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT (FAILED)\n"); + return 0; + } +diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c +index 7caa01652888..fd0203ce1f7f 100644 +--- a/fs/ufs/ialloc.c ++++ b/fs/ufs/ialloc.c +@@ -69,11 +69,11 @@ void ufs_free_inode (struct inode * inode) + + ino = inode->i_ino; + +- lock_ufs(sb); ++ mutex_lock(&UFS_SB(sb)->s_lock); + + if (!((ino > 1) && (ino < (uspi->s_ncg * uspi->s_ipg )))) { + ufs_warning(sb, "ufs_free_inode", "reserved inode or nonexistent inode %u\n", ino); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + return; + } + +@@ -81,7 +81,7 @@ void ufs_free_inode (struct inode * inode) + bit = ufs_inotocgoff (ino); + ucpi = ufs_load_cylinder (sb, cg); + if (!ucpi) { +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + return; + } + ucg = ubh_get_ucg(UCPI_UBH(ucpi)); +@@ -115,7 +115,7 @@ void ufs_free_inode (struct inode * inode) + ubh_sync_block(UCPI_UBH(ucpi)); + + ufs_mark_sb_dirty(sb); +- unlock_ufs(sb); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + UFSD("EXIT\n"); + } + +@@ -193,7 +193,7 @@ struct inode *ufs_new_inode(struct inode *dir, umode_t mode) + sbi = UFS_SB(sb); + uspi = sbi->s_uspi; + +- lock_ufs(sb); ++ mutex_lock(&sbi->s_lock); + + /* + * Try to place the inode in its parent directory +@@ -331,21 +331,21 @@ cg_found: + sync_dirty_buffer(bh); + brelse(bh); + } +- unlock_ufs(sb); ++ mutex_unlock(&sbi->s_lock); + + UFSD("allocating inode %lu\n", inode->i_ino); + UFSD("EXIT\n"); + return inode; + + fail_remove_inode: +- unlock_ufs(sb); ++ mutex_unlock(&sbi->s_lock); + clear_nlink(inode); + unlock_new_inode(inode); + iput(inode); + UFSD("EXIT (FAILED): err %d\n", err); + return ERR_PTR(err); + failed: +- unlock_ufs(sb); ++ mutex_unlock(&sbi->s_lock); + make_bad_inode(inode); + iput (inode); + UFSD("EXIT (FAILED): err %d\n", err); +diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c +index be7d42c7d938..2d93ab07da8a 100644 +--- a/fs/ufs/inode.c ++++ b/fs/ufs/inode.c +@@ -902,6 +902,9 @@ void ufs_evict_inode(struct inode * inode) + invalidate_inode_buffers(inode); + clear_inode(inode); + +- if (want_delete) ++ if (want_delete) { ++ lock_ufs(inode->i_sb); + ufs_free_inode(inode); ++ unlock_ufs(inode->i_sb); ++ } + } +diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c +index fd65deb4b5f0..e8ee2985b068 100644 +--- a/fs/ufs/namei.c ++++ b/fs/ufs/namei.c +@@ -128,12 +128,12 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, + if (l > sb->s_blocksize) + goto out_notlocked; + ++ lock_ufs(dir->i_sb); + inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); + err = PTR_ERR(inode); + if (IS_ERR(inode)) +- goto out_notlocked; ++ goto out; + +- lock_ufs(dir->i_sb); + if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { + /* slow symlink */ + inode->i_op = &ufs_symlink_inode_operations; +@@ -174,7 +174,12 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, + inode_inc_link_count(inode); + ihold(inode); + +- error = ufs_add_nondir(dentry, inode); ++ error = ufs_add_link(dentry, inode); ++ if (error) { ++ inode_dec_link_count(inode); ++ iput(inode); ++ } else ++ d_instantiate(dentry, inode); + unlock_ufs(dir->i_sb); + return error; + } +@@ -184,9 +189,13 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) + struct inode * inode; + int err; + ++ lock_ufs(dir->i_sb); ++ inode_inc_link_count(dir); ++ + inode = ufs_new_inode(dir, S_IFDIR|mode); ++ err = PTR_ERR(inode); + if (IS_ERR(inode)) +- return PTR_ERR(inode); ++ goto out_dir; + + inode->i_op = &ufs_dir_inode_operations; + inode->i_fop = &ufs_dir_operations; +@@ -194,9 +203,6 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) + + inode_inc_link_count(inode); + +- lock_ufs(dir->i_sb); +- inode_inc_link_count(dir); +- + err = ufs_make_empty(inode, dir); + if (err) + goto out_fail; +@@ -206,6 +212,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) + goto out_fail; + unlock_ufs(dir->i_sb); + ++ unlock_new_inode(inode); + d_instantiate(dentry, inode); + out: + return err; +@@ -215,6 +222,7 @@ out_fail: + inode_dec_link_count(inode); + unlock_new_inode(inode); + iput (inode); ++out_dir: + inode_dec_link_count(dir); + unlock_ufs(dir->i_sb); + goto out; +diff --git a/fs/ufs/super.c b/fs/ufs/super.c +index da73801301d5..ce02dff5572f 100644 +--- a/fs/ufs/super.c ++++ b/fs/ufs/super.c +@@ -698,6 +698,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait) + unsigned flags; + + lock_ufs(sb); ++ mutex_lock(&UFS_SB(sb)->s_lock); + + UFSD("ENTER\n"); + +@@ -715,6 +716,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait) + ufs_put_cstotal(sb); + + UFSD("EXIT\n"); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + + return 0; +@@ -803,6 +805,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) + UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); + + mutex_init(&sbi->mutex); ++ mutex_init(&sbi->s_lock); + spin_lock_init(&sbi->work_lock); + INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs); + /* +@@ -1281,6 +1284,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) + + sync_filesystem(sb); + lock_ufs(sb); ++ mutex_lock(&UFS_SB(sb)->s_lock); + uspi = UFS_SB(sb)->s_uspi; + flags = UFS_SB(sb)->s_flags; + usb1 = ubh_get_usb_first(uspi); +@@ -1294,6 +1298,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) + new_mount_opt = 0; + ufs_set_opt (new_mount_opt, ONERROR_LOCK); + if (!ufs_parse_options (data, &new_mount_opt)) { ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + return -EINVAL; + } +@@ -1301,12 +1306,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) + new_mount_opt |= ufstype; + } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { + pr_err("ufstype can't be changed during remount\n"); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + return -EINVAL; + } + + if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { + UFS_SB(sb)->s_mount_opt = new_mount_opt; ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + return 0; + } +@@ -1330,6 +1337,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) + */ + #ifndef CONFIG_UFS_FS_WRITE + pr_err("ufs was compiled with read-only support, can't be mounted as read-write\n"); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + return -EINVAL; + #else +@@ -1339,11 +1347,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) + ufstype != UFS_MOUNT_UFSTYPE_SUNx86 && + ufstype != UFS_MOUNT_UFSTYPE_UFS2) { + pr_err("this ufstype is read-only supported\n"); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + return -EINVAL; + } + if (!ufs_read_cylinder_structures(sb)) { + pr_err("failed during remounting\n"); ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + return -EPERM; + } +@@ -1351,6 +1361,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) + #endif + } + UFS_SB(sb)->s_mount_opt = new_mount_opt; ++ mutex_unlock(&UFS_SB(sb)->s_lock); + unlock_ufs(sb); + return 0; + } +diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h +index 2a07396d5f9e..cf6368d42d4a 100644 +--- a/fs/ufs/ufs.h ++++ b/fs/ufs/ufs.h +@@ -30,6 +30,7 @@ struct ufs_sb_info { + int work_queued; /* non-zero if the delayed work is queued */ + struct delayed_work sync_work; /* FS sync delayed work */ + spinlock_t work_lock; /* protects sync_work and work_queued */ ++ struct mutex s_lock; + }; + + struct ufs_inode_info { +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 9ab779e8a63c..84d672914bd8 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1791,6 +1791,7 @@ struct file_system_type { + #define FS_HAS_SUBTYPE 4 + #define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */ + #define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */ ++#define FS_USERNS_VISIBLE 32 /* FS must already be visible */ + #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ + struct dentry *(*mount) (struct file_system_type *, int, + const char *, void *); +@@ -1878,7 +1879,6 @@ extern int vfs_ustat(dev_t, struct kstatfs *); + extern int freeze_super(struct super_block *super); + extern int thaw_super(struct super_block *super); + extern bool our_mnt(struct vfsmount *mnt); +-extern bool fs_fully_visible(struct file_system_type *); + + extern int current_umask(void); + +diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h +index 7491ee5d8164..83338210ee04 100644 +--- a/include/xen/xen-ops.h ++++ b/include/xen/xen-ops.h +@@ -46,4 +46,30 @@ static inline efi_system_table_t __init *xen_efi_probe(void) + } + #endif + ++#ifdef CONFIG_PREEMPT ++ ++static inline void xen_preemptible_hcall_begin(void) ++{ ++} ++ ++static inline void xen_preemptible_hcall_end(void) ++{ ++} ++ ++#else ++ ++DECLARE_PER_CPU(bool, xen_in_preemptible_hcall); ++ ++static inline void xen_preemptible_hcall_begin(void) ++{ ++ __this_cpu_write(xen_in_preemptible_hcall, true); ++} ++ ++static inline void xen_preemptible_hcall_end(void) ++{ ++ __this_cpu_write(xen_in_preemptible_hcall, false); ++} ++ ++#endif /* CONFIG_PREEMPT */ ++ + #endif /* INCLUDE_XEN_OPS_H */ +diff --git a/kernel/events/core.c b/kernel/events/core.c +index e631dacdb165..cb86038cad47 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -4057,20 +4057,20 @@ static void ring_buffer_attach(struct perf_event *event, + WARN_ON_ONCE(event->rcu_pending); + + old_rb = event->rb; +- event->rcu_batches = get_state_synchronize_rcu(); +- event->rcu_pending = 1; +- + spin_lock_irqsave(&old_rb->event_lock, flags); + list_del_rcu(&event->rb_entry); + spin_unlock_irqrestore(&old_rb->event_lock, flags); +- } + +- if (event->rcu_pending && rb) { +- cond_synchronize_rcu(event->rcu_batches); +- event->rcu_pending = 0; ++ event->rcu_batches = get_state_synchronize_rcu(); ++ event->rcu_pending = 1; + } + + if (rb) { ++ if (event->rcu_pending) { ++ cond_synchronize_rcu(event->rcu_batches); ++ event->rcu_pending = 0; ++ } ++ + spin_lock_irqsave(&rb->event_lock, flags); + list_add_rcu(&event->rb_entry, &rb->event_list); + spin_unlock_irqrestore(&rb->event_lock, flags); +diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c +index bcb9145a7913..51afcb76d32b 100644 +--- a/kernel/trace/trace_events_filter.c ++++ b/kernel/trace/trace_events_filter.c +@@ -1369,19 +1369,24 @@ static int check_preds(struct filter_parse_state *ps) + { + int n_normal_preds = 0, n_logical_preds = 0; + struct postfix_elt *elt; ++ int cnt = 0; + + list_for_each_entry(elt, &ps->postfix, list) { +- if (elt->op == OP_NONE) ++ if (elt->op == OP_NONE) { ++ cnt++; + continue; ++ } + ++ cnt--; + if (elt->op == OP_AND || elt->op == OP_OR) { + n_logical_preds++; + continue; + } + n_normal_preds++; ++ WARN_ON_ONCE(cnt < 0); + } + +- if (!n_normal_preds || n_logical_preds >= n_normal_preds) { ++ if (cnt != 1 || !n_normal_preds || n_logical_preds >= n_normal_preds) { + parse_error(ps, FILT_ERR_INVALID_FILTER, 0); + return -EINVAL; + } +diff --git a/net/can/af_can.c b/net/can/af_can.c +index d6030d6949df..9a3244941a5c 100644 +--- a/net/can/af_can.c ++++ b/net/can/af_can.c +@@ -313,8 +313,12 @@ int can_send(struct sk_buff *skb, int loop) + return err; + } + +- if (newskb) ++ if (newskb) { ++ if (!(newskb->tstamp.tv64)) ++ __net_timestamp(newskb); ++ + netif_rx_ni(newskb); ++ } + + /* update statistics */ + can_stats.tx_frames++; +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 24d3242f0e01..c522f7a00eab 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -2229,9 +2229,6 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, + int err = -ENOBUFS; + size_t if_info_size; + +- if (dev->reg_state != NETREG_REGISTERED) +- return; +- + skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags); + if (skb == NULL) + goto errout; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 71b574c7bde9..9fe2baa01fbe 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -1221,7 +1221,10 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, + + if (nla[NFTA_CHAIN_POLICY]) { + if ((chain != NULL && +- !(chain->flags & NFT_BASE_CHAIN)) || ++ !(chain->flags & NFT_BASE_CHAIN))) ++ return -EOPNOTSUPP; ++ ++ if (chain == NULL && + nla[NFTA_CHAIN_HOOK] == NULL) + return -EOPNOTSUPP; + +diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c +index 9e287cb56a04..54330fb5efaf 100644 +--- a/net/netfilter/nfnetlink_cthelper.c ++++ b/net/netfilter/nfnetlink_cthelper.c +@@ -77,6 +77,9 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, + if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) + return -EINVAL; + ++ /* Not all fields are initialized so first zero the tuple */ ++ memset(tuple, 0, sizeof(struct nf_conntrack_tuple)); ++ + tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM])); + tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); + +@@ -86,7 +89,7 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, + static int + nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) + { +- const struct nf_conn_help *help = nfct_help(ct); ++ struct nf_conn_help *help = nfct_help(ct); + + if (attr == NULL) + return -EINVAL; +@@ -94,7 +97,7 @@ nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) + if (help->helper->data_len == 0) + return -EINVAL; + +- memcpy(&help->data, nla_data(attr), help->helper->data_len); ++ memcpy(help->data, nla_data(attr), help->helper->data_len); + return 0; + } + +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index 265e190f2218..e22a2961cc39 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -97,6 +97,9 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par, + entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; + break; + case AF_INET6: ++ if (proto) ++ entry->e6.ipv6.flags |= IP6T_F_PROTO; ++ + entry->e6.ipv6.proto = proto; + entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; + break; +@@ -304,6 +307,9 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, + entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; + break; + case AF_INET6: ++ if (proto) ++ entry->e6.ipv6.flags |= IP6T_F_PROTO; ++ + entry->e6.ipv6.proto = proto; + entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; + break; +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index c603b20356ad..b1e455b47b82 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -405,7 +405,8 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) + + if (sbsec->behavior == SECURITY_FS_USE_XATTR || + sbsec->behavior == SECURITY_FS_USE_TRANS || +- sbsec->behavior == SECURITY_FS_USE_TASK) ++ sbsec->behavior == SECURITY_FS_USE_TASK || ++ sbsec->behavior == SECURITY_FS_USE_NATIVE) + return 1; + + /* Special handling for sysfs. Is genfs but also has setxattr handler*/