From fd6f186bf0279077f91786fe4907d010536e8907 Mon Sep 17 00:00:00 2001 From: Jake Day Date: Sun, 12 Nov 2017 19:29:17 -0500 Subject: [PATCH] updating to mainline 4.14.0 --- kernel/.mailmap | 1 + kernel/CREDITS | 9 +- kernel/MAINTAINERS | 30 +- kernel/Makefile | 2 +- kernel/arch/arm/kernel/traps.c | 28 +- kernel/arch/mips/ar7/platform.c | 5 + kernel/arch/mips/ar7/prom.c | 2 - kernel/arch/mips/kernel/smp-bmips.c | 4 +- kernel/arch/powerpc/kvm/book3s_64_mmu_hv.c | 10 + kernel/arch/powerpc/kvm/book3s_hv.c | 29 +- .../crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S | 12 +- .../sha256-mb/sha256_mb_mgr_flush_avx2.S | 12 +- kernel/arch/x86/include/asm/elf.h | 2 +- kernel/arch/x86/kernel/cpu/Makefile | 2 +- kernel/arch/x86/kernel/cpu/aperfmperf.c | 11 +- kernel/arch/x86/kernel/cpu/proc.c | 4 +- kernel/arch/x86/kernel/idt.c | 2 - kernel/arch/x86/kernel/smpboot.c | 11 +- kernel/arch/x86/kernel/traps.c | 10 +- kernel/arch/x86/kernel/tsc.c | 8 +- kernel/arch/x86/kernel/unwind_orc.c | 2 +- kernel/arch/x86/mm/mem_encrypt.c | 2 +- kernel/arch/x86/oprofile/op_model_ppro.c | 4 +- kernel/crypto/ccm.c | 4 +- kernel/drivers/acpi/sleep.c | 28 ++ kernel/drivers/block/rbd.c | 4 +- .../gpu/drm/i915/i915_gem_execbuffer.c | 8 + kernel/drivers/gpu/drm/i915/i915_gem_gtt.c | 25 +- kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- kernel/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- kernel/drivers/ide/ide-cd.c | 7 +- kernel/drivers/input/mouse/elan_i2c_core.c | 1 + kernel/drivers/input/rmi4/rmi_smbus.c | 4 +- .../drivers/input/touchscreen/tsc200x-core.c | 1 + kernel/drivers/net/bonding/bond_main.c | 3 +- kernel/drivers/net/can/c_can/c_can_pci.c | 1 - kernel/drivers/net/can/c_can/c_can_platform.c | 1 - kernel/drivers/net/can/ifi_canfd/ifi_canfd.c | 6 +- .../net/can/peak_canfd/peak_pciefd_main.c | 14 +- kernel/drivers/net/can/sun4i_can.c | 12 +- .../net/ethernet/chelsio/cxgb4/t4fw_version.h | 6 +- kernel/drivers/net/ethernet/marvell/mvpp2.c | 4 + .../net/ethernet/mellanox/mlx5/core/dev.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en.h | 2 +- .../net/ethernet/mellanox/mlx5/core/en_fs.c | 13 +- .../net/ethernet/mellanox/mlx5/core/en_rx.c | 12 +- .../net/ethernet/mellanox/mlx5/core/en_txrx.c | 10 +- .../net/ethernet/mellanox/mlx5/core/main.c | 7 + kernel/drivers/net/usb/asix_devices.c | 4 +- kernel/drivers/net/usb/cdc_ether.c | 2 +- kernel/drivers/net/usb/qmi_wwan.c | 3 +- kernel/drivers/scsi/scsi_lib.c | 3 - kernel/drivers/scsi/scsi_transport_srp.c | 5 +- kernel/include/linux/skbuff.h | 7 + kernel/include/linux/sysctl.h | 5 + kernel/include/net/act_api.h | 4 +- kernel/include/net/pkt_cls.h | 24 ++ kernel/include/sound/seq_kernel.h | 3 +- kernel/include/sound/timer.h | 2 + kernel/include/uapi/drm/i915_drm.h | 1 + kernel/kernel/.cocciconfig | 3 + kernel/kernel/.gitignore | 120 ++++++- kernel/kernel/.mailmap | 191 +++++++++++ kernel/kernel/sched/cpufreq_schedutil.c | 6 +- kernel/kernel/workqueue_internal.h | 3 +- kernel/lib/asn1_decoder.c | 4 +- kernel/net/8021q/vlan.c | 6 +- kernel/net/core/skbuff.c | 1 + kernel/net/dsa/switch.c | 4 + kernel/net/ipv4/tcp_input.c | 5 +- kernel/net/ipv4/tcp_offload.c | 12 +- kernel/net/l2tp/l2tp_ip.c | 24 +- kernel/net/l2tp/l2tp_ip6.c | 24 +- kernel/net/qrtr/qrtr.c | 2 +- kernel/net/rds/ib_recv.c | 10 +- kernel/net/sched/act_api.c | 2 - kernel/net/sched/act_bpf.c | 2 +- kernel/net/sched/act_connmark.c | 2 +- kernel/net/sched/act_csum.c | 2 +- kernel/net/sched/act_gact.c | 2 +- kernel/net/sched/act_ife.c | 2 +- kernel/net/sched/act_ipt.c | 4 +- kernel/net/sched/act_mirred.c | 2 +- kernel/net/sched/act_nat.c | 2 +- kernel/net/sched/act_pedit.c | 2 +- kernel/net/sched/act_police.c | 2 +- kernel/net/sched/act_sample.c | 2 +- kernel/net/sched/act_simple.c | 2 +- kernel/net/sched/act_skbedit.c | 2 +- kernel/net/sched/act_skbmod.c | 2 +- kernel/net/sched/act_tunnel_key.c | 2 +- kernel/net/sched/act_vlan.c | 2 +- kernel/net/sched/cls_api.c | 1 + kernel/net/sched/cls_basic.c | 20 +- kernel/net/sched/cls_bpf.c | 7 +- kernel/net/sched/cls_cgroup.c | 24 +- kernel/net/sched/cls_flow.c | 24 +- kernel/net/sched/cls_flower.c | 16 +- kernel/net/sched/cls_fw.c | 17 +- kernel/net/sched/cls_matchall.c | 15 +- kernel/net/sched/cls_route.c | 17 +- kernel/net/sched/cls_rsvp.h | 15 +- kernel/net/sched/cls_tcindex.c | 33 +- kernel/net/sched/cls_u32.c | 8 +- kernel/net/xfrm/xfrm_input.c | 4 +- kernel/net/xfrm/xfrm_policy.c | 79 +++-- kernel/scripts/leaking_addresses.pl | 305 ++++++++++++++++++ kernel/security/apparmor/ipc.c | 4 +- kernel/sound/core/hrtimer.c | 1 + kernel/sound/core/seq/oss/seq_oss_midi.c | 4 +- kernel/sound/core/seq/oss/seq_oss_readq.c | 29 ++ kernel/sound/core/seq/oss/seq_oss_readq.h | 2 + kernel/sound/core/timer.c | 67 +++- kernel/sound/pci/hda/patch_realtek.c | 5 + kernel/sound/usb/quirks.c | 1 + kernel/tools/include/uapi/drm/i915_drm.h | 1 + kernel/tools/perf/builtin-trace.c | 10 + kernel/tools/perf/util/parse-events.l | 5 +- 118 files changed, 1278 insertions(+), 331 deletions(-) create mode 100644 kernel/kernel/.cocciconfig create mode 100644 kernel/kernel/.mailmap create mode 100644 kernel/scripts/leaking_addresses.pl diff --git a/kernel/.mailmap b/kernel/.mailmap index 4757d361f..c021f2977 100644 --- a/kernel/.mailmap +++ b/kernel/.mailmap @@ -102,6 +102,7 @@ Leonid I Ananiev Linas Vepstas Linus Lüssing Linus Lüssing +Maciej W. Rozycki Marcin Nowakowski Mark Brown Martin Kepplinger diff --git a/kernel/CREDITS b/kernel/CREDITS index 9fbd2c77b..a3ec0c744 100644 --- a/kernel/CREDITS +++ b/kernel/CREDITS @@ -2113,6 +2113,10 @@ S: J. Obrechtstr 23 S: NL-5216 GP 's-Hertogenbosch S: The Netherlands +N: Ashley Lai +E: ashleydlai@gmail.com +D: IBM VTPM driver + N: Savio Lam E: lam836@cs.cuhk.hk D: Author of the dialog utility, foundation @@ -3333,6 +3337,10 @@ S: Braunschweiger Strasse 79 S: 31134 Hildesheim S: Germany +N: Marcel Selhorst +E: tpmdd@selhorst.net +D: TPM driver + N: Darren Senn E: sinster@darkwater.com D: Whatever I notice needs doing (so far: itimers, /proc) @@ -4128,7 +4136,6 @@ D: MD driver D: EISA/sysfs subsystem S: France - # Don't add your name here, unless you really _are_ after Marc # alphabetically. Leonard used to be very proud of being the # last entry, and he'll get positively pissed if he can't even diff --git a/kernel/MAINTAINERS b/kernel/MAINTAINERS index 2f4e462aa..2811a2116 100644 --- a/kernel/MAINTAINERS +++ b/kernel/MAINTAINERS @@ -7745,6 +7745,11 @@ S: Maintained F: Documentation/scsi/53c700.txt F: drivers/scsi/53c700* +LEAKING_ADDRESSES +M: Tobin C. Harding +S: Maintained +F: scripts/leaking_addresses.pl + LED SUBSYSTEM M: Richard Purdie M: Jacek Anaszewski @@ -10336,7 +10341,6 @@ F: drivers/pci/host/vmd.c PCI DRIVER FOR MICROSEMI SWITCHTEC M: Kurt Schwemmer -M: Stephen Bates M: Logan Gunthorpe L: linux-pci@vger.kernel.org S: Maintained @@ -10401,6 +10405,7 @@ F: drivers/pci/dwc/*keystone* PCI ENDPOINT SUBSYSTEM M: Kishon Vijay Abraham I +M: Lorenzo Pieralisi L: linux-pci@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git S: Supported @@ -10452,6 +10457,15 @@ F: include/linux/pci* F: arch/x86/pci/ F: arch/x86/kernel/quirks.c +PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS +M: Lorenzo Pieralisi +L: linux-pci@vger.kernel.org +Q: http://patchwork.ozlabs.org/project/linux-pci/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/ +S: Supported +F: drivers/pci/host/ +F: drivers/pci/dwc/ + PCIE DRIVER FOR AXIS ARTPEC M: Niklas Cassel M: Jesper Nilsson @@ -10471,7 +10485,6 @@ F: drivers/pci/host/pci-thunder-* PCIE DRIVER FOR HISILICON M: Zhou Wang -M: Gabriele Paoloni L: linux-pci@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt @@ -13598,23 +13611,14 @@ F: drivers/platform/x86/toshiba-wmi.c TPM DEVICE DRIVER M: Peter Huewe -M: Marcel Selhorst M: Jarkko Sakkinen R: Jason Gunthorpe -W: http://tpmdd.sourceforge.net -L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) -Q: https://patchwork.kernel.org/project/tpmdd-devel/list/ +L: linux-integrity@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-integrity/list/ T: git git://git.infradead.org/users/jjs/linux-tpmdd.git S: Maintained F: drivers/char/tpm/ -TPM IBM_VTPM DEVICE DRIVER -M: Ashley Lai -W: http://tpmdd.sourceforge.net -L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) -S: Maintained -F: drivers/char/tpm/tpm_ibmvtpm* - TRACING M: Steven Rostedt M: Ingo Molnar diff --git a/kernel/Makefile b/kernel/Makefile index bee2033e7..ccd981892 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -2,7 +2,7 @@ VERSION = 4 PATCHLEVEL = 14 SUBLEVEL = 0 -EXTRAVERSION = -rc8 +EXTRAVERSION = NAME = Fearless Coyote # *DOCUMENTATION* diff --git a/kernel/arch/arm/kernel/traps.c b/kernel/arch/arm/kernel/traps.c index 948c648fe..0fcd82f01 100644 --- a/kernel/arch/arm/kernel/traps.c +++ b/kernel/arch/arm/kernel/traps.c @@ -154,30 +154,26 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, set_fs(fs); } -static void dump_instr(const char *lvl, struct pt_regs *regs) +static void __dump_instr(const char *lvl, struct pt_regs *regs) { unsigned long addr = instruction_pointer(regs); const int thumb = thumb_mode(regs); const int width = thumb ? 4 : 8; - mm_segment_t fs; char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; int i; /* - * We need to switch to kernel mode so that we can use __get_user - * to safely read from kernel space. Note that we now dump the - * code first, just in case the backtrace kills us. + * Note that we now dump the code first, just in case the backtrace + * kills us. */ - fs = get_fs(); - set_fs(KERNEL_DS); for (i = -4; i < 1 + !!thumb; i++) { unsigned int val, bad; if (thumb) - bad = __get_user(val, &((u16 *)addr)[i]); + bad = get_user(val, &((u16 *)addr)[i]); else - bad = __get_user(val, &((u32 *)addr)[i]); + bad = get_user(val, &((u32 *)addr)[i]); if (!bad) p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ", @@ -188,8 +184,20 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) } } printk("%sCode: %s\n", lvl, str); +} - set_fs(fs); +static void dump_instr(const char *lvl, struct pt_regs *regs) +{ + mm_segment_t fs; + + if (!user_mode(regs)) { + fs = get_fs(); + set_fs(KERNEL_DS); + __dump_instr(lvl, regs); + set_fs(fs); + } else { + __dump_instr(lvl, regs); + } } #ifdef CONFIG_ARM_UNWIND diff --git a/kernel/arch/mips/ar7/platform.c b/kernel/arch/mips/ar7/platform.c index df7acea37..4674f1efb 100644 --- a/kernel/arch/mips/ar7/platform.c +++ b/kernel/arch/mips/ar7/platform.c @@ -575,6 +575,7 @@ static int __init ar7_register_uarts(void) uart_port.type = PORT_AR7; uart_port.uartclk = clk_get_rate(bus_clk) / 2; uart_port.iotype = UPIO_MEM32; + uart_port.flags = UPF_FIXED_TYPE; uart_port.regshift = 2; uart_port.line = 0; @@ -653,6 +654,10 @@ static int __init ar7_register_devices(void) u32 val; int res; + res = ar7_gpio_init(); + if (res) + pr_warn("unable to register gpios: %d\n", res); + res = ar7_register_uarts(); if (res) pr_err("unable to setup uart(s): %d\n", res); diff --git a/kernel/arch/mips/ar7/prom.c b/kernel/arch/mips/ar7/prom.c index 4fd833361..dd53987a6 100644 --- a/kernel/arch/mips/ar7/prom.c +++ b/kernel/arch/mips/ar7/prom.c @@ -246,8 +246,6 @@ void __init prom_init(void) ar7_init_cmdline(fw_arg0, (char **)fw_arg1); ar7_init_env((struct env_var *)fw_arg2); console_config(); - - ar7_gpio_init(); } #define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4))) diff --git a/kernel/arch/mips/kernel/smp-bmips.c b/kernel/arch/mips/kernel/smp-bmips.c index 406072e26..87dcac244 100644 --- a/kernel/arch/mips/kernel/smp-bmips.c +++ b/kernel/arch/mips/kernel/smp-bmips.c @@ -591,11 +591,11 @@ void __init bmips_cpu_setup(void) /* Flush and enable RAC */ cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); - __raw_writel(cfg | 0x100, BMIPS_RAC_CONFIG); + __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG); __raw_readl(cbr + BMIPS_RAC_CONFIG); cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); - __raw_writel(cfg | 0xf, BMIPS_RAC_CONFIG); + __raw_writel(cfg | 0xf, cbr + BMIPS_RAC_CONFIG); __raw_readl(cbr + BMIPS_RAC_CONFIG); cfg = __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); diff --git a/kernel/arch/powerpc/kvm/book3s_64_mmu_hv.c b/kernel/arch/powerpc/kvm/book3s_64_mmu_hv.c index 7c62967d6..59247af5f 100644 --- a/kernel/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/kernel/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -646,6 +646,16 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, hnow_v = hpte_new_to_old_v(hnow_v, hnow_r); hnow_r = hpte_new_to_old_r(hnow_r); } + + /* + * If the HPT is being resized, don't update the HPTE, + * instead let the guest retry after the resize operation is complete. + * The synchronization for hpte_setup_done test vs. set is provided + * by the HPTE lock. + */ + if (!kvm->arch.hpte_setup_done) + goto out_unlock; + if ((hnow_v & ~HPTE_V_HVLOCK) != hpte[0] || hnow_r != hpte[1] || rev->guest_rpte != hpte[2]) /* HPTE has been changed under us; let the guest retry */ diff --git a/kernel/arch/powerpc/kvm/book3s_hv.c b/kernel/arch/powerpc/kvm/book3s_hv.c index 73bf1ebfa..8d43cf205 100644 --- a/kernel/arch/powerpc/kvm/book3s_hv.c +++ b/kernel/arch/powerpc/kvm/book3s_hv.c @@ -2705,11 +2705,14 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) * Hard-disable interrupts, and check resched flag and signals. * If we need to reschedule or deliver a signal, clean up * and return without going into the guest(s). + * If the hpte_setup_done flag has been cleared, don't go into the + * guest because that means a HPT resize operation is in progress. */ local_irq_disable(); hard_irq_disable(); if (lazy_irq_pending() || need_resched() || - recheck_signals(&core_info)) { + recheck_signals(&core_info) || + (!kvm_is_radix(vc->kvm) && !vc->kvm->arch.hpte_setup_done)) { local_irq_enable(); vc->vcore_state = VCORE_INACTIVE; /* Unlock all except the primary vcore */ @@ -3078,7 +3081,7 @@ out: static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) { - int n_ceded, i; + int n_ceded, i, r; struct kvmppc_vcore *vc; struct kvm_vcpu *v; @@ -3132,6 +3135,20 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE && !signal_pending(current)) { + /* See if the HPT and VRMA are ready to go */ + if (!kvm_is_radix(vcpu->kvm) && + !vcpu->kvm->arch.hpte_setup_done) { + spin_unlock(&vc->lock); + r = kvmppc_hv_setup_htab_rma(vcpu); + spin_lock(&vc->lock); + if (r) { + kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; + kvm_run->fail_entry.hardware_entry_failure_reason = 0; + vcpu->arch.ret = r; + break; + } + } + if (vc->vcore_state == VCORE_PREEMPT && vc->runner == NULL) kvmppc_vcore_end_preempt(vc); @@ -3249,13 +3266,6 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) /* Order vcpus_running vs. hpte_setup_done, see kvmppc_alloc_reset_hpt */ smp_mb(); - /* On the first time here, set up HTAB and VRMA */ - if (!kvm_is_radix(vcpu->kvm) && !vcpu->kvm->arch.hpte_setup_done) { - r = kvmppc_hv_setup_htab_rma(vcpu); - if (r) - goto out; - } - flush_all_to_thread(current); /* Save userspace EBB and other register values */ @@ -3303,7 +3313,6 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) } mtspr(SPRN_VRSAVE, user_vrsave); - out: vcpu->arch.state = KVMPPC_VCPU_NOTREADY; atomic_dec(&vcpu->kvm->arch.vcpus_running); return r; diff --git a/kernel/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S b/kernel/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S index 93b945597..7cfba738f 100644 --- a/kernel/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S +++ b/kernel/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S @@ -157,8 +157,8 @@ LABEL skip_ %I .endr # Find min length - vmovdqa _lens+0*16(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens+0*16(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} @@ -178,8 +178,8 @@ LABEL skip_ %I vpsubd %xmm2, %xmm0, %xmm0 vpsubd %xmm2, %xmm1, %xmm1 - vmovdqa %xmm0, _lens+0*16(state) - vmovdqa %xmm1, _lens+1*16(state) + vmovdqu %xmm0, _lens+0*16(state) + vmovdqu %xmm1, _lens+1*16(state) # "state" and "args" are the same address, arg1 # len is arg2 @@ -235,8 +235,8 @@ ENTRY(sha1_mb_mgr_get_comp_job_avx2) jc .return_null # Find min length - vmovdqa _lens(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} diff --git a/kernel/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S b/kernel/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S index 8fe6338bc..16c4ccb1f 100644 --- a/kernel/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S +++ b/kernel/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S @@ -155,8 +155,8 @@ LABEL skip_ %I .endr # Find min length - vmovdqa _lens+0*16(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens+0*16(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} @@ -176,8 +176,8 @@ LABEL skip_ %I vpsubd %xmm2, %xmm0, %xmm0 vpsubd %xmm2, %xmm1, %xmm1 - vmovdqa %xmm0, _lens+0*16(state) - vmovdqa %xmm1, _lens+1*16(state) + vmovdqu %xmm0, _lens+0*16(state) + vmovdqu %xmm1, _lens+1*16(state) # "state" and "args" are the same address, arg1 # len is arg2 @@ -234,8 +234,8 @@ ENTRY(sha256_mb_mgr_get_comp_job_avx2) jc .return_null # Find min length - vmovdqa _lens(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} diff --git a/kernel/arch/x86/include/asm/elf.h b/kernel/arch/x86/include/asm/elf.h index c1a125e47..3a091cea3 100644 --- a/kernel/arch/x86/include/asm/elf.h +++ b/kernel/arch/x86/include/asm/elf.h @@ -253,7 +253,7 @@ extern int force_personality32; * space open for things that want to use the area for 32-bit pointers. */ #define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \ - (TASK_SIZE / 3 * 2)) + (DEFAULT_MAP_WINDOW / 3 * 2)) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This could be done in user space, diff --git a/kernel/arch/x86/kernel/cpu/Makefile b/kernel/arch/x86/kernel/cpu/Makefile index 236999c54..c60922a66 100644 --- a/kernel/arch/x86/kernel/cpu/Makefile +++ b/kernel/arch/x86/kernel/cpu/Makefile @@ -22,7 +22,7 @@ obj-y += common.o obj-y += rdrand.o obj-y += match.o obj-y += bugs.o -obj-y += aperfmperf.o +obj-$(CONFIG_CPU_FREQ) += aperfmperf.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o diff --git a/kernel/arch/x86/kernel/cpu/aperfmperf.c b/kernel/arch/x86/kernel/cpu/aperfmperf.c index 957813e01..0ee83321a 100644 --- a/kernel/arch/x86/kernel/cpu/aperfmperf.c +++ b/kernel/arch/x86/kernel/cpu/aperfmperf.c @@ -42,6 +42,10 @@ static void aperfmperf_snapshot_khz(void *dummy) s64 time_delta = ktime_ms_delta(now, s->time); unsigned long flags; + /* Don't bother re-computing within the cache threshold time. */ + if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS) + return; + local_irq_save(flags); rdmsrl(MSR_IA32_APERF, aperf); rdmsrl(MSR_IA32_MPERF, mperf); @@ -70,7 +74,6 @@ static void aperfmperf_snapshot_khz(void *dummy) unsigned int arch_freq_get_on_cpu(int cpu) { - s64 time_delta; unsigned int khz; if (!cpu_khz) @@ -79,12 +82,6 @@ unsigned int arch_freq_get_on_cpu(int cpu) if (!static_cpu_has(X86_FEATURE_APERFMPERF)) return 0; - /* Don't bother re-computing within the cache threshold time. */ - time_delta = ktime_ms_delta(ktime_get(), per_cpu(samples.time, cpu)); - khz = per_cpu(samples.khz, cpu); - if (khz && time_delta < APERFMPERF_CACHE_THRESHOLD_MS) - return khz; - smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1); khz = per_cpu(samples.khz, cpu); if (khz) diff --git a/kernel/arch/x86/kernel/cpu/proc.c b/kernel/arch/x86/kernel/cpu/proc.c index 4378a729b..6b7e17bf0 100644 --- a/kernel/arch/x86/kernel/cpu/proc.c +++ b/kernel/arch/x86/kernel/cpu/proc.c @@ -78,10 +78,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "microcode\t: 0x%x\n", c->microcode); if (cpu_has(c, X86_FEATURE_TSC)) { - unsigned int freq = arch_freq_get_on_cpu(cpu); + unsigned int freq = cpufreq_quick_get(cpu); - if (!freq) - freq = cpufreq_quick_get(cpu); if (!freq) freq = cpu_khz; seq_printf(m, "cpu MHz\t\t: %u.%03u\n", diff --git a/kernel/arch/x86/kernel/idt.c b/kernel/arch/x86/kernel/idt.c index 6107ee1cb..014cb2fc4 100644 --- a/kernel/arch/x86/kernel/idt.c +++ b/kernel/arch/x86/kernel/idt.c @@ -92,8 +92,6 @@ static const __initdata struct idt_data def_idts[] = { INTG(X86_TRAP_DF, double_fault), #endif INTG(X86_TRAP_DB, debug), - INTG(X86_TRAP_NMI, nmi), - INTG(X86_TRAP_BP, int3), #ifdef CONFIG_X86_MCE INTG(X86_TRAP_MC, &machine_check), diff --git a/kernel/arch/x86/kernel/smpboot.c b/kernel/arch/x86/kernel/smpboot.c index ad59edd84..65a0ccdc3 100644 --- a/kernel/arch/x86/kernel/smpboot.c +++ b/kernel/arch/x86/kernel/smpboot.c @@ -193,6 +193,12 @@ static void smp_callin(void) */ smp_store_cpu_info(cpuid); + /* + * The topology information must be up to date before + * calibrate_delay() and notify_cpu_starting(). + */ + set_cpu_sibling_map(raw_smp_processor_id()); + /* * Get our bogomips. * Update loops_per_jiffy in cpu_data. Previous call to @@ -203,11 +209,6 @@ static void smp_callin(void) cpu_data(cpuid).loops_per_jiffy = loops_per_jiffy; pr_debug("Stack at about %p\n", &cpuid); - /* - * This must be done before setting cpu_online_mask - * or calling notify_cpu_starting. - */ - set_cpu_sibling_map(raw_smp_processor_id()); wmb(); notify_cpu_starting(cpuid); diff --git a/kernel/arch/x86/kernel/traps.c b/kernel/arch/x86/kernel/traps.c index 67db4f433..5a6b8f809 100644 --- a/kernel/arch/x86/kernel/traps.c +++ b/kernel/arch/x86/kernel/traps.c @@ -209,9 +209,6 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, if (fixup_exception(regs, trapnr)) return 0; - if (fixup_bug(regs, trapnr)) - return 0; - tsk->thread.error_code = error_code; tsk->thread.trap_nr = trapnr; die(str, regs, error_code); @@ -292,6 +289,13 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str, RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); + /* + * WARN*()s end up here; fix them up before we call the + * notifier chain. + */ + if (!user_mode(regs) && fixup_bug(regs, trapnr)) + return; + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != NOTIFY_STOP) { cond_local_irq_enable(regs); diff --git a/kernel/arch/x86/kernel/tsc.c b/kernel/arch/x86/kernel/tsc.c index 796d96bb0..ad2b925a8 100644 --- a/kernel/arch/x86/kernel/tsc.c +++ b/kernel/arch/x86/kernel/tsc.c @@ -1346,12 +1346,10 @@ void __init tsc_init(void) unsigned long calibrate_delay_is_known(void) { int sibling, cpu = smp_processor_id(); - struct cpumask *mask = topology_core_cpumask(cpu); + int constant_tsc = cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC); + const struct cpumask *mask = topology_core_cpumask(cpu); - if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC)) - return 0; - - if (!mask) + if (tsc_disabled || !constant_tsc || !mask) return 0; sibling = cpumask_any_but(mask, cpu); diff --git a/kernel/arch/x86/kernel/unwind_orc.c b/kernel/arch/x86/kernel/unwind_orc.c index b95007e7c..a3f973b2c 100644 --- a/kernel/arch/x86/kernel/unwind_orc.c +++ b/kernel/arch/x86/kernel/unwind_orc.c @@ -279,7 +279,7 @@ static bool deref_stack_reg(struct unwind_state *state, unsigned long addr, if (!stack_access_ok(state, addr, sizeof(long))) return false; - *val = READ_ONCE_TASK_STACK(state->task, *(unsigned long *)addr); + *val = READ_ONCE_NOCHECK(*(unsigned long *)addr); return true; } diff --git a/kernel/arch/x86/mm/mem_encrypt.c b/kernel/arch/x86/mm/mem_encrypt.c index 16c5f3793..0286327e6 100644 --- a/kernel/arch/x86/mm/mem_encrypt.c +++ b/kernel/arch/x86/mm/mem_encrypt.c @@ -40,7 +40,7 @@ static char sme_cmdline_off[] __initdata = "off"; * section is later cleared. */ u64 sme_me_mask __section(.data) = 0; -EXPORT_SYMBOL_GPL(sme_me_mask); +EXPORT_SYMBOL(sme_me_mask); /* Buffer used for early in-place encryption by BSP, no locking needed */ static char sme_early_buffer[PAGE_SIZE] __aligned(PAGE_SIZE); diff --git a/kernel/arch/x86/oprofile/op_model_ppro.c b/kernel/arch/x86/oprofile/op_model_ppro.c index 350f7096b..7913b6921 100644 --- a/kernel/arch/x86/oprofile/op_model_ppro.c +++ b/kernel/arch/x86/oprofile/op_model_ppro.c @@ -212,8 +212,8 @@ static void arch_perfmon_setup_counters(void) eax.full = cpuid_eax(0xa); /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */ - if (eax.split.version_id == 0 && __this_cpu_read(cpu_info.x86) == 6 && - __this_cpu_read(cpu_info.x86_model) == 15) { + if (eax.split.version_id == 0 && boot_cpu_data.x86 == 6 && + boot_cpu_data.x86_model == 15) { eax.split.version_id = 2; eax.split.num_counters = 2; eax.split.bit_width = 40; diff --git a/kernel/crypto/ccm.c b/kernel/crypto/ccm.c index 1ce37ae0c..0a083342e 100644 --- a/kernel/crypto/ccm.c +++ b/kernel/crypto/ccm.c @@ -363,7 +363,7 @@ static int crypto_ccm_decrypt(struct aead_request *req) unsigned int cryptlen = req->cryptlen; u8 *authtag = pctx->auth_tag; u8 *odata = pctx->odata; - u8 *iv = req->iv; + u8 *iv = pctx->idata; int err; cryptlen -= authsize; @@ -379,6 +379,8 @@ static int crypto_ccm_decrypt(struct aead_request *req) if (req->src != req->dst) dst = pctx->dst; + memcpy(iv, req->iv, 16); + skcipher_request_set_tfm(skreq, ctx->ctr); skcipher_request_set_callback(skreq, pctx->flags, crypto_ccm_decrypt_done, req); diff --git a/kernel/drivers/acpi/sleep.c b/kernel/drivers/acpi/sleep.c index 6804ddab3..8082871b4 100644 --- a/kernel/drivers/acpi/sleep.c +++ b/kernel/drivers/acpi/sleep.c @@ -160,6 +160,14 @@ static int __init init_nvs_nosave(const struct dmi_system_id *d) return 0; } +static bool acpi_sleep_no_lps0; + +static int __init init_no_lps0(const struct dmi_system_id *d) +{ + acpi_sleep_no_lps0 = true; + return 0; +} + static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { { .callback = init_old_suspend_ordering, @@ -343,6 +351,19 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), }, }, + /* + * https://bugzilla.kernel.org/show_bug.cgi?id=196907 + * Some Dell XPS13 9360 cannot do suspend-to-idle using the Low Power + * S0 Idle firmware interface. + */ + { + .callback = init_no_lps0, + .ident = "Dell XPS13 9360", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"), + }, + }, {}, }; @@ -485,6 +506,7 @@ static void acpi_pm_end(void) } #else /* !CONFIG_ACPI_SLEEP */ #define acpi_target_sleep_state ACPI_STATE_S0 +#define acpi_sleep_no_lps0 (false) static inline void acpi_sleep_dmi_check(void) {} #endif /* CONFIG_ACPI_SLEEP */ @@ -863,6 +885,12 @@ static int lps0_device_attach(struct acpi_device *adev, if (lps0_device_handle) return 0; + if (acpi_sleep_no_lps0) { + acpi_handle_info(adev->handle, + "Low Power S0 Idle interface disabled\n"); + return 0; + } + if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) return 0; diff --git a/kernel/drivers/block/rbd.c b/kernel/drivers/block/rbd.c index b640ad8a6..adc877dfe 100644 --- a/kernel/drivers/block/rbd.c +++ b/kernel/drivers/block/rbd.c @@ -2692,7 +2692,7 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request) * from the parent. */ page_count = (u32)calc_pages_for(0, length); - pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); + pages = ceph_alloc_page_vector(page_count, GFP_NOIO); if (IS_ERR(pages)) { result = PTR_ERR(pages); pages = NULL; @@ -2827,7 +2827,7 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request) */ size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32); page_count = (u32)calc_pages_for(0, size); - pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); + pages = ceph_alloc_page_vector(page_count, GFP_NOIO); if (IS_ERR(pages)) { ret = PTR_ERR(pages); goto fail_stat_request; diff --git a/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 4ac454ae5..83876a1c8 100644 --- a/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/kernel/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -2094,6 +2094,11 @@ get_fence_array(struct drm_i915_gem_execbuffer2 *args, goto err; } + if (fence.flags & __I915_EXEC_FENCE_UNKNOWN_FLAGS) { + err = -EINVAL; + goto err; + } + syncobj = drm_syncobj_find(file, fence.handle); if (!syncobj) { DRM_DEBUG("Invalid syncobj handle provided\n"); @@ -2101,6 +2106,9 @@ get_fence_array(struct drm_i915_gem_execbuffer2 *args, goto err; } + BUILD_BUG_ON(~(ARCH_KMALLOC_MINALIGN - 1) & + ~__I915_EXEC_FENCE_UNKNOWN_FLAGS); + fences[n] = ptr_pack_bits(syncobj, fence.flags, 2); } diff --git a/kernel/drivers/gpu/drm/i915/i915_gem_gtt.c b/kernel/drivers/gpu/drm/i915/i915_gem_gtt.c index e2410eb5d..ad524cb0f 100644 --- a/kernel/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/kernel/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -832,10 +832,14 @@ static void gen8_ppgtt_clear_4lvl(struct i915_address_space *vm, } } -struct sgt_dma { +static inline struct sgt_dma { struct scatterlist *sg; dma_addr_t dma, max; -}; +} sgt_dma(struct i915_vma *vma) { + struct scatterlist *sg = vma->pages->sgl; + dma_addr_t addr = sg_dma_address(sg); + return (struct sgt_dma) { sg, addr, addr + sg->length }; +} struct gen8_insert_pte { u16 pml4e; @@ -916,11 +920,7 @@ static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm, u32 unused) { struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); - struct sgt_dma iter = { - .sg = vma->pages->sgl, - .dma = sg_dma_address(iter.sg), - .max = iter.dma + iter.sg->length, - }; + struct sgt_dma iter = sgt_dma(vma); struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start); gen8_ppgtt_insert_pte_entries(ppgtt, &ppgtt->pdp, &iter, &idx, @@ -933,11 +933,7 @@ static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm, u32 unused) { struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); - struct sgt_dma iter = { - .sg = vma->pages->sgl, - .dma = sg_dma_address(iter.sg), - .max = iter.dma + iter.sg->length, - }; + struct sgt_dma iter = sgt_dma(vma); struct i915_page_directory_pointer **pdps = ppgtt->pml4.pdps; struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start); @@ -1632,13 +1628,10 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, unsigned act_pt = first_entry / GEN6_PTES; unsigned act_pte = first_entry % GEN6_PTES; const u32 pte_encode = vm->pte_encode(0, cache_level, flags); - struct sgt_dma iter; + struct sgt_dma iter = sgt_dma(vma); gen6_pte_t *vaddr; vaddr = kmap_atomic_px(ppgtt->pd.page_table[act_pt]); - iter.sg = vma->pages->sgl; - iter.dma = sg_dma_address(iter.sg); - iter.max = iter.dma + iter.sg->length; do { vaddr[act_pte] = pte_encode | GEN6_PTE_ADDR_ENCODE(iter.dma); diff --git a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index e84fee3ec..184340d48 100644 --- a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -721,7 +721,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) * allocation taken by fbdev */ if (!(dev_priv->capabilities & SVGA_CAP_3D)) - mem_size *= 2; + mem_size *= 3; dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE; dev_priv->prim_bb_mem = diff --git a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 3bbad22b3..d6b1c509a 100644 --- a/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/kernel/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -224,7 +224,7 @@ out: return ret; } -static struct dma_fence_ops vmw_fence_ops = { +static const struct dma_fence_ops vmw_fence_ops = { .get_driver_name = vmw_fence_get_driver_name, .get_timeline_name = vmw_fence_get_timeline_name, .enable_signaling = vmw_fence_enable_signaling, diff --git a/kernel/drivers/ide/ide-cd.c b/kernel/drivers/ide/ide-cd.c index a7355ab3b..6ff0be8cb 100644 --- a/kernel/drivers/ide/ide-cd.c +++ b/kernel/drivers/ide/ide-cd.c @@ -867,11 +867,16 @@ static void msf_from_bcd(struct atapi_msf *msf) int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) { struct cdrom_info *info = drive->driver_data; - struct cdrom_device_info *cdi = &info->devinfo; + struct cdrom_device_info *cdi; unsigned char cmd[BLK_MAX_CDB]; ide_debug_log(IDE_DBG_FUNC, "enter"); + if (!info) + return -EIO; + + cdi = &info->devinfo; + memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_TEST_UNIT_READY; diff --git a/kernel/drivers/input/mouse/elan_i2c_core.c b/kernel/drivers/input/mouse/elan_i2c_core.c index 6d6b092e2..d6135900d 100644 --- a/kernel/drivers/input/mouse/elan_i2c_core.c +++ b/kernel/drivers/input/mouse/elan_i2c_core.c @@ -1258,6 +1258,7 @@ static const struct acpi_device_id elan_acpi_id[] = { { "ELAN0605", 0 }, { "ELAN0609", 0 }, { "ELAN060B", 0 }, + { "ELAN060C", 0 }, { "ELAN0611", 0 }, { "ELAN1000", 0 }, { } diff --git a/kernel/drivers/input/rmi4/rmi_smbus.c b/kernel/drivers/input/rmi4/rmi_smbus.c index 225025a09..b6ccf39c6 100644 --- a/kernel/drivers/input/rmi4/rmi_smbus.c +++ b/kernel/drivers/input/rmi4/rmi_smbus.c @@ -312,7 +312,7 @@ static int rmi_smb_probe(struct i2c_client *client, rmi_smb->xport.dev = &client->dev; rmi_smb->xport.pdata = *pdata; rmi_smb->xport.pdata.irq = client->irq; - rmi_smb->xport.proto_name = "smb2"; + rmi_smb->xport.proto_name = "smb"; rmi_smb->xport.ops = &rmi_smb_ops; smbus_version = rmi_smb_get_version(rmi_smb); @@ -322,7 +322,7 @@ static int rmi_smb_probe(struct i2c_client *client, rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", smbus_version); - if (smbus_version != 2) { + if (smbus_version != 2 && smbus_version != 3) { dev_err(&client->dev, "Unrecognized SMB version %d\n", smbus_version); return -ENODEV; diff --git a/kernel/drivers/input/touchscreen/tsc200x-core.c b/kernel/drivers/input/touchscreen/tsc200x-core.c index 88ea5e1b7..abf27578b 100644 --- a/kernel/drivers/input/touchscreen/tsc200x-core.c +++ b/kernel/drivers/input/touchscreen/tsc200x-core.c @@ -531,6 +531,7 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, input_set_drvdata(input_dev, ts); + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); input_set_capability(input_dev, EV_KEY, BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, diff --git a/kernel/drivers/net/bonding/bond_main.c b/kernel/drivers/net/bonding/bond_main.c index c99dc59d7..b2db58113 100644 --- a/kernel/drivers/net/bonding/bond_main.c +++ b/kernel/drivers/net/bonding/bond_main.c @@ -2042,6 +2042,7 @@ static int bond_miimon_inspect(struct bonding *bond) bond_for_each_slave_rcu(bond, slave, iter) { slave->new_link = BOND_LINK_NOCHANGE; + slave->link_new_state = slave->link; link_state = bond_check_dev_link(bond, slave->dev, 0); @@ -3253,7 +3254,7 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb) hash ^= (hash >> 16); hash ^= (hash >> 8); - return hash; + return hash >> 1; } /*-------------------------- Device entry points ----------------------------*/ diff --git a/kernel/drivers/net/can/c_can/c_can_pci.c b/kernel/drivers/net/can/c_can/c_can_pci.c index cf7c18947..d065c0e2d 100644 --- a/kernel/drivers/net/can/c_can/c_can_pci.c +++ b/kernel/drivers/net/can/c_can/c_can_pci.c @@ -178,7 +178,6 @@ static int c_can_pci_probe(struct pci_dev *pdev, break; case BOSCH_D_CAN: priv->regs = reg_map_d_can; - priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; break; default: ret = -EINVAL; diff --git a/kernel/drivers/net/can/c_can/c_can_platform.c b/kernel/drivers/net/can/c_can/c_can_platform.c index 46a746ee8..b5145a7f8 100644 --- a/kernel/drivers/net/can/c_can/c_can_platform.c +++ b/kernel/drivers/net/can/c_can/c_can_platform.c @@ -320,7 +320,6 @@ static int c_can_plat_probe(struct platform_device *pdev) break; case BOSCH_D_CAN: priv->regs = reg_map_d_can; - priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; priv->read_reg32 = d_can_plat_read_reg32; diff --git a/kernel/drivers/net/can/ifi_canfd/ifi_canfd.c b/kernel/drivers/net/can/ifi_canfd/ifi_canfd.c index 4d1fe8d95..2772d05ff 100644 --- a/kernel/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/kernel/drivers/net/can/ifi_canfd/ifi_canfd.c @@ -670,9 +670,9 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev) priv->base + IFI_CANFD_FTIME); /* Configure transmitter delay */ - tdc = (dbt->brp * (dbt->phase_seg1 + 1)) & IFI_CANFD_TDELAY_MASK; - writel(IFI_CANFD_TDELAY_EN | IFI_CANFD_TDELAY_ABS | tdc, - priv->base + IFI_CANFD_TDELAY); + tdc = dbt->brp * (dbt->prop_seg + dbt->phase_seg1); + tdc &= IFI_CANFD_TDELAY_MASK; + writel(IFI_CANFD_TDELAY_EN | tdc, priv->base + IFI_CANFD_TDELAY); } static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id, diff --git a/kernel/drivers/net/can/peak_canfd/peak_pciefd_main.c b/kernel/drivers/net/can/peak_canfd/peak_pciefd_main.c index 51c2d182a..b4efd711f 100644 --- a/kernel/drivers/net/can/peak_canfd/peak_pciefd_main.c +++ b/kernel/drivers/net/can/peak_canfd/peak_pciefd_main.c @@ -29,14 +29,19 @@ #include "peak_canfd_user.h" MODULE_AUTHOR("Stephane Grosjean "); -MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe FD family cards"); -MODULE_SUPPORTED_DEVICE("PEAK PCAN PCIe FD CAN cards"); +MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards"); +MODULE_SUPPORTED_DEVICE("PEAK PCAN PCIe/M.2 FD CAN cards"); MODULE_LICENSE("GPL v2"); #define PCIEFD_DRV_NAME "peak_pciefd" #define PEAK_PCI_VENDOR_ID 0x001c /* The PCI device and vendor IDs */ #define PEAK_PCIEFD_ID 0x0013 /* for PCIe slot cards */ +#define PCAN_CPCIEFD_ID 0x0014 /* for Compact-PCI Serial slot cards */ +#define PCAN_PCIE104FD_ID 0x0017 /* for PCIe-104 Express slot cards */ +#define PCAN_MINIPCIEFD_ID 0x0018 /* for mini-PCIe slot cards */ +#define PCAN_PCIEFD_OEM_ID 0x0019 /* for PCIe slot OEM cards */ +#define PCAN_M2_ID 0x001a /* for M2 slot cards */ /* PEAK PCIe board access description */ #define PCIEFD_BAR0_SIZE (64 * 1024) @@ -203,6 +208,11 @@ struct pciefd_board { /* supported device ids. */ static const struct pci_device_id peak_pciefd_tbl[] = { {PEAK_PCI_VENDOR_ID, PEAK_PCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PEAK_PCI_VENDOR_ID, PCAN_CPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PEAK_PCI_VENDOR_ID, PCAN_PCIE104FD_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PEAK_PCI_VENDOR_ID, PCAN_MINIPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PEAK_PCI_VENDOR_ID, PCAN_PCIEFD_OEM_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PEAK_PCI_VENDOR_ID, PCAN_M2_ID, PCI_ANY_ID, PCI_ANY_ID,}, {0,} }; diff --git a/kernel/drivers/net/can/sun4i_can.c b/kernel/drivers/net/can/sun4i_can.c index b0c80859f..1ac2090a1 100644 --- a/kernel/drivers/net/can/sun4i_can.c +++ b/kernel/drivers/net/can/sun4i_can.c @@ -539,6 +539,13 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) } stats->rx_over_errors++; stats->rx_errors++; + + /* reset the CAN IP by entering reset mode + * ignoring timeout error + */ + set_reset_mode(dev); + set_normal_mode(dev); + /* clear bit */ sun4i_can_write_cmdreg(priv, SUN4I_CMD_CLEAR_OR_FLAG); } @@ -653,8 +660,9 @@ static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id) netif_wake_queue(dev); can_led_event(dev, CAN_LED_EVENT_TX); } - if (isrc & SUN4I_INT_RBUF_VLD) { - /* receive interrupt */ + if ((isrc & SUN4I_INT_RBUF_VLD) && + !(isrc & SUN4I_INT_DATA_OR)) { + /* receive interrupt - don't read if overrun occurred */ while (status & SUN4I_STA_RBUF_RDY) { /* RX buffer is not empty */ sun4i_can_rx(dev); diff --git a/kernel/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h b/kernel/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h index f2d623a7a..123e2c1b6 100644 --- a/kernel/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h +++ b/kernel/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h @@ -37,7 +37,7 @@ #define T4FW_VERSION_MAJOR 0x01 #define T4FW_VERSION_MINOR 0x10 -#define T4FW_VERSION_MICRO 0x2D +#define T4FW_VERSION_MICRO 0x3F #define T4FW_VERSION_BUILD 0x00 #define T4FW_MIN_VERSION_MAJOR 0x01 @@ -46,7 +46,7 @@ #define T5FW_VERSION_MAJOR 0x01 #define T5FW_VERSION_MINOR 0x10 -#define T5FW_VERSION_MICRO 0x2D +#define T5FW_VERSION_MICRO 0x3F #define T5FW_VERSION_BUILD 0x00 #define T5FW_MIN_VERSION_MAJOR 0x00 @@ -55,7 +55,7 @@ #define T6FW_VERSION_MAJOR 0x01 #define T6FW_VERSION_MINOR 0x10 -#define T6FW_VERSION_MICRO 0x2D +#define T6FW_VERSION_MICRO 0x3F #define T6FW_VERSION_BUILD 0x00 #define T6FW_MIN_VERSION_MAJOR 0x00 diff --git a/kernel/drivers/net/ethernet/marvell/mvpp2.c b/kernel/drivers/net/ethernet/marvell/mvpp2.c index a37af5813..fcf9ba5eb 100644 --- a/kernel/drivers/net/ethernet/marvell/mvpp2.c +++ b/kernel/drivers/net/ethernet/marvell/mvpp2.c @@ -6747,6 +6747,9 @@ static int mvpp2_irqs_init(struct mvpp2_port *port) for (i = 0; i < port->nqvecs; i++) { struct mvpp2_queue_vector *qv = port->qvecs + i; + if (qv->type == MVPP2_QUEUE_VECTOR_PRIVATE) + irq_set_status_flags(qv->irq, IRQ_NO_BALANCING); + err = request_irq(qv->irq, mvpp2_isr, 0, port->dev->name, qv); if (err) goto err; @@ -6776,6 +6779,7 @@ static void mvpp2_irqs_deinit(struct mvpp2_port *port) struct mvpp2_queue_vector *qv = port->qvecs + i; irq_set_affinity_hint(qv->irq, NULL); + irq_clear_status_flags(qv->irq, IRQ_NO_BALANCING); free_irq(qv->irq, qv); } } diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/dev.c index fc2817128..17b723218 100644 --- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/dev.c +++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/dev.c @@ -93,7 +93,7 @@ static void delayed_event_release(struct mlx5_device_context *dev_ctx, list_splice_init(&priv->waiting_events_list, &temp); if (!dev_ctx->context) goto out; - list_for_each_entry_safe(de, n, &priv->waiting_events_list, list) + list_for_each_entry_safe(de, n, &temp, list) dev_ctx->intf->event(dev, dev_ctx->context, de->event, de->param); out: diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en.h b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en.h index cc13d3dbd..13b5ef9d8 100644 --- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -67,7 +67,7 @@ #define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE 0xa #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE 0xd -#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW 0x1 +#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW 0x2 #define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW 0x3 #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW 0x6 diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c index 850cdc980..4837045ff 100644 --- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c @@ -365,21 +365,24 @@ static void mlx5e_execute_l2_action(struct mlx5e_priv *priv, struct mlx5e_l2_hash_node *hn) { u8 action = hn->action; + u8 mac_addr[ETH_ALEN]; int l2_err = 0; + ether_addr_copy(mac_addr, hn->ai.addr); + switch (action) { case MLX5E_ACTION_ADD: mlx5e_add_l2_flow_rule(priv, &hn->ai, MLX5E_FULLMATCH); - if (!is_multicast_ether_addr(hn->ai.addr)) { - l2_err = mlx5_mpfs_add_mac(priv->mdev, hn->ai.addr); + if (!is_multicast_ether_addr(mac_addr)) { + l2_err = mlx5_mpfs_add_mac(priv->mdev, mac_addr); hn->mpfs = !l2_err; } hn->action = MLX5E_ACTION_NONE; break; case MLX5E_ACTION_DEL: - if (!is_multicast_ether_addr(hn->ai.addr) && hn->mpfs) - l2_err = mlx5_mpfs_del_mac(priv->mdev, hn->ai.addr); + if (!is_multicast_ether_addr(mac_addr) && hn->mpfs) + l2_err = mlx5_mpfs_del_mac(priv->mdev, mac_addr); mlx5e_del_l2_flow_rule(priv, &hn->ai); mlx5e_del_l2_from_hash(hn); break; @@ -387,7 +390,7 @@ static void mlx5e_execute_l2_action(struct mlx5e_priv *priv, if (l2_err) netdev_warn(priv->netdev, "MPFS, failed to %s mac %pM, err(%d)\n", - action == MLX5E_ACTION_ADD ? "add" : "del", hn->ai.addr, l2_err); + action == MLX5E_ACTION_ADD ? "add" : "del", mac_addr, l2_err); } static void mlx5e_sync_netdev_addr(struct mlx5e_priv *priv) diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 15a168748..91b1b0938 100644 --- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -215,22 +215,20 @@ static inline bool mlx5e_rx_cache_get(struct mlx5e_rq *rq, static inline int mlx5e_page_alloc_mapped(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info) { - struct page *page; - if (mlx5e_rx_cache_get(rq, dma_info)) return 0; - page = dev_alloc_pages(rq->buff.page_order); - if (unlikely(!page)) + dma_info->page = dev_alloc_pages(rq->buff.page_order); + if (unlikely(!dma_info->page)) return -ENOMEM; - dma_info->addr = dma_map_page(rq->pdev, page, 0, + dma_info->addr = dma_map_page(rq->pdev, dma_info->page, 0, RQ_PAGE_SIZE(rq), rq->buff.map_dir); if (unlikely(dma_mapping_error(rq->pdev, dma_info->addr))) { - put_page(page); + put_page(dma_info->page); + dma_info->page = NULL; return -ENOMEM; } - dma_info->page = page; return 0; } diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c index e906b7544..ab92298ea 100644 --- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c +++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c @@ -49,7 +49,7 @@ int mlx5e_napi_poll(struct napi_struct *napi, int budget) struct mlx5e_channel *c = container_of(napi, struct mlx5e_channel, napi); bool busy = false; - int work_done; + int work_done = 0; int i; for (i = 0; i < c->num_tc; i++) @@ -58,15 +58,17 @@ int mlx5e_napi_poll(struct napi_struct *napi, int budget) if (c->xdp) busy |= mlx5e_poll_xdpsq_cq(&c->rq.xdpsq.cq); - work_done = mlx5e_poll_rx_cq(&c->rq.cq, budget); - busy |= work_done == budget; + if (likely(budget)) { /* budget=0 means: don't poll rx rings */ + work_done = mlx5e_poll_rx_cq(&c->rq.cq, budget); + busy |= work_done == budget; + } busy |= c->rq.post_wqes(&c->rq); if (busy) { if (likely(mlx5e_channel_no_affinity_change(c))) return budget; - if (work_done == budget) + if (budget && work_done == budget) work_done--; } diff --git a/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c b/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c index 0d2c8dcd6..06562c9a6 100644 --- a/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/kernel/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1482,9 +1482,16 @@ static int mlx5_try_fast_unload(struct mlx5_core_dev *dev) return -EAGAIN; } + /* Panic tear down fw command will stop the PCI bus communication + * with the HCA, so the health polll is no longer needed. + */ + mlx5_drain_health_wq(dev); + mlx5_stop_health_poll(dev); + ret = mlx5_cmd_force_teardown_hca(dev); if (ret) { mlx5_core_dbg(dev, "Firmware couldn't do fast unload error: %d\n", ret); + mlx5_start_health_poll(dev); return ret; } diff --git a/kernel/drivers/net/usb/asix_devices.c b/kernel/drivers/net/usb/asix_devices.c index b2ff88e69..3d4f7959d 100644 --- a/kernel/drivers/net/usb/asix_devices.c +++ b/kernel/drivers/net/usb/asix_devices.c @@ -626,7 +626,7 @@ static int asix_suspend(struct usb_interface *intf, pm_message_t message) struct usbnet *dev = usb_get_intfdata(intf); struct asix_common_private *priv = dev->driver_priv; - if (priv->suspend) + if (priv && priv->suspend) priv->suspend(dev); return usbnet_suspend(intf, message); @@ -678,7 +678,7 @@ static int asix_resume(struct usb_interface *intf) struct usbnet *dev = usb_get_intfdata(intf); struct asix_common_private *priv = dev->driver_priv; - if (priv->resume) + if (priv && priv->resume) priv->resume(dev); return usbnet_resume(intf); diff --git a/kernel/drivers/net/usb/cdc_ether.c b/kernel/drivers/net/usb/cdc_ether.c index e9a3148a9..59c2fcc0e 100644 --- a/kernel/drivers/net/usb/cdc_ether.c +++ b/kernel/drivers/net/usb/cdc_ether.c @@ -230,7 +230,7 @@ skip: goto bad_desc; } - if (header.usb_cdc_ether_desc) { + if (header.usb_cdc_ether_desc && info->ether->wMaxSegmentSize) { dev->hard_mtu = le16_to_cpu(info->ether->wMaxSegmentSize); /* because of Zaurus, we may be ignoring the host * side link address we were given. diff --git a/kernel/drivers/net/usb/qmi_wwan.c b/kernel/drivers/net/usb/qmi_wwan.c index 8c3733608..8d4a6f7cb 100644 --- a/kernel/drivers/net/usb/qmi_wwan.c +++ b/kernel/drivers/net/usb/qmi_wwan.c @@ -499,6 +499,7 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 1; } if (rawip) { + skb_reset_mac_header(skb); skb->dev = dev->net; /* normally set by eth_type_trans */ skb->protocol = proto; return 1; @@ -681,7 +682,7 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) } /* errors aren't fatal - we can live with the dynamic address */ - if (cdc_ether) { + if (cdc_ether && cdc_ether->wMaxSegmentSize) { dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize); usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress); } diff --git a/kernel/drivers/scsi/scsi_lib.c b/kernel/drivers/scsi/scsi_lib.c index ad3ea24f0..bcc1694ce 100644 --- a/kernel/drivers/scsi/scsi_lib.c +++ b/kernel/drivers/scsi/scsi_lib.c @@ -2685,7 +2685,6 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) } sdev->sdev_state = state; - sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state"); return 0; illegal: @@ -3109,7 +3108,6 @@ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev, case SDEV_BLOCK: case SDEV_TRANSPORT_OFFLINE: sdev->sdev_state = new_state; - sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state"); break; case SDEV_CREATED_BLOCK: if (new_state == SDEV_TRANSPORT_OFFLINE || @@ -3117,7 +3115,6 @@ int scsi_internal_device_unblock_nowait(struct scsi_device *sdev, sdev->sdev_state = new_state; else sdev->sdev_state = SDEV_CREATED; - sysfs_notify(&sdev->sdev_gendev.kobj, NULL, "state"); break; case SDEV_CANCEL: case SDEV_OFFLINE: diff --git a/kernel/drivers/scsi/scsi_transport_srp.c b/kernel/drivers/scsi/scsi_transport_srp.c index 4f6f01cf9..36f619093 100644 --- a/kernel/drivers/scsi/scsi_transport_srp.c +++ b/kernel/drivers/scsi/scsi_transport_srp.c @@ -556,11 +556,8 @@ int srp_reconnect_rport(struct srp_rport *rport) */ shost_for_each_device(sdev, shost) { mutex_lock(&sdev->state_mutex); - if (sdev->sdev_state == SDEV_OFFLINE) { + if (sdev->sdev_state == SDEV_OFFLINE) sdev->sdev_state = SDEV_RUNNING; - sysfs_notify(&sdev->sdev_gendev.kobj, - NULL, "state"); - } mutex_unlock(&sdev->state_mutex); } } else if (rport->state == SRP_RPORT_RUNNING) { diff --git a/kernel/include/linux/skbuff.h b/kernel/include/linux/skbuff.h index 72299ef00..d448a4804 100644 --- a/kernel/include/linux/skbuff.h +++ b/kernel/include/linux/skbuff.h @@ -3770,6 +3770,13 @@ static inline void nf_reset_trace(struct sk_buff *skb) #endif } +static inline void ipvs_reset(struct sk_buff *skb) +{ +#if IS_ENABLED(CONFIG_IP_VS) + skb->ipvs_property = 0; +#endif +} + /* Note: This doesn't put any conntrack and bridge info in dst. */ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src, bool copy) diff --git a/kernel/include/linux/sysctl.h b/kernel/include/linux/sysctl.h index 74f91eefe..b769ecfcc 100644 --- a/kernel/include/linux/sysctl.h +++ b/kernel/include/linux/sysctl.h @@ -213,6 +213,11 @@ static inline struct ctl_table_header *register_sysctl_paths( return NULL; } +static inline struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table) +{ + return NULL; +} + static inline void unregister_sysctl_table(struct ctl_table_header * table) { } diff --git a/kernel/include/net/act_api.h b/kernel/include/net/act_api.h index 1e6df0eb0..a10a3b181 100644 --- a/kernel/include/net/act_api.h +++ b/kernel/include/net/act_api.h @@ -14,7 +14,6 @@ struct tcf_idrinfo { spinlock_t lock; struct idr action_idr; - struct net *net; }; struct tc_action_ops; @@ -106,7 +105,7 @@ struct tc_action_net { static inline int tc_action_net_init(struct tc_action_net *tn, - const struct tc_action_ops *ops, struct net *net) + const struct tc_action_ops *ops) { int err = 0; @@ -114,7 +113,6 @@ int tc_action_net_init(struct tc_action_net *tn, if (!tn->idrinfo) return -ENOMEM; tn->ops = ops; - tn->idrinfo->net = net; spin_lock_init(&tn->idrinfo->lock); idr_init(&tn->idrinfo->action_idr); return err; diff --git a/kernel/include/net/pkt_cls.h b/kernel/include/net/pkt_cls.h index 70ca24377..8826747ef 100644 --- a/kernel/include/net/pkt_cls.h +++ b/kernel/include/net/pkt_cls.h @@ -94,6 +94,7 @@ struct tcf_exts { __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ int nr_actions; struct tc_action **actions; + struct net *net; #endif /* Map to export classifier specific extension TLV types to the * generic extensions API. Unsupported extensions must be set to 0. @@ -107,6 +108,7 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police) #ifdef CONFIG_NET_CLS_ACT exts->type = 0; exts->nr_actions = 0; + exts->net = NULL; exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *), GFP_KERNEL); if (!exts->actions) @@ -117,6 +119,28 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police) return 0; } +/* Return false if the netns is being destroyed in cleanup_net(). Callers + * need to do cleanup synchronously in this case, otherwise may race with + * tc_action_net_exit(). Return true for other cases. + */ +static inline bool tcf_exts_get_net(struct tcf_exts *exts) +{ +#ifdef CONFIG_NET_CLS_ACT + exts->net = maybe_get_net(exts->net); + return exts->net != NULL; +#else + return true; +#endif +} + +static inline void tcf_exts_put_net(struct tcf_exts *exts) +{ +#ifdef CONFIG_NET_CLS_ACT + if (exts->net) + put_net(exts->net); +#endif +} + static inline void tcf_exts_to_list(const struct tcf_exts *exts, struct list_head *actions) { diff --git a/kernel/include/sound/seq_kernel.h b/kernel/include/sound/seq_kernel.h index feb58d455..4b9ee3009 100644 --- a/kernel/include/sound/seq_kernel.h +++ b/kernel/include/sound/seq_kernel.h @@ -49,7 +49,8 @@ typedef union snd_seq_timestamp snd_seq_timestamp_t; #define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS 200 /* max delivery path length */ -#define SNDRV_SEQ_MAX_HOPS 10 +/* NOTE: this shouldn't be greater than MAX_LOCKDEP_SUBCLASSES */ +#define SNDRV_SEQ_MAX_HOPS 8 /* max size of event size */ #define SNDRV_SEQ_MAX_EVENT_LEN 0x3fffffff diff --git a/kernel/include/sound/timer.h b/kernel/include/sound/timer.h index c4d76ff05..7ae226ab6 100644 --- a/kernel/include/sound/timer.h +++ b/kernel/include/sound/timer.h @@ -90,6 +90,8 @@ struct snd_timer { struct list_head ack_list_head; struct list_head sack_list_head; /* slow ack list head */ struct tasklet_struct task_queue; + int max_instances; /* upper limit of timer instances */ + int num_instances; /* current number of timer instances */ }; struct snd_timer_instance { diff --git a/kernel/include/uapi/drm/i915_drm.h b/kernel/include/uapi/drm/i915_drm.h index 6598fb76d..9816590d3 100644 --- a/kernel/include/uapi/drm/i915_drm.h +++ b/kernel/include/uapi/drm/i915_drm.h @@ -829,6 +829,7 @@ struct drm_i915_gem_exec_fence { #define I915_EXEC_FENCE_WAIT (1<<0) #define I915_EXEC_FENCE_SIGNAL (1<<1) +#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1)) __u32 flags; }; diff --git a/kernel/kernel/.cocciconfig b/kernel/kernel/.cocciconfig new file mode 100644 index 000000000..43967c6b2 --- /dev/null +++ b/kernel/kernel/.cocciconfig @@ -0,0 +1,3 @@ +[spatch] + options = --timeout 200 + options = --use-gitgrep diff --git a/kernel/kernel/.gitignore b/kernel/kernel/.gitignore index b3097bde4..0c39aa20b 100644 --- a/kernel/kernel/.gitignore +++ b/kernel/kernel/.gitignore @@ -1,7 +1,117 @@ # -# Generated files +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. # -config_data.h -config_data.gz -timeconst.h -hz.bc +# NOTE! Please use 'git ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# +# Normal rules +# +.* +*.o +*.o.* +*.a +*.s +*.ko +*.so +*.so.dbg +*.mod.c +*.i +*.lst +*.symtypes +*.order +*.elf +*.bin +*.tar +*.gz +*.bz2 +*.lzma +*.xz +*.lz4 +*.lzo +*.patch +*.gcno +*.ll +modules.builtin +Module.symvers +*.dwo +*.su +*.c.[012]*.* + +# +# Top-level generic files +# +/tags +/TAGS +/linux +/vmlinux +/vmlinux.32 +/vmlinux-gdb.py +/vmlinuz +/System.map +/Module.markers + +# +# Debian directory (make deb-pkg) +# +/debian/ + +# +# tar directory (make tar*-pkg) +# +/tar-install/ + +# +# git files that we don't want to ignore even if they are dot-files +# +!.gitignore +!.mailmap +!.cocciconfig + +# +# Generated include files +# +include/config +include/generated +arch/*/include/generated + +# stgit generated dirs +patches-* + +# quilt's files +patches +series + +# cscope files +cscope.* +ncscope.* + +# gnu global files +GPATH +GRTAGS +GSYMS +GTAGS + +# id-utils files +ID + +*.orig +*~ +\#*# + +# +# Leavings from module signing +# +extra_certificates +signing_key.pem +signing_key.priv +signing_key.x509 +x509.genkey + +# Kconfig presets +all.config + +# Kdevelop4 +*.kdev4 diff --git a/kernel/kernel/.mailmap b/kernel/kernel/.mailmap new file mode 100644 index 000000000..c021f2977 --- /dev/null +++ b/kernel/kernel/.mailmap @@ -0,0 +1,191 @@ +# +# This list is used by git-shortlog to fix a few botched name translations +# in the git archive, either because the author's full name was messed up +# and/or not always written the same way, making contributions from the +# same person appearing not to be so or badly displayed. +# +# repo-abbrev: /pub/scm/linux/kernel/git/ +# + +Aaron Durbin +Adam Oldham +Adam Radford +Adrian Bunk +Adriana Reus +Alan Cox +Alan Cox +Aleksey Gorelov +Aleksandar Markovic +Al Viro +Al Viro +Andreas Herrmann +Andrey Ryabinin +Andrew Morton +Andrew Vasquez +Andy Adamson +Antoine Tenart +Antonio Ospite +Archit Taneja +Arnaud Patard +Arnd Bergmann +Axel Dyks +Axel Lin +Ben Gardner +Ben M Cahill +Björn Steinbrink +Boris Brezillon +Boris Brezillon +Boris Brezillon +Brian Avery +Brian King +Christoph Hellwig +Christophe Ricard +Corey Minyard +Damian Hobson-Garcia +David Brownell +David Woodhouse +Deng-Cheng Zhu +Dmitry Eremin-Solenikov +Domen Puncer +Douglas Gilbert +Ed L. Cashin +Evgeniy Polyakov +Felipe W Damasio +Felix Kuhling +Felix Moeller +Filipe Lautert +Franck Bui-Huu +Frank Rowand +Frank Rowand +Frank Rowand +Frank Zago +Greg Kroah-Hartman +Greg Kroah-Hartman +Greg Kroah-Hartman +Henk Vergonet +Henrik Kretzschmar +Henrik Rydberg +Herbert Xu +Jacob Shin +James Bottomley +James Bottomley +James E Wilson +James Hogan +James Hogan +James Ketrenos +Javi Merino + +Jean Tourrilhes +Jeff Garzik +Jens Axboe +Jens Osterkamp +Johan Hovold +Johan Hovold +John Paul Adrian Glaubitz +John Stultz + + + + + +Juha Yrjola +Juha Yrjola +Juha Yrjola +Kay Sievers +Kenneth W Chen +Konstantin Khlebnikov +Koushik +Krzysztof Kozlowski +Krzysztof Kozlowski +Kuninori Morimoto +Leonid I Ananiev +Linas Vepstas +Linus Lüssing +Linus Lüssing +Maciej W. Rozycki +Marcin Nowakowski +Mark Brown +Martin Kepplinger +Martin Kepplinger +Matthieu CASTET +Mauro Carvalho Chehab +Mauro Carvalho Chehab +Mauro Carvalho Chehab +Mauro Carvalho Chehab +Mauro Carvalho Chehab +Mauro Carvalho Chehab +Mauro Carvalho Chehab +Matt Ranostay Matthew Ranostay +Matt Ranostay +Matt Ranostay +Matt Redfearn +Mayuresh Janorkar +Michael Buesch +Michel Dänzer +Miodrag Dinic +Mitesh shah +Mohit Kumar +Morten Welinder +Morten Welinder +Morten Welinder +Morten Welinder +Mythri P K +Nguyen Anh Quynh +Paolo 'Blaisorblade' Giarrusso +Patrick Mochel +Paul Burton +Peter A Jonsson +Peter Oruba +Peter Oruba +Pratyush Anand +Praveen BP +Qais Yousef +Rajesh Shah +Ralf Baechle +Ralf Wildenhues +Randy Dunlap +Rémi Denis-Courmont +Ricardo Ribalda Delgado +Rudolf Marek +Rui Saraiva +Sachin P Sant +Sarangdhar Joshi +Sam Ravnborg +Santosh Shilimkar +Santosh Shilimkar +Sascha Hauer +S.Çağlar Onur +Sebastian Reichel +Sebastian Reichel +Shiraz Hashim +Shuah Khan +Shuah Khan +Shuah Khan +Shuah Khan +Simon Kelley +Stéphane Witzmann +Stephen Hemminger +Subash Abhinov Kasiviswanathan +Subhash Jadavani +Sudeep Holla Sudeep KarkadaNagesha +Sumit Semwal +Tejun Heo +Thomas Graf +Thomas Pedersen +Tony Luck +Tsuneo Yoshioka +Uwe Kleine-König +Uwe Kleine-König +Uwe Kleine-König +Valdis Kletnieks +Viresh Kumar +Viresh Kumar +Viresh Kumar +Vlad Dogaru +Vladimir Davydov +Vladimir Davydov +Takashi YOSHII +Yakir Yang +Yusuke Goda +Gustavo Padovan +Gustavo Padovan diff --git a/kernel/kernel/sched/cpufreq_schedutil.c b/kernel/kernel/sched/cpufreq_schedutil.c index 9209d83ec..ba0da243f 100644 --- a/kernel/kernel/sched/cpufreq_schedutil.c +++ b/kernel/kernel/sched/cpufreq_schedutil.c @@ -649,6 +649,7 @@ static int sugov_start(struct cpufreq_policy *policy) struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu); memset(sg_cpu, 0, sizeof(*sg_cpu)); + sg_cpu->cpu = cpu; sg_cpu->sg_policy = sg_policy; sg_cpu->flags = SCHED_CPUFREQ_RT; sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq; @@ -714,11 +715,6 @@ struct cpufreq_governor *cpufreq_default_governor(void) static int __init sugov_register(void) { - int cpu; - - for_each_possible_cpu(cpu) - per_cpu(sugov_cpu, cpu).cpu = cpu; - return cpufreq_register_governor(&schedutil_gov); } fs_initcall(sugov_register); diff --git a/kernel/kernel/workqueue_internal.h b/kernel/kernel/workqueue_internal.h index efdd72e15..d390d1be3 100644 --- a/kernel/kernel/workqueue_internal.h +++ b/kernel/kernel/workqueue_internal.h @@ -10,6 +10,7 @@ #include #include +#include struct worker_pool; @@ -60,7 +61,7 @@ struct worker { */ static inline struct worker *current_wq_worker(void) { - if (current->flags & PF_WQ_WORKER) + if (in_task() && (current->flags & PF_WQ_WORKER)) return kthread_data(current); return NULL; } diff --git a/kernel/lib/asn1_decoder.c b/kernel/lib/asn1_decoder.c index fef5d2e11..1ef0cec38 100644 --- a/kernel/lib/asn1_decoder.c +++ b/kernel/lib/asn1_decoder.c @@ -228,7 +228,7 @@ next_op: hdr = 2; /* Extract a tag from the data */ - if (unlikely(dp >= datalen - 1)) + if (unlikely(datalen - dp < 2)) goto data_overrun_error; tag = data[dp++]; if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) @@ -274,7 +274,7 @@ next_op: int n = len - 0x80; if (unlikely(n > 2)) goto length_too_long; - if (unlikely(dp >= datalen - n)) + if (unlikely(n > datalen - dp)) goto data_overrun_error; hdr += n; for (len = 0; n > 0; n--) { diff --git a/kernel/net/8021q/vlan.c b/kernel/net/8021q/vlan.c index 9649579b5..4a72ee4e2 100644 --- a/kernel/net/8021q/vlan.c +++ b/kernel/net/8021q/vlan.c @@ -376,6 +376,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, dev->name); vlan_vid_add(dev, htons(ETH_P_8021Q), 0); } + if (event == NETDEV_DOWN && + (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) + vlan_vid_del(dev, htons(ETH_P_8021Q), 0); vlan_info = rtnl_dereference(dev->vlan_info); if (!vlan_info) @@ -423,9 +426,6 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, struct net_device *tmp; LIST_HEAD(close_list); - if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) - vlan_vid_del(dev, htons(ETH_P_8021Q), 0); - /* Put all VLANs for this dev in the down state too. */ vlan_group_for_each_dev(grp, i, vlandev) { flgs = vlandev->flags; diff --git a/kernel/net/core/skbuff.c b/kernel/net/core/skbuff.c index 246560769..e140ba49b 100644 --- a/kernel/net/core/skbuff.c +++ b/kernel/net/core/skbuff.c @@ -4864,6 +4864,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) if (!xnet) return; + ipvs_reset(skb); skb_orphan(skb); skb->mark = 0; } diff --git a/kernel/net/dsa/switch.c b/kernel/net/dsa/switch.c index e6c06aa34..1e2929f42 100644 --- a/kernel/net/dsa/switch.c +++ b/kernel/net/dsa/switch.c @@ -133,6 +133,8 @@ static int dsa_switch_mdb_add(struct dsa_switch *ds, if (err) return err; } + + return 0; } for_each_set_bit(port, group, ds->num_ports) @@ -180,6 +182,8 @@ static int dsa_switch_vlan_add(struct dsa_switch *ds, if (err) return err; } + + return 0; } for_each_set_bit(port, members, ds->num_ports) diff --git a/kernel/net/ipv4/tcp_input.c b/kernel/net/ipv4/tcp_input.c index 5a87a0064..b6bb3cdfa 100644 --- a/kernel/net/ipv4/tcp_input.c +++ b/kernel/net/ipv4/tcp_input.c @@ -115,7 +115,7 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2; #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) -#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE) +#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) #define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) @@ -2615,7 +2615,6 @@ void tcp_simple_retransmit(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; unsigned int mss = tcp_current_mss(sk); - u32 prior_lost = tp->lost_out; tcp_for_write_queue(skb, sk) { if (skb == tcp_send_head(sk)) @@ -2632,7 +2631,7 @@ void tcp_simple_retransmit(struct sock *sk) tcp_clear_retrans_hints_partial(tp); - if (prior_lost == tp->lost_out) + if (!tp->lost_out) return; if (tcp_is_reno(tp)) diff --git a/kernel/net/ipv4/tcp_offload.c b/kernel/net/ipv4/tcp_offload.c index 11f69bbf9..b6a2aa1dc 100644 --- a/kernel/net/ipv4/tcp_offload.c +++ b/kernel/net/ipv4/tcp_offload.c @@ -149,11 +149,19 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb, * is freed by GSO engine */ if (copy_destructor) { + int delta; + swap(gso_skb->sk, skb->sk); swap(gso_skb->destructor, skb->destructor); sum_truesize += skb->truesize; - refcount_add(sum_truesize - gso_skb->truesize, - &skb->sk->sk_wmem_alloc); + delta = sum_truesize - gso_skb->truesize; + /* In some pathological cases, delta can be negative. + * We need to either use refcount_add() or refcount_sub_and_test() + */ + if (likely(delta >= 0)) + refcount_add(delta, &skb->sk->sk_wmem_alloc); + else + WARN_ON_ONCE(refcount_sub_and_test(-delta, &skb->sk->sk_wmem_alloc)); } delta = htonl(oldlen + (skb_tail_pointer(skb) - diff --git a/kernel/net/l2tp/l2tp_ip.c b/kernel/net/l2tp/l2tp_ip.c index 4d322c1b7..e4280b656 100644 --- a/kernel/net/l2tp/l2tp_ip.c +++ b/kernel/net/l2tp/l2tp_ip.c @@ -123,6 +123,7 @@ static int l2tp_ip_recv(struct sk_buff *skb) unsigned char *ptr, *optr; struct l2tp_session *session; struct l2tp_tunnel *tunnel = NULL; + struct iphdr *iph; int length; if (!pskb_may_pull(skb, 4)) @@ -178,24 +179,17 @@ pass_up: goto discard; tunnel_id = ntohl(*(__be32 *) &skb->data[4]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel) { - sk = tunnel->sock; - sock_hold(sk); - } else { - struct iphdr *iph = (struct iphdr *) skb_network_header(skb); + iph = (struct iphdr *)skb_network_header(skb); - read_lock_bh(&l2tp_ip_lock); - sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr, - inet_iif(skb), tunnel_id); - if (!sk) { - read_unlock_bh(&l2tp_ip_lock); - goto discard; - } - - sock_hold(sk); + read_lock_bh(&l2tp_ip_lock); + sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr, inet_iif(skb), + tunnel_id); + if (!sk) { read_unlock_bh(&l2tp_ip_lock); + goto discard; } + sock_hold(sk); + read_unlock_bh(&l2tp_ip_lock); if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_put; diff --git a/kernel/net/l2tp/l2tp_ip6.c b/kernel/net/l2tp/l2tp_ip6.c index 88b397c30..8bcaa975b 100644 --- a/kernel/net/l2tp/l2tp_ip6.c +++ b/kernel/net/l2tp/l2tp_ip6.c @@ -136,6 +136,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb) unsigned char *ptr, *optr; struct l2tp_session *session; struct l2tp_tunnel *tunnel = NULL; + struct ipv6hdr *iph; int length; if (!pskb_may_pull(skb, 4)) @@ -192,24 +193,17 @@ pass_up: goto discard; tunnel_id = ntohl(*(__be32 *) &skb->data[4]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel) { - sk = tunnel->sock; - sock_hold(sk); - } else { - struct ipv6hdr *iph = ipv6_hdr(skb); + iph = ipv6_hdr(skb); - read_lock_bh(&l2tp_ip6_lock); - sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr, - inet6_iif(skb), tunnel_id); - if (!sk) { - read_unlock_bh(&l2tp_ip6_lock); - goto discard; - } - - sock_hold(sk); + read_lock_bh(&l2tp_ip6_lock); + sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr, + inet6_iif(skb), tunnel_id); + if (!sk) { read_unlock_bh(&l2tp_ip6_lock); + goto discard; } + sock_hold(sk); + read_unlock_bh(&l2tp_ip6_lock); if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_put; diff --git a/kernel/net/qrtr/qrtr.c b/kernel/net/qrtr/qrtr.c index c2f5c1355..78418f384 100644 --- a/kernel/net/qrtr/qrtr.c +++ b/kernel/net/qrtr/qrtr.c @@ -1085,7 +1085,7 @@ static int __init qrtr_proto_init(void) return 0; } -module_init(qrtr_proto_init); +postcore_initcall(qrtr_proto_init); static void __exit qrtr_proto_fini(void) { diff --git a/kernel/net/rds/ib_recv.c b/kernel/net/rds/ib_recv.c index 9722bf839..b4e421aa9 100644 --- a/kernel/net/rds/ib_recv.c +++ b/kernel/net/rds/ib_recv.c @@ -410,14 +410,14 @@ void rds_ib_recv_refill(struct rds_connection *conn, int prefill, gfp_t gfp) break; } - /* XXX when can this fail? */ - ret = ib_post_recv(ic->i_cm_id->qp, &recv->r_wr, &failed_wr); - rdsdebug("recv %p ibinc %p page %p addr %lu ret %d\n", recv, + rdsdebug("recv %p ibinc %p page %p addr %lu\n", recv, recv->r_ibinc, sg_page(&recv->r_frag->f_sg), (long) ib_sg_dma_address( ic->i_cm_id->device, - &recv->r_frag->f_sg), - ret); + &recv->r_frag->f_sg)); + + /* XXX when can this fail? */ + ret = ib_post_recv(ic->i_cm_id->qp, &recv->r_wr, &failed_wr); if (ret) { rds_ib_conn_error(conn, "recv post on " "%pI4 returned %d, disconnecting and " diff --git a/kernel/net/sched/act_api.c b/kernel/net/sched/act_api.c index ca2ff0b31..8f2c63514 100644 --- a/kernel/net/sched/act_api.c +++ b/kernel/net/sched/act_api.c @@ -78,7 +78,6 @@ static void tcf_idr_remove(struct tcf_idrinfo *idrinfo, struct tc_action *p) spin_lock_bh(&idrinfo->lock); idr_remove_ext(&idrinfo->action_idr, p->tcfa_index); spin_unlock_bh(&idrinfo->lock); - put_net(idrinfo->net); gen_kill_estimator(&p->tcfa_rate_est); free_tcf(p); } @@ -337,7 +336,6 @@ err3: p->idrinfo = idrinfo; p->ops = ops; INIT_LIST_HEAD(&p->list); - get_net(idrinfo->net); *a = p; return 0; } diff --git a/kernel/net/sched/act_bpf.c b/kernel/net/sched/act_bpf.c index 9bce8cc84..c0c707eb2 100644 --- a/kernel/net/sched/act_bpf.c +++ b/kernel/net/sched/act_bpf.c @@ -398,7 +398,7 @@ static __net_init int bpf_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, bpf_net_id); - return tc_action_net_init(tn, &act_bpf_ops, net); + return tc_action_net_init(tn, &act_bpf_ops); } static void __net_exit bpf_exit_net(struct net *net) diff --git a/kernel/net/sched/act_connmark.c b/kernel/net/sched/act_connmark.c index 34e52d01a..10b7a8855 100644 --- a/kernel/net/sched/act_connmark.c +++ b/kernel/net/sched/act_connmark.c @@ -206,7 +206,7 @@ static __net_init int connmark_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, connmark_net_id); - return tc_action_net_init(tn, &act_connmark_ops, net); + return tc_action_net_init(tn, &act_connmark_ops); } static void __net_exit connmark_exit_net(struct net *net) diff --git a/kernel/net/sched/act_csum.c b/kernel/net/sched/act_csum.c index 35171df2e..1c40caadc 100644 --- a/kernel/net/sched/act_csum.c +++ b/kernel/net/sched/act_csum.c @@ -626,7 +626,7 @@ static __net_init int csum_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, csum_net_id); - return tc_action_net_init(tn, &act_csum_ops, net); + return tc_action_net_init(tn, &act_csum_ops); } static void __net_exit csum_exit_net(struct net *net) diff --git a/kernel/net/sched/act_gact.c b/kernel/net/sched/act_gact.c index ef7f7f39d..e29a48ef7 100644 --- a/kernel/net/sched/act_gact.c +++ b/kernel/net/sched/act_gact.c @@ -232,7 +232,7 @@ static __net_init int gact_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, gact_net_id); - return tc_action_net_init(tn, &act_gact_ops, net); + return tc_action_net_init(tn, &act_gact_ops); } static void __net_exit gact_exit_net(struct net *net) diff --git a/kernel/net/sched/act_ife.c b/kernel/net/sched/act_ife.c index f65e4b505..8ccd35825 100644 --- a/kernel/net/sched/act_ife.c +++ b/kernel/net/sched/act_ife.c @@ -818,7 +818,7 @@ static __net_init int ife_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, ife_net_id); - return tc_action_net_init(tn, &act_ife_ops, net); + return tc_action_net_init(tn, &act_ife_ops); } static void __net_exit ife_exit_net(struct net *net) diff --git a/kernel/net/sched/act_ipt.c b/kernel/net/sched/act_ipt.c index dbdf3b247..d9e399a7e 100644 --- a/kernel/net/sched/act_ipt.c +++ b/kernel/net/sched/act_ipt.c @@ -334,7 +334,7 @@ static __net_init int ipt_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, ipt_net_id); - return tc_action_net_init(tn, &act_ipt_ops, net); + return tc_action_net_init(tn, &act_ipt_ops); } static void __net_exit ipt_exit_net(struct net *net) @@ -384,7 +384,7 @@ static __net_init int xt_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, xt_net_id); - return tc_action_net_init(tn, &act_xt_ops, net); + return tc_action_net_init(tn, &act_xt_ops); } static void __net_exit xt_exit_net(struct net *net) diff --git a/kernel/net/sched/act_mirred.c b/kernel/net/sched/act_mirred.c index 84759cfd5..416627c66 100644 --- a/kernel/net/sched/act_mirred.c +++ b/kernel/net/sched/act_mirred.c @@ -343,7 +343,7 @@ static __net_init int mirred_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, mirred_net_id); - return tc_action_net_init(tn, &act_mirred_ops, net); + return tc_action_net_init(tn, &act_mirred_ops); } static void __net_exit mirred_exit_net(struct net *net) diff --git a/kernel/net/sched/act_nat.c b/kernel/net/sched/act_nat.c index 7eeaaf921..c365d01b9 100644 --- a/kernel/net/sched/act_nat.c +++ b/kernel/net/sched/act_nat.c @@ -307,7 +307,7 @@ static __net_init int nat_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, nat_net_id); - return tc_action_net_init(tn, &act_nat_ops, net); + return tc_action_net_init(tn, &act_nat_ops); } static void __net_exit nat_exit_net(struct net *net) diff --git a/kernel/net/sched/act_pedit.c b/kernel/net/sched/act_pedit.c index b3d82c334..491fe5deb 100644 --- a/kernel/net/sched/act_pedit.c +++ b/kernel/net/sched/act_pedit.c @@ -450,7 +450,7 @@ static __net_init int pedit_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, pedit_net_id); - return tc_action_net_init(tn, &act_pedit_ops, net); + return tc_action_net_init(tn, &act_pedit_ops); } static void __net_exit pedit_exit_net(struct net *net) diff --git a/kernel/net/sched/act_police.c b/kernel/net/sched/act_police.c index 9ec42b26e..3bb2ebf9e 100644 --- a/kernel/net/sched/act_police.c +++ b/kernel/net/sched/act_police.c @@ -331,7 +331,7 @@ static __net_init int police_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, police_net_id); - return tc_action_net_init(tn, &act_police_ops, net); + return tc_action_net_init(tn, &act_police_ops); } static void __net_exit police_exit_net(struct net *net) diff --git a/kernel/net/sched/act_sample.c b/kernel/net/sched/act_sample.c index e69a1e3a3..8b5abcd2f 100644 --- a/kernel/net/sched/act_sample.c +++ b/kernel/net/sched/act_sample.c @@ -240,7 +240,7 @@ static __net_init int sample_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, sample_net_id); - return tc_action_net_init(tn, &act_sample_ops, net); + return tc_action_net_init(tn, &act_sample_ops); } static void __net_exit sample_exit_net(struct net *net) diff --git a/kernel/net/sched/act_simple.c b/kernel/net/sched/act_simple.c index a8d0ea95f..e7b57e507 100644 --- a/kernel/net/sched/act_simple.c +++ b/kernel/net/sched/act_simple.c @@ -201,7 +201,7 @@ static __net_init int simp_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, simp_net_id); - return tc_action_net_init(tn, &act_simp_ops, net); + return tc_action_net_init(tn, &act_simp_ops); } static void __net_exit simp_exit_net(struct net *net) diff --git a/kernel/net/sched/act_skbedit.c b/kernel/net/sched/act_skbedit.c index fbac62472..59949d61f 100644 --- a/kernel/net/sched/act_skbedit.c +++ b/kernel/net/sched/act_skbedit.c @@ -238,7 +238,7 @@ static __net_init int skbedit_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbedit_net_id); - return tc_action_net_init(tn, &act_skbedit_ops, net); + return tc_action_net_init(tn, &act_skbedit_ops); } static void __net_exit skbedit_exit_net(struct net *net) diff --git a/kernel/net/sched/act_skbmod.c b/kernel/net/sched/act_skbmod.c index 8e12d8897..b642ad3d3 100644 --- a/kernel/net/sched/act_skbmod.c +++ b/kernel/net/sched/act_skbmod.c @@ -263,7 +263,7 @@ static __net_init int skbmod_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, skbmod_net_id); - return tc_action_net_init(tn, &act_skbmod_ops, net); + return tc_action_net_init(tn, &act_skbmod_ops); } static void __net_exit skbmod_exit_net(struct net *net) diff --git a/kernel/net/sched/act_tunnel_key.c b/kernel/net/sched/act_tunnel_key.c index c33faa373..30c96274c 100644 --- a/kernel/net/sched/act_tunnel_key.c +++ b/kernel/net/sched/act_tunnel_key.c @@ -322,7 +322,7 @@ static __net_init int tunnel_key_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); - return tc_action_net_init(tn, &act_tunnel_key_ops, net); + return tc_action_net_init(tn, &act_tunnel_key_ops); } static void __net_exit tunnel_key_exit_net(struct net *net) diff --git a/kernel/net/sched/act_vlan.c b/kernel/net/sched/act_vlan.c index 115fc33cc..16eb067a8 100644 --- a/kernel/net/sched/act_vlan.c +++ b/kernel/net/sched/act_vlan.c @@ -269,7 +269,7 @@ static __net_init int vlan_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, vlan_net_id); - return tc_action_net_init(tn, &act_vlan_ops, net); + return tc_action_net_init(tn, &act_vlan_ops); } static void __net_exit vlan_exit_net(struct net *net) diff --git a/kernel/net/sched/cls_api.c b/kernel/net/sched/cls_api.c index b2d310745..ecbb019ef 100644 --- a/kernel/net/sched/cls_api.c +++ b/kernel/net/sched/cls_api.c @@ -927,6 +927,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, exts->actions[i++] = act; exts->nr_actions = i; } + exts->net = net; } #else if ((exts->action && tb[exts->action]) || diff --git a/kernel/net/sched/cls_basic.c b/kernel/net/sched/cls_basic.c index f177649a2..e43c56d5b 100644 --- a/kernel/net/sched/cls_basic.c +++ b/kernel/net/sched/cls_basic.c @@ -85,16 +85,21 @@ static int basic_init(struct tcf_proto *tp) return 0; } +static void __basic_delete_filter(struct basic_filter *f) +{ + tcf_exts_destroy(&f->exts); + tcf_em_tree_destroy(&f->ematches); + tcf_exts_put_net(&f->exts); + kfree(f); +} + static void basic_delete_filter_work(struct work_struct *work) { struct basic_filter *f = container_of(work, struct basic_filter, work); rtnl_lock(); - tcf_exts_destroy(&f->exts); - tcf_em_tree_destroy(&f->ematches); + __basic_delete_filter(f); rtnl_unlock(); - - kfree(f); } static void basic_delete_filter(struct rcu_head *head) @@ -113,7 +118,10 @@ static void basic_destroy(struct tcf_proto *tp) list_for_each_entry_safe(f, n, &head->flist, link) { list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); - call_rcu(&f->rcu, basic_delete_filter); + if (tcf_exts_get_net(&f->exts)) + call_rcu(&f->rcu, basic_delete_filter); + else + __basic_delete_filter(f); } kfree_rcu(head, rcu); } @@ -125,6 +133,7 @@ static int basic_delete(struct tcf_proto *tp, void *arg, bool *last) list_del_rcu(&f->link); tcf_unbind_filter(tp, &f->res); + tcf_exts_get_net(&f->exts); call_rcu(&f->rcu, basic_delete_filter); *last = list_empty(&head->flist); return 0; @@ -219,6 +228,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb, if (fold) { list_replace_rcu(&fold->link, &fnew->link); tcf_unbind_filter(tp, &fold->res); + tcf_exts_get_net(&fold->exts); call_rcu(&fold->rcu, basic_delete_filter); } else { list_add_rcu(&fnew->link, &head->flist); diff --git a/kernel/net/sched/cls_bpf.c b/kernel/net/sched/cls_bpf.c index 037a3ae86..990eb4d91 100644 --- a/kernel/net/sched/cls_bpf.c +++ b/kernel/net/sched/cls_bpf.c @@ -249,6 +249,7 @@ static int cls_bpf_init(struct tcf_proto *tp) static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog) { tcf_exts_destroy(&prog->exts); + tcf_exts_put_net(&prog->exts); if (cls_bpf_is_ebpf(prog)) bpf_prog_put(prog->filter); @@ -282,7 +283,10 @@ static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog) cls_bpf_stop_offload(tp, prog); list_del_rcu(&prog->link); tcf_unbind_filter(tp, &prog->res); - call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu); + if (tcf_exts_get_net(&prog->exts)) + call_rcu(&prog->rcu, cls_bpf_delete_prog_rcu); + else + __cls_bpf_delete_prog(prog); } static int cls_bpf_delete(struct tcf_proto *tp, void *arg, bool *last) @@ -516,6 +520,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, if (oldprog) { list_replace_rcu(&oldprog->link, &prog->link); tcf_unbind_filter(tp, &oldprog->res); + tcf_exts_get_net(&oldprog->exts); call_rcu(&oldprog->rcu, cls_bpf_delete_prog_rcu); } else { list_add_rcu(&prog->link, &head->plist); diff --git a/kernel/net/sched/cls_cgroup.c b/kernel/net/sched/cls_cgroup.c index a97e069be..309d58992 100644 --- a/kernel/net/sched/cls_cgroup.c +++ b/kernel/net/sched/cls_cgroup.c @@ -60,15 +60,21 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = { [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, }; +static void __cls_cgroup_destroy(struct cls_cgroup_head *head) +{ + tcf_exts_destroy(&head->exts); + tcf_em_tree_destroy(&head->ematches); + tcf_exts_put_net(&head->exts); + kfree(head); +} + static void cls_cgroup_destroy_work(struct work_struct *work) { struct cls_cgroup_head *head = container_of(work, struct cls_cgroup_head, work); rtnl_lock(); - tcf_exts_destroy(&head->exts); - tcf_em_tree_destroy(&head->ematches); - kfree(head); + __cls_cgroup_destroy(head); rtnl_unlock(); } @@ -124,8 +130,10 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, goto errout; rcu_assign_pointer(tp->root, new); - if (head) + if (head) { + tcf_exts_get_net(&head->exts); call_rcu(&head->rcu, cls_cgroup_destroy_rcu); + } return 0; errout: tcf_exts_destroy(&new->exts); @@ -138,8 +146,12 @@ static void cls_cgroup_destroy(struct tcf_proto *tp) struct cls_cgroup_head *head = rtnl_dereference(tp->root); /* Head can still be NULL due to cls_cgroup_init(). */ - if (head) - call_rcu(&head->rcu, cls_cgroup_destroy_rcu); + if (head) { + if (tcf_exts_get_net(&head->exts)) + call_rcu(&head->rcu, cls_cgroup_destroy_rcu); + else + __cls_cgroup_destroy(head); + } } static int cls_cgroup_delete(struct tcf_proto *tp, void *arg, bool *last) diff --git a/kernel/net/sched/cls_flow.c b/kernel/net/sched/cls_flow.c index 67f3a2af6..85f765cff 100644 --- a/kernel/net/sched/cls_flow.c +++ b/kernel/net/sched/cls_flow.c @@ -372,15 +372,21 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, }; +static void __flow_destroy_filter(struct flow_filter *f) +{ + del_timer_sync(&f->perturb_timer); + tcf_exts_destroy(&f->exts); + tcf_em_tree_destroy(&f->ematches); + tcf_exts_put_net(&f->exts); + kfree(f); +} + static void flow_destroy_filter_work(struct work_struct *work) { struct flow_filter *f = container_of(work, struct flow_filter, work); rtnl_lock(); - del_timer_sync(&f->perturb_timer); - tcf_exts_destroy(&f->exts); - tcf_em_tree_destroy(&f->ematches); - kfree(f); + __flow_destroy_filter(f); rtnl_unlock(); } @@ -552,8 +558,10 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, *arg = fnew; - if (fold) + if (fold) { + tcf_exts_get_net(&fold->exts); call_rcu(&fold->rcu, flow_destroy_filter); + } return 0; err2: @@ -570,6 +578,7 @@ static int flow_delete(struct tcf_proto *tp, void *arg, bool *last) struct flow_filter *f = arg; list_del_rcu(&f->list); + tcf_exts_get_net(&f->exts); call_rcu(&f->rcu, flow_destroy_filter); *last = list_empty(&head->filters); return 0; @@ -594,7 +603,10 @@ static void flow_destroy(struct tcf_proto *tp) list_for_each_entry_safe(f, next, &head->filters, list) { list_del_rcu(&f->list); - call_rcu(&f->rcu, flow_destroy_filter); + if (tcf_exts_get_net(&f->exts)) + call_rcu(&f->rcu, flow_destroy_filter); + else + __flow_destroy_filter(f); } kfree_rcu(head, rcu); } diff --git a/kernel/net/sched/cls_flower.c b/kernel/net/sched/cls_flower.c index 5b5722c8b..7a838d1c1 100644 --- a/kernel/net/sched/cls_flower.c +++ b/kernel/net/sched/cls_flower.c @@ -218,13 +218,19 @@ static int fl_init(struct tcf_proto *tp) return 0; } +static void __fl_destroy_filter(struct cls_fl_filter *f) +{ + tcf_exts_destroy(&f->exts); + tcf_exts_put_net(&f->exts); + kfree(f); +} + static void fl_destroy_filter_work(struct work_struct *work) { struct cls_fl_filter *f = container_of(work, struct cls_fl_filter, work); rtnl_lock(); - tcf_exts_destroy(&f->exts); - kfree(f); + __fl_destroy_filter(f); rtnl_unlock(); } @@ -318,7 +324,10 @@ static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f) if (!tc_skip_hw(f->flags)) fl_hw_destroy_filter(tp, f); tcf_unbind_filter(tp, &f->res); - call_rcu(&f->rcu, fl_destroy_filter); + if (tcf_exts_get_net(&f->exts)) + call_rcu(&f->rcu, fl_destroy_filter); + else + __fl_destroy_filter(f); } static void fl_destroy_sleepable(struct work_struct *work) @@ -988,6 +997,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, idr_replace_ext(&head->handle_idr, fnew, fnew->handle); list_replace_rcu(&fold->list, &fnew->list); tcf_unbind_filter(tp, &fold->res); + tcf_exts_get_net(&fold->exts); call_rcu(&fold->rcu, fl_destroy_filter); } else { list_add_tail_rcu(&fnew->list, &head->filters); diff --git a/kernel/net/sched/cls_fw.c b/kernel/net/sched/cls_fw.c index 99183b862..7f45e5ab8 100644 --- a/kernel/net/sched/cls_fw.c +++ b/kernel/net/sched/cls_fw.c @@ -122,13 +122,19 @@ static int fw_init(struct tcf_proto *tp) return 0; } +static void __fw_delete_filter(struct fw_filter *f) +{ + tcf_exts_destroy(&f->exts); + tcf_exts_put_net(&f->exts); + kfree(f); +} + static void fw_delete_filter_work(struct work_struct *work) { struct fw_filter *f = container_of(work, struct fw_filter, work); rtnl_lock(); - tcf_exts_destroy(&f->exts); - kfree(f); + __fw_delete_filter(f); rtnl_unlock(); } @@ -154,7 +160,10 @@ static void fw_destroy(struct tcf_proto *tp) RCU_INIT_POINTER(head->ht[h], rtnl_dereference(f->next)); tcf_unbind_filter(tp, &f->res); - call_rcu(&f->rcu, fw_delete_filter); + if (tcf_exts_get_net(&f->exts)) + call_rcu(&f->rcu, fw_delete_filter); + else + __fw_delete_filter(f); } } kfree_rcu(head, rcu); @@ -179,6 +188,7 @@ static int fw_delete(struct tcf_proto *tp, void *arg, bool *last) if (pfp == f) { RCU_INIT_POINTER(*fp, rtnl_dereference(f->next)); tcf_unbind_filter(tp, &f->res); + tcf_exts_get_net(&f->exts); call_rcu(&f->rcu, fw_delete_filter); ret = 0; break; @@ -299,6 +309,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, RCU_INIT_POINTER(fnew->next, rtnl_dereference(pfp->next)); rcu_assign_pointer(*fp, fnew); tcf_unbind_filter(tp, &f->res); + tcf_exts_get_net(&f->exts); call_rcu(&f->rcu, fw_delete_filter); *arg = fnew; diff --git a/kernel/net/sched/cls_matchall.c b/kernel/net/sched/cls_matchall.c index c33f711b9..3684153cd 100644 --- a/kernel/net/sched/cls_matchall.c +++ b/kernel/net/sched/cls_matchall.c @@ -44,13 +44,19 @@ static int mall_init(struct tcf_proto *tp) return 0; } +static void __mall_destroy(struct cls_mall_head *head) +{ + tcf_exts_destroy(&head->exts); + tcf_exts_put_net(&head->exts); + kfree(head); +} + static void mall_destroy_work(struct work_struct *work) { struct cls_mall_head *head = container_of(work, struct cls_mall_head, work); rtnl_lock(); - tcf_exts_destroy(&head->exts); - kfree(head); + __mall_destroy(head); rtnl_unlock(); } @@ -109,7 +115,10 @@ static void mall_destroy(struct tcf_proto *tp) if (tc_should_offload(dev, head->flags)) mall_destroy_hw_filter(tp, head, (unsigned long) head); - call_rcu(&head->rcu, mall_destroy_rcu); + if (tcf_exts_get_net(&head->exts)) + call_rcu(&head->rcu, mall_destroy_rcu); + else + __mall_destroy(head); } static void *mall_get(struct tcf_proto *tp, u32 handle) diff --git a/kernel/net/sched/cls_route.c b/kernel/net/sched/cls_route.c index 4b14ccd8b..ac9a5b882 100644 --- a/kernel/net/sched/cls_route.c +++ b/kernel/net/sched/cls_route.c @@ -257,13 +257,19 @@ static int route4_init(struct tcf_proto *tp) return 0; } +static void __route4_delete_filter(struct route4_filter *f) +{ + tcf_exts_destroy(&f->exts); + tcf_exts_put_net(&f->exts); + kfree(f); +} + static void route4_delete_filter_work(struct work_struct *work) { struct route4_filter *f = container_of(work, struct route4_filter, work); rtnl_lock(); - tcf_exts_destroy(&f->exts); - kfree(f); + __route4_delete_filter(f); rtnl_unlock(); } @@ -297,7 +303,10 @@ static void route4_destroy(struct tcf_proto *tp) next = rtnl_dereference(f->next); RCU_INIT_POINTER(b->ht[h2], next); tcf_unbind_filter(tp, &f->res); - call_rcu(&f->rcu, route4_delete_filter); + if (tcf_exts_get_net(&f->exts)) + call_rcu(&f->rcu, route4_delete_filter); + else + __route4_delete_filter(f); } } RCU_INIT_POINTER(head->table[h1], NULL); @@ -338,6 +347,7 @@ static int route4_delete(struct tcf_proto *tp, void *arg, bool *last) /* Delete it */ tcf_unbind_filter(tp, &f->res); + tcf_exts_get_net(&f->exts); call_rcu(&f->rcu, route4_delete_filter); /* Strip RTNL protected tree */ @@ -541,6 +551,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, *arg = f; if (fold) { tcf_unbind_filter(tp, &fold->res); + tcf_exts_get_net(&fold->exts); call_rcu(&fold->rcu, route4_delete_filter); } return 0; diff --git a/kernel/net/sched/cls_rsvp.h b/kernel/net/sched/cls_rsvp.h index bdbc54178..cf325625c 100644 --- a/kernel/net/sched/cls_rsvp.h +++ b/kernel/net/sched/cls_rsvp.h @@ -285,13 +285,19 @@ static int rsvp_init(struct tcf_proto *tp) return -ENOBUFS; } +static void __rsvp_delete_filter(struct rsvp_filter *f) +{ + tcf_exts_destroy(&f->exts); + tcf_exts_put_net(&f->exts); + kfree(f); +} + static void rsvp_delete_filter_work(struct work_struct *work) { struct rsvp_filter *f = container_of(work, struct rsvp_filter, work); rtnl_lock(); - tcf_exts_destroy(&f->exts); - kfree(f); + __rsvp_delete_filter(f); rtnl_unlock(); } @@ -310,7 +316,10 @@ static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f) * grace period, since converted-to-rcu actions are relying on that * in cleanup() callback */ - call_rcu(&f->rcu, rsvp_delete_filter_rcu); + if (tcf_exts_get_net(&f->exts)) + call_rcu(&f->rcu, rsvp_delete_filter_rcu); + else + __rsvp_delete_filter(f); } static void rsvp_destroy(struct tcf_proto *tp) diff --git a/kernel/net/sched/cls_tcindex.c b/kernel/net/sched/cls_tcindex.c index beaa95e09..a76937ee0 100644 --- a/kernel/net/sched/cls_tcindex.c +++ b/kernel/net/sched/cls_tcindex.c @@ -139,13 +139,19 @@ static int tcindex_init(struct tcf_proto *tp) return 0; } +static void __tcindex_destroy_rexts(struct tcindex_filter_result *r) +{ + tcf_exts_destroy(&r->exts); + tcf_exts_put_net(&r->exts); +} + static void tcindex_destroy_rexts_work(struct work_struct *work) { struct tcindex_filter_result *r; r = container_of(work, struct tcindex_filter_result, work); rtnl_lock(); - tcf_exts_destroy(&r->exts); + __tcindex_destroy_rexts(r); rtnl_unlock(); } @@ -158,14 +164,20 @@ static void tcindex_destroy_rexts(struct rcu_head *head) tcf_queue_work(&r->work); } +static void __tcindex_destroy_fexts(struct tcindex_filter *f) +{ + tcf_exts_destroy(&f->result.exts); + tcf_exts_put_net(&f->result.exts); + kfree(f); +} + static void tcindex_destroy_fexts_work(struct work_struct *work) { struct tcindex_filter *f = container_of(work, struct tcindex_filter, work); rtnl_lock(); - tcf_exts_destroy(&f->result.exts); - kfree(f); + __tcindex_destroy_fexts(f); rtnl_unlock(); } @@ -210,10 +222,17 @@ found: * grace period, since converted-to-rcu actions are relying on that * in cleanup() callback */ - if (f) - call_rcu(&f->rcu, tcindex_destroy_fexts); - else - call_rcu(&r->rcu, tcindex_destroy_rexts); + if (f) { + if (tcf_exts_get_net(&f->result.exts)) + call_rcu(&f->rcu, tcindex_destroy_fexts); + else + __tcindex_destroy_fexts(f); + } else { + if (tcf_exts_get_net(&r->exts)) + call_rcu(&r->rcu, tcindex_destroy_rexts); + else + __tcindex_destroy_rexts(r); + } *last = false; return 0; diff --git a/kernel/net/sched/cls_u32.c b/kernel/net/sched/cls_u32.c index dadd1b344..b58eccb21 100644 --- a/kernel/net/sched/cls_u32.c +++ b/kernel/net/sched/cls_u32.c @@ -399,6 +399,7 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n, bool free_pf) { tcf_exts_destroy(&n->exts); + tcf_exts_put_net(&n->exts); if (n->ht_down) n->ht_down->refcnt--; #ifdef CONFIG_CLS_U32_PERF @@ -476,6 +477,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key) RCU_INIT_POINTER(*kp, key->next); tcf_unbind_filter(tp, &key->res); + tcf_exts_get_net(&key->exts); call_rcu(&key->rcu, u32_delete_key_freepf_rcu); return 0; } @@ -588,7 +590,10 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht) rtnl_dereference(n->next)); tcf_unbind_filter(tp, &n->res); u32_remove_hw_knode(tp, n->handle); - call_rcu(&n->rcu, u32_delete_key_freepf_rcu); + if (tcf_exts_get_net(&n->exts)) + call_rcu(&n->rcu, u32_delete_key_freepf_rcu); + else + u32_destroy_key(n->tp, n, true); } } } @@ -949,6 +954,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, u32_replace_knode(tp, tp_c, new); tcf_unbind_filter(tp, &n->res); + tcf_exts_get_net(&n->exts); call_rcu(&n->rcu, u32_delete_key_rcu); return 0; } diff --git a/kernel/net/xfrm/xfrm_input.c b/kernel/net/xfrm/xfrm_input.c index 82d20ee34..347ab3157 100644 --- a/kernel/net/xfrm/xfrm_input.c +++ b/kernel/net/xfrm/xfrm_input.c @@ -266,8 +266,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto lock; } - daddr = (xfrm_address_t *)(skb_network_header(skb) + - XFRM_SPI_SKB_CB(skb)->daddroff); family = XFRM_SPI_SKB_CB(skb)->family; /* if tunnel is present override skb->mark value with tunnel i_key */ @@ -294,6 +292,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop; } + daddr = (xfrm_address_t *)(skb_network_header(skb) + + XFRM_SPI_SKB_CB(skb)->daddroff); do { if (skb->sp->len == XFRM_MAX_DEPTH) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); diff --git a/kernel/net/xfrm/xfrm_policy.c b/kernel/net/xfrm/xfrm_policy.c index 8cafb3c0a..6eb228a70 100644 --- a/kernel/net/xfrm/xfrm_policy.c +++ b/kernel/net/xfrm/xfrm_policy.c @@ -1361,36 +1361,29 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl, struct net *net = xp_net(policy); int nx; int i, error; - xfrm_address_t *daddr = xfrm_flowi_daddr(fl, family); - xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family); xfrm_address_t tmp; for (nx = 0, i = 0; i < policy->xfrm_nr; i++) { struct xfrm_state *x; - xfrm_address_t *remote = daddr; - xfrm_address_t *local = saddr; + xfrm_address_t *local; + xfrm_address_t *remote; struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i]; - if (tmpl->mode == XFRM_MODE_TUNNEL || - tmpl->mode == XFRM_MODE_BEET) { - remote = &tmpl->id.daddr; - local = &tmpl->saddr; - if (xfrm_addr_any(local, tmpl->encap_family)) { - error = xfrm_get_saddr(net, fl->flowi_oif, - &tmp, remote, - tmpl->encap_family, 0); - if (error) - goto fail; - local = &tmp; - } + remote = &tmpl->id.daddr; + local = &tmpl->saddr; + if (xfrm_addr_any(local, tmpl->encap_family)) { + error = xfrm_get_saddr(net, fl->flowi_oif, + &tmp, remote, + tmpl->encap_family, 0); + if (error) + goto fail; + local = &tmp; } x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family); if (x && x->km.state == XFRM_STATE_VALID) { xfrm[nx++] = x; - daddr = remote; - saddr = local; continue; } if (x) { @@ -1787,19 +1780,23 @@ void xfrm_policy_cache_flush(void) put_online_cpus(); } -static bool xfrm_pol_dead(struct xfrm_dst *xdst) +static bool xfrm_xdst_can_reuse(struct xfrm_dst *xdst, + struct xfrm_state * const xfrm[], + int num) { - unsigned int num_pols = xdst->num_pols; - unsigned int pol_dead = 0, i; + const struct dst_entry *dst = &xdst->u.dst; + int i; - for (i = 0; i < num_pols; i++) - pol_dead |= xdst->pols[i]->walk.dead; + if (xdst->num_xfrms != num) + return false; - /* Mark DST_OBSOLETE_DEAD to fail the next xfrm_dst_check() */ - if (pol_dead) - xdst->u.dst.obsolete = DST_OBSOLETE_DEAD; + for (i = 0; i < num; i++) { + if (!dst || dst->xfrm != xfrm[i]) + return false; + dst = dst->child; + } - return pol_dead; + return xfrm_bundle_ok(xdst); } static struct xfrm_dst * @@ -1813,19 +1810,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, struct dst_entry *dst; int err; - xdst = this_cpu_read(xfrm_last_dst); - if (xdst && - xdst->u.dst.dev == dst_orig->dev && - xdst->num_pols == num_pols && - !xfrm_pol_dead(xdst) && - memcmp(xdst->pols, pols, - sizeof(struct xfrm_policy *) * num_pols) == 0 && - xfrm_bundle_ok(xdst)) { - dst_hold(&xdst->u.dst); - return xdst; - } - - old = xdst; /* Try to instantiate a bundle */ err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); if (err <= 0) { @@ -1834,6 +1818,21 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, return ERR_PTR(err); } + xdst = this_cpu_read(xfrm_last_dst); + if (xdst && + xdst->u.dst.dev == dst_orig->dev && + xdst->num_pols == num_pols && + memcmp(xdst->pols, pols, + sizeof(struct xfrm_policy *) * num_pols) == 0 && + xfrm_xdst_can_reuse(xdst, xfrm, err)) { + dst_hold(&xdst->u.dst); + while (err > 0) + xfrm_state_put(xfrm[--err]); + return xdst; + } + + old = xdst; + dst = xfrm_bundle_create(pols[0], xfrm, err, fl, dst_orig); if (IS_ERR(dst)) { XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLEGENERROR); diff --git a/kernel/scripts/leaking_addresses.pl b/kernel/scripts/leaking_addresses.pl new file mode 100644 index 000000000..2977371b2 --- /dev/null +++ b/kernel/scripts/leaking_addresses.pl @@ -0,0 +1,305 @@ +#!/usr/bin/env perl +# +# (c) 2017 Tobin C. Harding +# Licensed under the terms of the GNU GPL License version 2 +# +# leaking_addresses.pl: Scan 64 bit kernel for potential leaking addresses. +# - Scans dmesg output. +# - Walks directory tree and parses each file (for each directory in @DIRS). +# +# You can configure the behaviour of the script; +# +# - By adding paths, for directories you do not want to walk; +# absolute paths: @skip_walk_dirs_abs +# directory names: @skip_walk_dirs_any +# +# - By adding paths, for files you do not want to parse; +# absolute paths: @skip_parse_files_abs +# file names: @skip_parse_files_any +# +# The use of @skip_xxx_xxx_any causes files to be skipped where ever they occur. +# For example adding 'fd' to @skip_walk_dirs_any causes the fd/ directory to be +# skipped for all PID sub-directories of /proc +# +# The same thing can be achieved by passing command line options to --dont-walk +# and --dont-parse. If absolute paths are supplied to these options they are +# appended to the @skip_xxx_xxx_abs arrays. If file names are supplied to these +# options, they are appended to the @skip_xxx_xxx_any arrays. +# +# Use --debug to output path before parsing, this is useful to find files that +# cause the script to choke. +# +# You may like to set kptr_restrict=2 before running script +# (see Documentation/sysctl/kernel.txt). + +use warnings; +use strict; +use POSIX; +use File::Basename; +use File::Spec; +use Cwd 'abs_path'; +use Term::ANSIColor qw(:constants); +use Getopt::Long qw(:config no_auto_abbrev); + +my $P = $0; +my $V = '0.01'; + +# Directories to scan. +my @DIRS = ('/proc', '/sys'); + +# Command line options. +my $help = 0; +my $debug = 0; +my @dont_walk = (); +my @dont_parse = (); + +# Do not parse these files (absolute path). +my @skip_parse_files_abs = ('/proc/kmsg', + '/proc/kcore', + '/proc/fs/ext4/sdb1/mb_groups', + '/proc/1/fd/3', + '/sys/kernel/debug/tracing/trace_pipe', + '/sys/kernel/security/apparmor/revision'); + +# Do not parse thes files under any subdirectory. +my @skip_parse_files_any = ('0', + '1', + '2', + 'pagemap', + 'events', + 'access', + 'registers', + 'snapshot_raw', + 'trace_pipe_raw', + 'ptmx', + 'trace_pipe'); + +# Do not walk these directories (absolute path). +my @skip_walk_dirs_abs = (); + +# Do not walk these directories under any subdirectory. +my @skip_walk_dirs_any = ('self', + 'thread-self', + 'cwd', + 'fd', + 'stderr', + 'stdin', + 'stdout'); + +sub help +{ + my ($exitcode) = @_; + + print << "EOM"; +Usage: $P [OPTIONS] +Version: $V + +Options: + + --dont-walk= Don't walk tree starting at . + --dont-parse= Don't parse . + -d, --debug Display debugging output. + -h, --help, --version Display this help and exit. + +If an absolute path is passed to --dont_XXX then this path is skipped. If a +single filename is passed then this file/directory will be skipped when +appearing under any subdirectory. + +Example: + + # Just scan dmesg output. + scripts/leaking_addresses.pl --dont_walk_abs /proc --dont_walk_abs /sys + +Scans the running (64 bit) kernel for potential leaking addresses. + +EOM + exit($exitcode); +} + +GetOptions( + 'dont-walk=s' => \@dont_walk, + 'dont-parse=s' => \@dont_parse, + 'd|debug' => \$debug, + 'h|help' => \$help, + 'version' => \$help +) or help(1); + +help(0) if ($help); + +push_to_global(); + +parse_dmesg(); +walk(@DIRS); + +exit 0; + +sub debug_arrays +{ + print 'dirs_any: ' . join(", ", @skip_walk_dirs_any) . "\n"; + print 'dirs_abs: ' . join(", ", @skip_walk_dirs_abs) . "\n"; + print 'parse_any: ' . join(", ", @skip_parse_files_any) . "\n"; + print 'parse_abs: ' . join(", ", @skip_parse_files_abs) . "\n"; +} + +sub dprint +{ + printf(STDERR @_) if $debug; +} + +sub push_in_abs_any +{ + my ($in, $abs, $any) = @_; + + foreach my $path (@$in) { + if (File::Spec->file_name_is_absolute($path)) { + push @$abs, $path; + } elsif (index($path,'/') == -1) { + push @$any, $path; + } else { + print 'path error: ' . $path; + } + } +} + +# Push command line options to global arrays. +sub push_to_global +{ + push_in_abs_any(\@dont_walk, \@skip_walk_dirs_abs, \@skip_walk_dirs_any); + push_in_abs_any(\@dont_parse, \@skip_parse_files_abs, \@skip_parse_files_any); +} + +sub is_false_positive +{ + my ($match) = @_; + + if ($match =~ '\b(0x)?(f|F){16}\b' or + $match =~ '\b(0x)?0{16}\b') { + return 1; + } + + # vsyscall memory region, we should probably check against a range here. + if ($match =~ '\bf{10}600000\b' or + $match =~ '\bf{10}601000\b') { + return 1; + } + + return 0; +} + +# True if argument potentially contains a kernel address. +sub may_leak_address +{ + my ($line) = @_; + my $address = '\b(0x)?ffff[[:xdigit:]]{12}\b'; + + # Signal masks. + if ($line =~ '^SigBlk:' or + $line =~ '^SigCgt:') { + return 0; + } + + if ($line =~ '\bKEY=[[:xdigit:]]{14} [[:xdigit:]]{16} [[:xdigit:]]{16}\b' or + $line =~ '\b[[:xdigit:]]{14} [[:xdigit:]]{16} [[:xdigit:]]{16}\b') { + return 0; + } + + while (/($address)/g) { + if (!is_false_positive($1)) { + return 1; + } + } + + return 0; +} + +sub parse_dmesg +{ + open my $cmd, '-|', 'dmesg'; + while (<$cmd>) { + if (may_leak_address($_)) { + print 'dmesg: ' . $_; + } + } + close $cmd; +} + +# True if we should skip this path. +sub skip +{ + my ($path, $paths_abs, $paths_any) = @_; + + foreach (@$paths_abs) { + return 1 if (/^$path$/); + } + + my($filename, $dirs, $suffix) = fileparse($path); + foreach (@$paths_any) { + return 1 if (/^$filename$/); + } + + return 0; +} + +sub skip_parse +{ + my ($path) = @_; + return skip($path, \@skip_parse_files_abs, \@skip_parse_files_any); +} + +sub parse_file +{ + my ($file) = @_; + + if (! -R $file) { + return; + } + + if (skip_parse($file)) { + dprint "skipping file: $file\n"; + return; + } + dprint "parsing: $file\n"; + + open my $fh, "<", $file or return; + while ( <$fh> ) { + if (may_leak_address($_)) { + print $file . ': ' . $_; + } + } + close $fh; +} + + +# True if we should skip walking this directory. +sub skip_walk +{ + my ($path) = @_; + return skip($path, \@skip_walk_dirs_abs, \@skip_walk_dirs_any) +} + +# Recursively walk directory tree. +sub walk +{ + my @dirs = @_; + my %seen; + + while (my $pwd = shift @dirs) { + next if (skip_walk($pwd)); + next if (!opendir(DIR, $pwd)); + my @files = readdir(DIR); + closedir(DIR); + + foreach my $file (@files) { + next if ($file eq '.' or $file eq '..'); + + my $path = "$pwd/$file"; + next if (-l $path); + + if (-d $path) { + push @dirs, $path; + } else { + parse_file($path); + } + } + } +} diff --git a/kernel/security/apparmor/ipc.c b/kernel/security/apparmor/ipc.c index 66fb9ede9..7ca0032e7 100644 --- a/kernel/security/apparmor/ipc.c +++ b/kernel/security/apparmor/ipc.c @@ -128,7 +128,7 @@ static inline int map_signal_num(int sig) return SIGUNKNOWN; else if (sig >= SIGRTMIN) return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */ - else if (sig <= MAXMAPPED_SIG) + else if (sig < MAXMAPPED_SIG) return sig_map[sig]; return SIGUNKNOWN; } @@ -163,7 +163,7 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va) audit_signal_mask(ab, aad(sa)->denied); } } - if (aad(sa)->signal <= MAXMAPPED_SIG) + if (aad(sa)->signal < MAXMAPPED_SIG) audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]); else audit_log_format(ab, " signal=rtmin+%d", diff --git a/kernel/sound/core/hrtimer.c b/kernel/sound/core/hrtimer.c index 1ac0c4239..6e47b823b 100644 --- a/kernel/sound/core/hrtimer.c +++ b/kernel/sound/core/hrtimer.c @@ -159,6 +159,7 @@ static int __init snd_hrtimer_init(void) timer->hw = hrtimer_hw; timer->hw.resolution = resolution; timer->hw.ticks = NANO_SEC / resolution; + timer->max_instances = 100; /* lower the limit */ err = snd_timer_global_register(timer); if (err < 0) { diff --git a/kernel/sound/core/seq/oss/seq_oss_midi.c b/kernel/sound/core/seq/oss/seq_oss_midi.c index aaff9ee32..b30b2139e 100644 --- a/kernel/sound/core/seq/oss/seq_oss_midi.c +++ b/kernel/sound/core/seq/oss/seq_oss_midi.c @@ -612,9 +612,7 @@ send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq if (!dp->timer->running) len = snd_seq_oss_timer_start(dp->timer); if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { - if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE) - snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, - ev->data.ext.ptr, ev->data.ext.len); + snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev); } else { len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); if (len > 0) diff --git a/kernel/sound/core/seq/oss/seq_oss_readq.c b/kernel/sound/core/seq/oss/seq_oss_readq.c index 046cb586f..06b21226b 100644 --- a/kernel/sound/core/seq/oss/seq_oss_readq.c +++ b/kernel/sound/core/seq/oss/seq_oss_readq.c @@ -117,6 +117,35 @@ snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, in return 0; } +/* + * put MIDI sysex bytes; the event buffer may be chained, thus it has + * to be expanded via snd_seq_dump_var_event(). + */ +struct readq_sysex_ctx { + struct seq_oss_readq *readq; + int dev; +}; + +static int readq_dump_sysex(void *ptr, void *buf, int count) +{ + struct readq_sysex_ctx *ctx = ptr; + + return snd_seq_oss_readq_puts(ctx->readq, ctx->dev, buf, count); +} + +int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev, + struct snd_seq_event *ev) +{ + struct readq_sysex_ctx ctx = { + .readq = q, + .dev = dev + }; + + if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) + return 0; + return snd_seq_dump_var_event(ev, readq_dump_sysex, &ctx); +} + /* * copy an event to input queue: * return zero if enqueued diff --git a/kernel/sound/core/seq/oss/seq_oss_readq.h b/kernel/sound/core/seq/oss/seq_oss_readq.h index f1463f1f4..8d033ca2d 100644 --- a/kernel/sound/core/seq/oss/seq_oss_readq.h +++ b/kernel/sound/core/seq/oss/seq_oss_readq.h @@ -44,6 +44,8 @@ void snd_seq_oss_readq_delete(struct seq_oss_readq *q); void snd_seq_oss_readq_clear(struct seq_oss_readq *readq); unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait); int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len); +int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev, + struct snd_seq_event *ev); int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev); int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode); int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec); diff --git a/kernel/sound/core/timer.c b/kernel/sound/core/timer.c index 6cdd04a45..15e82a656 100644 --- a/kernel/sound/core/timer.c +++ b/kernel/sound/core/timer.c @@ -180,7 +180,7 @@ static void snd_timer_request(struct snd_timer_id *tid) * * call this with register_mutex down. */ -static void snd_timer_check_slave(struct snd_timer_instance *slave) +static int snd_timer_check_slave(struct snd_timer_instance *slave) { struct snd_timer *timer; struct snd_timer_instance *master; @@ -190,16 +190,21 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave) list_for_each_entry(master, &timer->open_list_head, open_list) { if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { + if (master->timer->num_instances >= + master->timer->max_instances) + return -EBUSY; list_move_tail(&slave->open_list, &master->slave_list_head); + master->timer->num_instances++; spin_lock_irq(&slave_active_lock); slave->master = master; slave->timer = master->timer; spin_unlock_irq(&slave_active_lock); - return; + return 0; } } } + return 0; } /* @@ -208,7 +213,7 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave) * * call this with register_mutex down. */ -static void snd_timer_check_master(struct snd_timer_instance *master) +static int snd_timer_check_master(struct snd_timer_instance *master) { struct snd_timer_instance *slave, *tmp; @@ -216,7 +221,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master) list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) { if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { + if (master->timer->num_instances >= + master->timer->max_instances) + return -EBUSY; list_move_tail(&slave->open_list, &master->slave_list_head); + master->timer->num_instances++; spin_lock_irq(&slave_active_lock); spin_lock(&master->timer->lock); slave->master = master; @@ -228,8 +237,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master) spin_unlock_irq(&slave_active_lock); } } + return 0; } +static int snd_timer_close_locked(struct snd_timer_instance *timeri); + /* * open a timer instance * when opening a master, the slave id must be here given. @@ -240,6 +252,7 @@ int snd_timer_open(struct snd_timer_instance **ti, { struct snd_timer *timer; struct snd_timer_instance *timeri = NULL; + int err; if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { /* open a slave instance */ @@ -259,10 +272,14 @@ int snd_timer_open(struct snd_timer_instance **ti, timeri->slave_id = tid->device; timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; list_add_tail(&timeri->open_list, &snd_timer_slave_list); - snd_timer_check_slave(timeri); + err = snd_timer_check_slave(timeri); + if (err < 0) { + snd_timer_close_locked(timeri); + timeri = NULL; + } mutex_unlock(®ister_mutex); *ti = timeri; - return 0; + return err; } /* open a master instance */ @@ -288,6 +305,10 @@ int snd_timer_open(struct snd_timer_instance **ti, return -EBUSY; } } + if (timer->num_instances >= timer->max_instances) { + mutex_unlock(®ister_mutex); + return -EBUSY; + } timeri = snd_timer_instance_new(owner, timer); if (!timeri) { mutex_unlock(®ister_mutex); @@ -314,25 +335,27 @@ int snd_timer_open(struct snd_timer_instance **ti, } list_add_tail(&timeri->open_list, &timer->open_list_head); - snd_timer_check_master(timeri); + timer->num_instances++; + err = snd_timer_check_master(timeri); + if (err < 0) { + snd_timer_close_locked(timeri); + timeri = NULL; + } mutex_unlock(®ister_mutex); *ti = timeri; - return 0; + return err; } EXPORT_SYMBOL(snd_timer_open); /* * close a timer instance + * call this with register_mutex down. */ -int snd_timer_close(struct snd_timer_instance *timeri) +static int snd_timer_close_locked(struct snd_timer_instance *timeri) { struct snd_timer *timer = NULL; struct snd_timer_instance *slave, *tmp; - if (snd_BUG_ON(!timeri)) - return -ENXIO; - - mutex_lock(®ister_mutex); list_del(&timeri->open_list); /* force to stop the timer */ @@ -340,6 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) timer = timeri->timer; if (timer) { + timer->num_instances--; /* wait, until the active callback is finished */ spin_lock_irq(&timer->lock); while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { @@ -355,6 +379,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, open_list) { list_move_tail(&slave->open_list, &snd_timer_slave_list); + timer->num_instances--; slave->master = NULL; slave->timer = NULL; list_del_init(&slave->ack_list); @@ -382,9 +407,24 @@ int snd_timer_close(struct snd_timer_instance *timeri) module_put(timer->module); } - mutex_unlock(®ister_mutex); return 0; } + +/* + * close a timer instance + */ +int snd_timer_close(struct snd_timer_instance *timeri) +{ + int err; + + if (snd_BUG_ON(!timeri)) + return -ENXIO; + + mutex_lock(®ister_mutex); + err = snd_timer_close_locked(timeri); + mutex_unlock(®ister_mutex); + return err; +} EXPORT_SYMBOL(snd_timer_close); unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) @@ -856,6 +896,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, spin_lock_init(&timer->lock); tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); + timer->max_instances = 1000; /* default limit per timer */ if (card != NULL) { timer->module = card->module; err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); diff --git a/kernel/sound/pci/hda/patch_realtek.c b/kernel/sound/pci/hda/patch_realtek.c index 546d515f3..dce0682c5 100644 --- a/kernel/sound/pci/hda/patch_realtek.c +++ b/kernel/sound/pci/hda/patch_realtek.c @@ -6544,6 +6544,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x14, 0x90170110}, {0x1b, 0x90a70130}, {0x21, 0x03211020}), + SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0xb7a60130}, + {0x13, 0xb8a61140}, + {0x16, 0x90170110}, + {0x21, 0x04211020}), SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, {0x12, 0x90a60130}, {0x14, 0x90170110}, diff --git a/kernel/sound/usb/quirks.c b/kernel/sound/usb/quirks.c index 4f5f18f22..20624320b 100644 --- a/kernel/sound/usb/quirks.c +++ b/kernel/sound/usb/quirks.c @@ -1375,6 +1375,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case 0x199: return SNDRV_PCM_FMTBIT_DSD_U32_LE; case 0x19b: + case 0x203: return SNDRV_PCM_FMTBIT_DSD_U32_BE; default: break; diff --git a/kernel/tools/include/uapi/drm/i915_drm.h b/kernel/tools/include/uapi/drm/i915_drm.h index 6598fb76d..9816590d3 100644 --- a/kernel/tools/include/uapi/drm/i915_drm.h +++ b/kernel/tools/include/uapi/drm/i915_drm.h @@ -829,6 +829,7 @@ struct drm_i915_gem_exec_fence { #define I915_EXEC_FENCE_WAIT (1<<0) #define I915_EXEC_FENCE_SIGNAL (1<<1) +#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1)) __u32 flags; }; diff --git a/kernel/tools/perf/builtin-trace.c b/kernel/tools/perf/builtin-trace.c index 771ddab94..d5d7fff1c 100644 --- a/kernel/tools/perf/builtin-trace.c +++ b/kernel/tools/perf/builtin-trace.c @@ -1138,6 +1138,14 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) return err; } +static void trace__symbols__exit(struct trace *trace) +{ + machine__exit(trace->host); + trace->host = NULL; + + symbol__exit(); +} + static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args) { int idx; @@ -2481,6 +2489,8 @@ out_disable: } out_delete_evlist: + trace__symbols__exit(trace); + perf_evlist__delete(evlist); trace->evlist = NULL; trace->live = false; diff --git a/kernel/tools/perf/util/parse-events.l b/kernel/tools/perf/util/parse-events.l index 6680e4fb7..025729510 100644 --- a/kernel/tools/perf/util/parse-events.l +++ b/kernel/tools/perf/util/parse-events.l @@ -5,6 +5,7 @@ %option stack %option bison-locations %option yylineno +%option reject %{ #include @@ -339,8 +340,8 @@ r{num_raw_hex} { return raw(yyscanner); } {num_hex} { return value(yyscanner, 16); } {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } -{bpf_object} { if (!isbpf(yyscanner)) USER_REJECT; return str(yyscanner, PE_BPF_OBJECT); } -{bpf_source} { if (!isbpf(yyscanner)) USER_REJECT; return str(yyscanner, PE_BPF_SOURCE); } +{bpf_object} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_OBJECT); } +{bpf_source} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_SOURCE); } {name} { return pmu_str_check(yyscanner); } "/" { BEGIN(config); return '/'; } - { return '-'; }