Merge branch 'linus' into locking/core, to pick up fixes
authorIngo Molnar <mingo@kernel.org>
Fri, 25 Aug 2017 09:04:51 +0000 (11:04 +0200)
committerIngo Molnar <mingo@kernel.org>
Fri, 25 Aug 2017 09:04:51 +0000 (11:04 +0200)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
412 files changed:
Documentation/fb/efifb.txt
Documentation/networking/switchdev.txt
Documentation/printk-formats.txt
Documentation/sysctl/net.txt
MAINTAINERS
Makefile
arch/arc/Kconfig
arch/arc/Makefile
arch/arc/boot/dts/axc001.dtsi
arch/arc/boot/dts/axc003.dtsi
arch/arc/boot/dts/axc003_idu.dtsi
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/configs/haps_hs_defconfig
arch/arc/configs/haps_hs_smp_defconfig
arch/arc/configs/nps_defconfig
arch/arc/configs/nsim_700_defconfig
arch/arc/configs/nsim_hs_defconfig
arch/arc/configs/nsim_hs_smp_defconfig
arch/arc/configs/nsimosci_defconfig
arch/arc/configs/nsimosci_hs_defconfig
arch/arc/configs/nsimosci_hs_smp_defconfig
arch/arc/configs/tb10x_defconfig
arch/arc/include/asm/cache.h
arch/arc/include/asm/mmu.h
arch/arc/kernel/intc-arcv2.c
arch/arc/kernel/intc-compact.c
arch/arc/mm/cache.c
arch/arc/mm/dma.c
arch/arc/mm/tlb.c
arch/arc/plat-sim/Kconfig [deleted file]
arch/arc/plat-sim/platform.c
arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
arch/arm/boot/dts/imx7d-sdb.dts
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/pm.c
arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
arch/arm64/boot/dts/renesas/salvator-common.dtsi
arch/arm64/include/asm/arch_timer.h
arch/arm64/include/asm/elf.h
arch/arm64/kernel/fpsimd.c
arch/arm64/kernel/head.S
arch/arm64/kernel/kaslr.c
arch/arm64/mm/fault.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/boot/compressed/.gitignore [new file with mode: 0644]
arch/mips/cavium-octeon/octeon-usb.c
arch/mips/dec/int-handler.S
arch/mips/include/asm/cache.h
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/octeon/cvmx-l2c-defs.h
arch/mips/include/asm/octeon/cvmx-l2d-defs.h [new file with mode: 0644]
arch/mips/include/asm/octeon/cvmx.h
arch/mips/kernel/smp.c
arch/mips/mm/uasm-mips.c
arch/mips/pci/pci.c
arch/mips/vdso/gettimeofday.c
arch/powerpc/Kconfig
arch/powerpc/configs/powernv_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/watchdog.c
arch/powerpc/platforms/powernv/idle.c
arch/sparc/include/asm/page_32.h
arch/sparc/kernel/pci_sun4v.c
arch/sparc/kernel/pcic.c
arch/sparc/lib/multi3.S
arch/x86/Kconfig
arch/x86/crypto/sha1_avx2_x86_64_asm.S
arch/x86/crypto/sha1_ssse3_glue.c
arch/x86/entry/entry_64.S
arch/x86/events/core.c
arch/x86/events/intel/bts.c
arch/x86/events/intel/p4.c
arch/x86/events/intel/rapl.c
arch/x86/events/intel/uncore.c
arch/x86/events/intel/uncore_nhmex.c
arch/x86/events/intel/uncore_snb.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/elf.h
arch/x86/include/asm/hypervisor.h
arch/x86/kernel/cpu/aperfmperf.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/head64.c
arch/x86/kernel/ksysfs.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/svm.c
arch/x86/mm/init.c
arch/x86/mm/mmap.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/xen/enlighten_hvm.c
block/bio-integrity.c
block/blk-mq-pci.c
block/blk-mq.c
drivers/acpi/acpica/nsxfeval.c
drivers/acpi/ec.c
drivers/acpi/internal.h
drivers/acpi/property.c
drivers/acpi/scan.c
drivers/acpi/spcr.c
drivers/base/firmware_class.c
drivers/block/xen-blkfront.c
drivers/clocksource/Kconfig
drivers/clocksource/arm_arch_timer.c
drivers/clocksource/em_sti.c
drivers/clocksource/timer-of.c
drivers/cpufreq/intel_pstate.c
drivers/cpuidle/cpuidle-powernv.c
drivers/crypto/ixp4xx_crypto.c
drivers/gpio/gpio-mvebu.c
drivers/gpio/gpiolib-sysfs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_render_state.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_lrc.h
drivers/iio/accel/bmc150-accel-core.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/aspeed_adc.c
drivers/iio/adc/axp288_adc.c
drivers/iio/adc/sun4i-gpadc-iio.c
drivers/iio/adc/vf610_adc.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/light/tsl2563.c
drivers/iio/pressure/st_pressure_core.c
drivers/infiniband/core/device.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/cxgb4/mem.c
drivers/infiniband/hw/hns/hns_roce_ah.c
drivers/infiniband/hw/i40iw/i40iw_ctrl.c
drivers/infiniband/hw/i40iw/i40iw_d.h
drivers/infiniband/hw/i40iw/i40iw_puda.c
drivers/infiniband/hw/i40iw/i40iw_status.h
drivers/infiniband/hw/i40iw/i40iw_uk.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/trackpoint.c
drivers/iommu/arm-smmu.c
drivers/irqchip/irq-atmel-aic-common.c
drivers/irqchip/irq-atmel-aic-common.h
drivers/irqchip/irq-atmel-aic.c
drivers/irqchip/irq-atmel-aic5.c
drivers/irqchip/irq-brcmstb-l2.c
drivers/irqchip/irq-gic-v3-its-platform-msi.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-gic.c
drivers/isdn/mISDN/fsm.c
drivers/isdn/mISDN/fsm.h
drivers/isdn/mISDN/layer1.c
drivers/isdn/mISDN/layer2.c
drivers/isdn/mISDN/tei.c
drivers/md/md.c
drivers/md/raid5-cache.c
drivers/memory/atmel-ebi.c
drivers/mfd/atmel-smc.c
drivers/mfd/da9062-core.c
drivers/misc/mei/pci-me.c
drivers/misc/mei/pci-txe.c
drivers/mmc/core/block.c
drivers/mmc/core/mmc.c
drivers/mmc/host/omap_hsmmc.c
drivers/mtd/mtd_blkdevs.c
drivers/net/bonding/bond_main.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/sge.c
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
drivers/net/ethernet/chelsio/cxgb4vf/sge.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
drivers/net/ethernet/sfc/mcdi_port.c
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
drivers/net/tun.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/nvme/host/core.c
drivers/nvme/host/fabrics.c
drivers/nvme/host/pci.c
drivers/nvme/target/admin-cmd.c
drivers/nvme/target/fc.c
drivers/of/device.c
drivers/parisc/dino.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/rtc/rtc-ds1307.c
drivers/scsi/Kconfig
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/csiostor/csio_hw.c
drivers/scsi/csiostor/csio_init.c
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/lpfc/lpfc_nvmet.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/qla2xxx/qla_tmpl.c
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/scsi.c
drivers/scsi/sd.c
drivers/scsi/sd_zbc.c
drivers/scsi/ses.c
drivers/scsi/st.c
drivers/soc/imx/gpcv2.c
drivers/soc/ti/knav_qmss_queue.c
drivers/soc/ti/ti_sci_pm_domains.c
drivers/staging/comedi/comedi_fops.c
drivers/staging/iio/resolver/ad2s1210.c
drivers/target/iscsi/cxgbit/cxgbit_cm.c
drivers/target/iscsi/cxgbit/cxgbit_target.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/target_core_tpg.c
drivers/target/target_core_transport.c
drivers/target/target_core_user.c
drivers/thunderbolt/eeprom.c
drivers/tty/pty.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/amba-pl011.c
drivers/tty/tty_io.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/udc/renesas_usb3.c
drivers/usb/host/pci-quirks.c
drivers/usb/musb/musb_host.c
drivers/usb/phy/phy-msm-usb.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/renesas_usbhs/rcar3.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/storage/unusual_uas.h
drivers/usb/storage/usb.c
drivers/video/fbdev/efifb.c
drivers/video/fbdev/imxfb.c
drivers/video/fbdev/omap2/omapfb/dss/core.c
drivers/xen/Makefile
drivers/xen/biomerge.c
drivers/xen/events/events_base.c
drivers/xen/xenbus/xenbus_xs.c
fs/binfmt_elf.c
fs/btrfs/disk-io.c
fs/btrfs/inode.c
fs/btrfs/raid56.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/devpts/inode.c
fs/ext4/mballoc.c
fs/ext4/xattr.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/iomap.c
fs/nfs/Kconfig
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/nfs4proc.c
fs/quota/dquot.c
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/xfs_log.c
fs/xfs/xfs_mount.c
include/asm-generic/vmlinux.lds.h
include/linux/acpi.h
include/linux/devpts_fs.h
include/linux/iio/common/st_sensors.h
include/linux/memblock.h
include/linux/memcontrol.h
include/linux/net.h
include/linux/nmi.h
include/linux/nvme-fc-driver.h
include/linux/oom.h
include/linux/pci.h
include/linux/perf_event.h
include/linux/pid.h
include/linux/platform_data/st_sensors_pdata.h
include/linux/ptr_ring.h
include/linux/sched.h
include/linux/skb_array.h
include/linux/wait.h
include/net/addrconf.h
include/net/bonding.h
include/net/busy_poll.h
include/net/ip.h
include/net/mac80211.h
include/net/sch_generic.h
include/net/sock.h
include/net/udp.h
include/rdma/ib_verbs.h
include/scsi/scsi_cmnd.h
include/target/iscsi/iscsi_target_core.h
kernel/audit_watch.c
kernel/events/core.c
kernel/irq/chip.c
kernel/irq/ipi.c
kernel/kmod.c
kernel/pid.c
kernel/signal.c
kernel/trace/bpf_trace.c
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/ring_buffer_benchmark.c
kernel/trace/trace.c
kernel/trace/trace_events_filter.c
kernel/trace/tracing_map.c
kernel/watchdog.c
kernel/watchdog_hld.c
lib/Kconfig.debug
mm/cma_debug.c
mm/huge_memory.c
mm/memblock.c
mm/memcontrol.c
mm/memory.c
mm/mempolicy.c
mm/migrate.c
mm/nobootmem.c
mm/page-writeback.c
mm/page_alloc.c
mm/slub.c
mm/vmalloc.c
net/core/datagram.c
net/core/filter.c
net/dccp/proto.c
net/dsa/tag_ksz.c
net/ipv4/fib_semantics.c
net/ipv4/igmp.c
net/ipv4/route.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_ulp.c
net/ipv4/udp.c
net/ipv6/ip6_fib.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/irda/af_irda.c
net/key/af_key.c
net/mac80211/agg-rx.c
net/openvswitch/actions.c
net/openvswitch/datapath.c
net/openvswitch/datapath.h
net/rxrpc/call_accept.c
net/sched/act_ipt.c
net/sched/cls_api.c
net/sched/sch_api.c
net/sched/sch_atm.c
net/sched/sch_cbq.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_sfq.c
net/sctp/ipv6.c
net/tipc/bearer.c
net/tipc/msg.c
net/tipc/netlink_compat.c
net/unix/af_unix.c
scripts/Kbuild.include
scripts/Makefile.asm-generic
scripts/Makefile.build
scripts/Makefile.dtbinst
scripts/basic/Makefile
scripts/basic/fixdep.c
sound/core/seq/Kconfig
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_queue.c
sound/core/seq/seq_queue.h
sound/pci/emu10k1/emufx.c
sound/pci/hda/patch_realtek.c
sound/usb/mixer.c
sound/usb/mixer.h
sound/usb/mixer_quirks.c
sound/usb/quirks.c
tools/lib/bpf/libbpf.c
tools/testing/selftests/futex/Makefile
tools/testing/selftests/kmod/kmod.sh [changed mode: 0644->0755]
tools/testing/selftests/sysctl/sysctl.sh [changed mode: 0644->0755]
tools/testing/selftests/timers/freq-step.c

index a59916c..1a85c1b 100644 (file)
@@ -27,5 +27,11 @@ You have to add the following kernel parameters in your elilo.conf:
        Macbook Pro 17", iMac 20" :
                video=efifb:i20
 
+Accepted options:
+
+nowc   Don't map the framebuffer write combined. This can be used
+       to workaround side-effects and slowdowns on other CPU cores
+       when large amounts of console data are written.
+
 --
 Edgar Hucek <gimli@dark-green.com>
index 3e7b946..5e40e1f 100644 (file)
@@ -228,7 +228,7 @@ Learning on the device port should be enabled, as well as learning_sync:
        bridge link set dev DEV learning on self
        bridge link set dev DEV learning_sync on self
 
-Learning_sync attribute enables syncing of the learned/forgotton FDB entry to
+Learning_sync attribute enables syncing of the learned/forgotten FDB entry to
 the bridge's FDB.  It's possible, but not optimal, to enable learning on the
 device port and on the bridge port, and disable learning_sync.
 
@@ -245,7 +245,7 @@ the responsibility of the port driver/device to age out these entries.  If the
 port device supports ageing, when the FDB entry expires, it will notify the
 driver which in turn will notify the bridge with SWITCHDEV_FDB_DEL.  If the
 device does not support ageing, the driver can simulate ageing using a
-garbage collection timer to monitor FBD entries.  Expired entries will be
+garbage collection timer to monitor FDB entries.  Expired entries will be
 notified to the bridge using SWITCHDEV_FDB_DEL.  See rocker driver for
 example of driver running ageing timer.
 
index 65ea591..074670b 100644 (file)
@@ -58,20 +58,23 @@ Symbols/Function Pointers
        %ps     versatile_init
        %pB     prev_fn_of_versatile_init+0x88/0x88
 
-For printing symbols and function pointers. The ``S`` and ``s`` specifiers
-result in the symbol name with (``S``) or without (``s``) offsets. Where
-this is used on a kernel without KALLSYMS - the symbol address is
-printed instead.
+The ``F`` and ``f`` specifiers are for printing function pointers,
+for example, f->func, &gettimeofday. They have the same result as
+``S`` and ``s`` specifiers. But they do an extra conversion on
+ia64, ppc64 and parisc64 architectures where the function pointers
+are actually function descriptors.
+
+The ``S`` and ``s`` specifiers can be used for printing symbols
+from direct addresses, for example, __builtin_return_address(0),
+(void *)regs->ip. They result in the symbol name with (``S``) or
+without (``s``) offsets. If KALLSYMS are disabled then the symbol
+address is printed instead.
 
 The ``B`` specifier results in the symbol name with offsets and should be
 used when printing stack backtraces. The specifier takes into
 consideration the effect of compiler optimisations which may occur
 when tail-call``s are used and marked with the noreturn GCC attribute.
 
-On ia64, ppc64 and parisc64 architectures function pointers are
-actually function descriptors which must first be resolved. The ``F`` and
-``f`` specifiers perform this resolution and then provide the same
-functionality as the ``S`` and ``s`` specifiers.
 
 Kernel Pointers
 ===============
index 14db18c..28596e0 100644 (file)
@@ -35,9 +35,34 @@ Table : Subdirectories in /proc/sys/net
 bpf_jit_enable
 --------------
 
-This enables Berkeley Packet Filter Just in Time compiler.
-Currently supported on x86_64 architecture, bpf_jit provides a framework
-to speed packet filtering, the one used by tcpdump/libpcap for example.
+This enables the BPF Just in Time (JIT) compiler. BPF is a flexible
+and efficient infrastructure allowing to execute bytecode at various
+hook points. It is used in a number of Linux kernel subsystems such
+as networking (e.g. XDP, tc), tracing (e.g. kprobes, uprobes, tracepoints)
+and security (e.g. seccomp). LLVM has a BPF back end that can compile
+restricted C into a sequence of BPF instructions. After program load
+through bpf(2) and passing a verifier in the kernel, a JIT will then
+translate these BPF proglets into native CPU instructions. There are
+two flavors of JITs, the newer eBPF JIT currently supported on:
+  - x86_64
+  - arm64
+  - ppc64
+  - sparc64
+  - mips64
+  - s390x
+
+And the older cBPF JIT supported on the following archs:
+  - arm
+  - mips
+  - ppc
+  - sparc
+
+eBPF JITs are a superset of cBPF JITs, meaning the kernel will
+migrate cBPF instructions into eBPF instructions and then JIT
+compile them transparently. Older cBPF JITs can only translate
+tcpdump filters, seccomp rules, etc, but not mentioned eBPF
+programs loaded through bpf(2).
+
 Values :
        0 - disable the JIT (default value)
        1 - enable the JIT
@@ -46,9 +71,9 @@ Values :
 bpf_jit_harden
 --------------
 
-This enables hardening for the Berkeley Packet Filter Just in Time compiler.
-Supported are eBPF JIT backends. Enabling hardening trades off performance,
-but can mitigate JIT spraying.
+This enables hardening for the BPF JIT compiler. Supported are eBPF
+JIT backends. Enabling hardening trades off performance, but can
+mitigate JIT spraying.
 Values :
        0 - disable JIT hardening (default value)
        1 - enable JIT hardening for unprivileged users only
@@ -57,11 +82,11 @@ Values :
 bpf_jit_kallsyms
 ----------------
 
-When Berkeley Packet Filter Just in Time compiler is enabled, then compiled
-images are unknown addresses to the kernel, meaning they neither show up in
-traces nor in /proc/kallsyms. This enables export of these addresses, which
-can be used for debugging/tracing. If bpf_jit_harden is enabled, this feature
-is disabled.
+When BPF JIT compiler is enabled, then compiled images are unknown
+addresses to the kernel, meaning they neither show up in traces nor
+in /proc/kallsyms. This enables export of these addresses, which can
+be used for debugging/tracing. If bpf_jit_harden is enabled, this
+feature is disabled.
 Values :
        0 - disable JIT kallsyms export (default value)
        1 - enable JIT kallsyms export for privileged users only
index 6f7721d..1c3feff 100644 (file)
@@ -7110,7 +7110,6 @@ M:        Marc Zyngier <marc.zyngier@arm.com>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
-T:     git git://git.infradead.org/users/jcooper/linux.git irqchip/core
 F:     Documentation/devicetree/bindings/interrupt-controller/
 F:     drivers/irqchip/
 
index 6eba23b..dda88e7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 13
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc6
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
@@ -396,7 +396,7 @@ LINUXINCLUDE    := \
 KBUILD_CPPFLAGS := -D__KERNEL__
 
 KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-                  -fno-strict-aliasing -fno-common \
+                  -fno-strict-aliasing -fno-common -fshort-wchar \
                   -Werror-implicit-function-declaration \
                   -Wno-format-security \
                   -std=gnu89 $(call cc-option,-fno-PIE)
@@ -442,7 +442,7 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \
 # ===========================================================================
 # Rules shared between *config targets and build targets
 
-# Basic helpers built in scripts/
+# Basic helpers built in scripts/basic/
 PHONY += scripts_basic
 scripts_basic:
        $(Q)$(MAKE) $(build)=scripts/basic
@@ -505,7 +505,7 @@ ifeq ($(KBUILD_EXTMOD),)
                 endif
         endif
 endif
-# install and module_install need also be processed one by one
+# install and modules_install need also be processed one by one
 ifneq ($(filter install,$(MAKECMDGOALS)),)
         ifneq ($(filter modules_install,$(MAKECMDGOALS)),)
                mixed-targets := 1
@@ -964,7 +964,7 @@ export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y2) $(drivers-y) $(net-y) $(virt-
 export KBUILD_VMLINUX_LIBS := $(libs-y1)
 export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds
 export LDFLAGS_vmlinux
-# used by scripts/pacmage/Makefile
+# used by scripts/package/Makefile
 export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools)
 
 vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_LIBS)
@@ -992,8 +992,8 @@ include/generated/autoksyms.h: FORCE
 ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
 
 # Final link of vmlinux with optional arch pass after final link
-    cmd_link-vmlinux =                                                 \
-       $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) ;       \
+cmd_link-vmlinux =                                                 \
+       $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) ;    \
        $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
 
 vmlinux: scripts/link-vmlinux.sh vmlinux_prereq $(vmlinux-deps) FORCE
@@ -1184,6 +1184,7 @@ PHONY += kselftest
 kselftest:
        $(Q)$(MAKE) -C tools/testing/selftests run_tests
 
+PHONY += kselftest-clean
 kselftest-clean:
        $(Q)$(MAKE) -C tools/testing/selftests clean
 
index a545969..7db85ab 100644 (file)
@@ -96,7 +96,6 @@ menu "ARC Architecture Configuration"
 
 menu "ARC Platform/SoC/Board"
 
-source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
index 44ef35d..3a61cfc 100644 (file)
@@ -107,7 +107,7 @@ core-y              += arch/arc/
 # w/o this dtb won't embed into kernel binary
 core-y         += arch/arc/boot/dts/
 
-core-$(CONFIG_ARC_PLAT_SIM)    += arch/arc/plat-sim/
+core-y                         += arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)  += arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/
 core-$(CONFIG_ARC_PLAT_EZNPS)  += arch/arc/plat-eznps/
index 53ce226..a380ffa 100644 (file)
 
 / {
        compatible = "snps,arc";
-       #address-cells = <1>;
-       #size-cells = <1>;
+       #address-cells = <2>;
+       #size-cells = <2>;
 
        cpu_card {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
 
-               ranges = <0x00000000 0xf0000000 0x10000000>;
+               ranges = <0x00000000 0x0 0xf0000000 0x10000000>;
 
                core_clk: core_clk {
                        #clock-cells = <0>;
        mb_intc: dw-apb-ictl@0xe0012000 {
                #interrupt-cells = <1>;
                compatible = "snps,dw-apb-ictl";
-               reg = < 0xe0012000 0x200 >;
+               reg = < 0x0 0xe0012000 0x0 0x200 >;
                interrupt-controller;
                interrupt-parent = <&core_intc>;
                interrupts = < 7 >;
        };
 
        memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges = <0x00000000 0x80000000 0x20000000>;
                device_type = "memory";
-               reg = <0x80000000 0x1b000000>;  /* (512 - 32) MiB */
+               /* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */
+               reg = <0x0 0x80000000 0x0 0x1b000000>;  /* (512 - 32) MiB */
        };
 
        reserved-memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
+               #address-cells = <2>;
+               #size-cells = <2>;
                ranges;
                /*
                 * We just move frame buffer area to the very end of
                 */
                frame_buffer: frame_buffer@9e000000 {
                        compatible = "shared-dma-pool";
-                       reg = <0x9e000000 0x2000000>;
+                       reg = <0x0 0x9e000000 0x0 0x2000000>;
                        no-map;
                };
        };
index 14df46f..cc9239e 100644 (file)
 
 / {
        compatible = "snps,arc";
-       #address-cells = <1>;
-       #size-cells = <1>;
+       #address-cells = <2>;
+       #size-cells = <2>;
 
        cpu_card {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
 
-               ranges = <0x00000000 0xf0000000 0x10000000>;
+               ranges = <0x00000000 0x0 0xf0000000 0x10000000>;
 
                core_clk: core_clk {
                        #clock-cells = <0>;
        mb_intc: dw-apb-ictl@0xe0012000 {
                #interrupt-cells = <1>;
                compatible = "snps,dw-apb-ictl";
-               reg = < 0xe0012000 0x200 >;
+               reg = < 0x0 0xe0012000 0x0 0x200 >;
                interrupt-controller;
                interrupt-parent = <&core_intc>;
                interrupts = < 24 >;
        };
 
        memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges = <0x00000000 0x80000000 0x40000000>;
                device_type = "memory";
-               reg = <0x80000000 0x20000000>;  /* 512MiB */
+               /* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */
+               reg = <0x0 0x80000000 0x0 0x20000000    /* 512 MiB low mem */
+                      0x1 0xc0000000 0x0 0x40000000>;  /* 1 GiB highmem */
        };
 
        reserved-memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
+               #address-cells = <2>;
+               #size-cells = <2>;
                ranges;
                /*
                 * Move frame buffer out of IOC aperture (0x8z-0xAz).
                 */
                frame_buffer: frame_buffer@be000000 {
                        compatible = "shared-dma-pool";
-                       reg = <0xbe000000 0x2000000>;
+                       reg = <0x0 0xbe000000 0x0 0x2000000>;
                        no-map;
                };
        };
index 695f9fa..4ebb217 100644 (file)
 
 / {
        compatible = "snps,arc";
-       #address-cells = <1>;
-       #size-cells = <1>;
+       #address-cells = <2>;
+       #size-cells = <2>;
 
        cpu_card {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
 
-               ranges = <0x00000000 0xf0000000 0x10000000>;
+               ranges = <0x00000000 0x0 0xf0000000 0x10000000>;
 
                core_clk: core_clk {
                        #clock-cells = <0>;
        mb_intc: dw-apb-ictl@0xe0012000 {
                #interrupt-cells = <1>;
                compatible = "snps,dw-apb-ictl";
-               reg = < 0xe0012000 0x200 >;
+               reg = < 0x0 0xe0012000 0x0 0x200 >;
                interrupt-controller;
                interrupt-parent = <&idu_intc>;
                interrupts = <0>;
        };
 
        memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges = <0x00000000 0x80000000 0x40000000>;
                device_type = "memory";
-               reg = <0x80000000 0x20000000>;  /* 512MiB */
+               /* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */
+               reg = <0x0 0x80000000 0x0 0x20000000    /* 512 MiB low mem */
+                      0x1 0xc0000000 0x0 0x40000000>;  /* 1 GiB highmem */
        };
 
        reserved-memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
+               #address-cells = <2>;
+               #size-cells = <2>;
                ranges;
                /*
                 * Move frame buffer out of IOC aperture (0x8z-0xAz).
                 */
                frame_buffer: frame_buffer@be000000 {
                        compatible = "shared-dma-pool";
-                       reg = <0xbe000000 0x2000000>;
+                       reg = <0x0 0xbe000000 0x0 0x2000000>;
                        no-map;
                };
        };
index 41cfb29..0ff7e07 100644 (file)
@@ -13,7 +13,7 @@
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
-               ranges = <0x00000000 0xe0000000 0x10000000>;
+               ranges = <0x00000000 0x0 0xe0000000 0x10000000>;
                interrupt-parent = <&mb_intc>;
 
                i2sclk: i2sclk@100a0 {
index 57b3e59..db04ea4 100644 (file)
@@ -21,7 +21,6 @@ CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs"
 CONFIG_PREEMPT=y
index f85985a..821a2e5 100644 (file)
@@ -23,7 +23,6 @@ CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
 CONFIG_ARC_BUILTIN_DTB_NAME="haps_hs_idu"
index ede625c..7c9c706 100644 (file)
@@ -39,7 +39,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
index b0066a7..6dff83a 100644 (file)
@@ -23,7 +23,6 @@ CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ARC_BUILTIN_DTB_NAME="nsim_700"
 CONFIG_PREEMPT=y
 # CONFIG_COMPACTION is not set
index ebe9ebb..31ee51b 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_ARC_BUILTIN_DTB_NAME="nsim_hs"
 CONFIG_PREEMPT=y
index 4bde432..8d3b1f6 100644 (file)
@@ -24,7 +24,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
 CONFIG_ARC_BUILTIN_DTB_NAME="nsim_hs_idu"
index f6fb3d2..6168ce2 100644 (file)
@@ -23,7 +23,6 @@ CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci"
 # CONFIG_COMPACTION is not set
 CONFIG_NET=y
index b9f0fe0..a70bdeb 100644 (file)
@@ -23,7 +23,6 @@ CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs"
 # CONFIG_COMPACTION is not set
index 155add7..ef96406 100644 (file)
@@ -18,7 +18,6 @@ CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARC_PLAT_SIM=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
 # CONFIG_ARC_TIMERS_64BIT is not set
index 4c51183..f301825 100644 (file)
@@ -38,7 +38,6 @@ CONFIG_IP_MULTICAST=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
index 19ebddf..02fd1ce 100644 (file)
@@ -96,7 +96,9 @@ extern unsigned long perip_base, perip_end;
 #define ARC_REG_SLC_FLUSH      0x904
 #define ARC_REG_SLC_INVALIDATE 0x905
 #define ARC_REG_SLC_RGN_START  0x914
+#define ARC_REG_SLC_RGN_START1 0x915
 #define ARC_REG_SLC_RGN_END    0x916
+#define ARC_REG_SLC_RGN_END1   0x917
 
 /* Bit val in SLC_CONTROL */
 #define SLC_CTRL_DIS           0x001
index db7319e..efb79fa 100644 (file)
@@ -94,6 +94,8 @@ static inline int is_pae40_enabled(void)
        return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
 }
 
+extern int pae40_exist_but_not_enab(void);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
index f928795..cf90714 100644 (file)
@@ -75,10 +75,13 @@ void arc_init_IRQ(void)
         * Set a default priority for all available interrupts to prevent
         * switching of register banks if Fast IRQ and multiple register banks
         * are supported by CPU.
+        * Also disable all IRQ lines so faulty external hardware won't
+        * trigger interrupt that kernel is not ready to handle.
         */
        for (i = NR_EXCEPTIONS; i < irq_bcr.irqs + NR_EXCEPTIONS; i++) {
                write_aux_reg(AUX_IRQ_SELECT, i);
                write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO);
+               write_aux_reg(AUX_IRQ_ENABLE, 0);
        }
 
        /* setup status32, don't enable intr yet as kernel doesn't want */
index 7e608c6..cef3880 100644 (file)
@@ -27,7 +27,7 @@
  */
 void arc_init_IRQ(void)
 {
-       int level_mask = 0;
+       int level_mask = 0, i;
 
        /* Is timer high priority Interrupt (Level2 in ARCompact jargon) */
        level_mask |= IS_ENABLED(CONFIG_ARC_COMPACT_IRQ_LEVELS) << TIMER0_IRQ;
@@ -40,6 +40,18 @@ void arc_init_IRQ(void)
 
        if (level_mask)
                pr_info("Level-2 interrupts bitset %x\n", level_mask);
+
+       /*
+        * Disable all IRQ lines so faulty external hardware won't
+        * trigger interrupt that kernel is not ready to handle.
+        */
+       for (i = TIMER0_IRQ; i < NR_CPU_IRQS; i++) {
+               unsigned int ienb;
+
+               ienb = read_aux_reg(AUX_IENABLE);
+               ienb &= ~(1 << i);
+               write_aux_reg(AUX_IENABLE, ienb);
+       }
 }
 
 /*
index a867575..7db283b 100644 (file)
@@ -665,6 +665,7 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
        static DEFINE_SPINLOCK(lock);
        unsigned long flags;
        unsigned int ctrl;
+       phys_addr_t end;
 
        spin_lock_irqsave(&lock, flags);
 
@@ -694,8 +695,19 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
         * END needs to be setup before START (latter triggers the operation)
         * END can't be same as START, so add (l2_line_sz - 1) to sz
         */
-       write_aux_reg(ARC_REG_SLC_RGN_END, (paddr + sz + l2_line_sz - 1));
-       write_aux_reg(ARC_REG_SLC_RGN_START, paddr);
+       end = paddr + sz + l2_line_sz - 1;
+       if (is_pae40_enabled())
+               write_aux_reg(ARC_REG_SLC_RGN_END1, upper_32_bits(end));
+
+       write_aux_reg(ARC_REG_SLC_RGN_END, lower_32_bits(end));
+
+       if (is_pae40_enabled())
+               write_aux_reg(ARC_REG_SLC_RGN_START1, upper_32_bits(paddr));
+
+       write_aux_reg(ARC_REG_SLC_RGN_START, lower_32_bits(paddr));
+
+       /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
+       read_aux_reg(ARC_REG_SLC_CTRL);
 
        while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY);
 
@@ -1111,6 +1123,13 @@ noinline void __init arc_ioc_setup(void)
        __dc_enable();
 }
 
+/*
+ * Cache related boot time checks/setups only needed on master CPU:
+ *  - Geometry checks (kernel build and hardware agree: e.g. L1_CACHE_BYTES)
+ *    Assume SMP only, so all cores will have same cache config. A check on
+ *    one core suffices for all
+ *  - IOC setup / dma callbacks only need to be done once
+ */
 void __init arc_cache_init_master(void)
 {
        unsigned int __maybe_unused cpu = smp_processor_id();
@@ -1190,12 +1209,27 @@ void __ref arc_cache_init(void)
 
        printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
 
-       /*
-        * Only master CPU needs to execute rest of function:
-        *  - Assume SMP so all cores will have same cache config so
-        *    any geomtry checks will be same for all
-        *  - IOC setup / dma callbacks only need to be setup once
-        */
        if (!cpu)
                arc_cache_init_master();
+
+       /*
+        * In PAE regime, TLB and cache maintenance ops take wider addresses
+        * And even if PAE is not enabled in kernel, the upper 32-bits still need
+        * to be zeroed to keep the ops sane.
+        * As an optimization for more common !PAE enabled case, zero them out
+        * once at init, rather than checking/setting to 0 for every runtime op
+        */
+       if (is_isa_arcv2() && pae40_exist_but_not_enab()) {
+
+               if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE))
+                       write_aux_reg(ARC_REG_IC_PTAG_HI, 0);
+
+               if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE))
+                       write_aux_reg(ARC_REG_DC_PTAG_HI, 0);
+
+               if (l2_line_sz) {
+                       write_aux_reg(ARC_REG_SLC_RGN_END1, 0);
+                       write_aux_reg(ARC_REG_SLC_RGN_START1, 0);
+               }
+       }
 }
index 71d3eff..e9d9360 100644 (file)
@@ -153,6 +153,19 @@ static void _dma_cache_sync(phys_addr_t paddr, size_t size,
        }
 }
 
+/*
+ * arc_dma_map_page - map a portion of a page for streaming DMA
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed.  The CPU
+ * can regain ownership by calling dma_unmap_page().
+ *
+ * Note: while it takes struct page as arg, caller can "abuse" it to pass
+ * a region larger than PAGE_SIZE, provided it is physically contiguous
+ * and this still works correctly
+ */
 static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
                unsigned long offset, size_t size, enum dma_data_direction dir,
                unsigned long attrs)
@@ -165,6 +178,24 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
        return plat_phys_to_dma(dev, paddr);
 }
 
+/*
+ * arc_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ *
+ * Note: historically this routine was not implemented for ARC
+ */
+static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle,
+                              size_t size, enum dma_data_direction dir,
+                              unsigned long attrs)
+{
+       phys_addr_t paddr = plat_dma_to_phys(dev, handle);
+
+       if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+               _dma_cache_sync(paddr, size, dir);
+}
+
 static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg,
           int nents, enum dma_data_direction dir, unsigned long attrs)
 {
@@ -178,6 +209,18 @@ static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg,
        return nents;
 }
 
+static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+                            int nents, enum dma_data_direction dir,
+                            unsigned long attrs)
+{
+       struct scatterlist *s;
+       int i;
+
+       for_each_sg(sg, s, nents, i)
+               arc_dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir,
+                                  attrs);
+}
+
 static void arc_dma_sync_single_for_cpu(struct device *dev,
                dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
 {
@@ -223,7 +266,9 @@ const struct dma_map_ops arc_dma_ops = {
        .free                   = arc_dma_free,
        .mmap                   = arc_dma_mmap,
        .map_page               = arc_dma_map_page,
+       .unmap_page             = arc_dma_unmap_page,
        .map_sg                 = arc_dma_map_sg,
+       .unmap_sg               = arc_dma_unmap_sg,
        .sync_single_for_device = arc_dma_sync_single_for_device,
        .sync_single_for_cpu    = arc_dma_sync_single_for_cpu,
        .sync_sg_for_cpu        = arc_dma_sync_sg_for_cpu,
index d0126fd..b181f3e 100644 (file)
 /* A copy of the ASID from the PID reg is kept in asid_cache */
 DEFINE_PER_CPU(unsigned int, asid_cache) = MM_CTXT_FIRST_CYCLE;
 
+static int __read_mostly pae_exists;
+
 /*
  * Utility Routine to erase a J-TLB entry
  * Caller needs to setup Index Reg (manually or via getIndex)
@@ -784,7 +786,7 @@ void read_decode_mmu_bcr(void)
                mmu->u_dtlb = mmu4->u_dtlb * 4;
                mmu->u_itlb = mmu4->u_itlb * 4;
                mmu->sasid = mmu4->sasid;
-               mmu->pae = mmu4->pae;
+               pae_exists = mmu->pae = mmu4->pae;
        }
 }
 
@@ -809,6 +811,11 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
        return buf;
 }
 
+int pae40_exist_but_not_enab(void)
+{
+       return pae_exists && !is_pae40_enabled();
+}
+
 void arc_mmu_init(void)
 {
        char str[256];
@@ -859,6 +866,9 @@ void arc_mmu_init(void)
        /* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
 #endif
+
+       if (pae40_exist_but_not_enab())
+               write_aux_reg(ARC_REG_TLBPD1HI, 0);
 }
 
 /*
diff --git a/arch/arc/plat-sim/Kconfig b/arch/arc/plat-sim/Kconfig
deleted file mode 100644 (file)
index ac6af96..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Copyright (C) 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-
-menuconfig ARC_PLAT_SIM
-       bool "ARC nSIM based simulation virtual platforms"
-       help
-         Support for nSIM based ARC simulation platforms
-         This includes the standalone nSIM (uart only) vs. System C OSCI VP
index aea8738..5cda56b 100644 (file)
  */
 
 static const char *simulation_compat[] __initconst = {
+#ifdef CONFIG_ISA_ARCOMPACT
        "snps,nsim",
-       "snps,nsim_hs",
        "snps,nsimosci",
+#else
+       "snps,nsim_hs",
        "snps,nsimosci_hs",
        "snps,zebu_hs",
+#endif
        NULL,
 };
 
index f92f957..a183b56 100644 (file)
 
 &hdmicec {
        status = "okay";
+       needs-hpd;
 };
 
 &hsi2c_4 {
index dfcc8e0..0ade361 100644 (file)
                                #address-cells = <1>;
                                #size-cells = <1>;
                                status = "disabled";
+                               ranges;
 
                                adc: adc@50030800 {
                                        compatible = "fsl,imx25-gcq";
index aeaa5a6..a24e4f1 100644 (file)
        pinctrl_pcie: pciegrp {
                fsl,pins = <
                        /* PCIe reset */
-                       MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x030b0
+                       MX6QDL_PAD_EIM_DA0__GPIO3_IO00  0x030b0
                        MX6QDL_PAD_EIM_DA4__GPIO3_IO04  0x030b0
                >;
        };
 &pcie {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pcie>;
-       reset-gpio = <&gpio6 31 GPIO_ACTIVE_LOW>;
+       reset-gpio = <&gpio3 0 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
 
index 54c4540..0a24d1b 100644 (file)
                        >;
                };
 
+               pinctrl_spi4: spi4grp {
+                       fsl,pins = <
+                               MX7D_PAD_GPIO1_IO09__GPIO1_IO9  0x59
+                               MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59
+                               MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59
+                       >;
+               };
+
                pinctrl_tsc2046_pendown: tsc2046_pendown {
                        fsl,pins = <
                                MX7D_PAD_EPDC_BDR1__GPIO2_IO29          0x59
                fsl,pins = <
                        MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT              0x110b0
                >;
-
-               pinctrl_spi4: spi4grp {
-                       fsl,pins = <
-                               MX7D_PAD_GPIO1_IO09__GPIO1_IO9  0x59
-                               MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59
-                               MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59
-                       >;
-               };
        };
 };
index cc06da3..60e69ae 100644 (file)
                        #size-cells = <1>;
                        atmel,smc = <&hsmc>;
                        reg = <0x10000000 0x10000000
-                              0x40000000 0x30000000>;
+                              0x60000000 0x30000000>;
                        ranges = <0x0 0x0 0x10000000 0x10000000
                                  0x1 0x0 0x60000000 0x10000000
                                  0x2 0x0 0x70000000 0x10000000
                        };
 
                        hsmc: hsmc@f8014000 {
-                               compatible = "atmel,sama5d3-smc", "syscon", "simple-mfd";
+                               compatible = "atmel,sama5d2-smc", "syscon", "simple-mfd";
                                reg = <0xf8014000 0x1000>;
-                               interrupts = <5 IRQ_TYPE_LEVEL_HIGH 6>;
+                               interrupts = <17 IRQ_TYPE_LEVEL_HIGH 6>;
                                clocks = <&hsmc_clk>;
                                #address-cells = <1>;
                                #size-cells = <1>;
                                ranges;
 
-                               pmecc: ecc-engine@ffffc070 {
+                               pmecc: ecc-engine@f8014070 {
                                        compatible = "atmel,sama5d2-pmecc";
-                                       reg = <0xffffc070 0x490>,
-                                             <0xffffc500 0x100>;
+                                       reg = <0xf8014070 0x490>,
+                                             <0xf8014500 0x100>;
                                };
                        };
 
index d735e5f..195da38 100644 (file)
@@ -1,7 +1,7 @@
 menuconfig ARCH_AT91
        bool "Atmel SoCs"
        depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND if PM && ARCH_MULTI_V7
        select COMMON_CLK_AT91
        select GPIOLIB
        select PINCTRL
index 667fdda..5036f99 100644 (file)
@@ -608,6 +608,9 @@ static void __init at91_pm_init(void (*pm_idle)(void))
 
 void __init at91rm9200_pm_init(void)
 {
+       if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
+               return;
+
        at91_dt_ramc();
 
        /*
@@ -620,18 +623,27 @@ void __init at91rm9200_pm_init(void)
 
 void __init at91sam9_pm_init(void)
 {
+       if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
+               return;
+
        at91_dt_ramc();
        at91_pm_init(at91sam9_idle);
 }
 
 void __init sama5_pm_init(void)
 {
+       if (!IS_ENABLED(CONFIG_SOC_SAMA5))
+               return;
+
        at91_dt_ramc();
        at91_pm_init(NULL);
 }
 
 void __init sama5d2_pm_init(void)
 {
+       if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
+               return;
+
        at91_pm_backup_init();
        sama5_pm_init();
 }
index 0d1f026..ba2fde2 100644 (file)
@@ -51,6 +51,7 @@
        compatible = "sinovoip,bananapi-m64", "allwinner,sun50i-a64";
 
        aliases {
+               ethernet0 = &emac;
                serial0 = &uart0;
                serial1 = &uart1;
        };
index 08cda24..827168b 100644 (file)
@@ -51,6 +51,7 @@
        compatible = "pine64,pine64", "allwinner,sun50i-a64";
 
        aliases {
+               ethernet0 = &emac;
                serial0 = &uart0;
                serial1 = &uart1;
                serial2 = &uart2;
index 17eb1cc..216e3a5 100644 (file)
@@ -53,6 +53,7 @@
                     "allwinner,sun50i-a64";
 
        aliases {
+               ethernet0 = &emac;
                serial0 = &uart0;
        };
 
index 732e2e0..d9a720b 100644 (file)
 };
 
 &pio {
+       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
        compatible = "allwinner,sun50i-h5-pinctrl";
 };
index a451996..f903957 100644 (file)
@@ -45,7 +45,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       audio_clkout: audio_clkout {
+       audio_clkout: audio-clkout {
                /*
                 * This is same as <&rcar_sound 0>
                 * but needed to avoid cs2000/rcar_sound probe dead-lock
index 74d08e4..a652ce0 100644 (file)
@@ -65,13 +65,13 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
        u64 _val;                                                       \
        if (needs_unstable_timer_counter_workaround()) {                \
                const struct arch_timer_erratum_workaround *wa;         \
-               preempt_disable();                                      \
+               preempt_disable_notrace();                              \
                wa = __this_cpu_read(timer_unstable_counter_workaround); \
                if (wa && wa->read_##reg)                               \
                        _val = wa->read_##reg();                        \
                else                                                    \
                        _val = read_sysreg(reg);                        \
-               preempt_enable();                                       \
+               preempt_enable_notrace();                               \
        } else {                                                        \
                _val = read_sysreg(reg);                                \
        }                                                               \
index acae781..3288c2b 100644 (file)
 
 /*
  * This is the base location for PIE (ET_DYN with INTERP) loads. On
- * 64-bit, this is raised to 4GB to leave the entire 32-bit address
+ * 64-bit, this is above 4GB to leave the entire 32-bit address
  * space open for things that want to use the area for 32-bit pointers.
  */
-#define ELF_ET_DYN_BASE                0x100000000UL
+#define ELF_ET_DYN_BASE                (2 * TASK_SIZE_64 / 3)
 
 #ifndef __ASSEMBLY__
 
index 06da8ea..c7b4995 100644 (file)
@@ -161,9 +161,11 @@ void fpsimd_flush_thread(void)
 {
        if (!system_supports_fpsimd())
                return;
+       preempt_disable();
        memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
        fpsimd_flush_task_state(current);
        set_thread_flag(TIF_FOREIGN_FPSTATE);
+       preempt_enable();
 }
 
 /*
index 973df7d..adb0910 100644 (file)
@@ -354,7 +354,6 @@ __primary_switched:
        tst     x23, ~(MIN_KIMG_ALIGN - 1)      // already running randomized?
        b.ne    0f
        mov     x0, x21                         // pass FDT address in x0
-       mov     x1, x23                         // pass modulo offset in x1
        bl      kaslr_early_init                // parse FDT for KASLR options
        cbz     x0, 0f                          // KASLR disabled? just proceed
        orr     x23, x23, x0                    // record KASLR offset
index a9710ef..47080c4 100644 (file)
@@ -75,7 +75,7 @@ extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size,
  * containing function pointers) to be reinitialized, and zero-initialized
  * .bss variables will be reset to 0.
  */
-u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset)
+u64 __init kaslr_early_init(u64 dt_phys)
 {
        void *fdt;
        u64 seed, offset, mask, module_range;
@@ -131,15 +131,17 @@ u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset)
        /*
         * The kernel Image should not extend across a 1GB/32MB/512MB alignment
         * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
-        * happens, increase the KASLR offset by the size of the kernel image
-        * rounded up by SWAPPER_BLOCK_SIZE.
+        * happens, round down the KASLR offset by (1 << SWAPPER_TABLE_SHIFT).
+        *
+        * NOTE: The references to _text and _end below will already take the
+        *       modulo offset (the physical displacement modulo 2 MB) into
+        *       account, given that the physical placement is controlled by
+        *       the loader, and will not change as a result of the virtual
+        *       mapping we choose.
         */
-       if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) !=
-           (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) {
-               u64 kimg_sz = _end - _text;
-               offset = (offset + round_up(kimg_sz, SWAPPER_BLOCK_SIZE))
-                               & mask;
-       }
+       if ((((u64)_text + offset) >> SWAPPER_TABLE_SHIFT) !=
+           (((u64)_end + offset) >> SWAPPER_TABLE_SHIFT))
+               offset = round_down(offset, 1 << SWAPPER_TABLE_SHIFT);
 
        if (IS_ENABLED(CONFIG_KASAN))
                /*
index 2509e4f..1f22a41 100644 (file)
@@ -435,8 +435,11 @@ retry:
                 * the mmap_sem because it would already be released
                 * in __lock_page_or_retry in mm/filemap.c.
                 */
-               if (fatal_signal_pending(current))
+               if (fatal_signal_pending(current)) {
+                       if (!user_mode(regs))
+                               goto no_context;
                        return 0;
+               }
 
                /*
                 * Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk of
index 8dd2035..48d91d5 100644 (file)
@@ -2260,7 +2260,7 @@ config CPU_R4K_CACHE_TLB
 
 config MIPS_MT_SMP
        bool "MIPS MT SMP support (1 TC on each available VPE)"
-       depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6
+       depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 && !CPU_MICROMIPS
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
        select SYNC_R4K
index 0434362..bc2708c 100644 (file)
@@ -243,8 +243,21 @@ include arch/mips/Kbuild.platforms
 ifdef CONFIG_PHYSICAL_START
 load-y                                 = $(CONFIG_PHYSICAL_START)
 endif
-entry-y                                = 0x$(shell $(NM) vmlinux 2>/dev/null \
+
+entry-noisa-y                          = 0x$(shell $(NM) vmlinux 2>/dev/null \
                                        | grep "\bkernel_entry\b" | cut -f1 -d \ )
+ifdef CONFIG_CPU_MICROMIPS
+  #
+  # Set the ISA bit, since the kernel_entry symbol in the ELF will have it
+  # clear which would lead to images containing addresses which bootloaders may
+  # jump to as MIPS32 code.
+  #
+  entry-y = $(patsubst %0,%1,$(patsubst %2,%3,$(patsubst %4,%5, \
+              $(patsubst %6,%7,$(patsubst %8,%9,$(patsubst %a,%b, \
+              $(patsubst %c,%d,$(patsubst %e,%f,$(entry-noisa-y)))))))))
+else
+  entry-y = $(entry-noisa-y)
+endif
 
 cflags-y                       += -I$(srctree)/arch/mips/include/asm/mach-generic
 drivers-$(CONFIG_PCI)          += arch/mips/pci/
diff --git a/arch/mips/boot/compressed/.gitignore b/arch/mips/boot/compressed/.gitignore
new file mode 100644 (file)
index 0000000..ebae133
--- /dev/null
@@ -0,0 +1,2 @@
+ashldi3.c
+bswapsi.c
index 542be1c..bfdfaf3 100644 (file)
@@ -13,9 +13,9 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/of_platform.h>
+#include <linux/io.h>
 
 #include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-gpio-defs.h>
 
 /* USB Control Register */
 union cvm_usbdrd_uctl_ctl {
index 1910223..cea2bb1 100644 (file)
                 * Find irq with highest priority
                 */
                # open coded PTR_LA t1, cpu_mask_nr_tbl
-#if (_MIPS_SZPTR == 32)
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
                # open coded la t1, cpu_mask_nr_tbl
                lui     t1, %hi(cpu_mask_nr_tbl)
                addiu   t1, %lo(cpu_mask_nr_tbl)
-
-#endif
-#if (_MIPS_SZPTR == 64)
-               # open coded dla t1, cpu_mask_nr_tbl
-               .set    push
-               .set    noat
-               lui     t1, %highest(cpu_mask_nr_tbl)
-               lui     AT, %hi(cpu_mask_nr_tbl)
-               daddiu  t1, t1, %higher(cpu_mask_nr_tbl)
-               daddiu  AT, AT, %lo(cpu_mask_nr_tbl)
-               dsll    t1, 32
-               daddu   t1, t1, AT
-               .set    pop
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
 #endif
 1:             lw      t2,(t1)
                nop
                 * Find irq with highest priority
                 */
                # open coded PTR_LA t1,asic_mask_nr_tbl
-#if (_MIPS_SZPTR == 32)
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
                # open coded la t1, asic_mask_nr_tbl
                lui     t1, %hi(asic_mask_nr_tbl)
                addiu   t1, %lo(asic_mask_nr_tbl)
-
-#endif
-#if (_MIPS_SZPTR == 64)
-               # open coded dla t1, asic_mask_nr_tbl
-               .set    push
-               .set    noat
-               lui     t1, %highest(asic_mask_nr_tbl)
-               lui     AT, %hi(asic_mask_nr_tbl)
-               daddiu  t1, t1, %higher(asic_mask_nr_tbl)
-               daddiu  AT, AT, %lo(asic_mask_nr_tbl)
-               dsll    t1, 32
-               daddu   t1, t1, AT
-               .set    pop
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
 #endif
 2:             lw      t2,(t1)
                nop
index fc67947..8b14c27 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef _ASM_CACHE_H
 #define _ASM_CACHE_H
 
+#include <kmalloc.h>
+
 #define L1_CACHE_SHIFT         CONFIG_MIPS_L1_CACHE_SHIFT
 #define L1_CACHE_BYTES         (1 << L1_CACHE_SHIFT)
 
index 8baa903..721b698 100644 (file)
 #ifndef cpu_scache_line_size
 #define cpu_scache_line_size() cpu_data[0].scache.linesz
 #endif
+#ifndef cpu_tcache_line_size
+#define cpu_tcache_line_size() cpu_data[0].tcache.linesz
+#endif
 
 #ifndef cpu_hwrena_impl_bits
 #define cpu_hwrena_impl_bits           0
index d045973..3ea84ac 100644 (file)
 #define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull))
 #define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull))
 #define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull))
+#define CVMX_L2C_ERR_TDTX(block_id)                                           \
+       (CVMX_ADD_IO_SEG(0x0001180080A007E0ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_ERR_TTGX(block_id)                                           \
+       (CVMX_ADD_IO_SEG(0x0001180080A007E8ull) + ((block_id) & 3) * 0x40000ull)
 #define CVMX_L2C_LCKBASE (CVMX_ADD_IO_SEG(0x0001180080000058ull))
 #define CVMX_L2C_LCKOFF (CVMX_ADD_IO_SEG(0x0001180080000060ull))
 #define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull))
                ((offset) & 1) * 8)
 #define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull)    + \
                ((offset) & 31) * 8)
-#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull))
 
 
+union cvmx_l2c_err_tdtx {
+       uint64_t u64;
+       struct cvmx_l2c_err_tdtx_s {
+               __BITFIELD_FIELD(uint64_t dbe:1,
+               __BITFIELD_FIELD(uint64_t sbe:1,
+               __BITFIELD_FIELD(uint64_t vdbe:1,
+               __BITFIELD_FIELD(uint64_t vsbe:1,
+               __BITFIELD_FIELD(uint64_t syn:10,
+               __BITFIELD_FIELD(uint64_t reserved_22_49:28,
+               __BITFIELD_FIELD(uint64_t wayidx:18,
+               __BITFIELD_FIELD(uint64_t reserved_2_3:2,
+               __BITFIELD_FIELD(uint64_t type:2,
+               ;)))))))))
+       } s;
+};
+
+union cvmx_l2c_err_ttgx {
+       uint64_t u64;
+       struct cvmx_l2c_err_ttgx_s {
+               __BITFIELD_FIELD(uint64_t dbe:1,
+               __BITFIELD_FIELD(uint64_t sbe:1,
+               __BITFIELD_FIELD(uint64_t noway:1,
+               __BITFIELD_FIELD(uint64_t reserved_56_60:5,
+               __BITFIELD_FIELD(uint64_t syn:6,
+               __BITFIELD_FIELD(uint64_t reserved_22_49:28,
+               __BITFIELD_FIELD(uint64_t wayidx:15,
+               __BITFIELD_FIELD(uint64_t reserved_2_6:5,
+               __BITFIELD_FIELD(uint64_t type:2,
+               ;)))))))))
+       } s;
+};
+
 union cvmx_l2c_cfg {
        uint64_t u64;
        struct cvmx_l2c_cfg_s {
diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
new file mode 100644 (file)
index 0000000..a951ad5
--- /dev/null
@@ -0,0 +1,60 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2017 Cavium, Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2D_DEFS_H__
+#define __CVMX_L2D_DEFS_H__
+
+#define CVMX_L2D_ERR   (CVMX_ADD_IO_SEG(0x0001180080000010ull))
+#define CVMX_L2D_FUS3  (CVMX_ADD_IO_SEG(0x00011800800007B8ull))
+
+
+union cvmx_l2d_err {
+       uint64_t u64;
+       struct cvmx_l2d_err_s {
+               __BITFIELD_FIELD(uint64_t reserved_6_63:58,
+               __BITFIELD_FIELD(uint64_t bmhclsel:1,
+               __BITFIELD_FIELD(uint64_t ded_err:1,
+               __BITFIELD_FIELD(uint64_t sec_err:1,
+               __BITFIELD_FIELD(uint64_t ded_intena:1,
+               __BITFIELD_FIELD(uint64_t sec_intena:1,
+               __BITFIELD_FIELD(uint64_t ecc_ena:1,
+               ;)))))))
+       } s;
+};
+
+union cvmx_l2d_fus3 {
+       uint64_t u64;
+       struct cvmx_l2d_fus3_s {
+               __BITFIELD_FIELD(uint64_t reserved_40_63:24,
+               __BITFIELD_FIELD(uint64_t ema_ctl:3,
+               __BITFIELD_FIELD(uint64_t reserved_34_36:3,
+               __BITFIELD_FIELD(uint64_t q3fus:34,
+               ;))))
+       } s;
+};
+
+#endif
index 9742202..e638735 100644 (file)
@@ -62,6 +62,7 @@ enum cvmx_mips_space {
 #include <asm/octeon/cvmx-iob-defs.h>
 #include <asm/octeon/cvmx-ipd-defs.h>
 #include <asm/octeon/cvmx-l2c-defs.h>
+#include <asm/octeon/cvmx-l2d-defs.h>
 #include <asm/octeon/cvmx-l2t-defs.h>
 #include <asm/octeon/cvmx-led-defs.h>
 #include <asm/octeon/cvmx-mio-defs.h>
index 770d4d1..6bace76 100644 (file)
@@ -376,9 +376,6 @@ asmlinkage void start_secondary(void)
        cpumask_set_cpu(cpu, &cpu_coherent_mask);
        notify_cpu_starting(cpu);
 
-       complete(&cpu_running);
-       synchronise_count_slave(cpu);
-
        set_cpu_online(cpu, true);
 
        set_cpu_sibling_map(cpu);
@@ -386,6 +383,9 @@ asmlinkage void start_secondary(void)
 
        calculate_cpu_foreign_map();
 
+       complete(&cpu_running);
+       synchronise_count_slave(cpu);
+
        /*
         * irq will be enabled in ->smp_finish(), enabling it too early
         * is dangerous.
index 3f74f6c..9fea6c6 100644 (file)
@@ -48,7 +48,7 @@
 
 #include "uasm.c"
 
-static const struct insn const insn_table[insn_invalid] = {
+static const struct insn insn_table[insn_invalid] = {
        [insn_addiu]    = {M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM},
        [insn_addu]     = {M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD},
        [insn_and]      = {M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD},
index bd67ac7..9632436 100644 (file)
@@ -28,16 +28,15 @@ EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
 
 static int __init pcibios_set_cache_line_size(void)
 {
-       struct cpuinfo_mips *c = &current_cpu_data;
        unsigned int lsize;
 
        /*
         * Set PCI cacheline size to that of the highest level in the
         * cache hierarchy.
         */
-       lsize = c->dcache.linesz;
-       lsize = c->scache.linesz ? : lsize;
-       lsize = c->tcache.linesz ? : lsize;
+       lsize = cpu_dcache_line_size();
+       lsize = cpu_scache_line_size() ? : lsize;
+       lsize = cpu_tcache_line_size() ? : lsize;
 
        BUG_ON(!lsize);
 
index 974276e..e2690d7 100644 (file)
@@ -35,7 +35,8 @@ static __always_inline long gettimeofday_fallback(struct timeval *_tv,
        "       syscall\n"
        : "=r" (ret), "=r" (error)
        : "r" (tv), "r" (tz), "r" (nr)
-       : "memory");
+       : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
+         "$14", "$15", "$24", "$25", "hi", "lo", "memory");
 
        return error ? -ret : ret;
 }
@@ -55,7 +56,8 @@ static __always_inline long clock_gettime_fallback(clockid_t _clkid,
        "       syscall\n"
        : "=r" (ret), "=r" (error)
        : "r" (clkid), "r" (ts), "r" (nr)
-       : "memory");
+       : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
+         "$14", "$15", "$24", "$25", "hi", "lo", "memory");
 
        return error ? -ret : ret;
 }
index 36f858c..81b0031 100644 (file)
@@ -199,7 +199,7 @@ config PPC
        select HAVE_OPTPROBES                   if PPC64
        select HAVE_PERF_EVENTS
        select HAVE_PERF_EVENTS_NMI             if PPC64
-       select HAVE_HARDLOCKUP_DETECTOR_PERF    if HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH
+       select HAVE_HARDLOCKUP_DETECTOR_PERF    if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_RCU_TABLE_FREE              if SMP
index 0695ce0..34fc9bb 100644 (file)
@@ -293,7 +293,8 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
 CONFIG_LATENCYTOP=y
 CONFIG_SCHED_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
index 5175028..c5246d2 100644 (file)
@@ -324,7 +324,8 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_LATENCYTOP=y
 CONFIG_SCHED_TRACER=y
index 1a61aa2..fd5d98a 100644 (file)
@@ -291,7 +291,8 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
 CONFIG_LATENCYTOP=y
 CONFIG_SCHED_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
index 49d8422..e925c1c 100644 (file)
@@ -223,17 +223,27 @@ system_call_exit:
        andi.   r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
        bne-    .Lsyscall_exit_work
 
-       /* If MSR_FP and MSR_VEC are set in user msr, then no need to restore */
-       li      r7,MSR_FP
+       andi.   r0,r8,MSR_FP
+       beq 2f
 #ifdef CONFIG_ALTIVEC
-       oris    r7,r7,MSR_VEC@h
+       andis.  r0,r8,MSR_VEC@h
+       bne     3f
 #endif
-       and     r0,r8,r7
-       cmpd    r0,r7
-       bne     .Lsyscall_restore_math
-.Lsyscall_restore_math_cont:
+2:     addi    r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_PPC_BOOK3S
+       li      r10,MSR_RI
+       mtmsrd  r10,1           /* Restore RI */
+#endif
+       bl      restore_math
+#ifdef CONFIG_PPC_BOOK3S
+       li      r11,0
+       mtmsrd  r11,1
+#endif
+       ld      r8,_MSR(r1)
+       ld      r3,RESULT(r1)
+       li      r11,-MAX_ERRNO
 
-       cmpld   r3,r11
+3:     cmpld   r3,r11
        ld      r5,_CCR(r1)
        bge-    .Lsyscall_error
 .Lsyscall_error_cont:
@@ -267,40 +277,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
        std     r5,_CCR(r1)
        b       .Lsyscall_error_cont
 
-.Lsyscall_restore_math:
-       /*
-        * Some initial tests from restore_math to avoid the heavyweight
-        * C code entry and MSR manipulations.
-        */
-       LOAD_REG_IMMEDIATE(r0, MSR_TS_MASK)
-       and.    r0,r0,r8
-       bne     1f
-
-       ld      r7,PACACURRENT(r13)
-       lbz     r0,THREAD+THREAD_LOAD_FP(r7)
-#ifdef CONFIG_ALTIVEC
-       lbz     r6,THREAD+THREAD_LOAD_VEC(r7)
-       add     r0,r0,r6
-#endif
-       cmpdi   r0,0
-       beq     .Lsyscall_restore_math_cont
-
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-#ifdef CONFIG_PPC_BOOK3S
-       li      r10,MSR_RI
-       mtmsrd  r10,1           /* Restore RI */
-#endif
-       bl      restore_math
-#ifdef CONFIG_PPC_BOOK3S
-       li      r11,0
-       mtmsrd  r11,1
-#endif
-       /* Restore volatiles, reload MSR from updated one */
-       ld      r8,_MSR(r1)
-       ld      r3,RESULT(r1)
-       li      r11,-MAX_ERRNO
-       b       .Lsyscall_restore_math_cont
-
 /* Traced system call support */
 .Lsyscall_dotrace:
        bl      save_nvgprs
index 9f3e2c9..1f0fd36 100644 (file)
@@ -362,7 +362,8 @@ void enable_kernel_vsx(void)
 
        cpumsr = msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX);
 
-       if (current->thread.regs && (current->thread.regs->msr & MSR_VSX)) {
+       if (current->thread.regs &&
+           (current->thread.regs->msr & (MSR_VSX|MSR_VEC|MSR_FP))) {
                check_if_tm_restore_required(current);
                /*
                 * If a thread has already been reclaimed then the
@@ -386,7 +387,7 @@ void flush_vsx_to_thread(struct task_struct *tsk)
 {
        if (tsk->thread.regs) {
                preempt_disable();
-               if (tsk->thread.regs->msr & MSR_VSX) {
+               if (tsk->thread.regs->msr & (MSR_VSX|MSR_VEC|MSR_FP)) {
                        BUG_ON(tsk != current);
                        giveup_vsx(tsk);
                }
@@ -511,10 +512,6 @@ void restore_math(struct pt_regs *regs)
 {
        unsigned long msr;
 
-       /*
-        * Syscall exit makes a similar initial check before branching
-        * to restore_math. Keep them in synch.
-        */
        if (!msr_tm_active(regs->msr) &&
                !current->thread.load_fp && !loadvec(current->thread))
                return;
index cf0e124..8d33205 100644 (file)
@@ -351,7 +351,7 @@ static void nmi_ipi_lock_start(unsigned long *flags)
        hard_irq_disable();
        while (atomic_cmpxchg(&__nmi_ipi_lock, 0, 1) == 1) {
                raw_local_irq_restore(*flags);
-               cpu_relax();
+               spin_until_cond(atomic_read(&__nmi_ipi_lock) == 0);
                raw_local_irq_save(*flags);
                hard_irq_disable();
        }
@@ -360,7 +360,7 @@ static void nmi_ipi_lock_start(unsigned long *flags)
 static void nmi_ipi_lock(void)
 {
        while (atomic_cmpxchg(&__nmi_ipi_lock, 0, 1) == 1)
-               cpu_relax();
+               spin_until_cond(atomic_read(&__nmi_ipi_lock) == 0);
 }
 
 static void nmi_ipi_unlock(void)
@@ -475,7 +475,7 @@ int smp_send_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us)
        nmi_ipi_lock_start(&flags);
        while (nmi_ipi_busy_count) {
                nmi_ipi_unlock_end(&flags);
-               cpu_relax();
+               spin_until_cond(nmi_ipi_busy_count == 0);
                nmi_ipi_lock_start(&flags);
        }
 
index b67f8b0..34721a2 100644 (file)
@@ -71,15 +71,20 @@ static inline void wd_smp_lock(unsigned long *flags)
         * This may be called from low level interrupt handlers at some
         * point in future.
         */
-       local_irq_save(*flags);
-       while (unlikely(test_and_set_bit_lock(0, &__wd_smp_lock)))
-               cpu_relax();
+       raw_local_irq_save(*flags);
+       hard_irq_disable(); /* Make it soft-NMI safe */
+       while (unlikely(test_and_set_bit_lock(0, &__wd_smp_lock))) {
+               raw_local_irq_restore(*flags);
+               spin_until_cond(!test_bit(0, &__wd_smp_lock));
+               raw_local_irq_save(*flags);
+               hard_irq_disable();
+       }
 }
 
 static inline void wd_smp_unlock(unsigned long *flags)
 {
        clear_bit_unlock(0, &__wd_smp_lock);
-       local_irq_restore(*flags);
+       raw_local_irq_restore(*flags);
 }
 
 static void wd_lockup_ipi(struct pt_regs *regs)
@@ -96,10 +101,10 @@ static void wd_lockup_ipi(struct pt_regs *regs)
                nmi_panic(regs, "Hard LOCKUP");
 }
 
-static void set_cpu_stuck(int cpu, u64 tb)
+static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb)
 {
-       cpumask_set_cpu(cpu, &wd_smp_cpus_stuck);
-       cpumask_clear_cpu(cpu, &wd_smp_cpus_pending);
+       cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask);
+       cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask);
        if (cpumask_empty(&wd_smp_cpus_pending)) {
                wd_smp_last_reset_tb = tb;
                cpumask_andnot(&wd_smp_cpus_pending,
@@ -107,6 +112,10 @@ static void set_cpu_stuck(int cpu, u64 tb)
                                &wd_smp_cpus_stuck);
        }
 }
+static void set_cpu_stuck(int cpu, u64 tb)
+{
+       set_cpumask_stuck(cpumask_of(cpu), tb);
+}
 
 static void watchdog_smp_panic(int cpu, u64 tb)
 {
@@ -135,11 +144,9 @@ static void watchdog_smp_panic(int cpu, u64 tb)
        }
        smp_flush_nmi_ipi(1000000);
 
-       /* Take the stuck CPU out of the watch group */
-       for_each_cpu(c, &wd_smp_cpus_pending)
-               set_cpu_stuck(c, tb);
+       /* Take the stuck CPUs out of the watch group */
+       set_cpumask_stuck(&wd_smp_cpus_pending, tb);
 
-out:
        wd_smp_unlock(&flags);
 
        printk_safe_flush();
@@ -152,6 +159,11 @@ out:
 
        if (hardlockup_panic)
                nmi_panic(NULL, "Hard LOCKUP");
+
+       return;
+
+out:
+       wd_smp_unlock(&flags);
 }
 
 static void wd_smp_clear_cpu_pending(int cpu, u64 tb)
@@ -258,9 +270,11 @@ static void wd_timer_fn(unsigned long data)
 
 void arch_touch_nmi_watchdog(void)
 {
+       unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000;
        int cpu = smp_processor_id();
 
-       watchdog_timer_interrupt(cpu);
+       if (get_tb() - per_cpu(wd_timer_tb, cpu) >= ticks)
+               watchdog_timer_interrupt(cpu);
 }
 EXPORT_SYMBOL(arch_touch_nmi_watchdog);
 
@@ -283,6 +297,8 @@ static void stop_watchdog_timer_on(unsigned int cpu)
 
 static int start_wd_on_cpu(unsigned int cpu)
 {
+       unsigned long flags;
+
        if (cpumask_test_cpu(cpu, &wd_cpus_enabled)) {
                WARN_ON(1);
                return 0;
@@ -297,12 +313,14 @@ static int start_wd_on_cpu(unsigned int cpu)
        if (!cpumask_test_cpu(cpu, &watchdog_cpumask))
                return 0;
 
+       wd_smp_lock(&flags);
        cpumask_set_cpu(cpu, &wd_cpus_enabled);
        if (cpumask_weight(&wd_cpus_enabled) == 1) {
                cpumask_set_cpu(cpu, &wd_smp_cpus_pending);
                wd_smp_last_reset_tb = get_tb();
        }
-       smp_wmb();
+       wd_smp_unlock(&flags);
+
        start_watchdog_timer_on(cpu);
 
        return 0;
@@ -310,12 +328,17 @@ static int start_wd_on_cpu(unsigned int cpu)
 
 static int stop_wd_on_cpu(unsigned int cpu)
 {
+       unsigned long flags;
+
        if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
                return 0; /* Can happen in CPU unplug case */
 
        stop_watchdog_timer_on(cpu);
 
+       wd_smp_lock(&flags);
        cpumask_clear_cpu(cpu, &wd_cpus_enabled);
+       wd_smp_unlock(&flags);
+
        wd_smp_clear_cpu_pending(cpu, get_tb());
 
        return 0;
index 2abee07..a553aee 100644 (file)
@@ -56,6 +56,7 @@ u64 pnv_first_deep_stop_state = MAX_STOP_STATE;
  */
 static u64 pnv_deepest_stop_psscr_val;
 static u64 pnv_deepest_stop_psscr_mask;
+static u64 pnv_deepest_stop_flag;
 static bool deepest_stop_found;
 
 static int pnv_save_sprs_for_deep_states(void)
@@ -185,8 +186,40 @@ static void pnv_alloc_idle_core_states(void)
 
        update_subcore_sibling_mask();
 
-       if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT)
-               pnv_save_sprs_for_deep_states();
+       if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) {
+               int rc = pnv_save_sprs_for_deep_states();
+
+               if (likely(!rc))
+                       return;
+
+               /*
+                * The stop-api is unable to restore hypervisor
+                * resources on wakeup from platform idle states which
+                * lose full context. So disable such states.
+                */
+               supported_cpuidle_states &= ~OPAL_PM_LOSE_FULL_CONTEXT;
+               pr_warn("cpuidle-powernv: Disabling idle states that lose full context\n");
+               pr_warn("cpuidle-powernv: Idle power-savings, CPU-Hotplug affected\n");
+
+               if (cpu_has_feature(CPU_FTR_ARCH_300) &&
+                   (pnv_deepest_stop_flag & OPAL_PM_LOSE_FULL_CONTEXT)) {
+                       /*
+                        * Use the default stop state for CPU-Hotplug
+                        * if available.
+                        */
+                       if (default_stop_found) {
+                               pnv_deepest_stop_psscr_val =
+                                       pnv_default_stop_val;
+                               pnv_deepest_stop_psscr_mask =
+                                       pnv_default_stop_mask;
+                               pr_warn("cpuidle-powernv: Offlined CPUs will stop with psscr = 0x%016llx\n",
+                                       pnv_deepest_stop_psscr_val);
+                       } else { /* Fallback to snooze loop for CPU-Hotplug */
+                               deepest_stop_found = false;
+                               pr_warn("cpuidle-powernv: Offlined CPUs will busy wait\n");
+                       }
+               }
+       }
 }
 
 u32 pnv_get_supported_cpuidle_states(void)
@@ -375,7 +408,8 @@ unsigned long pnv_cpu_offline(unsigned int cpu)
                                                pnv_deepest_stop_psscr_val;
                srr1 = power9_idle_stop(psscr);
 
-       } else if (idle_states & OPAL_PM_WINKLE_ENABLED) {
+       } else if ((idle_states & OPAL_PM_WINKLE_ENABLED) &&
+                  (idle_states & OPAL_PM_LOSE_FULL_CONTEXT)) {
                srr1 = power7_idle_insn(PNV_THREAD_WINKLE);
        } else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
                   (idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
@@ -553,6 +587,7 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags,
                        max_residency_ns = residency_ns[i];
                        pnv_deepest_stop_psscr_val = psscr_val[i];
                        pnv_deepest_stop_psscr_mask = psscr_mask[i];
+                       pnv_deepest_stop_flag = flags[i];
                        deepest_stop_found = true;
                }
 
index 0efd058..6249214 100644 (file)
@@ -68,6 +68,7 @@ typedef struct { unsigned long iopgprot; } iopgprot_t;
 #define iopgprot_val(x)        ((x).iopgprot)
 
 #define __pte(x)       ((pte_t) { (x) } )
+#define __pmd(x)       ((pmd_t) { { (x) }, })
 #define __iopte(x)     ((iopte_t) { (x) } )
 #define __pgd(x)       ((pgd_t) { (x) } )
 #define __ctxd(x)      ((ctxd_t) { (x) } )
@@ -95,6 +96,7 @@ typedef unsigned long iopgprot_t;
 #define iopgprot_val(x)        (x)
 
 #define __pte(x)       (x)
+#define __pmd(x)       ((pmd_t) { { (x) }, })
 #define __iopte(x)     (x)
 #define __pgd(x)       (x)
 #define __ctxd(x)      (x)
index f10e2f7..9ebebf1 100644 (file)
@@ -1266,8 +1266,6 @@ static int pci_sun4v_probe(struct platform_device *op)
                         * ATU group, but ATU hcalls won't be available.
                         */
                        hv_atu = false;
-                       pr_err(PFX "Could not register hvapi ATU err=%d\n",
-                              err);
                } else {
                        pr_info(PFX "Registered hvapi ATU major[%lu] minor[%lu]\n",
                                vatu_major, vatu_minor);
index a38787b..732af9a 100644 (file)
@@ -602,7 +602,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        int i, has_io, has_mem;
-       unsigned int cmd;
+       unsigned int cmd = 0;
        struct linux_pcic *pcic;
        /* struct linux_pbm_info* pbm = &pcic->pbm; */
        int node;
index d6b6c97..703127a 100644 (file)
@@ -5,26 +5,26 @@
        .align  4
 ENTRY(__multi3) /* %o0 = u, %o1 = v */
        mov     %o1, %g1
-       srl     %o3, 0, %g4
-       mulx    %g4, %g1, %o1
+       srl     %o3, 0, %o4
+       mulx    %o4, %g1, %o1
        srlx    %g1, 0x20, %g3
-       mulx    %g3, %g4, %g5
-       sllx    %g5, 0x20, %o5
-       srl     %g1, 0, %g4
+       mulx    %g3, %o4, %g7
+       sllx    %g7, 0x20, %o5
+       srl     %g1, 0, %o4
        sub     %o1, %o5, %o5
        srlx    %o5, 0x20, %o5
-       addcc   %g5, %o5, %g5
+       addcc   %g7, %o5, %g7
        srlx    %o3, 0x20, %o5
-       mulx    %g4, %o5, %g4
+       mulx    %o4, %o5, %o4
        mulx    %g3, %o5, %o5
        sethi   %hi(0x80000000), %g3
-       addcc   %g5, %g4, %g5
-       srlx    %g5, 0x20, %g5
+       addcc   %g7, %o4, %g7
+       srlx    %g7, 0x20, %g7
        add     %g3, %g3, %g3
        movcc   %xcc, %g0, %g3
-       addcc   %o5, %g5, %o5
-       sllx    %g4, 0x20, %g4
-       add     %o1, %g4, %o1
+       addcc   %o5, %g7, %o5
+       sllx    %o4, 0x20, %o4
+       add     %o1, %o4, %o1
        add     %o5, %g3, %g2
        mulx    %g1, %o2, %g1
        add     %g1, %g2, %g1
index 73574c9..6e01f58 100644 (file)
@@ -101,6 +101,7 @@ config X86
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
+       select HARDLOCKUP_CHECK_TIMESTAMP       if X86_64
        select HAVE_ACPI_APEI                   if ACPI
        select HAVE_ACPI_APEI_NMI               if ACPI
        select HAVE_ALIGNED_STRUCT_PAGE         if SLUB
@@ -164,7 +165,7 @@ config X86
        select HAVE_PCSPKR_PLATFORM
        select HAVE_PERF_EVENTS
        select HAVE_PERF_EVENTS_NMI
-       select HAVE_HARDLOCKUP_DETECTOR_PERF    if HAVE_PERF_EVENTS_NMI
+       select HAVE_HARDLOCKUP_DETECTOR_PERF    if PERF_EVENTS && HAVE_PERF_EVENTS_NMI
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_REGS_AND_STACK_ACCESS_API
index 1cd792d..1eab79c 100644 (file)
        .set T1, REG_T1
 .endm
 
-#define K_BASE         %r8
 #define HASH_PTR       %r9
+#define BLOCKS_CTR     %r8
 #define BUFFER_PTR     %r10
 #define BUFFER_PTR2    %r13
-#define BUFFER_END     %r11
 
 #define PRECALC_BUF    %r14
 #define WK_BUF         %r15
                 * blended AVX2 and ALU instruction scheduling
                 * 1 vector iteration per 8 rounds
                 */
-               vmovdqu ((i * 2) + PRECALC_OFFSET)(BUFFER_PTR), W_TMP
+               vmovdqu (i * 2)(BUFFER_PTR), W_TMP
        .elseif ((i & 7) == 1)
-               vinsertf128 $1, (((i-1) * 2)+PRECALC_OFFSET)(BUFFER_PTR2),\
+               vinsertf128 $1, ((i-1) * 2)(BUFFER_PTR2),\
                         WY_TMP, WY_TMP
        .elseif ((i & 7) == 2)
                vpshufb YMM_SHUFB_BSWAP, WY_TMP, WY
        .elseif ((i & 7) == 4)
-               vpaddd  K_XMM(K_BASE), WY, WY_TMP
+               vpaddd  K_XMM + K_XMM_AR(%rip), WY, WY_TMP
        .elseif ((i & 7) == 7)
                vmovdqu  WY_TMP, PRECALC_WK(i&~7)
 
                vpxor   WY, WY_TMP, WY_TMP
        .elseif ((i & 7) == 7)
                vpxor   WY_TMP2, WY_TMP, WY
-               vpaddd  K_XMM(K_BASE), WY, WY_TMP
+               vpaddd  K_XMM + K_XMM_AR(%rip), WY, WY_TMP
                vmovdqu WY_TMP, PRECALC_WK(i&~7)
 
                PRECALC_ROTATE_WY
                vpsrld  $30, WY, WY
                vpor    WY, WY_TMP, WY
        .elseif ((i & 7) == 7)
-               vpaddd  K_XMM(K_BASE), WY, WY_TMP
+               vpaddd  K_XMM + K_XMM_AR(%rip), WY, WY_TMP
                vmovdqu WY_TMP, PRECALC_WK(i&~7)
 
                PRECALC_ROTATE_WY
 
 .endm
 
+/* Add constant only if (%2 > %3) condition met (uses RTA as temp)
+ * %1 + %2 >= %3 ? %4 : 0
+ */
+.macro ADD_IF_GE a, b, c, d
+       mov     \a, RTA
+       add     $\d, RTA
+       cmp     $\c, \b
+       cmovge  RTA, \a
+.endm
+
 /*
  * macro implements 80 rounds of SHA-1, for multiple blocks with s/w pipelining
  */
        lea     (2*4*80+32)(%rsp), WK_BUF
 
        # Precalc WK for first 2 blocks
-       PRECALC_OFFSET = 0
+       ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 2, 64
        .set i, 0
        .rept    160
                PRECALC i
                .set i, i + 1
        .endr
-       PRECALC_OFFSET = 128
+
+       /* Go to next block if needed */
+       ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 3, 128
+       ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128
        xchg    WK_BUF, PRECALC_BUF
 
        .align 32
@@ -479,8 +491,8 @@ _loop:
         * we use K_BASE value as a signal of a last block,
         * it is set below by: cmovae BUFFER_PTR, K_BASE
         */
-       cmp     K_BASE, BUFFER_PTR
-       jne     _begin
+       test BLOCKS_CTR, BLOCKS_CTR
+       jnz _begin
        .align 32
        jmp     _end
        .align 32
@@ -512,10 +524,10 @@ _loop0:
                .set j, j+2
        .endr
 
-       add     $(2*64), BUFFER_PTR       /* move to next odd-64-byte block */
-       cmp     BUFFER_END, BUFFER_PTR    /* is current block the last one? */
-       cmovae  K_BASE, BUFFER_PTR      /* signal the last iteration smartly */
-
+       /* Update Counter */
+       sub $1, BLOCKS_CTR
+       /* Move to the next block only if needed*/
+       ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 4, 128
        /*
         * rounds
         * 60,62,64,66,68
@@ -532,8 +544,8 @@ _loop0:
        UPDATE_HASH     12(HASH_PTR), D
        UPDATE_HASH     16(HASH_PTR), E
 
-       cmp     K_BASE, BUFFER_PTR      /* is current block the last one? */
-       je      _loop
+       test    BLOCKS_CTR, BLOCKS_CTR
+       jz      _loop
 
        mov     TB, B
 
@@ -575,10 +587,10 @@ _loop2:
                .set j, j+2
        .endr
 
-       add     $(2*64), BUFFER_PTR2      /* move to next even-64-byte block */
-
-       cmp     BUFFER_END, BUFFER_PTR2   /* is current block the last one */
-       cmovae  K_BASE, BUFFER_PTR       /* signal the last iteration smartly */
+       /* update counter */
+       sub     $1, BLOCKS_CTR
+       /* Move to the next block only if needed*/
+       ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128
 
        jmp     _loop3
 _loop3:
@@ -641,19 +653,12 @@ _loop3:
 
        avx2_zeroupper
 
-       lea     K_XMM_AR(%rip), K_BASE
-
+       /* Setup initial values */
        mov     CTX, HASH_PTR
        mov     BUF, BUFFER_PTR
-       lea     64(BUF), BUFFER_PTR2
-
-       shl     $6, CNT                 /* mul by 64 */
-       add     BUF, CNT
-       add     $64, CNT
-       mov     CNT, BUFFER_END
 
-       cmp     BUFFER_END, BUFFER_PTR2
-       cmovae  K_BASE, BUFFER_PTR2
+       mov     BUF, BUFFER_PTR2
+       mov     CNT, BLOCKS_CTR
 
        xmm_mov BSWAP_SHUFB_CTL(%rip), YMM_SHUFB_BSWAP
 
index f960a04..fc61739 100644 (file)
@@ -201,7 +201,7 @@ asmlinkage void sha1_transform_avx2(u32 *digest, const char *data,
 
 static bool avx2_usable(void)
 {
-       if (false && avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
+       if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
                && boot_cpu_has(X86_FEATURE_BMI1)
                && boot_cpu_has(X86_FEATURE_BMI2))
                return true;
index daf8936..64b233a 100644 (file)
@@ -1313,6 +1313,8 @@ ENTRY(nmi)
         * other IST entries.
         */
 
+       ASM_CLAC
+
        /* Use %rdx as our temp variable throughout */
        pushq   %rdx
 
index 8e3db8f..af12e29 100644 (file)
@@ -2114,7 +2114,7 @@ static void refresh_pce(void *ignored)
        load_mm_cr4(this_cpu_read(cpu_tlbstate.loaded_mm));
 }
 
-static void x86_pmu_event_mapped(struct perf_event *event)
+static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm)
 {
        if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
                return;
@@ -2129,22 +2129,20 @@ static void x86_pmu_event_mapped(struct perf_event *event)
         * For now, this can't happen because all callers hold mmap_sem
         * for write.  If this changes, we'll need a different solution.
         */
-       lockdep_assert_held_exclusive(&current->mm->mmap_sem);
+       lockdep_assert_held_exclusive(&mm->mmap_sem);
 
-       if (atomic_inc_return(&current->mm->context.perf_rdpmc_allowed) == 1)
-               on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+       if (atomic_inc_return(&mm->context.perf_rdpmc_allowed) == 1)
+               on_each_cpu_mask(mm_cpumask(mm), refresh_pce, NULL, 1);
 }
 
-static void x86_pmu_event_unmapped(struct perf_event *event)
+static void x86_pmu_event_unmapped(struct perf_event *event, struct mm_struct *mm)
 {
-       if (!current->mm)
-               return;
 
        if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
                return;
 
-       if (atomic_dec_and_test(&current->mm->context.perf_rdpmc_allowed))
-               on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+       if (atomic_dec_and_test(&mm->context.perf_rdpmc_allowed))
+               on_each_cpu_mask(mm_cpumask(mm), refresh_pce, NULL, 1);
 }
 
 static int x86_pmu_event_idx(struct perf_event *event)
index 8ae8c5c..ddd8d35 100644 (file)
@@ -69,7 +69,7 @@ struct bts_buffer {
        struct bts_phys buf[0];
 };
 
-struct pmu bts_pmu;
+static struct pmu bts_pmu;
 
 static size_t buf_size(struct page *page)
 {
index eb05335..d32c0ee 100644 (file)
@@ -587,7 +587,7 @@ static __initconst const u64 p4_hw_cache_event_ids
  * P4_CONFIG_ALIASABLE or bits for P4_PEBS_METRIC, they are
  * either up to date automatically or not applicable at all.
  */
-struct p4_event_alias {
+static struct p4_event_alias {
        u64 original;
        u64 alternative;
 } p4_event_aliases[] = {
index a45e211..8e2457c 100644 (file)
@@ -559,7 +559,7 @@ static struct attribute_group rapl_pmu_format_group = {
        .attrs = rapl_formats_attr,
 };
 
-const struct attribute_group *rapl_attr_groups[] = {
+static const struct attribute_group *rapl_attr_groups[] = {
        &rapl_pmu_attr_group,
        &rapl_pmu_format_group,
        &rapl_pmu_events_group,
index 44ec523..1c5390f 100644 (file)
@@ -721,7 +721,7 @@ static struct attribute *uncore_pmu_attrs[] = {
        NULL,
 };
 
-static struct attribute_group uncore_pmu_attr_group = {
+static const struct attribute_group uncore_pmu_attr_group = {
        .attrs = uncore_pmu_attrs,
 };
 
index cda5693..6a5cbe9 100644 (file)
@@ -272,7 +272,7 @@ static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group nhmex_uncore_ubox_format_group = {
+static const struct attribute_group nhmex_uncore_ubox_format_group = {
        .name           = "format",
        .attrs          = nhmex_uncore_ubox_formats_attr,
 };
@@ -299,7 +299,7 @@ static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group nhmex_uncore_cbox_format_group = {
+static const struct attribute_group nhmex_uncore_cbox_format_group = {
        .name = "format",
        .attrs = nhmex_uncore_cbox_formats_attr,
 };
@@ -407,7 +407,7 @@ static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group nhmex_uncore_bbox_format_group = {
+static const struct attribute_group nhmex_uncore_bbox_format_group = {
        .name = "format",
        .attrs = nhmex_uncore_bbox_formats_attr,
 };
@@ -484,7 +484,7 @@ static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group nhmex_uncore_sbox_format_group = {
+static const struct attribute_group nhmex_uncore_sbox_format_group = {
        .name                   = "format",
        .attrs                  = nhmex_uncore_sbox_formats_attr,
 };
@@ -898,7 +898,7 @@ static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group nhmex_uncore_mbox_format_group = {
+static const struct attribute_group nhmex_uncore_mbox_format_group = {
        .name           = "format",
        .attrs          = nhmex_uncore_mbox_formats_attr,
 };
@@ -1163,7 +1163,7 @@ static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group nhmex_uncore_rbox_format_group = {
+static const struct attribute_group nhmex_uncore_rbox_format_group = {
        .name = "format",
        .attrs = nhmex_uncore_rbox_formats_attr,
 };
index a3dcc12..db1127c 100644 (file)
@@ -130,7 +130,7 @@ static struct attribute *snb_uncore_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group snb_uncore_format_group = {
+static const struct attribute_group snb_uncore_format_group = {
        .name           = "format",
        .attrs          = snb_uncore_formats_attr,
 };
@@ -289,7 +289,7 @@ static struct attribute *snb_uncore_imc_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group snb_uncore_imc_format_group = {
+static const struct attribute_group snb_uncore_imc_format_group = {
        .name = "format",
        .attrs = snb_uncore_imc_formats_attr,
 };
@@ -769,7 +769,7 @@ static struct attribute *nhm_uncore_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group nhm_uncore_format_group = {
+static const struct attribute_group nhm_uncore_format_group = {
        .name = "format",
        .attrs = nhm_uncore_formats_attr,
 };
index 4f91276..db1fe37 100644 (file)
@@ -602,27 +602,27 @@ static struct uncore_event_desc snbep_uncore_qpi_events[] = {
        { /* end: all zeroes */ },
 };
 
-static struct attribute_group snbep_uncore_format_group = {
+static const struct attribute_group snbep_uncore_format_group = {
        .name = "format",
        .attrs = snbep_uncore_formats_attr,
 };
 
-static struct attribute_group snbep_uncore_ubox_format_group = {
+static const struct attribute_group snbep_uncore_ubox_format_group = {
        .name = "format",
        .attrs = snbep_uncore_ubox_formats_attr,
 };
 
-static struct attribute_group snbep_uncore_cbox_format_group = {
+static const struct attribute_group snbep_uncore_cbox_format_group = {
        .name = "format",
        .attrs = snbep_uncore_cbox_formats_attr,
 };
 
-static struct attribute_group snbep_uncore_pcu_format_group = {
+static const struct attribute_group snbep_uncore_pcu_format_group = {
        .name = "format",
        .attrs = snbep_uncore_pcu_formats_attr,
 };
 
-static struct attribute_group snbep_uncore_qpi_format_group = {
+static const struct attribute_group snbep_uncore_qpi_format_group = {
        .name = "format",
        .attrs = snbep_uncore_qpi_formats_attr,
 };
@@ -1431,27 +1431,27 @@ static struct attribute *ivbep_uncore_qpi_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group ivbep_uncore_format_group = {
+static const struct attribute_group ivbep_uncore_format_group = {
        .name = "format",
        .attrs = ivbep_uncore_formats_attr,
 };
 
-static struct attribute_group ivbep_uncore_ubox_format_group = {
+static const struct attribute_group ivbep_uncore_ubox_format_group = {
        .name = "format",
        .attrs = ivbep_uncore_ubox_formats_attr,
 };
 
-static struct attribute_group ivbep_uncore_cbox_format_group = {
+static const struct attribute_group ivbep_uncore_cbox_format_group = {
        .name = "format",
        .attrs = ivbep_uncore_cbox_formats_attr,
 };
 
-static struct attribute_group ivbep_uncore_pcu_format_group = {
+static const struct attribute_group ivbep_uncore_pcu_format_group = {
        .name = "format",
        .attrs = ivbep_uncore_pcu_formats_attr,
 };
 
-static struct attribute_group ivbep_uncore_qpi_format_group = {
+static const struct attribute_group ivbep_uncore_qpi_format_group = {
        .name = "format",
        .attrs = ivbep_uncore_qpi_formats_attr,
 };
@@ -1887,7 +1887,7 @@ static struct attribute *knl_uncore_ubox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group knl_uncore_ubox_format_group = {
+static const struct attribute_group knl_uncore_ubox_format_group = {
        .name = "format",
        .attrs = knl_uncore_ubox_formats_attr,
 };
@@ -1927,7 +1927,7 @@ static struct attribute *knl_uncore_cha_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group knl_uncore_cha_format_group = {
+static const struct attribute_group knl_uncore_cha_format_group = {
        .name = "format",
        .attrs = knl_uncore_cha_formats_attr,
 };
@@ -2037,7 +2037,7 @@ static struct attribute *knl_uncore_pcu_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group knl_uncore_pcu_format_group = {
+static const struct attribute_group knl_uncore_pcu_format_group = {
        .name = "format",
        .attrs = knl_uncore_pcu_formats_attr,
 };
@@ -2187,7 +2187,7 @@ static struct attribute *knl_uncore_irp_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group knl_uncore_irp_format_group = {
+static const struct attribute_group knl_uncore_irp_format_group = {
        .name = "format",
        .attrs = knl_uncore_irp_formats_attr,
 };
@@ -2385,7 +2385,7 @@ static struct attribute *hswep_uncore_ubox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group hswep_uncore_ubox_format_group = {
+static const struct attribute_group hswep_uncore_ubox_format_group = {
        .name = "format",
        .attrs = hswep_uncore_ubox_formats_attr,
 };
@@ -2439,7 +2439,7 @@ static struct attribute *hswep_uncore_cbox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group hswep_uncore_cbox_format_group = {
+static const struct attribute_group hswep_uncore_cbox_format_group = {
        .name = "format",
        .attrs = hswep_uncore_cbox_formats_attr,
 };
@@ -2621,7 +2621,7 @@ static struct attribute *hswep_uncore_sbox_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group hswep_uncore_sbox_format_group = {
+static const struct attribute_group hswep_uncore_sbox_format_group = {
        .name = "format",
        .attrs = hswep_uncore_sbox_formats_attr,
 };
@@ -3314,7 +3314,7 @@ static struct attribute *skx_uncore_cha_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group skx_uncore_chabox_format_group = {
+static const struct attribute_group skx_uncore_chabox_format_group = {
        .name = "format",
        .attrs = skx_uncore_cha_formats_attr,
 };
@@ -3427,7 +3427,7 @@ static struct attribute *skx_uncore_iio_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group skx_uncore_iio_format_group = {
+static const struct attribute_group skx_uncore_iio_format_group = {
        .name = "format",
        .attrs = skx_uncore_iio_formats_attr,
 };
@@ -3484,7 +3484,7 @@ static struct attribute *skx_uncore_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group skx_uncore_format_group = {
+static const struct attribute_group skx_uncore_format_group = {
        .name = "format",
        .attrs = skx_uncore_formats_attr,
 };
@@ -3605,7 +3605,7 @@ static struct attribute *skx_upi_uncore_formats_attr[] = {
        NULL,
 };
 
-static struct attribute_group skx_upi_uncore_format_group = {
+static const struct attribute_group skx_upi_uncore_format_group = {
        .name = "format",
        .attrs = skx_upi_uncore_formats_attr,
 };
index ca3c48c..5a28e8e 100644 (file)
 #define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */
 #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
 #define X86_FEATURE_AVIC       (15*32+13) /* Virtual Interrupt Controller */
-#define X86_FEATURE_VIRTUAL_VMLOAD_VMSAVE (15*32+15) /* Virtual VMLOAD VMSAVE */
+#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
 #define X86_FEATURE_AVX512VBMI  (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/
index 1c18d83..9aeb919 100644 (file)
@@ -247,11 +247,11 @@ extern int force_personality32;
 
 /*
  * This is the base location for PIE (ET_DYN with INTERP) loads. On
- * 64-bit, this is raised to 4GB to leave the entire 32-bit address
+ * 64-bit, this is above 4GB to leave the entire 32-bit address
  * space open for things that want to use the area for 32-bit pointers.
  */
 #define ELF_ET_DYN_BASE                (mmap_is_ia32() ? 0x000400000UL : \
-                                                 0x100000000UL)
+                                                 (TASK_SIZE / 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,
index 2112615..0ead9db 100644 (file)
@@ -43,6 +43,9 @@ struct hypervisor_x86 {
 
        /* pin current vcpu to specified physical cpu (run rarely) */
        void            (*pin_vcpu)(int);
+
+       /* called during init_mem_mapping() to setup early mappings. */
+       void            (*init_mem_mapping)(void);
 };
 
 extern const struct hypervisor_x86 *x86_hyper;
@@ -57,8 +60,15 @@ extern const struct hypervisor_x86 x86_hyper_kvm;
 extern void init_hypervisor_platform(void);
 extern bool hypervisor_x2apic_available(void);
 extern void hypervisor_pin_vcpu(int cpu);
+
+static inline void hypervisor_init_mem_mapping(void)
+{
+       if (x86_hyper && x86_hyper->init_mem_mapping)
+               x86_hyper->init_mem_mapping();
+}
 #else
 static inline void init_hypervisor_platform(void) { }
 static inline bool hypervisor_x2apic_available(void) { return false; }
+static inline void hypervisor_init_mem_mapping(void) { }
 #endif /* CONFIG_HYPERVISOR_GUEST */
 #endif /* _ASM_X86_HYPERVISOR_H */
index 7cf7c70..0ee8332 100644 (file)
@@ -40,13 +40,16 @@ static void aperfmperf_snapshot_khz(void *dummy)
        struct aperfmperf_sample *s = this_cpu_ptr(&samples);
        ktime_t now = ktime_get();
        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);
+       local_irq_restore(flags);
 
        aperf_delta = aperf - s->aperf;
        mperf_delta = mperf - s->mperf;
index d7cc190..f7370ab 100644 (file)
@@ -122,7 +122,7 @@ static struct attribute *thermal_throttle_attrs[] = {
        NULL
 };
 
-static struct attribute_group thermal_attr_group = {
+static const struct attribute_group thermal_attr_group = {
        .attrs  = thermal_throttle_attrs,
        .name   = "thermal_throttle"
 };
index 9cb98ee..86e8f0b 100644 (file)
@@ -561,7 +561,7 @@ static struct attribute *mc_default_attrs[] = {
        NULL
 };
 
-static struct attribute_group mc_attr_group = {
+static const struct attribute_group mc_attr_group = {
        .attrs                  = mc_default_attrs,
        .name                   = "microcode",
 };
@@ -707,7 +707,7 @@ static struct attribute *cpu_root_microcode_attrs[] = {
        NULL
 };
 
-static struct attribute_group cpu_root_microcode_group = {
+static const struct attribute_group cpu_root_microcode_group = {
        .name  = "microcode",
        .attrs = cpu_root_microcode_attrs,
 };
index c5bb63b..40d5a8a 100644 (file)
@@ -237,6 +237,18 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
        stop_machine(mtrr_rendezvous_handler, &data, cpu_online_mask);
 }
 
+static void set_mtrr_cpuslocked(unsigned int reg, unsigned long base,
+                               unsigned long size, mtrr_type type)
+{
+       struct set_mtrr_data data = { .smp_reg = reg,
+                                     .smp_base = base,
+                                     .smp_size = size,
+                                     .smp_type = type
+                                   };
+
+       stop_machine_cpuslocked(mtrr_rendezvous_handler, &data, cpu_online_mask);
+}
+
 static void set_mtrr_from_inactive_cpu(unsigned int reg, unsigned long base,
                                      unsigned long size, mtrr_type type)
 {
@@ -370,7 +382,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
        /* Search for an empty MTRR */
        i = mtrr_if->get_free_region(base, size, replace);
        if (i >= 0) {
-               set_mtrr(i, base, size, type);
+               set_mtrr_cpuslocked(i, base, size, type);
                if (likely(replace < 0)) {
                        mtrr_usage_table[i] = 1;
                } else {
@@ -378,7 +390,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
                        if (increment)
                                mtrr_usage_table[i]++;
                        if (unlikely(replace != i)) {
-                               set_mtrr(replace, 0, 0, 0);
+                               set_mtrr_cpuslocked(replace, 0, 0, 0);
                                mtrr_usage_table[replace] = 0;
                        }
                }
@@ -506,7 +518,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
                goto out;
        }
        if (--mtrr_usage_table[reg] < 1)
-               set_mtrr(reg, 0, 0, 0);
+               set_mtrr_cpuslocked(reg, 0, 0, 0);
        error = reg;
  out:
        mutex_unlock(&mtrr_mutex);
index 46c3c73..9ba7954 100644 (file)
@@ -53,6 +53,7 @@ void __head __startup_64(unsigned long physaddr)
        pudval_t *pud;
        pmdval_t *pmd, pmd_entry;
        int i;
+       unsigned int *next_pgt_ptr;
 
        /* Is the address too large? */
        if (physaddr >> MAX_PHYSMEM_BITS)
@@ -91,9 +92,9 @@ void __head __startup_64(unsigned long physaddr)
         * creates a bunch of nonsense entries but that is fine --
         * it avoids problems around wraparound.
         */
-
-       pud = fixup_pointer(early_dynamic_pgts[next_early_pgt++], physaddr);
-       pmd = fixup_pointer(early_dynamic_pgts[next_early_pgt++], physaddr);
+       next_pgt_ptr = fixup_pointer(&next_early_pgt, physaddr);
+       pud = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr);
+       pmd = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr);
 
        if (IS_ENABLED(CONFIG_X86_5LEVEL)) {
                p4d = fixup_pointer(early_dynamic_pgts[next_early_pgt++], physaddr);
index 4afc67f..06e1ff5 100644 (file)
@@ -55,7 +55,7 @@ static struct bin_attribute *boot_params_data_attrs[] = {
        NULL,
 };
 
-static struct attribute_group boot_params_attr_group = {
+static const struct attribute_group boot_params_attr_group = {
        .attrs = boot_params_version_attrs,
        .bin_attrs = boot_params_data_attrs,
 };
@@ -202,7 +202,7 @@ static struct bin_attribute *setup_data_data_attrs[] = {
        NULL,
 };
 
-static struct attribute_group setup_data_attr_group = {
+static const struct attribute_group setup_data_attr_group = {
        .attrs = setup_data_type_attrs,
        .bin_attrs = setup_data_data_attrs,
 };
index b474c8d..54b9e89 100644 (file)
@@ -971,7 +971,8 @@ void common_cpu_up(unsigned int cpu, struct task_struct *idle)
  * Returns zero if CPU booted OK, else error code from
  * ->wakeup_secondary_cpu.
  */
-static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
+static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle,
+                      int *cpu0_nmi_registered)
 {
        volatile u32 *trampoline_status =
                (volatile u32 *) __va(real_mode_header->trampoline_status);
@@ -979,7 +980,6 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
        unsigned long start_ip = real_mode_header->trampoline_start;
 
        unsigned long boot_error = 0;
-       int cpu0_nmi_registered = 0;
        unsigned long timeout;
 
        idle->thread.sp = (unsigned long)task_pt_regs(idle);
@@ -1035,7 +1035,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
                boot_error = apic->wakeup_secondary_cpu(apicid, start_ip);
        else
                boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid,
-                                                    &cpu0_nmi_registered);
+                                                    cpu0_nmi_registered);
 
        if (!boot_error) {
                /*
@@ -1080,12 +1080,6 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
                 */
                smpboot_restore_warm_reset_vector();
        }
-       /*
-        * Clean up the nmi handler. Do this after the callin and callout sync
-        * to avoid impact of possible long unregister time.
-        */
-       if (cpu0_nmi_registered)
-               unregister_nmi_handler(NMI_LOCAL, "wake_cpu0");
 
        return boot_error;
 }
@@ -1093,8 +1087,9 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
        int apicid = apic->cpu_present_to_apicid(cpu);
+       int cpu0_nmi_registered = 0;
        unsigned long flags;
-       int err;
+       int err, ret = 0;
 
        WARN_ON(irqs_disabled());
 
@@ -1131,10 +1126,11 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
 
        common_cpu_up(cpu, tidle);
 
-       err = do_boot_cpu(apicid, cpu, tidle);
+       err = do_boot_cpu(apicid, cpu, tidle, &cpu0_nmi_registered);
        if (err) {
                pr_err("do_boot_cpu failed(%d) to wakeup CPU#%u\n", err, cpu);
-               return -EIO;
+               ret = -EIO;
+               goto unreg_nmi;
        }
 
        /*
@@ -1150,7 +1146,15 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
                touch_nmi_watchdog();
        }
 
-       return 0;
+unreg_nmi:
+       /*
+        * Clean up the nmi handler. Do this after the callin and callout sync
+        * to avoid impact of possible long unregister time.
+        */
+       if (cpu0_nmi_registered)
+               unregister_nmi_handler(NMI_LOCAL, "wake_cpu0");
+
+       return ret;
 }
 
 /**
index 1107626..56ba053 100644 (file)
@@ -1100,7 +1100,7 @@ static __init int svm_hardware_setup(void)
 
        if (vls) {
                if (!npt_enabled ||
-                   !boot_cpu_has(X86_FEATURE_VIRTUAL_VMLOAD_VMSAVE) ||
+                   !boot_cpu_has(X86_FEATURE_V_VMSAVE_VMLOAD) ||
                    !IS_ENABLED(CONFIG_X86_64)) {
                        vls = false;
                } else {
index 673541e..bf3f106 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/dma.h>           /* for MAX_DMA_PFN */
 #include <asm/microcode.h>
 #include <asm/kaslr.h>
+#include <asm/hypervisor.h>
 
 /*
  * We need to define the tracepoints somewhere, and tlb.c
@@ -636,6 +637,8 @@ void __init init_mem_mapping(void)
        load_cr3(swapper_pg_dir);
        __flush_tlb_all();
 
+       hypervisor_init_mem_mapping();
+
        early_memtest(0, max_pfn_mapped << PAGE_SHIFT);
 }
 
index 229d04a..a88cfbf 100644 (file)
@@ -50,8 +50,7 @@ unsigned long tasksize_64bit(void)
 static unsigned long stack_maxrandom_size(unsigned long task_size)
 {
        unsigned long max = 0;
-       if ((current->flags & PF_RANDOMIZE) &&
-               !(current->personality & ADDR_NO_RANDOMIZE)) {
+       if (current->flags & PF_RANDOMIZE) {
                max = (-1UL) & __STACK_RND_MASK(task_size == tasksize_32bit());
                max <<= PAGE_SHIFT;
        }
@@ -79,13 +78,13 @@ static int mmap_is_legacy(void)
 
 static unsigned long arch_rnd(unsigned int rndbits)
 {
+       if (!(current->flags & PF_RANDOMIZE))
+               return 0;
        return (get_random_long() & ((1UL << rndbits) - 1)) << PAGE_SHIFT;
 }
 
 unsigned long arch_mmap_rnd(void)
 {
-       if (!(current->flags & PF_RANDOMIZE))
-               return 0;
        return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits);
 }
 
index 3e4bdb4..f44c0bc 100644 (file)
@@ -26,7 +26,7 @@
 static struct bau_operations ops __ro_after_init;
 
 /* timeouts in nanoseconds (indexed by UVH_AGING_PRESCALE_SEL urgency7 30:28) */
-static int timeout_base_ns[] = {
+static const int timeout_base_ns[] = {
                20,
                160,
                1280,
@@ -1216,7 +1216,7 @@ static struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg,
  * set a bit in the UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE register.
  * Such a message must be ignored.
  */
-void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp)
+static void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp)
 {
        unsigned long mmr_image;
        unsigned char swack_vec;
index 87d7913..de503c2 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/setup.h>
 #include <asm/hypervisor.h>
 #include <asm/e820/api.h>
+#include <asm/early_ioremap.h>
 
 #include <asm/xen/cpuid.h>
 #include <asm/xen/hypervisor.h>
 #include "mmu.h"
 #include "smp.h"
 
-void __ref xen_hvm_init_shared_info(void)
+static unsigned long shared_info_pfn;
+
+void xen_hvm_init_shared_info(void)
 {
        struct xen_add_to_physmap xatp;
-       u64 pa;
-
-       if (HYPERVISOR_shared_info == &xen_dummy_shared_info) {
-               /*
-                * Search for a free page starting at 4kB physical address.
-                * Low memory is preferred to avoid an EPT large page split up
-                * by the mapping.
-                * Starting below X86_RESERVE_LOW (usually 64kB) is fine as
-                * the BIOS used for HVM guests is well behaved and won't
-                * clobber memory other than the first 4kB.
-                */
-               for (pa = PAGE_SIZE;
-                    !e820__mapped_all(pa, pa + PAGE_SIZE, E820_TYPE_RAM) ||
-                    memblock_is_reserved(pa);
-                    pa += PAGE_SIZE)
-                       ;
-
-               memblock_reserve(pa, PAGE_SIZE);
-               HYPERVISOR_shared_info = __va(pa);
-       }
 
        xatp.domid = DOMID_SELF;
        xatp.idx = 0;
        xatp.space = XENMAPSPACE_shared_info;
-       xatp.gpfn = virt_to_pfn(HYPERVISOR_shared_info);
+       xatp.gpfn = shared_info_pfn;
        if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
                BUG();
 }
 
+static void __init reserve_shared_info(void)
+{
+       u64 pa;
+
+       /*
+        * Search for a free page starting at 4kB physical address.
+        * Low memory is preferred to avoid an EPT large page split up
+        * by the mapping.
+        * Starting below X86_RESERVE_LOW (usually 64kB) is fine as
+        * the BIOS used for HVM guests is well behaved and won't
+        * clobber memory other than the first 4kB.
+        */
+       for (pa = PAGE_SIZE;
+            !e820__mapped_all(pa, pa + PAGE_SIZE, E820_TYPE_RAM) ||
+            memblock_is_reserved(pa);
+            pa += PAGE_SIZE)
+               ;
+
+       shared_info_pfn = PHYS_PFN(pa);
+
+       memblock_reserve(pa, PAGE_SIZE);
+       HYPERVISOR_shared_info = early_memremap(pa, PAGE_SIZE);
+}
+
+static void __init xen_hvm_init_mem_mapping(void)
+{
+       early_memunmap(HYPERVISOR_shared_info, PAGE_SIZE);
+       HYPERVISOR_shared_info = __va(PFN_PHYS(shared_info_pfn));
+}
+
 static void __init init_hvm_pv_info(void)
 {
        int major, minor;
@@ -153,6 +166,7 @@ static void __init xen_hvm_guest_init(void)
 
        init_hvm_pv_info();
 
+       reserve_shared_info();
        xen_hvm_init_shared_info();
 
        /*
@@ -218,5 +232,6 @@ const struct hypervisor_x86 x86_hyper_xen_hvm = {
        .init_platform          = xen_hvm_guest_init,
        .pin_vcpu               = xen_pin_vcpu,
        .x2apic_available       = xen_x2apic_para_available,
+       .init_mem_mapping       = xen_hvm_init_mem_mapping,
 };
 EXPORT_SYMBOL(x86_hyper_xen_hvm);
index 83e92be..9b1ea47 100644 (file)
@@ -387,9 +387,11 @@ static void bio_integrity_verify_fn(struct work_struct *work)
  */
 bool __bio_integrity_endio(struct bio *bio)
 {
-       if (bio_op(bio) == REQ_OP_READ && !bio->bi_status) {
-               struct bio_integrity_payload *bip = bio_integrity(bio);
+       struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
+       struct bio_integrity_payload *bip = bio_integrity(bio);
 
+       if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
+           (bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->profile->verify_fn) {
                INIT_WORK(&bip->bip_work, bio_integrity_verify_fn);
                queue_work(kintegrityd_wq, &bip->bip_work);
                return false;
index 0c3354c..76944e3 100644 (file)
@@ -36,12 +36,18 @@ int blk_mq_pci_map_queues(struct blk_mq_tag_set *set, struct pci_dev *pdev)
        for (queue = 0; queue < set->nr_hw_queues; queue++) {
                mask = pci_irq_get_affinity(pdev, queue);
                if (!mask)
-                       return -EINVAL;
+                       goto fallback;
 
                for_each_cpu(cpu, mask)
                        set->mq_map[cpu] = queue;
        }
 
        return 0;
+
+fallback:
+       WARN_ON_ONCE(set->nr_hw_queues > 1);
+       for_each_possible_cpu(cpu)
+               set->mq_map[cpu] = 0;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(blk_mq_pci_map_queues);
index 211ef36..4603b11 100644 (file)
@@ -360,12 +360,12 @@ struct request *blk_mq_alloc_request(struct request_queue *q, unsigned int op,
                return ERR_PTR(ret);
 
        rq = blk_mq_get_request(q, NULL, op, &alloc_data);
+       blk_queue_exit(q);
 
        if (!rq)
                return ERR_PTR(-EWOULDBLOCK);
 
        blk_mq_put_ctx(alloc_data.ctx);
-       blk_queue_exit(q);
 
        rq->__data_len = 0;
        rq->__sector = (sector_t) -1;
@@ -411,12 +411,11 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
        alloc_data.ctx = __blk_mq_get_ctx(q, cpu);
 
        rq = blk_mq_get_request(q, NULL, op, &alloc_data);
+       blk_queue_exit(q);
 
        if (!rq)
                return ERR_PTR(-EWOULDBLOCK);
 
-       blk_queue_exit(q);
-
        return rq;
 }
 EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx);
@@ -684,8 +683,8 @@ EXPORT_SYMBOL(blk_mq_kick_requeue_list);
 void blk_mq_delay_kick_requeue_list(struct request_queue *q,
                                    unsigned long msecs)
 {
-       kblockd_schedule_delayed_work(&q->requeue_work,
-                                     msecs_to_jiffies(msecs));
+       kblockd_mod_delayed_work_on(WORK_CPU_UNBOUND, &q->requeue_work,
+                                   msecs_to_jiffies(msecs));
 }
 EXPORT_SYMBOL(blk_mq_delay_kick_requeue_list);
 
index 538c616..783f4c8 100644 (file)
@@ -100,9 +100,13 @@ acpi_evaluate_object_typed(acpi_handle handle,
                free_buffer_on_error = TRUE;
        }
 
-       status = acpi_get_handle(handle, pathname, &target_handle);
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
+       if (pathname) {
+               status = acpi_get_handle(handle, pathname, &target_handle);
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       } else {
+               target_handle = handle;
        }
 
        full_pathname = acpi_ns_get_external_pathname(target_handle);
index 62068a5..ae3d6d1 100644 (file)
@@ -1741,7 +1741,7 @@ error:
  * functioning ECDT EC first in order to handle the events.
  * https://bugzilla.kernel.org/show_bug.cgi?id=115021
  */
-int __init acpi_ec_ecdt_start(void)
+static int __init acpi_ec_ecdt_start(void)
 {
        acpi_handle handle;
 
@@ -2003,20 +2003,17 @@ static inline void acpi_ec_query_exit(void)
 int __init acpi_ec_init(void)
 {
        int result;
+       int ecdt_fail, dsdt_fail;
 
        /* register workqueue for _Qxx evaluations */
        result = acpi_ec_query_init();
        if (result)
-               goto err_exit;
-       /* Now register the driver for the EC */
-       result = acpi_bus_register_driver(&acpi_ec_driver);
-       if (result)
-               goto err_exit;
+               return result;
 
-err_exit:
-       if (result)
-               acpi_ec_query_exit();
-       return result;
+       /* Drivers must be started after acpi_ec_query_init() */
+       ecdt_fail = acpi_ec_ecdt_start();
+       dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver);
+       return ecdt_fail && dsdt_fail ? -ENODEV : 0;
 }
 
 /* EC driver currently not unloadable */
index 58dd7ab..3f5af4d 100644 (file)
@@ -185,7 +185,6 @@ typedef int (*acpi_ec_query_func) (void *data);
 int acpi_ec_init(void);
 int acpi_ec_ecdt_probe(void);
 int acpi_ec_dsdt_probe(void);
-int acpi_ec_ecdt_start(void);
 void acpi_ec_block_transactions(void);
 void acpi_ec_unblock_transactions(void);
 int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
index 917c789..476a52c 100644 (file)
@@ -1047,7 +1047,7 @@ static struct fwnode_handle *acpi_graph_get_child_prop_value(
        fwnode_for_each_child_node(fwnode, child) {
                u32 nr;
 
-               if (!fwnode_property_read_u32(fwnode, prop_name, &nr))
+               if (fwnode_property_read_u32(child, prop_name, &nr))
                        continue;
 
                if (val == nr)
index 3389729..70fd550 100644 (file)
@@ -2084,7 +2084,6 @@ int __init acpi_scan_init(void)
 
        acpi_gpe_apply_masked_gpes();
        acpi_update_all_gpes();
-       acpi_ec_ecdt_start();
 
        acpi_scan_initialized = true;
 
index 4ac3e06..98aa8c8 100644 (file)
 #include <linux/serial_core.h>
 
 /*
+ * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
+ * occasionally getting stuck as 1. To avoid the potential for a hang, check
+ * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
+ * implementations, so only do so if an affected platform is detected in
+ * parse_spcr().
+ */
+bool qdf2400_e44_present;
+EXPORT_SYMBOL(qdf2400_e44_present);
+
+/*
  * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
  * Detect them by examining the OEM fields in the SPCR header, similiar to PCI
  * quirk detection in pci_mcfg.c.
@@ -147,8 +157,30 @@ int __init parse_spcr(bool earlycon)
                goto done;
        }
 
-       if (qdf2400_erratum_44_present(&table->header))
-               uart = "qdf2400_e44";
+       /*
+        * If the E44 erratum is required, then we need to tell the pl011
+        * driver to implement the work-around.
+        *
+        * The global variable is used by the probe function when it
+        * creates the UARTs, whether or not they're used as a console.
+        *
+        * If the user specifies "traditional" earlycon, the qdf2400_e44
+        * console name matches the EARLYCON_DECLARE() statement, and
+        * SPCR is not used.  Parameter "earlycon" is false.
+        *
+        * If the user specifies "SPCR" earlycon, then we need to update
+        * the console name so that it also says "qdf2400_e44".  Parameter
+        * "earlycon" is true.
+        *
+        * For consistency, if we change the console name, then we do it
+        * for everyone, not just earlycon.
+        */
+       if (qdf2400_erratum_44_present(&table->header)) {
+               qdf2400_e44_present = true;
+               if (earlycon)
+                       uart = "qdf2400_e44";
+       }
+
        if (xgene_8250_erratum_present(table))
                iotype = "mmio32";
 
index b9f907e..bfbe1e1 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/syscore_ops.h>
 #include <linux/reboot.h>
 #include <linux/security.h>
-#include <linux/swait.h>
 
 #include <generated/utsrelease.h>
 
@@ -112,13 +111,13 @@ static inline long firmware_loading_timeout(void)
  * state of the firmware loading.
  */
 struct fw_state {
-       struct swait_queue_head wq;
+       struct completion completion;
        enum fw_status status;
 };
 
 static void fw_state_init(struct fw_state *fw_st)
 {
-       init_swait_queue_head(&fw_st->wq);
+       init_completion(&fw_st->completion);
        fw_st->status = FW_STATUS_UNKNOWN;
 }
 
@@ -131,9 +130,7 @@ static int __fw_state_wait_common(struct fw_state *fw_st, long timeout)
 {
        long ret;
 
-       ret = swait_event_interruptible_timeout(fw_st->wq,
-                               __fw_state_is_done(READ_ONCE(fw_st->status)),
-                               timeout);
+       ret = wait_for_completion_killable_timeout(&fw_st->completion, timeout);
        if (ret != 0 && fw_st->status == FW_STATUS_ABORTED)
                return -ENOENT;
        if (!ret)
@@ -148,35 +145,34 @@ static void __fw_state_set(struct fw_state *fw_st,
        WRITE_ONCE(fw_st->status, status);
 
        if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED)
-               swake_up(&fw_st->wq);
+               complete_all(&fw_st->completion);
 }
 
 #define fw_state_start(fw_st)                                  \
        __fw_state_set(fw_st, FW_STATUS_LOADING)
 #define fw_state_done(fw_st)                                   \
        __fw_state_set(fw_st, FW_STATUS_DONE)
+#define fw_state_aborted(fw_st)                                        \
+       __fw_state_set(fw_st, FW_STATUS_ABORTED)
 #define fw_state_wait(fw_st)                                   \
        __fw_state_wait_common(fw_st, MAX_SCHEDULE_TIMEOUT)
 
-#ifndef CONFIG_FW_LOADER_USER_HELPER
-
-#define fw_state_is_aborted(fw_st)     false
-
-#else /* CONFIG_FW_LOADER_USER_HELPER */
-
 static int __fw_state_check(struct fw_state *fw_st, enum fw_status status)
 {
        return fw_st->status == status;
 }
 
+#define fw_state_is_aborted(fw_st)                             \
+       __fw_state_check(fw_st, FW_STATUS_ABORTED)
+
+#ifdef CONFIG_FW_LOADER_USER_HELPER
+
 #define fw_state_aborted(fw_st)                                        \
        __fw_state_set(fw_st, FW_STATUS_ABORTED)
 #define fw_state_is_done(fw_st)                                        \
        __fw_state_check(fw_st, FW_STATUS_DONE)
 #define fw_state_is_loading(fw_st)                             \
        __fw_state_check(fw_st, FW_STATUS_LOADING)
-#define fw_state_is_aborted(fw_st)                             \
-       __fw_state_check(fw_st, FW_STATUS_ABORTED)
 #define fw_state_wait_timeout(fw_st, timeout)                  \
        __fw_state_wait_common(fw_st, timeout)
 
@@ -1200,6 +1196,28 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
        return 1; /* need to load */
 }
 
+/*
+ * Batched requests need only one wake, we need to do this step last due to the
+ * fallback mechanism. The buf is protected with kref_get(), and it won't be
+ * released until the last user calls release_firmware().
+ *
+ * Failed batched requests are possible as well, in such cases we just share
+ * the struct firmware_buf and won't release it until all requests are woken
+ * and have gone through this same path.
+ */
+static void fw_abort_batch_reqs(struct firmware *fw)
+{
+       struct firmware_buf *buf;
+
+       /* Loaded directly? */
+       if (!fw || !fw->priv)
+               return;
+
+       buf = fw->priv;
+       if (!fw_state_is_aborted(&buf->fw_st))
+               fw_state_aborted(&buf->fw_st);
+}
+
 /* called from request_firmware() and request_firmware_work_func() */
 static int
 _request_firmware(const struct firmware **firmware_p, const char *name,
@@ -1243,6 +1261,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
 
  out:
        if (ret < 0) {
+               fw_abort_batch_reqs(fw);
                release_firmware(fw);
                fw = NULL;
        }
index 98e34e4..2468c28 100644 (file)
@@ -2075,9 +2075,9 @@ static int blkfront_resume(struct xenbus_device *dev)
                        /*
                         * Get the bios in the request so we can re-queue them.
                         */
-                       if (req_op(shadow[i].request) == REQ_OP_FLUSH ||
-                           req_op(shadow[i].request) == REQ_OP_DISCARD ||
-                           req_op(shadow[i].request) == REQ_OP_SECURE_ERASE ||
+                       if (req_op(shadow[j].request) == REQ_OP_FLUSH ||
+                           req_op(shadow[j].request) == REQ_OP_DISCARD ||
+                           req_op(shadow[j].request) == REQ_OP_SECURE_ERASE ||
                            shadow[j].request->cmd_flags & REQ_FUA) {
                                /*
                                 * Flush operations don't contain bios, so
index fcae5ca..54a67f8 100644 (file)
@@ -262,7 +262,7 @@ config CLKSRC_LPC32XX
 
 config CLKSRC_PISTACHIO
        bool "Clocksource for Pistachio SoC" if COMPILE_TEST
-       depends on HAS_IOMEM
+       depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
        select TIMER_OF
        help
          Enables the clocksource for the Pistachio SoC.
index c62e716..fd4b7f6 100644 (file)
@@ -1444,7 +1444,7 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count)
         * While unlikely, it's theoretically possible that none of the frames
         * in a timer expose the combination of feature we want.
         */
-       for (i = i; i < timer_count; i++) {
+       for (i = 0; i < timer_count; i++) {
                timer = &timers[i];
 
                frame = arch_timer_mem_find_best_frame(timer);
index bc48cbf..269db74 100644 (file)
@@ -305,7 +305,7 @@ static int em_sti_probe(struct platform_device *pdev)
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                dev_err(&pdev->dev, "failed to get irq\n");
-               return -EINVAL;
+               return irq;
        }
 
        /* map memory, let base point to the STI instance */
@@ -314,11 +314,12 @@ static int em_sti_probe(struct platform_device *pdev)
        if (IS_ERR(p->base))
                return PTR_ERR(p->base);
 
-       if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
-                            IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
-                            dev_name(&pdev->dev), p)) {
+       ret = devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
+                              IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
+                              dev_name(&pdev->dev), p);
+       if (ret) {
                dev_err(&pdev->dev, "failed to request low IRQ\n");
-               return -ENOENT;
+               return ret;
        }
 
        /* get hold of clock */
index d509b50..4d7aef9 100644 (file)
@@ -128,9 +128,9 @@ static __init int timer_base_init(struct device_node *np,
        const char *name = of_base->name ? of_base->name : np->full_name;
 
        of_base->base = of_io_request_and_map(np, of_base->index, name);
-       if (!of_base->base) {
+       if (IS_ERR(of_base->base)) {
                pr_err("Failed to iomap (%s)\n", name);
-               return -ENXIO;
+               return PTR_ERR(of_base->base);
        }
 
        return 0;
index 0566455..65ee4fc 100644 (file)
@@ -1613,8 +1613,7 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time)
 
 static inline int32_t get_avg_frequency(struct cpudata *cpu)
 {
-       return mul_ext_fp(cpu->sample.core_avg_perf,
-                         cpu->pstate.max_pstate_physical * cpu->pstate.scaling);
+       return mul_ext_fp(cpu->sample.core_avg_perf, cpu_khz);
 }
 
 static inline int32_t get_avg_pstate(struct cpudata *cpu)
index 37b0698..42896a6 100644 (file)
@@ -235,6 +235,7 @@ static inline int validate_dt_prop_sizes(const char *prop1, int prop1_len,
        return -1;
 }
 
+extern u32 pnv_get_supported_cpuidle_states(void);
 static int powernv_add_idle_states(void)
 {
        struct device_node *power_mgt;
@@ -248,6 +249,8 @@ static int powernv_add_idle_states(void)
        const char *names[CPUIDLE_STATE_MAX];
        u32 has_stop_states = 0;
        int i, rc;
+       u32 supported_flags = pnv_get_supported_cpuidle_states();
+
 
        /* Currently we have snooze statically defined */
 
@@ -362,6 +365,13 @@ static int powernv_add_idle_states(void)
        for (i = 0; i < dt_idle_states; i++) {
                unsigned int exit_latency, target_residency;
                bool stops_timebase = false;
+
+               /*
+                * Skip the platform idle state whose flag isn't in
+                * the supported_cpuidle_states flag mask.
+                */
+               if ((flags[i] & supported_flags) != flags[i])
+                       continue;
                /*
                 * If an idle state has exit latency beyond
                 * POWERNV_THRESHOLD_LATENCY_NS then don't use it
index 427cbe0..dadc4a8 100644 (file)
@@ -1073,7 +1073,7 @@ static int aead_perform(struct aead_request *req, int encrypt,
                req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags,
                                &crypt->icv_rev_aes);
                if (unlikely(!req_ctx->hmac_virt))
-                       goto free_buf_src;
+                       goto free_buf_dst;
                if (!encrypt) {
                        scatterwalk_map_and_copy(req_ctx->hmac_virt,
                                req->src, cryptlen, authsize, 0);
@@ -1088,10 +1088,10 @@ static int aead_perform(struct aead_request *req, int encrypt,
        BUG_ON(qmgr_stat_overflow(SEND_QID));
        return -EINPROGRESS;
 
-free_buf_src:
-       free_buf_chain(dev, req_ctx->src, crypt->src_buf);
 free_buf_dst:
        free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
+free_buf_src:
+       free_buf_chain(dev, req_ctx->src, crypt->src_buf);
        crypt->ctl_flags = CTL_FLAG_UNUSED;
        return -ENOMEM;
 }
index e338c37..45c65f8 100644 (file)
@@ -557,7 +557,7 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc)
        edge_cause = mvebu_gpio_read_edge_cause(mvchip);
        edge_mask  = mvebu_gpio_read_edge_mask(mvchip);
 
-       cause = (data_in ^ level_mask) | (edge_cause & edge_mask);
+       cause = (data_in & level_mask) | (edge_cause & edge_mask);
 
        for (i = 0; i < mvchip->chip.ngpio; i++) {
                int irq;
index 16fe974..fc80add 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/sysfs.h>
+#include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
@@ -432,6 +433,11 @@ static struct attribute *gpiochip_attrs[] = {
 };
 ATTRIBUTE_GROUPS(gpiochip);
 
+static struct gpio_desc *gpio_to_valid_desc(int gpio)
+{
+       return gpio_is_valid(gpio) ? gpio_to_desc(gpio) : NULL;
+}
+
 /*
  * /sys/class/gpio/export ... write-only
  *     integer N ... number of GPIO to export (full access)
@@ -450,7 +456,7 @@ static ssize_t export_store(struct class *class,
        if (status < 0)
                goto done;
 
-       desc = gpio_to_desc(gpio);
+       desc = gpio_to_valid_desc(gpio);
        /* reject invalid GPIOs */
        if (!desc) {
                pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
@@ -493,7 +499,7 @@ static ssize_t unexport_store(struct class *class,
        if (status < 0)
                goto done;
 
-       desc = gpio_to_desc(gpio);
+       desc = gpio_to_valid_desc(gpio);
        /* reject bogus commands (gpio_unexport ignores them) */
        if (!desc) {
                pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
index a689918..c586f44 100644 (file)
@@ -244,6 +244,12 @@ struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
                struct dma_fence *f = e->fence;
                struct amd_sched_fence *s_fence = to_amd_sched_fence(f);
 
+               if (dma_fence_is_signaled(f)) {
+                       hash_del(&e->node);
+                       dma_fence_put(f);
+                       kmem_cache_free(amdgpu_sync_slab, e);
+                       continue;
+               }
                if (ring && s_fence) {
                        /* For fences from the same ring it is sufficient
                         * when they are scheduled.
@@ -256,13 +262,6 @@ struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
                        }
                }
 
-               if (dma_fence_is_signaled(f)) {
-                       hash_del(&e->node);
-                       dma_fence_put(f);
-                       kmem_cache_free(amdgpu_sync_slab, e);
-                       continue;
-               }
-
                return f;
        }
 
index 0511fce..e3a81ed 100644 (file)
@@ -4581,7 +4581,7 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,
 
                sseu->slice_mask |= BIT(s);
 
-               if (IS_GEN9_BC(dev_priv))
+               if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
                        sseu->subslice_mask =
                                INTEL_INFO(dev_priv)->sseu.subslice_mask;
 
index 39ed58a..e1e971e 100644 (file)
@@ -688,19 +688,19 @@ static inline bool skip_rcs_switch(struct i915_hw_ppgtt *ppgtt,
 }
 
 static bool
-needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt,
-                 struct intel_engine_cs *engine,
-                 struct i915_gem_context *to)
+needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *engine)
 {
+       struct i915_gem_context *from = engine->legacy_active_context;
+
        if (!ppgtt)
                return false;
 
        /* Always load the ppgtt on first use */
-       if (!engine->legacy_active_context)
+       if (!from)
                return true;
 
        /* Same context without new entries, skip */
-       if (engine->legacy_active_context == to &&
+       if ((!from->ppgtt || from->ppgtt == ppgtt) &&
            !(intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
                return false;
 
@@ -744,7 +744,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
        if (skip_rcs_switch(ppgtt, engine, to))
                return 0;
 
-       if (needs_pd_load_pre(ppgtt, engine, to)) {
+       if (needs_pd_load_pre(ppgtt, engine)) {
                /* Older GENs and non render rings still want the load first,
                 * "PP_DCLV followed by PP_DIR_BASE register through Load
                 * Register Immediate commands in Ring Buffer before submitting
@@ -841,7 +841,7 @@ int i915_switch_context(struct drm_i915_gem_request *req)
                struct i915_hw_ppgtt *ppgtt =
                        to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
 
-               if (needs_pd_load_pre(ppgtt, engine, to)) {
+               if (needs_pd_load_pre(ppgtt, engine)) {
                        int ret;
 
                        trace_switch_mm(engine, to);
@@ -852,6 +852,7 @@ int i915_switch_context(struct drm_i915_gem_request *req)
                        ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
                }
 
+               engine->legacy_active_context = to;
                return 0;
        }
 
index 7032c54..4dd4c21 100644 (file)
@@ -242,6 +242,10 @@ int i915_gem_render_state_emit(struct drm_i915_gem_request *req)
                        goto err_unpin;
        }
 
+       ret = req->engine->emit_flush(req, EMIT_INVALIDATE);
+       if (ret)
+               goto err_unpin;
+
        ret = req->engine->emit_bb_start(req,
                                         so->batch_offset, so->batch_size,
                                         I915_DISPATCH_SECURE);
index 9edeaae..d3b3252 100644 (file)
@@ -1762,7 +1762,7 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv,
        if (dev_priv->vbt.edp.low_vswing) {
                if (voltage == VOLTAGE_INFO_0_85V) {
                        *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_85V);
-                       return cnl_ddi_translations_dp_0_85V;
+                       return cnl_ddi_translations_edp_0_85V;
                } else if (voltage == VOLTAGE_INFO_0_95V) {
                        *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_95V);
                        return cnl_ddi_translations_edp_0_95V;
index 9471c88..cc484b5 100644 (file)
@@ -3485,6 +3485,13 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
            !gpu_reset_clobbers_display(dev_priv))
                return;
 
+       /* We have a modeset vs reset deadlock, defensively unbreak it.
+        *
+        * FIXME: We can do a _lot_ better, this is just a first iteration.
+        */
+       i915_gem_set_wedged(dev_priv);
+       DRM_DEBUG_DRIVER("Wedging GPU to avoid deadlocks with pending modeset updates\n");
+
        /*
         * Need mode_config.mutex so that we don't
         * trample ongoing ->detect() and whatnot.
index 52b3a1f..57ef583 100644 (file)
@@ -63,7 +63,6 @@ enum {
 };
 
 /* Logical Rings */
-void intel_logical_ring_stop(struct intel_engine_cs *engine);
 void intel_logical_ring_cleanup(struct intel_engine_cs *engine);
 int logical_render_ring_init(struct intel_engine_cs *engine);
 int logical_xcs_ring_init(struct intel_engine_cs *engine);
index 6b5d3be..807299d 100644 (file)
@@ -193,7 +193,6 @@ struct bmc150_accel_data {
        struct regmap *regmap;
        int irq;
        struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
-       atomic_t active_intr;
        struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
        struct mutex mutex;
        u8 fifo_mode, watermark;
@@ -493,11 +492,6 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
                goto out_fix_power_state;
        }
 
-       if (state)
-               atomic_inc(&data->active_intr);
-       else
-               atomic_dec(&data->active_intr);
-
        return 0;
 
 out_fix_power_state:
@@ -1710,8 +1704,7 @@ static int bmc150_accel_resume(struct device *dev)
        struct bmc150_accel_data *data = iio_priv(indio_dev);
 
        mutex_lock(&data->mutex);
-       if (atomic_read(&data->active_intr))
-               bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
+       bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
        bmc150_accel_fifo_set_mode(data);
        mutex_unlock(&data->mutex);
 
index 07d1489..e44f62b 100644 (file)
@@ -166,6 +166,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                        .mask_ihl = 0x02,
                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
                },
+               .sim = {
+                       .addr = 0x23,
+                       .value = BIT(0),
+               },
                .multi_read_bit = true,
                .bootime = 2,
        },
@@ -234,6 +238,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                        .mask_od = 0x40,
                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
                },
+               .sim = {
+                       .addr = 0x23,
+                       .value = BIT(0),
+               },
                .multi_read_bit = true,
                .bootime = 2,
        },
@@ -316,6 +324,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                                .en_mask = 0x08,
                        },
                },
+               .sim = {
+                       .addr = 0x24,
+                       .value = BIT(0),
+               },
                .multi_read_bit = false,
                .bootime = 2,
        },
@@ -379,6 +391,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                        .mask_int1 = 0x04,
                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
                },
+               .sim = {
+                       .addr = 0x21,
+                       .value = BIT(1),
+               },
                .multi_read_bit = true,
                .bootime = 2, /* guess */
        },
@@ -437,6 +453,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                        .mask_od = 0x40,
                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
                },
+               .sim = {
+                       .addr = 0x21,
+                       .value = BIT(7),
+               },
                .multi_read_bit = false,
                .bootime = 2, /* guess */
        },
@@ -499,6 +519,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                        .addr_ihl = 0x22,
                        .mask_ihl = 0x80,
                },
+               .sim = {
+                       .addr = 0x23,
+                       .value = BIT(0),
+               },
                .multi_read_bit = true,
                .bootime = 2,
        },
@@ -547,6 +571,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                        .mask_int1 = 0x04,
                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
                },
+               .sim = {
+                       .addr = 0x21,
+                       .value = BIT(1),
+               },
                .multi_read_bit = false,
                .bootime = 2,
        },
@@ -614,6 +642,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                        .mask_ihl = 0x02,
                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
                },
+               .sim = {
+                       .addr = 0x23,
+                       .value = BIT(0),
+               },
                .multi_read_bit = true,
                .bootime = 2,
        },
index e0ea411..c02b23d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
+#include <linux/iopoll.h>
 
 #define ASPEED_RESOLUTION_BITS         10
 #define ASPEED_CLOCKS_PER_SAMPLE       12
 
 #define ASPEED_ENGINE_ENABLE           BIT(0)
 
+#define ASPEED_ADC_CTRL_INIT_RDY       BIT(8)
+
+#define ASPEED_ADC_INIT_POLLING_TIME   500
+#define ASPEED_ADC_INIT_TIMEOUT                500000
+
 struct aspeed_adc_model_data {
        const char *model_name;
        unsigned int min_sampling_rate; // Hz
        unsigned int max_sampling_rate; // Hz
        unsigned int vref_voltage;      // mV
+       bool wait_init_sequence;
 };
 
 struct aspeed_adc_data {
@@ -211,6 +218,24 @@ static int aspeed_adc_probe(struct platform_device *pdev)
                goto scaler_error;
        }
 
+       model_data = of_device_get_match_data(&pdev->dev);
+
+       if (model_data->wait_init_sequence) {
+               /* Enable engine in normal mode. */
+               writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
+                      data->base + ASPEED_REG_ENGINE_CONTROL);
+
+               /* Wait for initial sequence complete. */
+               ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL,
+                                        adc_engine_control_reg_val,
+                                        adc_engine_control_reg_val &
+                                        ASPEED_ADC_CTRL_INIT_RDY,
+                                        ASPEED_ADC_INIT_POLLING_TIME,
+                                        ASPEED_ADC_INIT_TIMEOUT);
+               if (ret)
+                       goto scaler_error;
+       }
+
        /* Start all channels in normal mode. */
        ret = clk_prepare_enable(data->clk_scaler->clk);
        if (ret)
@@ -274,6 +299,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
        .vref_voltage = 1800, // mV
        .min_sampling_rate = 1,
        .max_sampling_rate = 1000000,
+       .wait_init_sequence = true,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
index 64799ad..462a99c 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/iio/driver.h>
 
 #define AXP288_ADC_EN_MASK             0xF1
+#define AXP288_ADC_TS_PIN_GPADC                0xF2
+#define AXP288_ADC_TS_PIN_ON           0xF3
 
 enum axp288_adc_id {
        AXP288_ADC_TS,
@@ -121,6 +123,26 @@ static int axp288_adc_read_channel(int *val, unsigned long address,
        return IIO_VAL_INT;
 }
 
+static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
+                               unsigned long address)
+{
+       int ret;
+
+       /* channels other than GPADC do not need to switch TS pin */
+       if (address != AXP288_GP_ADC_H)
+               return 0;
+
+       ret = regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
+       if (ret)
+               return ret;
+
+       /* When switching to the GPADC pin give things some time to settle */
+       if (mode == AXP288_ADC_TS_PIN_GPADC)
+               usleep_range(6000, 10000);
+
+       return 0;
+}
+
 static int axp288_adc_read_raw(struct iio_dev *indio_dev,
                        struct iio_chan_spec const *chan,
                        int *val, int *val2, long mask)
@@ -131,7 +153,16 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
        mutex_lock(&indio_dev->mlock);
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
+               if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
+                                       chan->address)) {
+                       dev_err(&indio_dev->dev, "GPADC mode\n");
+                       ret = -EINVAL;
+                       break;
+               }
                ret = axp288_adc_read_channel(val, chan->address, info->regmap);
+               if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON,
+                                               chan->address))
+                       dev_err(&indio_dev->dev, "TS pin restore\n");
                break;
        default:
                ret = -EINVAL;
@@ -141,6 +172,15 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
        return ret;
 }
 
+static int axp288_adc_set_state(struct regmap *regmap)
+{
+       /* ADC should be always enabled for internal FG to function */
+       if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
+               return -EIO;
+
+       return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
+}
+
 static const struct iio_info axp288_adc_iio_info = {
        .read_raw = &axp288_adc_read_raw,
        .driver_module = THIS_MODULE,
@@ -169,7 +209,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
         * Set ADC to enabled state at all time, including system suspend.
         * otherwise internal fuel gauge functionality may be affected.
         */
-       ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
+       ret = axp288_adc_set_state(axp20x->regmap);
        if (ret) {
                dev_err(&pdev->dev, "unable to enable ADC device\n");
                return ret;
index 81d4c39..137f577 100644 (file)
@@ -256,6 +256,7 @@ static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
 
 err:
        pm_runtime_put_autosuspend(indio_dev->dev.parent);
+       disable_irq(irq);
        mutex_unlock(&info->mutex);
 
        return ret;
@@ -365,7 +366,6 @@ static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
                complete(&info->completion);
 
 out:
-       disable_irq_nosync(info->temp_data_irq);
        return IRQ_HANDLED;
 }
 
@@ -380,7 +380,6 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
                complete(&info->completion);
 
 out:
-       disable_irq_nosync(info->fifo_data_irq);
        return IRQ_HANDLED;
 }
 
index 01fc76f..c168e0d 100644 (file)
@@ -77,7 +77,7 @@
 #define VF610_ADC_ADSTS_MASK           0x300
 #define VF610_ADC_ADLPC_EN             0x80
 #define VF610_ADC_ADHSC_EN             0x400
-#define VF610_ADC_REFSEL_VALT          0x100
+#define VF610_ADC_REFSEL_VALT          0x800
 #define VF610_ADC_REFSEL_VBG           0x1000
 #define VF610_ADC_ADTRG_HARD           0x2000
 #define VF610_ADC_AVGS_8               0x4000
index 79c8c7c..6e6a1ec 100644 (file)
@@ -550,6 +550,31 @@ out:
 }
 EXPORT_SYMBOL(st_sensors_read_info_raw);
 
+static int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
+                       const struct st_sensor_settings *sensor_settings)
+{
+       struct st_sensor_data *sdata = iio_priv(indio_dev);
+       struct device_node *np = sdata->dev->of_node;
+       struct st_sensors_platform_data *pdata;
+
+       pdata = (struct st_sensors_platform_data *)sdata->dev->platform_data;
+       if (((np && of_property_read_bool(np, "spi-3wire")) ||
+            (pdata && pdata->spi_3wire)) && sensor_settings->sim.addr) {
+               int err;
+
+               err = sdata->tf->write_byte(&sdata->tb, sdata->dev,
+                                           sensor_settings->sim.addr,
+                                           sensor_settings->sim.value);
+               if (err < 0) {
+                       dev_err(&indio_dev->dev,
+                               "failed to init interface mode\n");
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
 int st_sensors_check_device_support(struct iio_dev *indio_dev,
                        int num_sensors_list,
                        const struct st_sensor_settings *sensor_settings)
@@ -574,6 +599,10 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
                return -ENODEV;
        }
 
+       err = st_sensors_init_interface_mode(indio_dev, &sensor_settings[i]);
+       if (err < 0)
+               return err;
+
        if (sensor_settings[i].wai_addr) {
                err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
                                           sensor_settings[i].wai_addr, &wai);
index e7d4ea7..7599693 100644 (file)
@@ -626,7 +626,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
        struct tsl2563_chip *chip = iio_priv(dev_info);
 
        iio_push_event(dev_info,
-                      IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+                      IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
                                            0,
                                            IIO_EV_TYPE_THRESH,
                                            IIO_EV_DIR_EITHER),
index aa61ec1..f1bce05 100644 (file)
@@ -456,7 +456,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
                        .mask_od = 0x40,
                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
                },
-               .multi_read_bit = true,
+               .multi_read_bit = false,
                .bootime = 2,
        },
 };
index a5dfab6..221468f 100644 (file)
@@ -537,10 +537,11 @@ void ib_unregister_device(struct ib_device *device)
        }
        up_read(&lists_rwsem);
 
-       mutex_unlock(&device_mutex);
-
        ib_device_unregister_rdmacg(device);
        ib_device_unregister_sysfs(device);
+
+       mutex_unlock(&device_mutex);
+
        ib_cache_cleanup_one(device);
 
        ib_security_destroy_port_pkey_list(device);
index c551d2b..739bd69 100644 (file)
@@ -1015,7 +1015,7 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
        cq->uobject       = &obj->uobject;
        cq->comp_handler  = ib_uverbs_comp_handler;
        cq->event_handler = ib_uverbs_cq_event_handler;
-       cq->cq_context    = &ev_file->ev_queue;
+       cq->cq_context    = ev_file ? &ev_file->ev_queue : NULL;
        atomic_set(&cq->usecnt, 0);
 
        obj->uobject.object = cq;
@@ -1522,6 +1522,7 @@ static int create_qp(struct ib_uverbs_file *file,
                qp->qp_type       = attr.qp_type;
                atomic_set(&qp->usecnt, 0);
                atomic_inc(&pd->usecnt);
+               qp->port = 0;
                if (attr.send_cq)
                        atomic_inc(&attr.send_cq->usecnt);
                if (attr.recv_cq)
@@ -1962,8 +1963,9 @@ static int modify_qp(struct ib_uverbs_file *file,
        attr->alt_timeout         = cmd->base.alt_timeout;
        attr->rate_limit          = cmd->rate_limit;
 
-       attr->ah_attr.type = rdma_ah_find_type(qp->device,
-                                              cmd->base.dest.port_num);
+       if (cmd->base.attr_mask & IB_QP_AV)
+               attr->ah_attr.type = rdma_ah_find_type(qp->device,
+                                                      cmd->base.dest.port_num);
        if (cmd->base.dest.is_global) {
                rdma_ah_set_grh(&attr->ah_attr, NULL,
                                cmd->base.dest.flow_label,
@@ -1981,8 +1983,9 @@ static int modify_qp(struct ib_uverbs_file *file,
        rdma_ah_set_port_num(&attr->ah_attr,
                             cmd->base.dest.port_num);
 
-       attr->alt_ah_attr.type = rdma_ah_find_type(qp->device,
-                                                  cmd->base.dest.port_num);
+       if (cmd->base.attr_mask & IB_QP_ALT_PATH)
+               attr->alt_ah_attr.type =
+                       rdma_ah_find_type(qp->device, cmd->base.dest.port_num);
        if (cmd->base.alt_dest.is_global) {
                rdma_ah_set_grh(&attr->alt_ah_attr, NULL,
                                cmd->base.alt_dest.flow_label,
index c023e2c..5e530d2 100644 (file)
@@ -1153,7 +1153,6 @@ static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev,
                kref_get(&file->ref);
                mutex_unlock(&uverbs_dev->lists_mutex);
 
-               ib_uverbs_event_handler(&file->event_handler, &event);
 
                mutex_lock(&file->cleanup_mutex);
                ucontext = file->ucontext;
@@ -1170,6 +1169,7 @@ static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev,
                         * for example due to freeing the resources
                         * (e.g mmput).
                         */
+                       ib_uverbs_event_handler(&file->event_handler, &event);
                        ib_dev->disassociate_ucontext(ucontext);
                        mutex_lock(&file->cleanup_mutex);
                        ib_uverbs_cleanup_ucontext(file, ucontext, true);
index 7f8fe44..b456e3c 100644 (file)
@@ -838,6 +838,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
        spin_lock_init(&qp->mr_lock);
        INIT_LIST_HEAD(&qp->rdma_mrs);
        INIT_LIST_HEAD(&qp->sig_mrs);
+       qp->port = 0;
 
        if (qp_init_attr->qp_type == IB_QPT_XRC_TGT)
                return ib_create_xrc_qp(qp, qp_init_attr);
@@ -1297,7 +1298,11 @@ int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
                if (ret)
                        return ret;
        }
-       return ib_security_modify_qp(qp, attr, attr_mask, udata);
+       ret = ib_security_modify_qp(qp, attr, attr_mask, udata);
+       if (!ret && (attr_mask & IB_QP_PORT))
+               qp->port = attr->port_num;
+
+       return ret;
 }
 EXPORT_SYMBOL(ib_modify_qp_with_udata);
 
index 5332f06..c2fba76 100644 (file)
@@ -661,7 +661,7 @@ struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd,
        rhp = php->rhp;
 
        if (mr_type != IB_MR_TYPE_MEM_REG ||
-           max_num_sg > t4_max_fr_depth(&rhp->rdev.lldi.ulptx_memwrite_dsgl &&
+           max_num_sg > t4_max_fr_depth(rhp->rdev.lldi.ulptx_memwrite_dsgl &&
                                         use_dsgl))
                return ERR_PTR(-EINVAL);
 
index f78a733..d545302 100644 (file)
@@ -64,8 +64,10 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
        } else {
                u8 *dmac = rdma_ah_retrieve_dmac(ah_attr);
 
-               if (!dmac)
+               if (!dmac) {
+                       kfree(ah);
                        return ERR_PTR(-EINVAL);
+               }
                memcpy(ah->av.mac, dmac, ETH_ALEN);
        }
 
index 9ec1ae9..a49ff2e 100644 (file)
@@ -130,20 +130,32 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_commit_buf(
        u64 base = 0;
        u32 i, j;
        u32 k = 0;
-       u32 low;
 
        /* copy base values in obj_info */
-       for (i = I40IW_HMC_IW_QP, j = 0;
-                       i <= I40IW_HMC_IW_PBLE; i++, j += 8) {
+       for (i = I40IW_HMC_IW_QP, j = 0; i <= I40IW_HMC_IW_PBLE; i++, j += 8) {
+               if ((i == I40IW_HMC_IW_SRQ) ||
+                       (i == I40IW_HMC_IW_FSIMC) ||
+                       (i == I40IW_HMC_IW_FSIAV)) {
+                       info[i].base = 0;
+                       info[i].cnt = 0;
+                       continue;
+               }
                get_64bit_val(buf, j, &temp);
                info[i].base = RS_64_1(temp, 32) * 512;
                if (info[i].base > base) {
                        base = info[i].base;
                        k = i;
                }
-               low = (u32)(temp);
-               if (low)
-                       info[i].cnt = low;
+               if (i == I40IW_HMC_IW_APBVT_ENTRY) {
+                       info[i].cnt = 1;
+                       continue;
+               }
+               if (i == I40IW_HMC_IW_QP)
+                       info[i].cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS);
+               else if (i == I40IW_HMC_IW_CQ)
+                       info[i].cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS);
+               else
+                       info[i].cnt = (u32)(temp);
        }
        size = info[k].cnt * info[k].size + info[k].base;
        if (size & 0x1FFFFF)
@@ -155,6 +167,31 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_commit_buf(
 }
 
 /**
+ * i40iw_sc_decode_fpm_query() - Decode a 64 bit value into max count and size
+ * @buf: ptr to fpm query buffer
+ * @buf_idx: index into buf
+ * @info: ptr to i40iw_hmc_obj_info struct
+ * @rsrc_idx: resource index into info
+ *
+ * Decode a 64 bit value from fpm query buffer into max count and size
+ */
+static u64 i40iw_sc_decode_fpm_query(u64 *buf,
+                                           u32 buf_idx,
+                                           struct i40iw_hmc_obj_info *obj_info,
+                                           u32 rsrc_idx)
+{
+       u64 temp;
+       u32 size;
+
+       get_64bit_val(buf, buf_idx, &temp);
+       obj_info[rsrc_idx].max_cnt = (u32)temp;
+       size = (u32)RS_64_1(temp, 32);
+       obj_info[rsrc_idx].size = LS_64_1(1, size);
+
+       return temp;
+}
+
+/**
  * i40iw_sc_parse_fpm_query_buf() - parses fpm query buffer
  * @buf: ptr to fpm query buffer
  * @info: ptr to i40iw_hmc_obj_info struct
@@ -168,9 +205,9 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_query_buf(
                                struct i40iw_hmc_info *hmc_info,
                                struct i40iw_hmc_fpm_misc *hmc_fpm_misc)
 {
-       u64 temp;
        struct i40iw_hmc_obj_info *obj_info;
-       u32 i, j, size;
+       u64 temp;
+       u32 size;
        u16 max_pe_sds;
 
        obj_info = hmc_info->hmc_obj;
@@ -185,41 +222,52 @@ static enum i40iw_status_code i40iw_sc_parse_fpm_query_buf(
        hmc_fpm_misc->max_sds = max_pe_sds;
        hmc_info->sd_table.sd_cnt = max_pe_sds + hmc_info->first_sd_index;
 
-       for (i = I40IW_HMC_IW_QP, j = 8;
-            i <= I40IW_HMC_IW_ARP; i++, j += 8) {
-               get_64bit_val(buf, j, &temp);
-               if (i == I40IW_HMC_IW_QP)
-                       obj_info[i].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS);
-               else if (i == I40IW_HMC_IW_CQ)
-                       obj_info[i].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS);
-               else
-                       obj_info[i].max_cnt = (u32)temp;
+       get_64bit_val(buf, 8, &temp);
+       obj_info[I40IW_HMC_IW_QP].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_QPS);
+       size = (u32)RS_64_1(temp, 32);
+       obj_info[I40IW_HMC_IW_QP].size = LS_64_1(1, size);
 
-               size = (u32)RS_64_1(temp, 32);
-               obj_info[i].size = ((u64)1 << size);
-       }
-       for (i = I40IW_HMC_IW_MR, j = 48;
-                       i <= I40IW_HMC_IW_PBLE; i++, j += 8) {
-               get_64bit_val(buf, j, &temp);
-               obj_info[i].max_cnt = (u32)temp;
-               size = (u32)RS_64_1(temp, 32);
-               obj_info[i].size = LS_64_1(1, size);
-       }
+       get_64bit_val(buf, 16, &temp);
+       obj_info[I40IW_HMC_IW_CQ].max_cnt = (u32)RS_64(temp, I40IW_QUERY_FPM_MAX_CQS);
+       size = (u32)RS_64_1(temp, 32);
+       obj_info[I40IW_HMC_IW_CQ].size = LS_64_1(1, size);
+
+       i40iw_sc_decode_fpm_query(buf, 32, obj_info, I40IW_HMC_IW_HTE);
+       i40iw_sc_decode_fpm_query(buf, 40, obj_info, I40IW_HMC_IW_ARP);
+
+       obj_info[I40IW_HMC_IW_APBVT_ENTRY].size = 8192;
+       obj_info[I40IW_HMC_IW_APBVT_ENTRY].max_cnt = 1;
+
+       i40iw_sc_decode_fpm_query(buf, 48, obj_info, I40IW_HMC_IW_MR);
+       i40iw_sc_decode_fpm_query(buf, 56, obj_info, I40IW_HMC_IW_XF);
 
-       get_64bit_val(buf, 120, &temp);
-       hmc_fpm_misc->max_ceqs = (u8)RS_64(temp, I40IW_QUERY_FPM_MAX_CEQS);
-       get_64bit_val(buf, 120, &temp);
-       hmc_fpm_misc->ht_multiplier = RS_64(temp, I40IW_QUERY_FPM_HTMULTIPLIER);
-       get_64bit_val(buf, 120, &temp);
-       hmc_fpm_misc->timer_bucket = RS_64(temp, I40IW_QUERY_FPM_TIMERBUCKET);
        get_64bit_val(buf, 64, &temp);
+       obj_info[I40IW_HMC_IW_XFFL].max_cnt = (u32)temp;
+       obj_info[I40IW_HMC_IW_XFFL].size = 4;
        hmc_fpm_misc->xf_block_size = RS_64(temp, I40IW_QUERY_FPM_XFBLOCKSIZE);
        if (!hmc_fpm_misc->xf_block_size)
                return I40IW_ERR_INVALID_SIZE;
+
+       i40iw_sc_decode_fpm_query(buf, 72, obj_info, I40IW_HMC_IW_Q1);
+
        get_64bit_val(buf, 80, &temp);
+       obj_info[I40IW_HMC_IW_Q1FL].max_cnt = (u32)temp;
+       obj_info[I40IW_HMC_IW_Q1FL].size = 4;
        hmc_fpm_misc->q1_block_size = RS_64(temp, I40IW_QUERY_FPM_Q1BLOCKSIZE);
        if (!hmc_fpm_misc->q1_block_size)
                return I40IW_ERR_INVALID_SIZE;
+
+       i40iw_sc_decode_fpm_query(buf, 88, obj_info, I40IW_HMC_IW_TIMER);
+
+       get_64bit_val(buf, 112, &temp);
+       obj_info[I40IW_HMC_IW_PBLE].max_cnt = (u32)temp;
+       obj_info[I40IW_HMC_IW_PBLE].size = 8;
+
+       get_64bit_val(buf, 120, &temp);
+       hmc_fpm_misc->max_ceqs = (u8)RS_64(temp, I40IW_QUERY_FPM_MAX_CEQS);
+       hmc_fpm_misc->ht_multiplier = RS_64(temp, I40IW_QUERY_FPM_HTMULTIPLIER);
+       hmc_fpm_misc->timer_bucket = RS_64(temp, I40IW_QUERY_FPM_TIMERBUCKET);
+
        return 0;
 }
 
@@ -3392,13 +3440,6 @@ enum i40iw_status_code i40iw_sc_init_iw_hmc(struct i40iw_sc_dev *dev, u8 hmc_fn_
                hmc_info->sd_table.sd_entry = virt_mem.va;
        }
 
-       /* fill size of objects which are fixed */
-       hmc_info->hmc_obj[I40IW_HMC_IW_XFFL].size = 4;
-       hmc_info->hmc_obj[I40IW_HMC_IW_Q1FL].size = 4;
-       hmc_info->hmc_obj[I40IW_HMC_IW_PBLE].size = 8;
-       hmc_info->hmc_obj[I40IW_HMC_IW_APBVT_ENTRY].size = 8192;
-       hmc_info->hmc_obj[I40IW_HMC_IW_APBVT_ENTRY].max_cnt = 1;
-
        return ret_code;
 }
 
@@ -4840,7 +4881,7 @@ void i40iw_vsi_stats_free(struct i40iw_sc_vsi *vsi)
 {
        u8 fcn_id = vsi->fcn_id;
 
-       if ((vsi->stats_fcn_id_alloc) && (fcn_id != I40IW_INVALID_FCN_ID))
+       if (vsi->stats_fcn_id_alloc && fcn_id < I40IW_MAX_STATS_COUNT)
                vsi->dev->fcn_id_array[fcn_id] = false;
        i40iw_hw_stats_stop_timer(vsi);
 }
index a39ac12..2ebaadb 100644 (file)
@@ -1507,8 +1507,8 @@ enum {
        I40IW_CQ0_ALIGNMENT_MASK =              (256 - 1),
        I40IW_HOST_CTX_ALIGNMENT_MASK =         (4 - 1),
        I40IW_SHADOWAREA_MASK =                 (128 - 1),
-       I40IW_FPM_QUERY_BUF_ALIGNMENT_MASK =    0,
-       I40IW_FPM_COMMIT_BUF_ALIGNMENT_MASK =   0
+       I40IW_FPM_QUERY_BUF_ALIGNMENT_MASK =    (4 - 1),
+       I40IW_FPM_COMMIT_BUF_ALIGNMENT_MASK =   (4 - 1)
 };
 
 enum i40iw_alignment {
index 71050c5..7f5583d 100644 (file)
@@ -685,7 +685,7 @@ static enum i40iw_status_code i40iw_puda_cq_create(struct i40iw_puda_rsrc *rsrc)
        cqsize = rsrc->cq_size * (sizeof(struct i40iw_cqe));
        tsize = cqsize + sizeof(struct i40iw_cq_shadow_area);
        ret = i40iw_allocate_dma_mem(dev->hw, &rsrc->cqmem, tsize,
-                                    I40IW_CQ0_ALIGNMENT_MASK);
+                                    I40IW_CQ0_ALIGNMENT);
        if (ret)
                return ret;
 
index 91c4217..f7013f1 100644 (file)
@@ -62,7 +62,7 @@ enum i40iw_status_code {
        I40IW_ERR_INVALID_ALIGNMENT = -23,
        I40IW_ERR_FLUSHED_QUEUE = -24,
        I40IW_ERR_INVALID_PUSH_PAGE_INDEX = -25,
-       I40IW_ERR_INVALID_IMM_DATA_SIZE = -26,
+       I40IW_ERR_INVALID_INLINE_DATA_SIZE = -26,
        I40IW_ERR_TIMEOUT = -27,
        I40IW_ERR_OPCODE_MISMATCH = -28,
        I40IW_ERR_CQP_COMPL_ERROR = -29,
index b0d3a0e..1060725 100644 (file)
@@ -435,7 +435,7 @@ static enum i40iw_status_code i40iw_inline_rdma_write(struct i40iw_qp_uk *qp,
 
        op_info = &info->op.inline_rdma_write;
        if (op_info->len > I40IW_MAX_INLINE_DATA_SIZE)
-               return I40IW_ERR_INVALID_IMM_DATA_SIZE;
+               return I40IW_ERR_INVALID_INLINE_DATA_SIZE;
 
        ret_code = i40iw_inline_data_size_to_wqesize(op_info->len, &wqe_size);
        if (ret_code)
@@ -511,7 +511,7 @@ static enum i40iw_status_code i40iw_inline_send(struct i40iw_qp_uk *qp,
 
        op_info = &info->op.inline_send;
        if (op_info->len > I40IW_MAX_INLINE_DATA_SIZE)
-               return I40IW_ERR_INVALID_IMM_DATA_SIZE;
+               return I40IW_ERR_INVALID_INLINE_DATA_SIZE;
 
        ret_code = i40iw_inline_data_size_to_wqesize(op_info->len, &wqe_size);
        if (ret_code)
@@ -784,7 +784,7 @@ static enum i40iw_status_code i40iw_cq_poll_completion(struct i40iw_cq_uk *cq,
        get_64bit_val(cqe, 0, &qword0);
        get_64bit_val(cqe, 16, &qword2);
 
-       info->tcp_seq_num = (u8)RS_64(qword0, I40IWCQ_TCPSEQNUM);
+       info->tcp_seq_num = (u32)RS_64(qword0, I40IWCQ_TCPSEQNUM);
 
        info->qp_id = (u32)RS_64(qword2, I40IWCQ_QPID);
 
@@ -1187,7 +1187,7 @@ enum i40iw_status_code i40iw_inline_data_size_to_wqesize(u32 data_size,
                                                         u8 *wqe_size)
 {
        if (data_size > I40IW_MAX_INLINE_DATA_SIZE)
-               return I40IW_ERR_INVALID_IMM_DATA_SIZE;
+               return I40IW_ERR_INVALID_INLINE_DATA_SIZE;
 
        if (data_size <= 16)
                *wqe_size = I40IW_QP_WQE_MIN_SIZE;
index a7f2e60..f7fcde1 100644 (file)
@@ -1085,6 +1085,12 @@ static int mlx5_ib_modify_port(struct ib_device *ibdev, u8 port, int mask,
        bool is_ib = (mlx5_ib_port_link_layer(ibdev, port) ==
                      IB_LINK_LAYER_INFINIBAND);
 
+       /* CM layer calls ib_modify_port() regardless of the link layer. For
+        * Ethernet ports, qkey violation and Port capabilities are meaningless.
+        */
+       if (!is_ib)
+               return 0;
+
        if (MLX5_CAP_GEN(dev->mdev, ib_virt) && is_ib) {
                change_mask = props->clr_port_cap_mask | props->set_port_cap_mask;
                value = ~props->clr_port_cap_mask | props->set_port_cap_mask;
index 0889ff3..f58f8f5 100644 (file)
@@ -1238,6 +1238,7 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
                        goto err_destroy_tis;
 
                sq->base.container_mibqp = qp;
+               sq->base.mqp.event = mlx5_ib_qp_event;
        }
 
        if (qp->rq.wqe_cnt) {
index 69bda61..90aa326 100644 (file)
@@ -65,13 +65,28 @@ int pvrdma_req_notify_cq(struct ib_cq *ibcq,
        struct pvrdma_dev *dev = to_vdev(ibcq->device);
        struct pvrdma_cq *cq = to_vcq(ibcq);
        u32 val = cq->cq_handle;
+       unsigned long flags;
+       int has_data = 0;
 
        val |= (notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
                PVRDMA_UAR_CQ_ARM_SOL : PVRDMA_UAR_CQ_ARM;
 
+       spin_lock_irqsave(&cq->cq_lock, flags);
+
        pvrdma_write_uar_cq(dev, val);
 
-       return 0;
+       if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) {
+               unsigned int head;
+
+               has_data = pvrdma_idx_ring_has_data(&cq->ring_state->rx,
+                                                   cq->ibcq.cqe, &head);
+               if (unlikely(has_data == PVRDMA_INVALID_IDX))
+                       dev_err(&dev->pdev->dev, "CQ ring state invalid\n");
+       }
+
+       spin_unlock_irqrestore(&cq->cq_lock, flags);
+
+       return has_data;
 }
 
 /**
index 3b616cb..714cf7f 100644 (file)
@@ -1248,6 +1248,10 @@ static const struct acpi_device_id elan_acpi_id[] = {
        { "ELAN0100", 0 },
        { "ELAN0600", 0 },
        { "ELAN0605", 0 },
+       { "ELAN0608", 0 },
+       { "ELAN0605", 0 },
+       { "ELAN0609", 0 },
+       { "ELAN060B", 0 },
        { "ELAN1000", 0 },
        { }
 };
index 922ea02..20b5b21 100644 (file)
@@ -380,8 +380,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
                return 0;
 
        if (trackpoint_read(ps2dev, TP_EXT_BTN, &button_info)) {
-               psmouse_warn(psmouse, "failed to get extended button data\n");
-               button_info = 0;
+               psmouse_warn(psmouse, "failed to get extended button data, assuming 3 buttons\n");
+               button_info = 0x33;
        }
 
        psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
index b97188a..2d80fa8 100644 (file)
@@ -1519,6 +1519,13 @@ static int arm_smmu_add_device(struct device *dev)
 
        if (using_legacy_binding) {
                ret = arm_smmu_register_legacy_master(dev, &smmu);
+
+               /*
+                * If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
+                * will allocate/initialise a new one. Thus we need to update fwspec for
+                * later use.
+                */
+               fwspec = dev->iommu_fwspec;
                if (ret)
                        goto out_free;
        } else if (fwspec && fwspec->ops == &arm_smmu_ops) {
index 28b26c8..072bd22 100644 (file)
@@ -137,14 +137,14 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain)
 #define AT91_RTC_IMR           0x28
 #define AT91_RTC_IRQ_MASK      0x1f
 
-void __init aic_common_rtc_irq_fixup(struct device_node *root)
+void __init aic_common_rtc_irq_fixup(void)
 {
        struct device_node *np;
        void __iomem *regs;
 
-       np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc");
+       np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc");
        if (!np)
-               np = of_find_compatible_node(root, NULL,
+               np = of_find_compatible_node(NULL, NULL,
                                             "atmel,at91sam9x5-rtc");
 
        if (!np)
@@ -165,7 +165,7 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root)
 #define AT91_RTT_ALMIEN                (1 << 16)               /* Alarm Interrupt Enable */
 #define AT91_RTT_RTTINCIEN     (1 << 17)               /* Real Time Timer Increment Interrupt Enable */
 
-void __init aic_common_rtt_irq_fixup(struct device_node *root)
+void __init aic_common_rtt_irq_fixup(void)
 {
        struct device_node *np;
        void __iomem *regs;
@@ -196,11 +196,10 @@ static void __init aic_common_irq_fixup(const struct of_device_id *matches)
                return;
 
        match = of_match_node(matches, root);
-       of_node_put(root);
 
        if (match) {
-               void (*fixup)(struct device_node *) = match->data;
-               fixup(root);
+               void (*fixup)(void) = match->data;
+               fixup();
        }
 
        of_node_put(root);
index af60376..242e62c 100644 (file)
@@ -33,8 +33,8 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node,
                                             const char *name, int nirqs,
                                             const struct of_device_id *matches);
 
-void __init aic_common_rtc_irq_fixup(struct device_node *root);
+void __init aic_common_rtc_irq_fixup(void);
 
-void __init aic_common_rtt_irq_fixup(struct device_node *root);
+void __init aic_common_rtt_irq_fixup(void);
 
 #endif /* __IRQ_ATMEL_AIC_COMMON_H */
index 37f952d..bb1ad45 100644 (file)
@@ -209,20 +209,20 @@ static const struct irq_domain_ops aic_irq_ops = {
        .xlate  = aic_irq_domain_xlate,
 };
 
-static void __init at91rm9200_aic_irq_fixup(struct device_node *root)
+static void __init at91rm9200_aic_irq_fixup(void)
 {
-       aic_common_rtc_irq_fixup(root);
+       aic_common_rtc_irq_fixup();
 }
 
-static void __init at91sam9260_aic_irq_fixup(struct device_node *root)
+static void __init at91sam9260_aic_irq_fixup(void)
 {
-       aic_common_rtt_irq_fixup(root);
+       aic_common_rtt_irq_fixup();
 }
 
-static void __init at91sam9g45_aic_irq_fixup(struct device_node *root)
+static void __init at91sam9g45_aic_irq_fixup(void)
 {
-       aic_common_rtc_irq_fixup(root);
-       aic_common_rtt_irq_fixup(root);
+       aic_common_rtc_irq_fixup();
+       aic_common_rtt_irq_fixup();
 }
 
 static const struct of_device_id aic_irq_fixups[] __initconst = {
index c04ee9a..6acad2e 100644 (file)
@@ -305,9 +305,9 @@ static const struct irq_domain_ops aic5_irq_ops = {
        .xlate  = aic5_irq_domain_xlate,
 };
 
-static void __init sama5d3_aic_irq_fixup(struct device_node *root)
+static void __init sama5d3_aic_irq_fixup(void)
 {
-       aic_common_rtc_irq_fixup(root);
+       aic_common_rtc_irq_fixup();
 }
 
 static const struct of_device_id aic5_irq_fixups[] __initconst = {
index bddf169..b009b91 100644 (file)
@@ -189,6 +189,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
 
        ct->chip.irq_suspend = brcmstb_l2_intc_suspend;
        ct->chip.irq_resume = brcmstb_l2_intc_resume;
+       ct->chip.irq_pm_shutdown = brcmstb_l2_intc_suspend;
 
        if (data->can_wake) {
                /* This IRQ chip can wake the system, set all child interrupts
index 249240d..833a90f 100644 (file)
@@ -43,6 +43,7 @@ static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
                        *dev_id = args.args[0];
                        break;
                }
+               index++;
        } while (!ret);
 
        return ret;
index 6893287..284738a 100644 (file)
@@ -1835,7 +1835,7 @@ static int __init its_of_probe(struct device_node *node)
 
 #define ACPI_GICV3_ITS_MEM_SIZE (SZ_128K)
 
-#if defined(CONFIG_ACPI_NUMA) && (ACPI_CA_VERSION >= 0x20170531)
+#ifdef CONFIG_ACPI_NUMA
 struct its_srat_map {
        /* numa node id */
        u32     numa_node;
@@ -1843,7 +1843,7 @@ struct its_srat_map {
        u32     its_id;
 };
 
-static struct its_srat_map its_srat_maps[MAX_NUMNODES] __initdata;
+static struct its_srat_map *its_srat_maps __initdata;
 static int its_in_srat __initdata;
 
 static int __init acpi_get_its_numa_node(u32 its_id)
@@ -1857,6 +1857,12 @@ static int __init acpi_get_its_numa_node(u32 its_id)
        return NUMA_NO_NODE;
 }
 
+static int __init gic_acpi_match_srat_its(struct acpi_subtable_header *header,
+                                         const unsigned long end)
+{
+       return 0;
+}
+
 static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
                         const unsigned long end)
 {
@@ -1873,12 +1879,6 @@ static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
                return -EINVAL;
        }
 
-       if (its_in_srat >= MAX_NUMNODES) {
-               pr_err("SRAT: ITS affinity exceeding max count[%d]\n",
-                               MAX_NUMNODES);
-               return -EINVAL;
-       }
-
        node = acpi_map_pxm_to_node(its_affinity->proximity_domain);
 
        if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
@@ -1897,14 +1897,37 @@ static int __init gic_acpi_parse_srat_its(struct acpi_subtable_header *header,
 
 static void __init acpi_table_parse_srat_its(void)
 {
+       int count;
+
+       count = acpi_table_parse_entries(ACPI_SIG_SRAT,
+                       sizeof(struct acpi_table_srat),
+                       ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
+                       gic_acpi_match_srat_its, 0);
+       if (count <= 0)
+               return;
+
+       its_srat_maps = kmalloc(count * sizeof(struct its_srat_map),
+                               GFP_KERNEL);
+       if (!its_srat_maps) {
+               pr_warn("SRAT: Failed to allocate memory for its_srat_maps!\n");
+               return;
+       }
+
        acpi_table_parse_entries(ACPI_SIG_SRAT,
                        sizeof(struct acpi_table_srat),
                        ACPI_SRAT_TYPE_GIC_ITS_AFFINITY,
                        gic_acpi_parse_srat_its, 0);
 }
+
+/* free the its_srat_maps after ITS probing */
+static void __init acpi_its_srat_maps_free(void)
+{
+       kfree(its_srat_maps);
+}
 #else
 static void __init acpi_table_parse_srat_its(void)     { }
 static int __init acpi_get_its_numa_node(u32 its_id) { return NUMA_NO_NODE; }
+static void __init acpi_its_srat_maps_free(void) { }
 #endif
 
 static int __init gic_acpi_parse_madt_its(struct acpi_subtable_header *header,
@@ -1951,6 +1974,7 @@ static void __init its_acpi_probe(void)
        acpi_table_parse_srat_its();
        acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
                              gic_acpi_parse_madt_its, 0);
+       acpi_its_srat_maps_free();
 }
 #else
 static void __init its_acpi_probe(void) { }
index dbffb7a..984c3ec 100644 (file)
@@ -353,6 +353,8 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 
                        if (static_key_true(&supports_deactivate))
                                gic_write_eoir(irqnr);
+                       else
+                               isb();
 
                        err = handle_domain_irq(gic_data.domain, irqnr, regs);
                        if (err) {
@@ -640,11 +642,16 @@ static void gic_smp_init(void)
 static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
                            bool force)
 {
-       unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+       unsigned int cpu;
        void __iomem *reg;
        int enabled;
        u64 val;
 
+       if (force)
+               cpu = cpumask_first(mask_val);
+       else
+               cpu = cpumask_any_and(mask_val, cpu_online_mask);
+
        if (cpu >= nr_cpu_ids)
                return -EINVAL;
 
@@ -831,8 +838,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
        if (ret)
                return ret;
 
-       for (i = 0; i < nr_irqs; i++)
-               gic_irq_domain_map(domain, virq + i, hwirq + i);
+       for (i = 0; i < nr_irqs; i++) {
+               ret = gic_irq_domain_map(domain, virq + i, hwirq + i);
+               if (ret)
+                       return ret;
+       }
 
        return 0;
 }
index 1b1df4f..d3e7c43 100644 (file)
@@ -361,6 +361,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
                if (likely(irqnr > 15 && irqnr < 1020)) {
                        if (static_key_true(&supports_deactivate))
                                writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
+                       isb();
                        handle_domain_irq(gic->domain, irqnr, regs);
                        continue;
                }
@@ -401,10 +402,12 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
                goto out;
 
        cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
-       if (unlikely(gic_irq < 32 || gic_irq > 1020))
+       if (unlikely(gic_irq < 32 || gic_irq > 1020)) {
                handle_bad_irq(desc);
-       else
+       } else {
+               isb();
                generic_handle_irq(cascade_irq);
+       }
 
  out:
        chained_irq_exit(chip, desc);
@@ -1027,8 +1030,11 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
        if (ret)
                return ret;
 
-       for (i = 0; i < nr_irqs; i++)
-               gic_irq_domain_map(domain, virq + i, hwirq + i);
+       for (i = 0; i < nr_irqs; i++) {
+               ret = gic_irq_domain_map(domain, virq + i, hwirq + i);
+               if (ret)
+                       return ret;
+       }
 
        return 0;
 }
index 78fc5d5..92e6570 100644 (file)
@@ -26,7 +26,7 @@
 
 #define FSM_TIMER_DEBUG 0
 
-void
+int
 mISDN_FsmNew(struct Fsm *fsm,
             struct FsmNode *fnlist, int fncount)
 {
@@ -34,6 +34,8 @@ mISDN_FsmNew(struct Fsm *fsm,
 
        fsm->jumpmatrix = kzalloc(sizeof(FSMFNPTR) * fsm->state_count *
                                  fsm->event_count, GFP_KERNEL);
+       if (fsm->jumpmatrix == NULL)
+               return -ENOMEM;
 
        for (i = 0; i < fncount; i++)
                if ((fnlist[i].state >= fsm->state_count) ||
@@ -45,6 +47,7 @@ mISDN_FsmNew(struct Fsm *fsm,
                } else
                        fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
                                        fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
+       return 0;
 }
 EXPORT_SYMBOL(mISDN_FsmNew);
 
index 928f5be..e1def84 100644 (file)
@@ -55,7 +55,7 @@ struct FsmTimer {
        void *arg;
 };
 
-extern void mISDN_FsmNew(struct Fsm *, struct FsmNode *, int);
+extern int mISDN_FsmNew(struct Fsm *, struct FsmNode *, int);
 extern void mISDN_FsmFree(struct Fsm *);
 extern int mISDN_FsmEvent(struct FsmInst *, int , void *);
 extern void mISDN_FsmChangeState(struct FsmInst *, int);
index bebc57b..3192b0e 100644 (file)
@@ -414,8 +414,7 @@ l1_init(u_int *deb)
        l1fsm_s.event_count = L1_EVENT_COUNT;
        l1fsm_s.strEvent = strL1Event;
        l1fsm_s.strState = strL1SState;
-       mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
-       return 0;
+       return mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
 }
 
 void
index 7243a67..9ff0903 100644 (file)
@@ -2247,15 +2247,26 @@ static struct Bprotocol X75SLP = {
 int
 Isdnl2_Init(u_int *deb)
 {
+       int res;
        debug = deb;
        mISDN_register_Bprotocol(&X75SLP);
        l2fsm.state_count = L2_STATE_COUNT;
        l2fsm.event_count = L2_EVENT_COUNT;
        l2fsm.strEvent = strL2Event;
        l2fsm.strState = strL2State;
-       mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
-       TEIInit(deb);
+       res = mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
+       if (res)
+               goto error;
+       res = TEIInit(deb);
+       if (res)
+               goto error_fsm;
        return 0;
+
+error_fsm:
+       mISDN_FsmFree(&l2fsm);
+error:
+       mISDN_unregister_Bprotocol(&X75SLP);
+       return res;
 }
 
 void
index 908127e..12d9e5f 100644 (file)
@@ -1387,23 +1387,37 @@ create_teimanager(struct mISDNdevice *dev)
 
 int TEIInit(u_int *deb)
 {
+       int res;
        debug = deb;
        teifsmu.state_count = TEI_STATE_COUNT;
        teifsmu.event_count = TEI_EVENT_COUNT;
        teifsmu.strEvent = strTeiEvent;
        teifsmu.strState = strTeiState;
-       mISDN_FsmNew(&teifsmu, TeiFnListUser, ARRAY_SIZE(TeiFnListUser));
+       res = mISDN_FsmNew(&teifsmu, TeiFnListUser, ARRAY_SIZE(TeiFnListUser));
+       if (res)
+               goto error;
        teifsmn.state_count = TEI_STATE_COUNT;
        teifsmn.event_count = TEI_EVENT_COUNT;
        teifsmn.strEvent = strTeiEvent;
        teifsmn.strState = strTeiState;
-       mISDN_FsmNew(&teifsmn, TeiFnListNet, ARRAY_SIZE(TeiFnListNet));
+       res = mISDN_FsmNew(&teifsmn, TeiFnListNet, ARRAY_SIZE(TeiFnListNet));
+       if (res)
+               goto error_smn;
        deactfsm.state_count =  DEACT_STATE_COUNT;
        deactfsm.event_count = DEACT_EVENT_COUNT;
        deactfsm.strEvent = strDeactEvent;
        deactfsm.strState = strDeactState;
-       mISDN_FsmNew(&deactfsm, DeactFnList, ARRAY_SIZE(DeactFnList));
+       res = mISDN_FsmNew(&deactfsm, DeactFnList, ARRAY_SIZE(DeactFnList));
+       if (res)
+               goto error_deact;
        return 0;
+
+error_deact:
+       mISDN_FsmFree(&teifsmn);
+error_smn:
+       mISDN_FsmFree(&teifsmu);
+error:
+       return res;
 }
 
 void TEIFree(void)
index c996346..b01e458 100644 (file)
@@ -7996,7 +7996,7 @@ bool md_write_start(struct mddev *mddev, struct bio *bi)
        if (mddev->safemode == 1)
                mddev->safemode = 0;
        /* sync_checkers is always 0 when writes_pending is in per-cpu mode */
-       if (mddev->in_sync || !mddev->sync_checkers) {
+       if (mddev->in_sync || mddev->sync_checkers) {
                spin_lock(&mddev->lock);
                if (mddev->in_sync) {
                        mddev->in_sync = 0;
@@ -8656,6 +8656,9 @@ void md_check_recovery(struct mddev *mddev)
        if (mddev_trylock(mddev)) {
                int spares = 0;
 
+               if (!mddev->external && mddev->safemode == 1)
+                       mddev->safemode = 0;
+
                if (mddev->ro) {
                        struct md_rdev *rdev;
                        if (!mddev->external && mddev->in_sync)
index bfa1e90..2dcbafa 100644 (file)
@@ -236,9 +236,10 @@ struct r5l_io_unit {
        bool need_split_bio;
        struct bio *split_bio;
 
-       unsigned int has_flush:1;      /* include flush request */
-       unsigned int has_fua:1;        /* include fua request */
-       unsigned int has_null_flush:1; /* include empty flush request */
+       unsigned int has_flush:1;               /* include flush request */
+       unsigned int has_fua:1;                 /* include fua request */
+       unsigned int has_null_flush:1;          /* include null flush request */
+       unsigned int has_flush_payload:1;       /* include flush payload  */
        /*
         * io isn't sent yet, flush/fua request can only be submitted till it's
         * the first IO in running_ios list
@@ -571,6 +572,8 @@ static void r5l_log_endio(struct bio *bio)
        struct r5l_io_unit *io_deferred;
        struct r5l_log *log = io->log;
        unsigned long flags;
+       bool has_null_flush;
+       bool has_flush_payload;
 
        if (bio->bi_status)
                md_error(log->rdev->mddev, log->rdev);
@@ -580,6 +583,16 @@ static void r5l_log_endio(struct bio *bio)
 
        spin_lock_irqsave(&log->io_list_lock, flags);
        __r5l_set_io_unit_state(io, IO_UNIT_IO_END);
+
+       /*
+        * if the io doesn't not have null_flush or flush payload,
+        * it is not safe to access it after releasing io_list_lock.
+        * Therefore, it is necessary to check the condition with
+        * the lock held.
+        */
+       has_null_flush = io->has_null_flush;
+       has_flush_payload = io->has_flush_payload;
+
        if (log->need_cache_flush && !list_empty(&io->stripe_list))
                r5l_move_to_end_ios(log);
        else
@@ -600,19 +613,23 @@ static void r5l_log_endio(struct bio *bio)
        if (log->need_cache_flush)
                md_wakeup_thread(log->rdev->mddev->thread);
 
-       if (io->has_null_flush) {
+       /* finish flush only io_unit and PAYLOAD_FLUSH only io_unit */
+       if (has_null_flush) {
                struct bio *bi;
 
                WARN_ON(bio_list_empty(&io->flush_barriers));
                while ((bi = bio_list_pop(&io->flush_barriers)) != NULL) {
                        bio_endio(bi);
-                       atomic_dec(&io->pending_stripe);
+                       if (atomic_dec_and_test(&io->pending_stripe)) {
+                               __r5l_stripe_write_finished(io);
+                               return;
+                       }
                }
        }
-
-       /* finish flush only io_unit and PAYLOAD_FLUSH only io_unit */
-       if (atomic_read(&io->pending_stripe) == 0)
-               __r5l_stripe_write_finished(io);
+       /* decrease pending_stripe for flush payload */
+       if (has_flush_payload)
+               if (atomic_dec_and_test(&io->pending_stripe))
+                       __r5l_stripe_write_finished(io);
 }
 
 static void r5l_do_submit_io(struct r5l_log *log, struct r5l_io_unit *io)
@@ -881,6 +898,11 @@ static void r5l_append_flush_payload(struct r5l_log *log, sector_t sect)
        payload->size = cpu_to_le32(sizeof(__le64));
        payload->flush_stripes[0] = cpu_to_le64(sect);
        io->meta_offset += meta_size;
+       /* multiple flush payloads count as one pending_stripe */
+       if (!io->has_flush_payload) {
+               io->has_flush_payload = 1;
+               atomic_inc(&io->pending_stripe);
+       }
        mutex_unlock(&log->io_mutex);
 }
 
@@ -2540,23 +2562,32 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
  */
 int r5c_journal_mode_set(struct mddev *mddev, int mode)
 {
-       struct r5conf *conf = mddev->private;
-       struct r5l_log *log = conf->log;
-
-       if (!log)
-               return -ENODEV;
+       struct r5conf *conf;
+       int err;
 
        if (mode < R5C_JOURNAL_MODE_WRITE_THROUGH ||
            mode > R5C_JOURNAL_MODE_WRITE_BACK)
                return -EINVAL;
 
+       err = mddev_lock(mddev);
+       if (err)
+               return err;
+       conf = mddev->private;
+       if (!conf || !conf->log) {
+               mddev_unlock(mddev);
+               return -ENODEV;
+       }
+
        if (raid5_calc_degraded(conf) > 0 &&
-           mode == R5C_JOURNAL_MODE_WRITE_BACK)
+           mode == R5C_JOURNAL_MODE_WRITE_BACK) {
+               mddev_unlock(mddev);
                return -EINVAL;
+       }
 
        mddev_suspend(mddev);
        conf->log->r5c_journal_mode = mode;
        mddev_resume(mddev);
+       mddev_unlock(mddev);
 
        pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
                 mdname(mddev), mode, r5c_journal_mode_str[mode]);
index 99e644c..ebf69ff 100644 (file)
@@ -72,7 +72,7 @@ struct atmel_smc_timing_xlate {
        { .name = nm, .converter = atmel_smc_cs_conf_set_pulse, .shift = pos}
 
 #define ATMEL_SMC_CYCLE_XLATE(nm, pos) \
-       { .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos}
+       { .name = nm, .converter = atmel_smc_cs_conf_set_cycle, .shift = pos}
 
 static void at91sam9_ebi_get_config(struct atmel_ebi_dev *ebid,
                                    struct atmel_ebi_dev_config *conf)
@@ -120,12 +120,14 @@ static int atmel_ebi_xslate_smc_timings(struct atmel_ebi_dev *ebid,
        if (!ret) {
                required = true;
                ncycles = DIV_ROUND_UP(val, clk_period_ns);
-               if (ncycles > ATMEL_SMC_MODE_TDF_MAX ||
-                   ncycles < ATMEL_SMC_MODE_TDF_MIN) {
+               if (ncycles > ATMEL_SMC_MODE_TDF_MAX) {
                        ret = -EINVAL;
                        goto out;
                }
 
+               if (ncycles < ATMEL_SMC_MODE_TDF_MIN)
+                       ncycles = ATMEL_SMC_MODE_TDF_MIN;
+
                smcconf->mode |= ATMEL_SMC_MODE_TDF(ncycles);
        }
 
@@ -263,7 +265,7 @@ static int atmel_ebi_xslate_smc_config(struct atmel_ebi_dev *ebid,
        }
 
        ret = atmel_ebi_xslate_smc_timings(ebid, np, &conf->smcconf);
-       if (ret)
+       if (ret < 0)
                return -EINVAL;
 
        if ((ret > 0 && !required) || (!ret && required)) {
index 954cf0f..20cc0ea 100644 (file)
@@ -206,7 +206,7 @@ EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_set_pulse);
  *          parameter
  *
  * This function encodes the @ncycles value as described in the datasheet
- * (section "SMC Pulse Register"), and then stores the result in the
+ * (section "SMC Cycle Register"), and then stores the result in the
  * @conf->setup field at @shift position.
  *
  * Returns -EINVAL if @shift is invalid, -ERANGE if @ncycles does not fit in
index fbe0f24..fe18115 100644 (file)
@@ -645,6 +645,9 @@ static const struct regmap_range da9062_aa_readable_ranges[] = {
                .range_min = DA9062AA_VLDO1_B,
                .range_max = DA9062AA_VLDO4_B,
        }, {
+               .range_min = DA9062AA_BBAT_CONT,
+               .range_max = DA9062AA_BBAT_CONT,
+       }, {
                .range_min = DA9062AA_INTERFACE,
                .range_max = DA9062AA_CONFIG_E,
        }, {
@@ -721,6 +724,9 @@ static const struct regmap_range da9062_aa_writeable_ranges[] = {
                .range_min = DA9062AA_VLDO1_B,
                .range_max = DA9062AA_VLDO4_B,
        }, {
+               .range_min = DA9062AA_BBAT_CONT,
+               .range_max = DA9062AA_BBAT_CONT,
+       }, {
                .range_min = DA9062AA_GP_ID_0,
                .range_max = DA9062AA_GP_ID_19,
        },
index 8621a19..bac3331 100644 (file)
@@ -216,6 +216,12 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_set_drvdata(pdev, dev);
 
        /*
+        * MEI requires to resume from runtime suspend mode
+        * in order to perform link reset flow upon system suspend.
+        */
+       pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME;
+
+       /*
        * For not wake-able HW runtime pm framework
        * can't be used on pci device level.
        * Use domain runtime pm callbacks instead.
index f811cd5..e38a5f1 100644 (file)
@@ -138,6 +138,12 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_set_drvdata(pdev, dev);
 
        /*
+        * MEI requires to resume from runtime suspend mode
+        * in order to perform link reset flow upon system suspend.
+        */
+       pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME;
+
+       /*
        * For not wake-able HW runtime pm framework
        * can't be used on pci device level.
        * Use domain runtime pm callbacks instead.
index e5938c7..f1bbfd3 100644 (file)
@@ -2170,7 +2170,9 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
                 * from being accepted.
                 */
                card = md->queue.card;
+               spin_lock_irq(md->queue.queue->queue_lock);
                queue_flag_set(QUEUE_FLAG_BYPASS, md->queue.queue);
+               spin_unlock_irq(md->queue.queue->queue_lock);
                blk_set_queue_dying(md->queue.queue);
                mmc_cleanup_queue(&md->queue);
                if (md->disk->flags & GENHD_FL_UP) {
index 4ffea14..2bae69e 100644 (file)
@@ -1289,7 +1289,7 @@ out_err:
 static int mmc_select_hs400es(struct mmc_card *card)
 {
        struct mmc_host *host = card->host;
-       int err = 0;
+       int err = -EINVAL;
        u8 val;
 
        if (!(host->caps & MMC_CAP_8_BIT_DATA)) {
index 04ff3c9..2ab4788 100644 (file)
@@ -2086,7 +2086,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
        mmc->max_seg_size = mmc->max_req_size;
 
        mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                    MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
+                    MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE | MMC_CAP_CMD23;
 
        mmc->caps |= mmc_pdata(host)->caps;
        if (mmc->caps & MMC_CAP_8_BIT_DATA)
index f336a9b..9ec8f03 100644 (file)
@@ -113,6 +113,7 @@ static blk_status_t do_blktrans_request(struct mtd_blktrans_ops *tr,
                for (; nsect > 0; nsect--, block++, buf += tr->blksize)
                        if (tr->writesect(dev, block, buf))
                                return BLK_STS_IOERR;
+               return BLK_STS_OK;
        default:
                return BLK_STS_IOERR;
        }
index 9bee6c1..fc63992 100644 (file)
@@ -1569,7 +1569,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        new_slave->delay = 0;
        new_slave->link_failure_count = 0;
 
-       if (bond_update_speed_duplex(new_slave))
+       if (bond_update_speed_duplex(new_slave) &&
+           bond_needs_speed_duplex(bond))
                new_slave->link = BOND_LINK_DOWN;
 
        new_slave->last_rx = jiffies -
@@ -2140,11 +2141,13 @@ static void bond_miimon_commit(struct bonding *bond)
                        continue;
 
                case BOND_LINK_UP:
-                       if (bond_update_speed_duplex(slave)) {
+                       if (bond_update_speed_duplex(slave) &&
+                           bond_needs_speed_duplex(bond)) {
                                slave->link = BOND_LINK_DOWN;
-                               netdev_warn(bond->dev,
-                                           "failed to get link speed/duplex for %s\n",
-                                           slave->dev->name);
+                               if (net_ratelimit())
+                                       netdev_warn(bond->dev,
+                                                   "failed to get link speed/duplex for %s\n",
+                                                   slave->dev->name);
                                continue;
                        }
                        bond_set_slave_link_state(slave, BOND_LINK_UP,
index ef4be78..09ea62e 100644 (file)
@@ -529,6 +529,7 @@ enum {                                 /* adapter flags */
        USING_SOFT_PARAMS  = (1 << 6),
        MASTER_PF          = (1 << 7),
        FW_OFLD_CONN       = (1 << 9),
+       ROOT_NO_RELAXED_ORDERING = (1 << 10),
 };
 
 enum {
index e403fa1..33bb867 100644 (file)
@@ -4654,11 +4654,6 @@ static void print_port_info(const struct net_device *dev)
                    dev->name, adap->params.vpd.id, adap->name, buf);
 }
 
-static void enable_pcie_relaxed_ordering(struct pci_dev *dev)
-{
-       pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
-}
-
 /*
  * Free the following resources:
  * - memory used for tables
@@ -4908,7 +4903,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        pci_enable_pcie_error_reporting(pdev);
-       enable_pcie_relaxed_ordering(pdev);
        pci_set_master(pdev);
        pci_save_state(pdev);
 
@@ -4947,6 +4941,23 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->msg_enable = DFLT_MSG_ENABLE;
        memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
 
+       /* If possible, we use PCIe Relaxed Ordering Attribute to deliver
+        * Ingress Packet Data to Free List Buffers in order to allow for
+        * chipset performance optimizations between the Root Complex and
+        * Memory Controllers.  (Messages to the associated Ingress Queue
+        * notifying new Packet Placement in the Free Lists Buffers will be
+        * send without the Relaxed Ordering Attribute thus guaranteeing that
+        * all preceding PCIe Transaction Layer Packets will be processed
+        * first.)  But some Root Complexes have various issues with Upstream
+        * Transaction Layer Packets with the Relaxed Ordering Attribute set.
+        * The PCIe devices which under the Root Complexes will be cleared the
+        * Relaxed Ordering bit in the configuration space, So we check our
+        * PCIe configuration space to see if it's flagged with advice against
+        * using Relaxed Ordering.
+        */
+       if (!pcie_relaxed_ordering_enabled(pdev))
+               adapter->flags |= ROOT_NO_RELAXED_ORDERING;
+
        spin_lock_init(&adapter->stats_lock);
        spin_lock_init(&adapter->tid_release_lock);
        spin_lock_init(&adapter->win0_lock);
index ede1220..4ef68f6 100644 (file)
@@ -2719,6 +2719,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
        struct fw_iq_cmd c;
        struct sge *s = &adap->sge;
        struct port_info *pi = netdev_priv(dev);
+       int relaxed = !(adap->flags & ROOT_NO_RELAXED_ORDERING);
 
        /* Size needs to be multiple of 16, including status entry. */
        iq->size = roundup(iq->size, 16);
@@ -2772,8 +2773,8 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
 
                flsz = fl->size / 8 + s->stat_len / sizeof(struct tx_desc);
                c.iqns_to_fl0congen |= htonl(FW_IQ_CMD_FL0PACKEN_F |
-                                            FW_IQ_CMD_FL0FETCHRO_F |
-                                            FW_IQ_CMD_FL0DATARO_F |
+                                            FW_IQ_CMD_FL0FETCHRO_V(relaxed) |
+                                            FW_IQ_CMD_FL0DATARO_V(relaxed) |
                                             FW_IQ_CMD_FL0PADEN_F);
                if (cong >= 0)
                        c.iqns_to_fl0congen |=
index 109bc63..08c6ddb 100644 (file)
@@ -408,6 +408,7 @@ enum { /* adapter flags */
        USING_MSI          = (1UL << 1),
        USING_MSIX         = (1UL << 2),
        QUEUES_BOUND       = (1UL << 3),
+       ROOT_NO_RELAXED_ORDERING = (1UL << 4),
 };
 
 /*
index ac7a150..2b85b87 100644 (file)
@@ -2888,6 +2888,24 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
         */
        adapter->name = pci_name(pdev);
        adapter->msg_enable = DFLT_MSG_ENABLE;
+
+       /* If possible, we use PCIe Relaxed Ordering Attribute to deliver
+        * Ingress Packet Data to Free List Buffers in order to allow for
+        * chipset performance optimizations between the Root Complex and
+        * Memory Controllers.  (Messages to the associated Ingress Queue
+        * notifying new Packet Placement in the Free Lists Buffers will be
+        * send without the Relaxed Ordering Attribute thus guaranteeing that
+        * all preceding PCIe Transaction Layer Packets will be processed
+        * first.)  But some Root Complexes have various issues with Upstream
+        * Transaction Layer Packets with the Relaxed Ordering Attribute set.
+        * The PCIe devices which under the Root Complexes will be cleared the
+        * Relaxed Ordering bit in the configuration space, So we check our
+        * PCIe configuration space to see if it's flagged with advice against
+        * using Relaxed Ordering.
+        */
+       if (!pcie_relaxed_ordering_enabled(pdev))
+               adapter->flags |= ROOT_NO_RELAXED_ORDERING;
+
        err = adap_init0(adapter);
        if (err)
                goto err_unmap_bar;
index e37dde2..05498e7 100644 (file)
@@ -2205,6 +2205,7 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq,
        struct port_info *pi = netdev_priv(dev);
        struct fw_iq_cmd cmd, rpl;
        int ret, iqandst, flsz = 0;
+       int relaxed = !(adapter->flags & ROOT_NO_RELAXED_ORDERING);
 
        /*
         * If we're using MSI interrupts and we're not initializing the
@@ -2300,6 +2301,8 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq,
                        cpu_to_be32(
                                FW_IQ_CMD_FL0HOSTFCMODE_V(SGE_HOSTFCMODE_NONE) |
                                FW_IQ_CMD_FL0PACKEN_F |
+                               FW_IQ_CMD_FL0FETCHRO_V(relaxed) |
+                               FW_IQ_CMD_FL0DATARO_V(relaxed) |
                                FW_IQ_CMD_FL0PADEN_F);
 
                /* In T6, for egress queue type FL there is internal overhead
index 09b9bc1..5fe5cdc 100644 (file)
@@ -432,7 +432,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                /* Virtual PCI function needs to determine UAR page size from
                 * firmware. Only master PCI function can set the uar page size
                 */
-               if (enable_4k_uar)
+               if (enable_4k_uar || !dev->persist->num_vfs)
                        dev->uar_page_shift = DEFAULT_UAR_PAGE_SHIFT;
                else
                        dev->uar_page_shift = PAGE_SHIFT;
@@ -2277,7 +2277,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
 
                dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1;
 
-               if (enable_4k_uar) {
+               if (enable_4k_uar || !dev->persist->num_vfs) {
                        init_hca.log_uar_sz = ilog2(dev->caps.num_uars) +
                                                    PAGE_SHIFT - DEFAULT_UAR_PAGE_SHIFT;
                        init_hca.uar_page_sz = DEFAULT_UAR_PAGE_SHIFT - 12;
index dd7fa9c..b0837b5 100644 (file)
@@ -115,14 +115,10 @@ nfp_flower_cmsg_portmod_rx(struct nfp_app *app, struct sk_buff *skb)
                return;
        }
 
-       if (link) {
+       if (link)
                netif_carrier_on(netdev);
-               rtnl_lock();
-               dev_set_mtu(netdev, be16_to_cpu(msg->mtu));
-               rtnl_unlock();
-       } else {
+       else
                netif_carrier_off(netdev);
-       }
        rcu_read_unlock();
 }
 
index 4631ca8..9f77ce0 100644 (file)
@@ -908,8 +908,7 @@ static int nfp_net_tx(struct sk_buff *skb, struct net_device *netdev)
        return NETDEV_TX_OK;
 
 err_unmap:
-       --f;
-       while (f >= 0) {
+       while (--f >= 0) {
                frag = &skb_shinfo(skb)->frags[f];
                dma_unmap_page(dp->dev, tx_ring->txbufs[wr_idx].dma_addr,
                               skb_frag_size(frag), DMA_TO_DEVICE);
index 66ff15d..0a66389 100644 (file)
@@ -2311,7 +2311,7 @@ netxen_md_rdqueue(struct netxen_adapter *adapter,
                                 loop_cnt++) {
                NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, queue_id);
                read_addr = queueEntry->read_addr;
-               for (k = 0; k < read_cnt; k--) {
+               for (k = 0; k < read_cnt; k++) {
                        NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0,
                                                        &read_value);
                        *data_buff++ = read_value;
index c905971..990a63d 100644 (file)
@@ -938,7 +938,6 @@ enum efx_stats_action {
 static int efx_mcdi_mac_stats(struct efx_nic *efx,
                              enum efx_stats_action action, int clear)
 {
-       struct efx_ef10_nic_data *nic_data = efx->nic_data;
        MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
        int rc;
        int change = action == EFX_STATS_PULL ? 0 : 1;
@@ -960,7 +959,12 @@ static int efx_mcdi_mac_stats(struct efx_nic *efx,
                              MAC_STATS_IN_PERIODIC_NOEVENT, 1,
                              MAC_STATS_IN_PERIOD_MS, period);
        MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
-       MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, nic_data->vport_id);
+
+       if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) {
+               struct efx_ef10_nic_data *nic_data = efx->nic_data;
+
+               MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, nic_data->vport_id);
+       }
 
        rc = efx_mcdi_rpc_quiet(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
                                NULL, 0, NULL);
index db157a4..72ec711 100644 (file)
@@ -204,6 +204,7 @@ int stmmac_mdio_register(struct net_device *ndev)
        struct stmmac_priv *priv = netdev_priv(ndev);
        struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
        struct device_node *mdio_node = priv->plat->mdio_node;
+       struct device *dev = ndev->dev.parent;
        int addr, found;
 
        if (!mdio_bus_data)
@@ -237,7 +238,7 @@ int stmmac_mdio_register(struct net_device *ndev)
        else
                err = mdiobus_register(new_bus);
        if (err != 0) {
-               netdev_err(ndev, "Cannot register the MDIO bus\n");
+               dev_err(dev, "Cannot register the MDIO bus\n");
                goto bus_register_fail;
        }
 
@@ -285,14 +286,12 @@ int stmmac_mdio_register(struct net_device *ndev)
                        irq_str = irq_num;
                        break;
                }
-               netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n",
-                           phydev->phy_id, addr, irq_str, phydev_name(phydev),
-                           act ? " active" : "");
+               phy_attached_info(phydev);
                found = 1;
        }
 
        if (!found && !mdio_node) {
-               netdev_warn(ndev, "No PHY found\n");
+               dev_warn(dev, "No PHY found\n");
                mdiobus_unregister(new_bus);
                mdiobus_free(new_bus);
                return -ENODEV;
index 32ad873..0a2c0a4 100644 (file)
@@ -1879,6 +1879,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
 err_detach:
        tun_detach_all(dev);
+       /* register_netdevice() already called tun_free_netdev() */
+       goto err_free_dev;
+
 err_free_flow:
        tun_flow_uninit(tun);
        security_tun_dev_free_security(tun->security);
index d21258d..f1b6074 100644 (file)
@@ -159,8 +159,10 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
 
        brcmf_feat_firmware_capabilities(ifp);
        memset(&gscan_cfg, 0, sizeof(gscan_cfg));
-       brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN, "pfn_gscan_cfg",
-                                 &gscan_cfg, sizeof(gscan_cfg));
+       if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID)
+               brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN,
+                                         "pfn_gscan_cfg",
+                                         &gscan_cfg, sizeof(gscan_cfg));
        brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
        if (drvr->bus_if->wowl_supported)
                brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
index b4ecd1f..97208ce 100644 (file)
@@ -154,7 +154,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
 const struct iwl_cfg iwl9160_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 9160",
        .fw_name_pre = IWL9260A_FW_PRE,
-       .fw_name_pre_next_step = IWL9260B_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
        IWL_DEVICE_9000,
        .ht_params = &iwl9000_ht_params,
        .nvm_ver = IWL9000_NVM_VERSION,
@@ -165,7 +165,7 @@ const struct iwl_cfg iwl9160_2ac_cfg = {
 const struct iwl_cfg iwl9260_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 9260",
        .fw_name_pre = IWL9260A_FW_PRE,
-       .fw_name_pre_next_step = IWL9260B_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
        IWL_DEVICE_9000,
        .ht_params = &iwl9000_ht_params,
        .nvm_ver = IWL9000_NVM_VERSION,
@@ -176,7 +176,7 @@ const struct iwl_cfg iwl9260_2ac_cfg = {
 const struct iwl_cfg iwl9270_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 9270",
        .fw_name_pre = IWL9260A_FW_PRE,
-       .fw_name_pre_next_step = IWL9260B_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
        IWL_DEVICE_9000,
        .ht_params = &iwl9000_ht_params,
        .nvm_ver = IWL9000_NVM_VERSION,
@@ -186,8 +186,8 @@ const struct iwl_cfg iwl9270_2ac_cfg = {
 
 const struct iwl_cfg iwl9460_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 9460",
-       .fw_name_pre = IWL9000_FW_PRE,
-       .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+       .fw_name_pre = IWL9260A_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
        IWL_DEVICE_9000,
        .ht_params = &iwl9000_ht_params,
        .nvm_ver = IWL9000_NVM_VERSION,
@@ -198,8 +198,8 @@ const struct iwl_cfg iwl9460_2ac_cfg = {
 
 const struct iwl_cfg iwl9560_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 9560",
-       .fw_name_pre = IWL9000_FW_PRE,
-       .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+       .fw_name_pre = IWL9260A_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
        IWL_DEVICE_9000,
        .ht_params = &iwl9000_ht_params,
        .nvm_ver = IWL9000_NVM_VERSION,
index 0fa8c47..c73a643 100644 (file)
@@ -328,6 +328,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
  * @IWL_UCODE_TLV_CAPA_TX_POWER_ACK: reduced TX power API has larger
  *     command size (command version 4) that supports toggling ACK TX
  *     power reduction.
+ * @IWL_UCODE_TLV_CAPA_MLME_OFFLOAD: supports MLME offload
  *
  * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
  */
@@ -373,6 +374,7 @@ enum iwl_ucode_tlv_capa {
        IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG        = (__force iwl_ucode_tlv_capa_t)80,
        IWL_UCODE_TLV_CAPA_LQM_SUPPORT                  = (__force iwl_ucode_tlv_capa_t)81,
        IWL_UCODE_TLV_CAPA_TX_POWER_ACK                 = (__force iwl_ucode_tlv_capa_t)84,
+       IWL_UCODE_TLV_CAPA_MLME_OFFLOAD                 = (__force iwl_ucode_tlv_capa_t)96,
 
        NUM_IWL_UCODE_TLV_CAPA
 #ifdef __CHECKER__
index c52623c..d19c748 100644 (file)
@@ -276,10 +276,10 @@ struct iwl_pwr_tx_backoff {
  * @fw_name_pre: Firmware filename prefix. The api version and extension
  *     (.ucode) will be added to filename before loading from disk. The
  *     filename is constructed as fw_name_pre<api>.ucode.
- * @fw_name_pre_next_step: same as @fw_name_pre, only for next step
+ * @fw_name_pre_b_or_c_step: same as @fw_name_pre, only for b or c steps
  *     (if supported)
- * @fw_name_pre_rf_next_step: same as @fw_name_pre_next_step, only for rf next
- *     step. Supported only in integrated solutions.
+ * @fw_name_pre_rf_next_step: same as @fw_name_pre_b_or_c_step, only for rf
+ *     next step. Supported only in integrated solutions.
  * @ucode_api_max: Highest version of uCode API supported by driver.
  * @ucode_api_min: Lowest version of uCode API supported by driver.
  * @max_inst_size: The maximal length of the fw inst section
@@ -330,7 +330,7 @@ struct iwl_cfg {
        /* params specific to an individual device within a device family */
        const char *name;
        const char *fw_name_pre;
-       const char *fw_name_pre_next_step;
+       const char *fw_name_pre_b_or_c_step;
        const char *fw_name_pre_rf_next_step;
        /* params not likely to change within a device family */
        const struct iwl_base_params *base_params;
index 6fdb592..4e0f86f 100644 (file)
@@ -216,8 +216,9 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
        const char *fw_pre_name;
 
        if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
-           CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_B_STEP)
-               fw_pre_name = cfg->fw_name_pre_next_step;
+           (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_B_STEP ||
+            CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_C_STEP))
+               fw_pre_name = cfg->fw_name_pre_b_or_c_step;
        else if (drv->trans->cfg->integrated &&
                 CSR_HW_RFID_STEP(drv->trans->hw_rf_id) == SILICON_B_STEP &&
                 cfg->fw_name_pre_rf_next_step)
index 5c08f4d..3ee6767 100644 (file)
@@ -785,7 +785,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
                       int num_of_ch, __le32 *channels, u16 fw_mcc)
 {
        int ch_idx;
-       u16 ch_flags, prev_ch_flags = 0;
+       u16 ch_flags;
+       u32 reg_rule_flags, prev_reg_rule_flags = 0;
        const u8 *nvm_chan = cfg->ext_nvm ?
                             iwl_ext_nvm_channels : iwl_nvm_channels;
        struct ieee80211_regdomain *regd;
@@ -834,8 +835,11 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
                        continue;
                }
 
+               reg_rule_flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
+                                                            ch_flags, cfg);
+
                /* we can't continue the same rule */
-               if (ch_idx == 0 || prev_ch_flags != ch_flags ||
+               if (ch_idx == 0 || prev_reg_rule_flags != reg_rule_flags ||
                    center_freq - prev_center_freq > 20) {
                        valid_rules++;
                        new_rule = true;
@@ -854,18 +858,17 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
                rule->power_rule.max_eirp =
                        DBM_TO_MBM(IWL_DEFAULT_MAX_TX_POWER);
 
-               rule->flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
-                                                         ch_flags, cfg);
+               rule->flags = reg_rule_flags;
 
                /* rely on auto-calculation to merge BW of contiguous chans */
                rule->flags |= NL80211_RRF_AUTO_BW;
                rule->freq_range.max_bandwidth_khz = 0;
 
-               prev_ch_flags = ch_flags;
                prev_center_freq = center_freq;
+               prev_reg_rule_flags = reg_rule_flags;
 
                IWL_DEBUG_DEV(dev, IWL_DL_LAR,
-                             "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x): Ad-Hoc %ssupported\n",
+                             "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x) reg_flags 0x%x: %s\n",
                              center_freq,
                              band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
                              CHECK_AND_PRINT_I(VALID),
@@ -877,10 +880,10 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
                              CHECK_AND_PRINT_I(160MHZ),
                              CHECK_AND_PRINT_I(INDOOR_ONLY),
                              CHECK_AND_PRINT_I(GO_CONCURRENT),
-                             ch_flags,
+                             ch_flags, reg_rule_flags,
                              ((ch_flags & NVM_CHANNEL_ACTIVE) &&
                               !(ch_flags & NVM_CHANNEL_RADAR))
-                                        ? "" : "not ");
+                                        ? "Ad-Hoc" : "");
        }
 
        regd->n_reg_rules = valid_rules;
index 79e7a7a..82863e9 100644 (file)
@@ -1275,8 +1275,10 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
 
                        entry = &wifi_pkg->package.elements[idx++];
                        if ((entry->type != ACPI_TYPE_INTEGER) ||
-                           (entry->integer.value > U8_MAX))
-                               return -EINVAL;
+                           (entry->integer.value > U8_MAX)) {
+                               ret = -EINVAL;
+                               goto out_free;
+                       }
 
                        mvm->geo_profiles[i].values[j] = entry->integer.value;
                }
index c7b1e58..ce901be 100644 (file)
@@ -2597,8 +2597,18 @@ static void iwl_mvm_purge_deferred_tx_frames(struct iwl_mvm *mvm,
        spin_lock_bh(&mvm_sta->lock);
        for (i = 0; i <= IWL_MAX_TID_COUNT; i++) {
                tid_data = &mvm_sta->tid_data[i];
-               while ((skb = __skb_dequeue(&tid_data->deferred_tx_frames)))
+
+               while ((skb = __skb_dequeue(&tid_data->deferred_tx_frames))) {
+                       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+                       /*
+                        * The first deferred frame should've stopped the MAC
+                        * queues, so we should never get a second deferred
+                        * frame for the RA/TID.
+                        */
+                       iwl_mvm_start_mac_queues(mvm, info->hw_queue);
                        ieee80211_free_txskb(mvm->hw, skb);
+               }
        }
        spin_unlock_bh(&mvm_sta->lock);
 }
index 65beca3..8999a11 100644 (file)
@@ -1291,7 +1291,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
         * first index into rate scale table.
         */
        if (info->flags & IEEE80211_TX_STAT_AMPDU) {
-               rs_collect_tpc_data(mvm, lq_sta, curr_tbl, lq_rate.index,
+               rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,
                                    info->status.ampdu_len,
                                    info->status.ampdu_ack_len,
                                    reduced_txp);
@@ -1312,7 +1312,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                if (info->status.ampdu_ack_len == 0)
                        info->status.ampdu_len = 1;
 
-               rs_collect_tlc_data(mvm, lq_sta, curr_tbl, lq_rate.index,
+               rs_collect_tlc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,
                                    info->status.ampdu_len,
                                    info->status.ampdu_ack_len);
 
@@ -1348,11 +1348,11 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                                continue;
 
                        rs_collect_tpc_data(mvm, lq_sta, tmp_tbl,
-                                           lq_rate.index, 1,
+                                           tx_resp_rate.index, 1,
                                            i < retries ? 0 : legacy_success,
                                            reduced_txp);
                        rs_collect_tlc_data(mvm, lq_sta, tmp_tbl,
-                                           lq_rate.index, 1,
+                                           tx_resp_rate.index, 1,
                                            i < retries ? 0 : legacy_success);
                }
 
index f3e6081..71c8b80 100644 (file)
@@ -636,9 +636,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
 
        baid_data = rcu_dereference(mvm->baid_map[baid]);
        if (!baid_data) {
-               WARN(!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN),
-                    "Received baid %d, but no data exists for this BAID\n",
-                    baid);
+               IWL_DEBUG_RX(mvm,
+                            "Got valid BAID but no baid allocated, bypass the re-ordering buffer. Baid %d reorder 0x%x\n",
+                             baid, reorder);
                return false;
        }
 
@@ -759,7 +759,9 @@ static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm,
 
        data = rcu_dereference(mvm->baid_map[baid]);
        if (!data) {
-               WARN_ON(!(reorder_data & IWL_RX_MPDU_REORDER_BA_OLD_SN));
+               IWL_DEBUG_RX(mvm,
+                            "Got valid BAID but no baid allocated, bypass the re-ordering buffer. Baid %d reorder 0x%x\n",
+                             baid, reorder_data);
                goto out;
        }
 
index ab66b43..027ee5e 100644 (file)
@@ -121,7 +121,8 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                .mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color),
                .add_modify = update ? 1 : 0,
                .station_flags_msk = cpu_to_le32(STA_FLG_FAT_EN_MSK |
-                                                STA_FLG_MIMO_EN_MSK),
+                                                STA_FLG_MIMO_EN_MSK |
+                                                STA_FLG_RTS_MIMO_PROT),
                .tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg),
        };
        int ret;
@@ -290,8 +291,8 @@ static void iwl_mvm_rx_agg_session_expired(unsigned long data)
                goto unlock;
 
        mvm_sta = iwl_mvm_sta_from_mac80211(sta);
-       ieee80211_stop_rx_ba_session_offl(mvm_sta->vif,
-                                         sta->addr, ba_data->tid);
+       ieee80211_rx_ba_timer_expired(mvm_sta->vif,
+                                     sta->addr, ba_data->tid);
 unlock:
        rcu_read_unlock();
 }
index 60360ed..5fcc9dd 100644 (file)
@@ -185,8 +185,14 @@ static u16 iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
        else
                udp_hdr(skb)->check = 0;
 
-       /* mac header len should include IV, size is in words */
-       if (info->control.hw_key)
+       /*
+        * mac header len should include IV, size is in words unless
+        * the IV is added by the firmware like in WEP.
+        * In new Tx API, the IV is always added by the firmware.
+        */
+       if (!iwl_mvm_has_new_tx_api(mvm) && info->control.hw_key &&
+           info->control.hw_key->cipher != WLAN_CIPHER_SUITE_WEP40 &&
+           info->control.hw_key->cipher != WLAN_CIPHER_SUITE_WEP104)
                mh_len += info->control.hw_key->iv_len;
        mh_len /= 2;
        offload_assist |= mh_len << TX_CMD_OFFLD_MH_SIZE;
@@ -1815,6 +1821,8 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
        struct iwl_mvm_tid_data *tid_data;
        struct iwl_mvm_sta *mvmsta;
 
+       ba_info.flags = IEEE80211_TX_STAT_AMPDU;
+
        if (iwl_mvm_has_new_tx_api(mvm)) {
                struct iwl_mvm_compressed_ba_notif *ba_res =
                        (void *)pkt->data;
index f16c1bb..84f4ba0 100644 (file)
@@ -510,9 +510,17 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
 
 /* 9000 Series */
        {IWL_PCI_DEVICE(0x271B, 0x0010, iwl9160_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x271B, 0x0014, iwl9160_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)},
        {IWL_PCI_DEVICE(0x2526, 0x0000, iwl9260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0xA014, iwl9260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0210, iwl9260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0214, iwl9260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x2526, 0x1410, iwl9270_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x1610, iwl9270_2ac_cfg)},
        {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0x9DF0, 0x0210, iwl9460_2ac_cfg)},
@@ -527,10 +535,22 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0x2526, 0x0060, iwl9460_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0260, iwl9460_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0064, iwl9460_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x00A4, iwl9460_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9460_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x02A4, iwl9460_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x00A0, iwl9460_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x02A0, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0x9DF0, 0x0060, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0xA370, 0x0060, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0x31DC, 0x0060, iwl9460_2ac_cfg)},
        {IWL_PCI_DEVICE(0x2526, 0x0030, iwl9560_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0230, iwl9560_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0234, iwl9560_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x0238, iwl9560_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x2526, 0x023C, iwl9560_2ac_cfg)},
        {IWL_PCI_DEVICE(0x9DF0, 0x0030, iwl9560_2ac_cfg)},
        {IWL_PCI_DEVICE(0xA370, 0x0030, iwl9560_2ac_cfg)},
        {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg)},
index c49f1f8..37046ac 100644 (file)
@@ -336,7 +336,7 @@ static int nvme_get_stream_params(struct nvme_ctrl *ctrl,
 
        c.directive.opcode = nvme_admin_directive_recv;
        c.directive.nsid = cpu_to_le32(nsid);
-       c.directive.numd = cpu_to_le32(sizeof(*s));
+       c.directive.numd = cpu_to_le32((sizeof(*s) >> 2) - 1);
        c.directive.doper = NVME_DIR_RCV_ST_OP_PARAM;
        c.directive.dtype = NVME_DIR_STREAMS;
 
@@ -1509,7 +1509,7 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
        blk_queue_write_cache(q, vwc, vwc);
 }
 
-static void nvme_configure_apst(struct nvme_ctrl *ctrl)
+static int nvme_configure_apst(struct nvme_ctrl *ctrl)
 {
        /*
         * APST (Autonomous Power State Transition) lets us program a
@@ -1538,16 +1538,16 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
         * then don't do anything.
         */
        if (!ctrl->apsta)
-               return;
+               return 0;
 
        if (ctrl->npss > 31) {
                dev_warn(ctrl->device, "NPSS is invalid; not using APST\n");
-               return;
+               return 0;
        }
 
        table = kzalloc(sizeof(*table), GFP_KERNEL);
        if (!table)
-               return;
+               return 0;
 
        if (!ctrl->apst_enabled || ctrl->ps_max_latency_us == 0) {
                /* Turn off APST. */
@@ -1629,6 +1629,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
                dev_err(ctrl->device, "failed to set APST feature (%d)\n", ret);
 
        kfree(table);
+       return ret;
 }
 
 static void nvme_set_latency_tolerance(struct device *dev, s32 val)
@@ -1835,13 +1836,16 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
                 * In fabrics we need to verify the cntlid matches the
                 * admin connect
                 */
-               if (ctrl->cntlid != le16_to_cpu(id->cntlid))
+               if (ctrl->cntlid != le16_to_cpu(id->cntlid)) {
                        ret = -EINVAL;
+                       goto out_free;
+               }
 
                if (!ctrl->opts->discovery_nqn && !ctrl->kas) {
                        dev_err(ctrl->device,
                                "keep-alive support is mandatory for fabrics\n");
                        ret = -EINVAL;
+                       goto out_free;
                }
        } else {
                ctrl->cntlid = le16_to_cpu(id->cntlid);
@@ -1856,11 +1860,20 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
        else if (!ctrl->apst_enabled && prev_apst_enabled)
                dev_pm_qos_hide_latency_tolerance(ctrl->device);
 
-       nvme_configure_apst(ctrl);
-       nvme_configure_directives(ctrl);
+       ret = nvme_configure_apst(ctrl);
+       if (ret < 0)
+               return ret;
+
+       ret = nvme_configure_directives(ctrl);
+       if (ret < 0)
+               return ret;
 
        ctrl->identified = true;
 
+       return 0;
+
+out_free:
+       kfree(id);
        return ret;
 }
 EXPORT_SYMBOL_GPL(nvme_init_identify);
@@ -2004,9 +2017,11 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
        if (memchr_inv(ns->eui, 0, sizeof(ns->eui)))
                return sprintf(buf, "eui.%8phN\n", ns->eui);
 
-       while (ctrl->serial[serial_len - 1] == ' ')
+       while (serial_len > 0 && (ctrl->serial[serial_len - 1] == ' ' ||
+                                 ctrl->serial[serial_len - 1] == '\0'))
                serial_len--;
-       while (ctrl->model[model_len - 1] == ' ')
+       while (model_len > 0 && (ctrl->model[model_len - 1] == ' ' ||
+                                ctrl->model[model_len - 1] == '\0'))
                model_len--;
 
        return sprintf(buf, "nvme.%04x-%*phN-%*phN-%08x\n", ctrl->vid,
index 2e582a2..5f5cd30 100644 (file)
@@ -794,7 +794,8 @@ static int nvmf_check_allowed_opts(struct nvmf_ctrl_options *opts,
                int i;
 
                for (i = 0; i < ARRAY_SIZE(opt_tokens); i++) {
-                       if (opt_tokens[i].token & ~allowed_opts) {
+                       if ((opt_tokens[i].token & opts->mask) &&
+                           (opt_tokens[i].token & ~allowed_opts)) {
                                pr_warn("invalid parameter '%s'\n",
                                        opt_tokens[i].pattern);
                        }
index cd888a4..925467b 100644 (file)
@@ -801,6 +801,7 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq,
                return;
        }
 
+       nvmeq->cqe_seen = 1;
        req = blk_mq_tag_to_rq(*nvmeq->tags, cqe->command_id);
        nvme_end_request(req, cqe->status, cqe->result);
 }
@@ -830,10 +831,8 @@ static void nvme_process_cq(struct nvme_queue *nvmeq)
                consumed++;
        }
 
-       if (consumed) {
+       if (consumed)
                nvme_ring_cq_doorbell(nvmeq);
-               nvmeq->cqe_seen = 1;
-       }
 }
 
 static irqreturn_t nvme_irq(int irq, void *data)
@@ -1558,11 +1557,9 @@ static inline void nvme_release_cmb(struct nvme_dev *dev)
        if (dev->cmb) {
                iounmap(dev->cmb);
                dev->cmb = NULL;
-               if (dev->cmbsz) {
-                       sysfs_remove_file_from_group(&dev->ctrl.device->kobj,
-                                                    &dev_attr_cmb.attr, NULL);
-                       dev->cmbsz = 0;
-               }
+               sysfs_remove_file_from_group(&dev->ctrl.device->kobj,
+                                            &dev_attr_cmb.attr, NULL);
+               dev->cmbsz = 0;
        }
 }
 
@@ -1953,16 +1950,14 @@ static int nvme_pci_enable(struct nvme_dev *dev)
 
        /*
         * CMBs can currently only exist on >=1.2 PCIe devices. We only
-        * populate sysfs if a CMB is implemented. Note that we add the
-        * CMB attribute to the nvme_ctrl kobj which removes the need to remove
-        * it on exit. Since nvme_dev_attrs_group has no name we can pass
-        * NULL as final argument to sysfs_add_file_to_group.
+        * populate sysfs if a CMB is implemented. Since nvme_dev_attrs_group
+        * has no name we can pass NULL as final argument to
+        * sysfs_add_file_to_group.
         */
 
        if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2, 0)) {
                dev->cmb = nvme_map_cmb(dev);
-
-               if (dev->cmbsz) {
+               if (dev->cmb) {
                        if (sysfs_add_file_to_group(&dev->ctrl.device->kobj,
                                                    &dev_attr_cmb.attr, NULL))
                                dev_warn(dev->ctrl.device,
index 2d7a98a..a53bb66 100644 (file)
@@ -199,12 +199,6 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
        copy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1);
        copy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE));
 
-       memset(id->mn, ' ', sizeof(id->mn));
-       strncpy((char *)id->mn, "Linux", sizeof(id->mn));
-
-       memset(id->fr, ' ', sizeof(id->fr));
-       strncpy((char *)id->fr, UTS_RELEASE, sizeof(id->fr));
-
        id->rab = 6;
 
        /*
index 31ca55d..309c84a 100644 (file)
@@ -114,6 +114,11 @@ struct nvmet_fc_tgtport {
        struct kref                     ref;
 };
 
+struct nvmet_fc_defer_fcp_req {
+       struct list_head                req_list;
+       struct nvmefc_tgt_fcp_req       *fcp_req;
+};
+
 struct nvmet_fc_tgt_queue {
        bool                            ninetypercent;
        u16                             qid;
@@ -132,6 +137,8 @@ struct nvmet_fc_tgt_queue {
        struct nvmet_fc_tgt_assoc       *assoc;
        struct nvmet_fc_fcp_iod         *fod;           /* array of fcp_iods */
        struct list_head                fod_list;
+       struct list_head                pending_cmd_list;
+       struct list_head                avail_defer_list;
        struct workqueue_struct         *work_q;
        struct kref                     ref;
 } __aligned(sizeof(unsigned long long));
@@ -223,6 +230,8 @@ static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue);
 static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue);
 static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport);
 static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport);
+static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport,
+                                       struct nvmet_fc_fcp_iod *fod);
 
 
 /* *********************** FC-NVME DMA Handling **************************** */
@@ -385,7 +394,7 @@ nvmet_fc_free_ls_iodlist(struct nvmet_fc_tgtport *tgtport)
 static struct nvmet_fc_ls_iod *
 nvmet_fc_alloc_ls_iod(struct nvmet_fc_tgtport *tgtport)
 {
-       static struct nvmet_fc_ls_iod *iod;
+       struct nvmet_fc_ls_iod *iod;
        unsigned long flags;
 
        spin_lock_irqsave(&tgtport->lock, flags);
@@ -462,10 +471,10 @@ nvmet_fc_destroy_fcp_iodlist(struct nvmet_fc_tgtport *tgtport,
 static struct nvmet_fc_fcp_iod *
 nvmet_fc_alloc_fcp_iod(struct nvmet_fc_tgt_queue *queue)
 {
-       static struct nvmet_fc_fcp_iod *fod;
-       unsigned long flags;
+       struct nvmet_fc_fcp_iod *fod;
+
+       lockdep_assert_held(&queue->qlock);
 
-       spin_lock_irqsave(&queue->qlock, flags);
        fod = list_first_entry_or_null(&queue->fod_list,
                                        struct nvmet_fc_fcp_iod, fcp_list);
        if (fod) {
@@ -477,17 +486,37 @@ nvmet_fc_alloc_fcp_iod(struct nvmet_fc_tgt_queue *queue)
                 * will "inherit" that reference.
                 */
        }
-       spin_unlock_irqrestore(&queue->qlock, flags);
        return fod;
 }
 
 
 static void
+nvmet_fc_queue_fcp_req(struct nvmet_fc_tgtport *tgtport,
+                      struct nvmet_fc_tgt_queue *queue,
+                      struct nvmefc_tgt_fcp_req *fcpreq)
+{
+       struct nvmet_fc_fcp_iod *fod = fcpreq->nvmet_fc_private;
+
+       /*
+        * put all admin cmds on hw queue id 0. All io commands go to
+        * the respective hw queue based on a modulo basis
+        */
+       fcpreq->hwqid = queue->qid ?
+                       ((queue->qid - 1) % tgtport->ops->max_hw_queues) : 0;
+
+       if (tgtport->ops->target_features & NVMET_FCTGTFEAT_CMD_IN_ISR)
+               queue_work_on(queue->cpu, queue->work_q, &fod->work);
+       else
+               nvmet_fc_handle_fcp_rqst(tgtport, fod);
+}
+
+static void
 nvmet_fc_free_fcp_iod(struct nvmet_fc_tgt_queue *queue,
                        struct nvmet_fc_fcp_iod *fod)
 {
        struct nvmefc_tgt_fcp_req *fcpreq = fod->fcpreq;
        struct nvmet_fc_tgtport *tgtport = fod->tgtport;
+       struct nvmet_fc_defer_fcp_req *deferfcp;
        unsigned long flags;
 
        fc_dma_sync_single_for_cpu(tgtport->dev, fod->rspdma,
@@ -495,21 +524,56 @@ nvmet_fc_free_fcp_iod(struct nvmet_fc_tgt_queue *queue,
 
        fcpreq->nvmet_fc_private = NULL;
 
-       spin_lock_irqsave(&queue->qlock, flags);
-       list_add_tail(&fod->fcp_list, &fod->queue->fod_list);
        fod->active = false;
        fod->abort = false;
        fod->aborted = false;
        fod->writedataactive = false;
        fod->fcpreq = NULL;
+
+       tgtport->ops->fcp_req_release(&tgtport->fc_target_port, fcpreq);
+
+       spin_lock_irqsave(&queue->qlock, flags);
+       deferfcp = list_first_entry_or_null(&queue->pending_cmd_list,
+                               struct nvmet_fc_defer_fcp_req, req_list);
+       if (!deferfcp) {
+               list_add_tail(&fod->fcp_list, &fod->queue->fod_list);
+               spin_unlock_irqrestore(&queue->qlock, flags);
+
+               /* Release reference taken at queue lookup and fod allocation */
+               nvmet_fc_tgt_q_put(queue);
+               return;
+       }
+
+       /* Re-use the fod for the next pending cmd that was deferred */
+       list_del(&deferfcp->req_list);
+
+       fcpreq = deferfcp->fcp_req;
+
+       /* deferfcp can be reused for another IO at a later date */
+       list_add_tail(&deferfcp->req_list, &queue->avail_defer_list);
+
        spin_unlock_irqrestore(&queue->qlock, flags);
 
+       /* Save NVME CMD IO in fod */
+       memcpy(&fod->cmdiubuf, fcpreq->rspaddr, fcpreq->rsplen);
+
+       /* Setup new fcpreq to be processed */
+       fcpreq->rspaddr = NULL;
+       fcpreq->rsplen  = 0;
+       fcpreq->nvmet_fc_private = fod;
+       fod->fcpreq = fcpreq;
+       fod->active = true;
+
+       /* inform LLDD IO is now being processed */
+       tgtport->ops->defer_rcv(&tgtport->fc_target_port, fcpreq);
+
+       /* Submit deferred IO for processing */
+       nvmet_fc_queue_fcp_req(tgtport, queue, fcpreq);
+
        /*
-        * release the reference taken at queue lookup and fod allocation
+        * Leave the queue lookup get reference taken when
+        * fod was originally allocated.
         */
-       nvmet_fc_tgt_q_put(queue);
-
-       tgtport->ops->fcp_req_release(&tgtport->fc_target_port, fcpreq);
 }
 
 static int
@@ -569,6 +633,8 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc,
        queue->port = assoc->tgtport->port;
        queue->cpu = nvmet_fc_queue_to_cpu(assoc->tgtport, qid);
        INIT_LIST_HEAD(&queue->fod_list);
+       INIT_LIST_HEAD(&queue->avail_defer_list);
+       INIT_LIST_HEAD(&queue->pending_cmd_list);
        atomic_set(&queue->connected, 0);
        atomic_set(&queue->sqtail, 0);
        atomic_set(&queue->rsn, 1);
@@ -638,6 +704,7 @@ nvmet_fc_delete_target_queue(struct nvmet_fc_tgt_queue *queue)
 {
        struct nvmet_fc_tgtport *tgtport = queue->assoc->tgtport;
        struct nvmet_fc_fcp_iod *fod = queue->fod;
+       struct nvmet_fc_defer_fcp_req *deferfcp, *tempptr;
        unsigned long flags;
        int i, writedataactive;
        bool disconnect;
@@ -666,6 +733,36 @@ nvmet_fc_delete_target_queue(struct nvmet_fc_tgt_queue *queue)
                        }
                }
        }
+
+       /* Cleanup defer'ed IOs in queue */
+       list_for_each_entry_safe(deferfcp, tempptr, &queue->avail_defer_list,
+                               req_list) {
+               list_del(&deferfcp->req_list);
+               kfree(deferfcp);
+       }
+
+       for (;;) {
+               deferfcp = list_first_entry_or_null(&queue->pending_cmd_list,
+                               struct nvmet_fc_defer_fcp_req, req_list);
+               if (!deferfcp)
+                       break;
+
+               list_del(&deferfcp->req_list);
+               spin_unlock_irqrestore(&queue->qlock, flags);
+
+               tgtport->ops->defer_rcv(&tgtport->fc_target_port,
+                               deferfcp->fcp_req);
+
+               tgtport->ops->fcp_abort(&tgtport->fc_target_port,
+                               deferfcp->fcp_req);
+
+               tgtport->ops->fcp_req_release(&tgtport->fc_target_port,
+                               deferfcp->fcp_req);
+
+               kfree(deferfcp);
+
+               spin_lock_irqsave(&queue->qlock, flags);
+       }
        spin_unlock_irqrestore(&queue->qlock, flags);
 
        flush_workqueue(queue->work_q);
@@ -2172,11 +2269,38 @@ nvmet_fc_handle_fcp_rqst_work(struct work_struct *work)
  * Pass a FC-NVME FCP CMD IU received from the FC link to the nvmet-fc
  * layer for processing.
  *
- * The nvmet-fc layer will copy cmd payload to an internal structure for
- * processing.  As such, upon completion of the routine, the LLDD may
- * immediately free/reuse the CMD IU buffer passed in the call.
+ * The nvmet_fc layer allocates a local job structure (struct
+ * nvmet_fc_fcp_iod) from the queue for the io and copies the
+ * CMD IU buffer to the job structure. As such, on a successful
+ * completion (returns 0), the LLDD may immediately free/reuse
+ * the CMD IU buffer passed in the call.
  *
- * If this routine returns error, the lldd should abort the exchange.
+ * However, in some circumstances, due to the packetized nature of FC
+ * and the api of the FC LLDD which may issue a hw command to send the
+ * response, but the LLDD may not get the hw completion for that command
+ * and upcall the nvmet_fc layer before a new command may be
+ * asynchronously received - its possible for a command to be received
+ * before the LLDD and nvmet_fc have recycled the job structure. It gives
+ * the appearance of more commands received than fits in the sq.
+ * To alleviate this scenario, a temporary queue is maintained in the
+ * transport for pending LLDD requests waiting for a queue job structure.
+ * In these "overrun" cases, a temporary queue element is allocated
+ * the LLDD request and CMD iu buffer information remembered, and the
+ * routine returns a -EOVERFLOW status. Subsequently, when a queue job
+ * structure is freed, it is immediately reallocated for anything on the
+ * pending request list. The LLDDs defer_rcv() callback is called,
+ * informing the LLDD that it may reuse the CMD IU buffer, and the io
+ * is then started normally with the transport.
+ *
+ * The LLDD, when receiving an -EOVERFLOW completion status, is to treat
+ * the completion as successful but must not reuse the CMD IU buffer
+ * until the LLDD's defer_rcv() callback has been called for the
+ * corresponding struct nvmefc_tgt_fcp_req pointer.
+ *
+ * If there is any other condition in which an error occurs, the
+ * transport will return a non-zero status indicating the error.
+ * In all cases other than -EOVERFLOW, the transport has not accepted the
+ * request and the LLDD should abort the exchange.
  *
  * @target_port: pointer to the (registered) target port the FCP CMD IU
  *              was received on.
@@ -2194,6 +2318,8 @@ nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *target_port,
        struct nvme_fc_cmd_iu *cmdiu = cmdiubuf;
        struct nvmet_fc_tgt_queue *queue;
        struct nvmet_fc_fcp_iod *fod;
+       struct nvmet_fc_defer_fcp_req *deferfcp;
+       unsigned long flags;
 
        /* validate iu, so the connection id can be used to find the queue */
        if ((cmdiubuf_len != sizeof(*cmdiu)) ||
@@ -2214,29 +2340,60 @@ nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *target_port,
         * when the fod is freed.
         */
 
+       spin_lock_irqsave(&queue->qlock, flags);
+
        fod = nvmet_fc_alloc_fcp_iod(queue);
-       if (!fod) {
+       if (fod) {
+               spin_unlock_irqrestore(&queue->qlock, flags);
+
+               fcpreq->nvmet_fc_private = fod;
+               fod->fcpreq = fcpreq;
+
+               memcpy(&fod->cmdiubuf, cmdiubuf, cmdiubuf_len);
+
+               nvmet_fc_queue_fcp_req(tgtport, queue, fcpreq);
+
+               return 0;
+       }
+
+       if (!tgtport->ops->defer_rcv) {
+               spin_unlock_irqrestore(&queue->qlock, flags);
                /* release the queue lookup reference */
                nvmet_fc_tgt_q_put(queue);
                return -ENOENT;
        }
 
-       fcpreq->nvmet_fc_private = fod;
-       fod->fcpreq = fcpreq;
-       /*
-        * put all admin cmds on hw queue id 0. All io commands go to
-        * the respective hw queue based on a modulo basis
-        */
-       fcpreq->hwqid = queue->qid ?
-                       ((queue->qid - 1) % tgtport->ops->max_hw_queues) : 0;
-       memcpy(&fod->cmdiubuf, cmdiubuf, cmdiubuf_len);
+       deferfcp = list_first_entry_or_null(&queue->avail_defer_list,
+                       struct nvmet_fc_defer_fcp_req, req_list);
+       if (deferfcp) {
+               /* Just re-use one that was previously allocated */
+               list_del(&deferfcp->req_list);
+       } else {
+               spin_unlock_irqrestore(&queue->qlock, flags);
 
-       if (tgtport->ops->target_features & NVMET_FCTGTFEAT_CMD_IN_ISR)
-               queue_work_on(queue->cpu, queue->work_q, &fod->work);
-       else
-               nvmet_fc_handle_fcp_rqst(tgtport, fod);
+               /* Now we need to dynamically allocate one */
+               deferfcp = kmalloc(sizeof(*deferfcp), GFP_KERNEL);
+               if (!deferfcp) {
+                       /* release the queue lookup reference */
+                       nvmet_fc_tgt_q_put(queue);
+                       return -ENOMEM;
+               }
+               spin_lock_irqsave(&queue->qlock, flags);
+       }
 
-       return 0;
+       /* For now, use rspaddr / rsplen to save payload information */
+       fcpreq->rspaddr = cmdiubuf;
+       fcpreq->rsplen  = cmdiubuf_len;
+       deferfcp->fcp_req = fcpreq;
+
+       /* defer processing till a fod becomes available */
+       list_add_tail(&deferfcp->req_list, &queue->pending_cmd_list);
+
+       /* NOTE: the queue lookup reference is still valid */
+
+       spin_unlock_irqrestore(&queue->qlock, flags);
+
+       return -EOVERFLOW;
 }
 EXPORT_SYMBOL_GPL(nvmet_fc_rcv_fcp_req);
 
index 28c38c7..e0a28ea 100644 (file)
@@ -89,6 +89,7 @@ int of_dma_configure(struct device *dev, struct device_node *np)
        bool coherent;
        unsigned long offset;
        const struct iommu_ops *iommu;
+       u64 mask;
 
        /*
         * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
@@ -134,10 +135,9 @@ int of_dma_configure(struct device *dev, struct device_node *np)
         * Limit coherent and dma mask based on size and default mask
         * set by the driver.
         */
-       dev->coherent_dma_mask = min(dev->coherent_dma_mask,
-                                    DMA_BIT_MASK(ilog2(dma_addr + size)));
-       *dev->dma_mask = min((*dev->dma_mask),
-                            DMA_BIT_MASK(ilog2(dma_addr + size)));
+       mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
+       dev->coherent_dma_mask &= mask;
+       *dev->dma_mask &= mask;
 
        coherent = of_dma_is_coherent(np);
        dev_dbg(dev, "device is%sdma coherent\n",
index 5c63b92..ed92c12 100644 (file)
@@ -956,7 +956,7 @@ static int __init dino_probe(struct parisc_device *dev)
 
        dino_dev->hba.dev = dev;
        dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096);
-       dino_dev->hba.lmmio_space_offset = 0;   /* CPU addrs == bus addrs */
+       dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND;
        spin_lock_init(&dino_dev->dinosaur_pen);
        dino_dev->hba.iommu = ccio_get_iommu(dev);
 
index b4b7eab..fdf65a6 100644 (file)
@@ -514,7 +514,7 @@ EXPORT_SYMBOL(pci_find_resource);
  */
 struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev)
 {
-       struct pci_dev *bridge, *highest_pcie_bridge = NULL;
+       struct pci_dev *bridge, *highest_pcie_bridge = dev;
 
        bridge = pci_upstream_bridge(dev);
        while (bridge && pci_is_pcie(bridge)) {
index c31310d..e6a917b 100644 (file)
@@ -1762,6 +1762,48 @@ static void pci_configure_extended_tags(struct pci_dev *dev)
                                         PCI_EXP_DEVCTL_EXT_TAG);
 }
 
+/**
+ * pcie_relaxed_ordering_enabled - Probe for PCIe relaxed ordering enable
+ * @dev: PCI device to query
+ *
+ * Returns true if the device has enabled relaxed ordering attribute.
+ */
+bool pcie_relaxed_ordering_enabled(struct pci_dev *dev)
+{
+       u16 v;
+
+       pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &v);
+
+       return !!(v & PCI_EXP_DEVCTL_RELAX_EN);
+}
+EXPORT_SYMBOL(pcie_relaxed_ordering_enabled);
+
+static void pci_configure_relaxed_ordering(struct pci_dev *dev)
+{
+       struct pci_dev *root;
+
+       /* PCI_EXP_DEVICE_RELAX_EN is RsvdP in VFs */
+       if (dev->is_virtfn)
+               return;
+
+       if (!pcie_relaxed_ordering_enabled(dev))
+               return;
+
+       /*
+        * For now, we only deal with Relaxed Ordering issues with Root
+        * Ports. Peer-to-Peer DMA is another can of worms.
+        */
+       root = pci_find_pcie_root_port(dev);
+       if (!root)
+               return;
+
+       if (root->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) {
+               pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
+                                          PCI_EXP_DEVCTL_RELAX_EN);
+               dev_info(&dev->dev, "Disable Relaxed Ordering because the Root Port didn't support it\n");
+       }
+}
+
 static void pci_configure_device(struct pci_dev *dev)
 {
        struct hotplug_params hpp;
@@ -1769,6 +1811,7 @@ static void pci_configure_device(struct pci_dev *dev)
 
        pci_configure_mps(dev);
        pci_configure_extended_tags(dev);
+       pci_configure_relaxed_ordering(dev);
 
        memset(&hpp, 0, sizeof(hpp));
        ret = pci_get_hp_params(dev, &hpp);
index 6967c6b..1407604 100644 (file)
@@ -4016,6 +4016,95 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6869, PCI_CLASS_NOT_DEFINED, 8,
                              quirk_tw686x_class);
 
 /*
+ * Some devices have problems with Transaction Layer Packets with the Relaxed
+ * Ordering Attribute set.  Such devices should mark themselves and other
+ * Device Drivers should check before sending TLPs with RO set.
+ */
+static void quirk_relaxedordering_disable(struct pci_dev *dev)
+{
+       dev->dev_flags |= PCI_DEV_FLAGS_NO_RELAXED_ORDERING;
+       dev_info(&dev->dev, "Disable Relaxed Ordering Attributes to avoid PCIe Completion erratum\n");
+}
+
+/*
+ * Intel Xeon processors based on Broadwell/Haswell microarchitecture Root
+ * Complex has a Flow Control Credit issue which can cause performance
+ * problems with Upstream Transaction Layer Packets with Relaxed Ordering set.
+ */
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f01, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f02, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f03, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f04, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f05, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f06, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f07, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f08, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f09, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f0a, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f0b, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f0c, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f0d, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x6f0e, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f01, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f02, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f03, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f04, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f05, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f06, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f07, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f08, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f09, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f0a, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f0b, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f0c, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f0d, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f0e, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+
+/*
+ * The AMD ARM A1100 (AKA "SEATTLE") SoC has a bug in its PCIe Root Complex
+ * where Upstream Transaction Layer Packets with the Relaxed Ordering
+ * Attribute clear are allowed to bypass earlier TLPs with Relaxed Ordering
+ * set.  This is a violation of the PCIe 3.0 Transaction Ordering Rules
+ * outlined in Section 2.4.1 (PCI Express(r) Base Specification Revision 3.0
+ * November 10, 2010).  As a result, on this platform we can't use Relaxed
+ * Ordering for Upstream TLPs.
+ */
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, 0x1a00, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, 0x1a01, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, 0x1a02, PCI_CLASS_NOT_DEFINED, 8,
+                             quirk_relaxedordering_disable);
+
+/*
  * Per PCIe r3.0, sec 2.2.9, "Completion headers must supply the same
  * values for the Attribute as were supplied in the header of the
  * corresponding Request, except as explicitly allowed when IDO is used."
index 4fac49e..4b43aa6 100644 (file)
@@ -1301,7 +1301,6 @@ static void ds1307_clks_register(struct ds1307 *ds1307)
 static const struct regmap_config regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
-       .max_register = 0x12,
 };
 
 static int ds1307_probe(struct i2c_client *client,
index f4538d7..d145e0d 100644 (file)
@@ -47,6 +47,17 @@ config SCSI_NETLINK
        default n
        depends on NET
 
+config SCSI_MQ_DEFAULT
+       bool "SCSI: use blk-mq I/O path by default"
+       depends on SCSI
+       ---help---
+         This option enables the new blk-mq based I/O path for SCSI
+         devices by default.  With the option the scsi_mod.use_blk_mq
+         module/boot option defaults to Y, without it to N, but it can
+         still be overridden either way.
+
+         If unsure say N.
+
 config SCSI_PROC_FS
        bool "legacy /proc/scsi/ support"
        depends on SCSI && PROC_FS
index 4591113..a1a2c71 100644 (file)
@@ -549,7 +549,9 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
        if ((le32_to_cpu(get_name_reply->status) == CT_OK)
         && (get_name_reply->data[0] != '\0')) {
                char *sp = get_name_reply->data;
-               sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0';
+               int data_size = FIELD_SIZEOF(struct aac_get_name_resp, data);
+
+               sp[data_size - 1] = '\0';
                while (*sp == ' ')
                        ++sp;
                if (*sp) {
@@ -579,12 +581,15 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
 static int aac_get_container_name(struct scsi_cmnd * scsicmd)
 {
        int status;
+       int data_size;
        struct aac_get_name *dinfo;
        struct fib * cmd_fibcontext;
        struct aac_dev * dev;
 
        dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 
+       data_size = FIELD_SIZEOF(struct aac_get_name_resp, data);
+
        cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
 
        aac_fib_init(cmd_fibcontext);
@@ -593,7 +598,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
        dinfo->command = cpu_to_le32(VM_ContainerConfig);
        dinfo->type = cpu_to_le32(CT_READ_NAME);
        dinfo->cid = cpu_to_le32(scmd_id(scsicmd));
-       dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data));
+       dinfo->count = cpu_to_le32(data_size - 1);
 
        status = aac_fib_send(ContainerCommand,
                  cmd_fibcontext,
index d31a9bc..ee2667e 100644 (file)
@@ -2274,7 +2274,7 @@ struct aac_get_name_resp {
        __le32          parm3;
        __le32          parm4;
        __le32          parm5;
-       u8              data[16];
+       u8              data[17];
 };
 
 #define CT_CID_TO_32BITS_UID 165
index 2029ad2..5be0086 100644 (file)
@@ -3845,8 +3845,10 @@ csio_hw_start(struct csio_hw *hw)
 
        if (csio_is_hw_ready(hw))
                return 0;
-       else
+       else if (csio_match_state(hw, csio_hws_uninit))
                return -EINVAL;
+       else
+               return -ENODEV;
 }
 
 int
index ea0c310..dcd0741 100644 (file)
@@ -969,10 +969,14 @@ static int csio_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        pci_set_drvdata(pdev, hw);
 
-       if (csio_hw_start(hw) != 0) {
-               dev_err(&pdev->dev,
-                       "Failed to start FW, continuing in debug mode.\n");
-               return 0;
+       rv = csio_hw_start(hw);
+       if (rv) {
+               if (rv == -EINVAL) {
+                       dev_err(&pdev->dev,
+                               "Failed to start FW, continuing in debug mode.\n");
+                       return 0;
+               }
+               goto err_lnode_exit;
        }
 
        sprintf(hw->fwrev_str, "%u.%u.%u.%u\n",
index a69a9ac..1d02cf9 100644 (file)
@@ -1635,6 +1635,9 @@ static int init_act_open(struct cxgbi_sock *csk)
                goto rel_resource;
        }
 
+       if (!(n->nud_state & NUD_VALID))
+               neigh_event_send(n, NULL);
+
        csk->atid = cxgb4_alloc_atid(lldi->tids, csk);
        if (csk->atid < 0) {
                pr_err("%s, NO atid available.\n", ndev->name);
index b0c68d2..da5bdbd 100644 (file)
@@ -3351,6 +3351,16 @@ static void ipr_worker_thread(struct work_struct *work)
                return;
        }
 
+       if (ioa_cfg->scsi_unblock) {
+               ioa_cfg->scsi_unblock = 0;
+               ioa_cfg->scsi_blocked = 0;
+               spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+               scsi_unblock_requests(ioa_cfg->host);
+               spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+               if (ioa_cfg->scsi_blocked)
+                       scsi_block_requests(ioa_cfg->host);
+       }
+
        if (!ioa_cfg->scan_enabled) {
                spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
                return;
@@ -7211,9 +7221,8 @@ static int ipr_ioa_bringdown_done(struct ipr_cmnd *ipr_cmd)
        ENTER;
        if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {
                ipr_trace;
-               spin_unlock_irq(ioa_cfg->host->host_lock);
-               scsi_unblock_requests(ioa_cfg->host);
-               spin_lock_irq(ioa_cfg->host->host_lock);
+               ioa_cfg->scsi_unblock = 1;
+               schedule_work(&ioa_cfg->work_q);
        }
 
        ioa_cfg->in_reset_reload = 0;
@@ -7287,13 +7296,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd)
        list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
        wake_up_all(&ioa_cfg->reset_wait_q);
 
-       spin_unlock(ioa_cfg->host->host_lock);
-       scsi_unblock_requests(ioa_cfg->host);
-       spin_lock(ioa_cfg->host->host_lock);
-
-       if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds)
-               scsi_block_requests(ioa_cfg->host);
-
+       ioa_cfg->scsi_unblock = 1;
        schedule_work(&ioa_cfg->work_q);
        LEAVE;
        return IPR_RC_JOB_RETURN;
@@ -9249,8 +9252,11 @@ static void _ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
                spin_unlock(&ioa_cfg->hrrq[i]._lock);
        }
        wmb();
-       if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa)
+       if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {
+               ioa_cfg->scsi_unblock = 0;
+               ioa_cfg->scsi_blocked = 1;
                scsi_block_requests(ioa_cfg->host);
+       }
 
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
        ioa_cfg->reset_cmd = ipr_cmd;
@@ -9306,9 +9312,8 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
                        wake_up_all(&ioa_cfg->reset_wait_q);
 
                        if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {
-                               spin_unlock_irq(ioa_cfg->host->host_lock);
-                               scsi_unblock_requests(ioa_cfg->host);
-                               spin_lock_irq(ioa_cfg->host->host_lock);
+                               ioa_cfg->scsi_unblock = 1;
+                               schedule_work(&ioa_cfg->work_q);
                        }
                        return;
                } else {
index e98a87a..c7f0e9e 100644 (file)
@@ -1488,6 +1488,8 @@ struct ipr_ioa_cfg {
        u8 cfg_locked:1;
        u8 clear_isr:1;
        u8 probe_done:1;
+       u8 scsi_unblock:1;
+       u8 scsi_blocked:1;
 
        u8 revid;
 
index 4ed48ed..7ee1a94 100644 (file)
@@ -205,8 +205,10 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
                                atomic_read(&tgtp->xmt_ls_rsp_error));
 
                len += snprintf(buf+len, PAGE_SIZE-len,
-                               "FCP: Rcv %08x Release %08x Drop %08x\n",
+                               "FCP: Rcv %08x Defer %08x Release %08x "
+                               "Drop %08x\n",
                                atomic_read(&tgtp->rcv_fcp_cmd_in),
+                               atomic_read(&tgtp->rcv_fcp_cmd_defer),
                                atomic_read(&tgtp->xmt_fcp_release),
                                atomic_read(&tgtp->rcv_fcp_cmd_drop));
 
index 5cc8b0f..744f3f3 100644 (file)
@@ -782,8 +782,11 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)
                                atomic_read(&tgtp->xmt_ls_rsp_error));
 
                len += snprintf(buf + len, size - len,
-                               "FCP: Rcv %08x Drop %08x\n",
+                               "FCP: Rcv %08x Defer %08x Release %08x "
+                               "Drop %08x\n",
                                atomic_read(&tgtp->rcv_fcp_cmd_in),
+                               atomic_read(&tgtp->rcv_fcp_cmd_defer),
+                               atomic_read(&tgtp->xmt_fcp_release),
                                atomic_read(&tgtp->rcv_fcp_cmd_drop));
 
                if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
index fbeec34..bbbd0f8 100644 (file)
@@ -841,12 +841,31 @@ lpfc_nvmet_xmt_fcp_release(struct nvmet_fc_target_port *tgtport,
        lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf);
 }
 
+static void
+lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
+                    struct nvmefc_tgt_fcp_req *rsp)
+{
+       struct lpfc_nvmet_tgtport *tgtp;
+       struct lpfc_nvmet_rcv_ctx *ctxp =
+               container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
+       struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer;
+       struct lpfc_hba *phba = ctxp->phba;
+
+       lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n",
+                        ctxp->oxid, ctxp->size, smp_processor_id());
+
+       tgtp = phba->targetport->private;
+       atomic_inc(&tgtp->rcv_fcp_cmd_defer);
+       lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */
+}
+
 static struct nvmet_fc_target_template lpfc_tgttemplate = {
        .targetport_delete = lpfc_nvmet_targetport_delete,
        .xmt_ls_rsp     = lpfc_nvmet_xmt_ls_rsp,
        .fcp_op         = lpfc_nvmet_xmt_fcp_op,
        .fcp_abort      = lpfc_nvmet_xmt_fcp_abort,
        .fcp_req_release = lpfc_nvmet_xmt_fcp_release,
+       .defer_rcv      = lpfc_nvmet_defer_rcv,
 
        .max_hw_queues  = 1,
        .max_sgl_segments = LPFC_NVMET_DEFAULT_SEGS,
@@ -1504,6 +1523,17 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
                return;
        }
 
+       /* Processing of FCP command is deferred */
+       if (rc == -EOVERFLOW) {
+               lpfc_nvmeio_data(phba,
+                                "NVMET RCV BUSY: xri x%x sz %d from %06x\n",
+                                oxid, size, sid);
+               /* defer reposting rcv buffer till .defer_rcv callback */
+               ctxp->rqb_buffer = nvmebuf;
+               atomic_inc(&tgtp->rcv_fcp_cmd_out);
+               return;
+       }
+
        atomic_inc(&tgtp->rcv_fcp_cmd_drop);
        lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
                        "6159 FCP Drop IO x%x: err x%x: x%x x%x x%x\n",
index e675ef1..48a7678 100644 (file)
@@ -49,6 +49,7 @@ struct lpfc_nvmet_tgtport {
        atomic_t rcv_fcp_cmd_in;
        atomic_t rcv_fcp_cmd_out;
        atomic_t rcv_fcp_cmd_drop;
+       atomic_t rcv_fcp_cmd_defer;
        atomic_t xmt_fcp_release;
 
        /* Stats counters - lpfc_nvmet_xmt_fcp_op */
index 316c3df..71c4746 100644 (file)
@@ -6228,8 +6228,8 @@ static int megasas_probe_one(struct pci_dev *pdev,
 fail_start_aen:
 fail_io_attach:
        megasas_mgmt_info.count--;
-       megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
        megasas_mgmt_info.max_index--;
+       megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
 
        instance->instancet->disable_intr(instance);
        megasas_destroy_irqs(instance);
index 3314261..b18646d 100644 (file)
@@ -401,9 +401,6 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
                for (i = 0; i < vha->hw->max_req_queues; i++) {
                        struct req_que *req = vha->hw->req_q_map[i];
 
-                       if (!test_bit(i, vha->hw->req_qid_map))
-                               continue;
-
                        if (req || !buf) {
                                length = req ?
                                    req->length : REQUEST_ENTRY_CNT_24XX;
@@ -418,9 +415,6 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
                for (i = 0; i < vha->hw->max_rsp_queues; i++) {
                        struct rsp_que *rsp = vha->hw->rsp_q_map[i];
 
-                       if (!test_bit(i, vha->hw->rsp_qid_map))
-                               continue;
-
                        if (rsp || !buf) {
                                length = rsp ?
                                    rsp->length : RESPONSE_ENTRY_CNT_MQ;
@@ -660,9 +654,6 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
                for (i = 0; i < vha->hw->max_req_queues; i++) {
                        struct req_que *req = vha->hw->req_q_map[i];
 
-                       if (!test_bit(i, vha->hw->req_qid_map))
-                               continue;
-
                        if (req || !buf) {
                                qla27xx_insert16(i, buf, len);
                                qla27xx_insert16(1, buf, len);
@@ -675,9 +666,6 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
                for (i = 0; i < vha->hw->max_rsp_queues; i++) {
                        struct rsp_que *rsp = vha->hw->rsp_q_map[i];
 
-                       if (!test_bit(i, vha->hw->rsp_qid_map))
-                               continue;
-
                        if (rsp || !buf) {
                                qla27xx_insert16(i, buf, len);
                                qla27xx_insert16(1, buf, len);
index b20da0d..3f82ea1 100644 (file)
@@ -500,7 +500,6 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
 static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
 {
        struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
-       unsigned long flags;
 
        /*
         * Ensure that the complete FCP WRITE payload has been received.
@@ -508,17 +507,6 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
         */
        cmd->cmd_in_wq = 0;
 
-       spin_lock_irqsave(&cmd->cmd_lock, flags);
-       cmd->data_work = 1;
-       if (cmd->aborted) {
-               cmd->data_work_free = 1;
-               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
-
-               tcm_qla2xxx_free_cmd(cmd);
-               return;
-       }
-       spin_unlock_irqrestore(&cmd->cmd_lock, flags);
-
        cmd->qpair->tgt_counters.qla_core_ret_ctio++;
        if (!cmd->write_data_transferred) {
                /*
@@ -765,31 +753,13 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
        qlt_xmit_tm_rsp(mcmd);
 }
 
-#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)
 static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
 {
        struct qla_tgt_cmd *cmd = container_of(se_cmd,
                                struct qla_tgt_cmd, se_cmd);
-       unsigned long flags;
 
        if (qlt_abort_cmd(cmd))
                return;
-
-       spin_lock_irqsave(&cmd->cmd_lock, flags);
-       if ((cmd->state == QLA_TGT_STATE_NEW)||
-           ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
-               DATA_WORK_NOT_FREE(cmd))) {
-               cmd->data_work_free = 1;
-               spin_unlock_irqrestore(&cmd->cmd_lock, flags);
-               /*
-                * cmd has not reached fw, Use this trigger to free it.
-                */
-               tcm_qla2xxx_free_cmd(cmd);
-               return;
-       }
-       spin_unlock_irqrestore(&cmd->cmd_lock, flags);
-       return;
-
 }
 
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
index 3d38c6d..1bf274e 100644 (file)
@@ -800,7 +800,11 @@ MODULE_LICENSE("GPL");
 module_param(scsi_logging_level, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels");
 
+#ifdef CONFIG_SCSI_MQ_DEFAULT
 bool scsi_use_blk_mq = true;
+#else
+bool scsi_use_blk_mq = false;
+#endif
 module_param_named(use_blk_mq, scsi_use_blk_mq, bool, S_IWUSR | S_IRUGO);
 
 static int __init init_scsi(void)
index bea36ad..e2647f2 100644 (file)
@@ -1277,6 +1277,9 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
 {
        struct request *rq = SCpnt->request;
 
+       if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK)
+               sd_zbc_write_unlock_zone(SCpnt);
+
        if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
                __free_page(rq->special_vec.bv_page);
 
index 96855df..8aa5477 100644 (file)
@@ -294,6 +294,9 @@ int sd_zbc_write_lock_zone(struct scsi_cmnd *cmd)
            test_and_set_bit(zno, sdkp->zones_wlock))
                return BLKPREP_DEFER;
 
+       WARN_ON_ONCE(cmd->flags & SCMD_ZONE_WRITE_LOCK);
+       cmd->flags |= SCMD_ZONE_WRITE_LOCK;
+
        return BLKPREP_OK;
 }
 
@@ -302,9 +305,10 @@ void sd_zbc_write_unlock_zone(struct scsi_cmnd *cmd)
        struct request *rq = cmd->request;
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
 
-       if (sdkp->zones_wlock) {
+       if (sdkp->zones_wlock && cmd->flags & SCMD_ZONE_WRITE_LOCK) {
                unsigned int zno = sd_zbc_zone_no(sdkp, blk_rq_pos(rq));
                WARN_ON_ONCE(!test_bit(zno, sdkp->zones_wlock));
+               cmd->flags &= ~SCMD_ZONE_WRITE_LOCK;
                clear_bit_unlock(zno, sdkp->zones_wlock);
                smp_mb__after_atomic();
        }
@@ -335,9 +339,6 @@ void sd_zbc_complete(struct scsi_cmnd *cmd,
        case REQ_OP_WRITE_ZEROES:
        case REQ_OP_WRITE_SAME:
 
-               /* Unlock the zone */
-               sd_zbc_write_unlock_zone(cmd);
-
                if (result &&
                    sshdr->sense_key == ILLEGAL_REQUEST &&
                    sshdr->asc == 0x21)
index f1cdf32..8927f9f 100644 (file)
@@ -99,7 +99,7 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
 
        ret =  scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
                                NULL, SES_TIMEOUT, SES_RETRIES, NULL);
-       if (unlikely(!ret))
+       if (unlikely(ret))
                return ret;
 
        recv_page_code = ((unsigned char *)buf)[0];
index 8e5013d..94e402e 100644 (file)
@@ -4299,11 +4299,11 @@ static int st_probe(struct device *dev)
        kref_init(&tpnt->kref);
        tpnt->disk = disk;
        disk->private_data = &tpnt->driver;
-       disk->queue = SDp->request_queue;
        /* SCSI tape doesn't register this gendisk via add_disk().  Manually
         * take queue reference that release_disk() expects. */
-       if (!blk_get_queue(disk->queue))
+       if (!blk_get_queue(SDp->request_queue))
                goto out_put_disk;
+       disk->queue = SDp->request_queue;
        tpnt->driver = &st_template;
 
        tpnt->device = SDp;
index 3039072..afc7ecc 100644 (file)
@@ -200,16 +200,11 @@ static int imx7_pgc_domain_probe(struct platform_device *pdev)
 
        domain->dev = &pdev->dev;
 
-       ret = pm_genpd_init(&domain->genpd, NULL, true);
-       if (ret) {
-               dev_err(domain->dev, "Failed to init power domain\n");
-               return ret;
-       }
-
        domain->regulator = devm_regulator_get_optional(domain->dev, "power");
        if (IS_ERR(domain->regulator)) {
                if (PTR_ERR(domain->regulator) != -ENODEV) {
-                       dev_err(domain->dev, "Failed to get domain's regulator\n");
+                       if (PTR_ERR(domain->regulator) != -EPROBE_DEFER)
+                               dev_err(domain->dev, "Failed to get domain's regulator\n");
                        return PTR_ERR(domain->regulator);
                }
        } else {
@@ -217,6 +212,12 @@ static int imx7_pgc_domain_probe(struct platform_device *pdev)
                                      domain->voltage, domain->voltage);
        }
 
+       ret = pm_genpd_init(&domain->genpd, NULL, true);
+       if (ret) {
+               dev_err(domain->dev, "Failed to init power domain\n");
+               return ret;
+       }
+
        ret = of_genpd_add_provider_simple(domain->dev->of_node,
                                           &domain->genpd);
        if (ret) {
index 279e7c5..39225de 100644 (file)
@@ -745,6 +745,9 @@ void *knav_pool_create(const char *name,
        bool slot_found;
        int ret;
 
+       if (!kdev)
+               return ERR_PTR(-EPROBE_DEFER);
+
        if (!kdev->dev)
                return ERR_PTR(-ENODEV);
 
index b0b2838..de31b93 100644 (file)
@@ -176,6 +176,8 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
 
        ti_sci_pd->dev = dev;
 
+       ti_sci_pd->pd.name = "ti_sci_pd";
+
        ti_sci_pd->pd.attach_dev = ti_sci_pd_attach_dev;
        ti_sci_pd->pd.detach_dev = ti_sci_pd_detach_dev;
 
index ca11be2..34ca782 100644 (file)
@@ -2396,6 +2396,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
                        continue;
                }
 
+               set_current_state(TASK_RUNNING);
                wp = async->buf_write_ptr;
                n1 = min(n, async->prealloc_bufsz - wp);
                n2 = n - n1;
@@ -2528,6 +2529,8 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
                        }
                        continue;
                }
+
+               set_current_state(TASK_RUNNING);
                rp = async->buf_read_ptr;
                n1 = min(n, async->prealloc_bufsz - rp);
                n2 = n - n1;
index a6a8393..3e00df7 100644 (file)
@@ -472,7 +472,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
                             long m)
 {
        struct ad2s1210_state *st = iio_priv(indio_dev);
-       bool negative;
+       u16 negative;
        int ret = 0;
        u16 pos;
        s16 vel;
index e583dd8..d4fa41b 100644 (file)
@@ -1510,11 +1510,13 @@ cxgbit_pass_open_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)
 
        if (!cnp) {
                pr_info("%s stid %d lookup failure\n", __func__, stid);
-               return;
+               goto rel_skb;
        }
 
        cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status);
        cxgbit_put_cnp(cnp);
+rel_skb:
+       __kfree_skb(skb);
 }
 
 static void
@@ -1530,11 +1532,13 @@ cxgbit_close_listsrv_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)
 
        if (!cnp) {
                pr_info("%s stid %d lookup failure\n", __func__, stid);
-               return;
+               goto rel_skb;
        }
 
        cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status);
        cxgbit_put_cnp(cnp);
+rel_skb:
+       __kfree_skb(skb);
 }
 
 static void
@@ -1819,12 +1823,16 @@ static void cxgbit_set_tcb_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)
        struct tid_info *t = lldi->tids;
 
        csk = lookup_tid(t, tid);
-       if (unlikely(!csk))
+       if (unlikely(!csk)) {
                pr_err("can't find connection for tid %u.\n", tid);
-       else
+               goto rel_skb;
+       } else {
                cxgbit_wake_up(&csk->com.wr_wait, __func__, rpl->status);
+       }
 
        cxgbit_put_csk(csk);
+rel_skb:
+       __kfree_skb(skb);
 }
 
 static void cxgbit_rx_data(struct cxgbit_device *cdev, struct sk_buff *skb)
index dda13f1..514986b 100644 (file)
@@ -827,7 +827,7 @@ cxgbit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,
 
 static void
 cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
-                     unsigned int nents)
+                     unsigned int nents, u32 skip)
 {
        struct skb_seq_state st;
        const u8 *buf;
@@ -846,7 +846,7 @@ cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
                }
 
                consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf,
-                                                buf_len, consumed);
+                                                buf_len, skip + consumed);
        }
 }
 
@@ -912,7 +912,7 @@ cxgbit_handle_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
                struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0];
                u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE));
 
-               cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents);
+               cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents, 0);
        }
 
        cmd->write_data_done += pdu_cb->dlen;
@@ -1069,11 +1069,13 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
                  cmd->se_cmd.data_length);
 
        if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) {
+               u32 skip = data_offset % PAGE_SIZE;
+
                sg_off = data_offset / PAGE_SIZE;
                sg_start = &cmd->se_cmd.t_data_sg[sg_off];
-               sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE));
+               sg_nents = max(1UL, DIV_ROUND_UP(skip + data_len, PAGE_SIZE));
 
-               cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents);
+               cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip);
        }
 
 check_payload:
index 74e4975..5001261 100644 (file)
@@ -418,6 +418,7 @@ int iscsit_reset_np_thread(
                return 0;
        }
        np->np_thread_state = ISCSI_NP_THREAD_RESET;
+       atomic_inc(&np->np_reset_count);
 
        if (np->np_thread) {
                spin_unlock_bh(&np->np_thread_lock);
@@ -2167,6 +2168,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
        cmd->cmd_sn             = be32_to_cpu(hdr->cmdsn);
        cmd->exp_stat_sn        = be32_to_cpu(hdr->exp_statsn);
        cmd->data_direction     = DMA_NONE;
+       kfree(cmd->text_in_ptr);
        cmd->text_in_ptr        = NULL;
 
        return 0;
@@ -3487,9 +3489,9 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
                return text_length;
 
        if (completed) {
-               hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+               hdr->flags = ISCSI_FLAG_CMD_FINAL;
        } else {
-               hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE;
+               hdr->flags = ISCSI_FLAG_TEXT_CONTINUE;
                cmd->read_data_done += text_length;
                if (cmd->targ_xfer_tag == 0xFFFFFFFF)
                        cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
index e9bdc8b..dc13afb 100644 (file)
@@ -1243,9 +1243,11 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
        flush_signals(current);
 
        spin_lock_bh(&np->np_thread_lock);
-       if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+       if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
                np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
+               spin_unlock_bh(&np->np_thread_lock);
                complete(&np->np_restart_comp);
+               return 1;
        } else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
                spin_unlock_bh(&np->np_thread_lock);
                goto exit;
@@ -1278,7 +1280,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
                goto exit;
        } else if (rc < 0) {
                spin_lock_bh(&np->np_thread_lock);
-               if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+               if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
+                       np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
                        spin_unlock_bh(&np->np_thread_lock);
                        complete(&np->np_restart_comp);
                        iscsit_put_transport(conn->conn_transport);
index 3691373..02e8a5d 100644 (file)
@@ -364,7 +364,7 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl)
        mutex_lock(&tpg->acl_node_mutex);
        if (acl->dynamic_node_acl)
                acl->dynamic_node_acl = 0;
-       list_del(&acl->acl_list);
+       list_del_init(&acl->acl_list);
        mutex_unlock(&tpg->acl_node_mutex);
 
        target_shutdown_sessions(acl);
@@ -548,7 +548,7 @@ int core_tpg_deregister(struct se_portal_group *se_tpg)
         * in transport_deregister_session().
         */
        list_for_each_entry_safe(nacl, nacl_tmp, &node_list, acl_list) {
-               list_del(&nacl->acl_list);
+               list_del_init(&nacl->acl_list);
 
                core_tpg_wait_for_nacl_pr_ref(nacl);
                core_free_device_list_for_node(nacl, se_tpg);
index 97fed9a..836d552 100644 (file)
@@ -466,7 +466,7 @@ static void target_complete_nacl(struct kref *kref)
        }
 
        mutex_lock(&se_tpg->acl_node_mutex);
-       list_del(&nacl->acl_list);
+       list_del_init(&nacl->acl_list);
        mutex_unlock(&se_tpg->acl_node_mutex);
 
        core_tpg_wait_for_nacl_pr_ref(nacl);
@@ -538,7 +538,7 @@ void transport_free_session(struct se_session *se_sess)
                        spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
 
                        if (se_nacl->dynamic_stop)
-                               list_del(&se_nacl->acl_list);
+                               list_del_init(&se_nacl->acl_list);
                }
                mutex_unlock(&se_tpg->acl_node_mutex);
 
index 80ee130..942d094 100644 (file)
@@ -563,8 +563,6 @@ static int scatter_data_area(struct tcmu_dev *udev,
                                        block_remaining);
                        to_offset = get_block_offset_user(udev, dbi,
                                        block_remaining);
-                       offset = DATA_BLOCK_SIZE - block_remaining;
-                       to += offset;
 
                        if (*iov_cnt != 0 &&
                            to_offset == iov_tail(*iov)) {
@@ -575,8 +573,10 @@ static int scatter_data_area(struct tcmu_dev *udev,
                                (*iov)->iov_len = copy_bytes;
                        }
                        if (copy_data) {
-                               memcpy(to, from + sg->length - sg_remaining,
-                                       copy_bytes);
+                               offset = DATA_BLOCK_SIZE - block_remaining;
+                               memcpy(to + offset,
+                                      from + sg->length - sg_remaining,
+                                      copy_bytes);
                                tcmu_flush_dcache_range(to, copy_bytes);
                        }
                        sg_remaining -= copy_bytes;
@@ -637,9 +637,8 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
                        copy_bytes = min_t(size_t, sg_remaining,
                                        block_remaining);
                        offset = DATA_BLOCK_SIZE - block_remaining;
-                       from += offset;
                        tcmu_flush_dcache_range(from, copy_bytes);
-                       memcpy(to + sg->length - sg_remaining, from,
+                       memcpy(to + sg->length - sg_remaining, from + offset,
                                        copy_bytes);
 
                        sg_remaining -= copy_bytes;
@@ -1433,6 +1432,8 @@ static int tcmu_update_uio_info(struct tcmu_dev *udev)
        if (udev->dev_config[0])
                snprintf(str + used, size - used, "/%s", udev->dev_config);
 
+       /* If the old string exists, free it */
+       kfree(info->name);
        info->name = str;
 
        return 0;
index 308b6e1..fe2f00c 100644 (file)
@@ -333,6 +333,15 @@ static int tb_drom_parse_entry_port(struct tb_switch *sw,
        int res;
        enum tb_port_type type;
 
+       /*
+        * Some DROMs list more ports than the controller actually has
+        * so we skip those but allow the parser to continue.
+        */
+       if (header->index > sw->config.max_port_number) {
+               dev_info_once(&sw->dev, "ignoring unnecessary extra entries in DROM\n");
+               return 0;
+       }
+
        port = &sw->ports[header->index];
        port->disabled = header->port_disabled;
        if (port->disabled)
index 284749f..a6d5164 100644 (file)
@@ -69,13 +69,8 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
 #ifdef CONFIG_UNIX98_PTYS
                if (tty->driver == ptm_driver) {
                        mutex_lock(&devpts_mutex);
-                       if (tty->link->driver_data) {
-                               struct path *path = tty->link->driver_data;
-
-                               devpts_pty_kill(path->dentry);
-                               path_put(path);
-                               kfree(path);
-                       }
+                       if (tty->link->driver_data)
+                               devpts_pty_kill(tty->link->driver_data);
                        mutex_unlock(&devpts_mutex);
                }
 #endif
@@ -607,25 +602,24 @@ static inline void legacy_pty_init(void) { }
 static struct cdev ptmx_cdev;
 
 /**
- *     pty_open_peer - open the peer of a pty
- *     @tty: the peer of the pty being opened
+ *     ptm_open_peer - open the peer of a pty
+ *     @master: the open struct file of the ptmx device node
+ *     @tty: the master of the pty being opened
+ *     @flags: the flags for open
  *
- *     Open the cached dentry in tty->link, providing a safe way for userspace
- *     to get the slave end of a pty (where they have the master fd and cannot
- *     access or trust the mount namespace /dev/pts was mounted inside).
+ *     Provide a race free way for userspace to open the slave end of a pty
+ *     (where they have the master fd and cannot access or trust the mount
+ *     namespace /dev/pts was mounted inside).
  */
-static struct file *pty_open_peer(struct tty_struct *tty, int flags)
-{
-       if (tty->driver->subtype != PTY_TYPE_MASTER)
-               return ERR_PTR(-EIO);
-       return dentry_open(tty->link->driver_data, flags, current_cred());
-}
-
-static int pty_get_peer(struct tty_struct *tty, int flags)
+int ptm_open_peer(struct file *master, struct tty_struct *tty, int flags)
 {
        int fd = -1;
-       struct file *filp = NULL;
+       struct file *filp;
        int retval = -EINVAL;
+       struct path path;
+
+       if (tty->driver != ptm_driver)
+               return -EIO;
 
        fd = get_unused_fd_flags(0);
        if (fd < 0) {
@@ -633,7 +627,16 @@ static int pty_get_peer(struct tty_struct *tty, int flags)
                goto err;
        }
 
-       filp = pty_open_peer(tty, flags);
+       /* Compute the slave's path */
+       path.mnt = devpts_mntget(master, tty->driver_data);
+       if (IS_ERR(path.mnt)) {
+               retval = PTR_ERR(path.mnt);
+               goto err_put;
+       }
+       path.dentry = tty->link->driver_data;
+
+       filp = dentry_open(&path, flags, current_cred());
+       mntput(path.mnt);
        if (IS_ERR(filp)) {
                retval = PTR_ERR(filp);
                goto err_put;
@@ -662,8 +665,6 @@ static int pty_unix98_ioctl(struct tty_struct *tty,
                return pty_get_pktmode(tty, (int __user *)arg);
        case TIOCGPTN: /* Get PT Number */
                return put_user(tty->index, (unsigned int __user *)arg);
-       case TIOCGPTPEER: /* Open the other end */
-               return pty_get_peer(tty, (int) arg);
        case TIOCSIG:    /* Send signal to other side of pty */
                return pty_signal(tty, (int) arg);
        }
@@ -791,7 +792,6 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 {
        struct pts_fs_info *fsi;
        struct tty_struct *tty;
-       struct path *pts_path;
        struct dentry *dentry;
        int retval;
        int index;
@@ -845,26 +845,16 @@ static int ptmx_open(struct inode *inode, struct file *filp)
                retval = PTR_ERR(dentry);
                goto err_release;
        }
-       /* We need to cache a fake path for TIOCGPTPEER. */
-       pts_path = kmalloc(sizeof(struct path), GFP_KERNEL);
-       if (!pts_path)
-               goto err_release;
-       pts_path->mnt = filp->f_path.mnt;
-       pts_path->dentry = dentry;
-       path_get(pts_path);
-       tty->link->driver_data = pts_path;
+       tty->link->driver_data = dentry;
 
        retval = ptm_driver->ops->open(tty, filp);
        if (retval)
-               goto err_path_put;
+               goto err_release;
 
        tty_debug_hangup(tty, "opening (count=%d)\n", tty->count);
 
        tty_unlock(tty);
        return 0;
-err_path_put:
-       path_put(pts_path);
-       kfree(pts_path);
 err_release:
        tty_unlock(tty);
        // This will also put-ref the fsi
index b5def35..1aab301 100644 (file)
@@ -1043,13 +1043,24 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                if (up->dl_write)
                        uart->dl_write = up->dl_write;
 
-               if (serial8250_isa_config != NULL)
-                       serial8250_isa_config(0, &uart->port,
-                                       &uart->capabilities);
+               if (uart->port.type != PORT_8250_CIR) {
+                       if (serial8250_isa_config != NULL)
+                               serial8250_isa_config(0, &uart->port,
+                                               &uart->capabilities);
+
+                       ret = uart_add_one_port(&serial8250_reg,
+                                               &uart->port);
+                       if (ret == 0)
+                               ret = uart->port.line;
+               } else {
+                       dev_info(uart->port.dev,
+                               "skipping CIR port at 0x%lx / 0x%llx, IRQ %d\n",
+                               uart->port.iobase,
+                               (unsigned long long)uart->port.mapbase,
+                               uart->port.irq);
 
-               ret = uart_add_one_port(&serial8250_reg, &uart->port);
-               if (ret == 0)
-                       ret = uart->port.line;
+                       ret = 0;
+               }
        }
        mutex_unlock(&serial_mutex);
 
index 8a857bb..1888d16 100644 (file)
@@ -142,15 +142,7 @@ static struct vendor_data vendor_sbsa = {
        .fixed_options          = true,
 };
 
-/*
- * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
- * occasionally getting stuck as 1. To avoid the potential for a hang, check
- * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
- * implementations, so only do so if an affected platform is detected in
- * parse_spcr().
- */
-static bool qdf2400_e44_present = false;
-
+#ifdef CONFIG_ACPI_SPCR_TABLE
 static struct vendor_data vendor_qdt_qdf2400_e44 = {
        .reg_offset             = pl011_std_offsets,
        .fr_busy                = UART011_FR_TXFE,
@@ -165,6 +157,7 @@ static struct vendor_data vendor_qdt_qdf2400_e44 = {
        .always_enabled         = true,
        .fixed_options          = true,
 };
+#endif
 
 static u16 pl011_st_offsets[REG_ARRAY_SIZE] = {
        [REG_DR] = UART01x_DR,
@@ -2375,12 +2368,14 @@ static int __init pl011_console_match(struct console *co, char *name, int idx,
        resource_size_t addr;
        int i;
 
-       if (strcmp(name, "qdf2400_e44") == 0) {
-               pr_info_once("UART: Working around QDF2400 SoC erratum 44");
-               qdf2400_e44_present = true;
-       } else if (strcmp(name, "pl011") != 0) {
+       /*
+        * Systems affected by the Qualcomm Technologies QDF2400 E44 erratum
+        * have a distinct console name, so make sure we check for that.
+        * The actual implementation of the erratum occurs in the probe
+        * function.
+        */
+       if ((strcmp(name, "qdf2400_e44") != 0) && (strcmp(name, "pl011") != 0))
                return -ENODEV;
-       }
 
        if (uart_parse_earlycon(options, &iotype, &addr, &options))
                return -ENODEV;
@@ -2734,11 +2729,17 @@ static int sbsa_uart_probe(struct platform_device *pdev)
        }
        uap->port.irq   = ret;
 
-       uap->reg_offset = vendor_sbsa.reg_offset;
-       uap->vendor     = qdf2400_e44_present ?
-                                       &vendor_qdt_qdf2400_e44 : &vendor_sbsa;
+#ifdef CONFIG_ACPI_SPCR_TABLE
+       if (qdf2400_e44_present) {
+               dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n");
+               uap->vendor = &vendor_qdt_qdf2400_e44;
+       } else
+#endif
+               uap->vendor = &vendor_sbsa;
+
+       uap->reg_offset = uap->vendor->reg_offset;
        uap->fifosize   = 32;
-       uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM;
+       uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM;
        uap->port.ops   = &sbsa_uart_pops;
        uap->fixed_baud = baudrate;
 
index 974b13d..10c4038 100644 (file)
@@ -2518,6 +2518,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case TIOCSSERIAL:
                tty_warn_deprecated_flags(p);
                break;
+       case TIOCGPTPEER:
+               /* Special because the struct file is needed */
+               return ptm_open_peer(file, tty, (int)arg);
        default:
                retval = tty_jobctrl_ioctl(tty, real_tty, file, cmd, arg);
                if (retval != -ENOIOCTLCMD)
index ab1bb3b..7f277b0 100644 (file)
@@ -1888,7 +1888,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
        /* No more submits can occur */
        spin_lock_irq(&hcd_urb_list_lock);
 rescan:
-       list_for_each_entry (urb, &ep->urb_list, urb_list) {
+       list_for_each_entry_reverse(urb, &ep->urb_list, urb_list) {
                int     is_in;
 
                if (urb->unlinked)
@@ -2485,6 +2485,8 @@ void usb_hc_died (struct usb_hcd *hcd)
        }
        if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) {
                hcd = hcd->shared_hcd;
+               clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
+               set_bit(HCD_FLAG_DEAD, &hcd->flags);
                if (hcd->rh_registered) {
                        clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
 
index 6e6797d..822f8c5 100644 (file)
@@ -4725,7 +4725,8 @@ hub_power_remaining(struct usb_hub *hub)
 static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
                u16 portchange)
 {
-       int status, i;
+       int status = -ENODEV;
+       int i;
        unsigned unit_load;
        struct usb_device *hdev = hub->hdev;
        struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
@@ -4929,9 +4930,10 @@ loop:
 
 done:
        hub_port_disable(hub, port1, 1);
-       if (hcd->driver->relinquish_port && !hub->hdev->parent)
-               hcd->driver->relinquish_port(hcd, port1);
-
+       if (hcd->driver->relinquish_port && !hub->hdev->parent) {
+               if (status != -ENOTCONN && status != -ENODEV)
+                       hcd->driver->relinquish_port(hcd, port1);
+       }
 }
 
 /* Handle physical or logical connection change events.
index 3116edf..574da2b 100644 (file)
@@ -150,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* appletouch */
        { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */
+       { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM },
+
        /* Avision AV600U */
        { USB_DEVICE(0x0638, 0x0a13), .driver_info =
          USB_QUIRK_STRING_FETCH_255 },
@@ -249,6 +252,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
        { USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
        { USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
        { USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
+       { USB_DEVICE(0x03f0, 0x2b4a), .driver_info = USB_QUIRK_RESET_RESUME },
 
        /* Logitech Optical Mouse M90/M100 */
        { USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
index 6b299c7..f064f15 100644 (file)
@@ -896,9 +896,40 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
                if (!node) {
                        trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
 
+                       /*
+                        * USB Specification 2.0 Section 5.9.2 states that: "If
+                        * there is only a single transaction in the microframe,
+                        * only a DATA0 data packet PID is used.  If there are
+                        * two transactions per microframe, DATA1 is used for
+                        * the first transaction data packet and DATA0 is used
+                        * for the second transaction data packet.  If there are
+                        * three transactions per microframe, DATA2 is used for
+                        * the first transaction data packet, DATA1 is used for
+                        * the second, and DATA0 is used for the third."
+                        *
+                        * IOW, we should satisfy the following cases:
+                        *
+                        * 1) length <= maxpacket
+                        *      - DATA0
+                        *
+                        * 2) maxpacket < length <= (2 * maxpacket)
+                        *      - DATA1, DATA0
+                        *
+                        * 3) (2 * maxpacket) < length <= (3 * maxpacket)
+                        *      - DATA2, DATA1, DATA0
+                        */
                        if (speed == USB_SPEED_HIGH) {
                                struct usb_ep *ep = &dep->endpoint;
-                               trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1);
+                               unsigned int mult = ep->mult - 1;
+                               unsigned int maxp = usb_endpoint_maxp(ep->desc);
+
+                               if (length <= (2 * maxp))
+                                       mult--;
+
+                               if (length <= maxp)
+                                       mult--;
+
+                               trb->size |= DWC3_TRB_SIZE_PCM1(mult);
                        }
                } else {
                        trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
index 62dc9c7..e1de8fe 100644 (file)
@@ -838,21 +838,32 @@ static struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep
        return usb3_req;
 }
 
-static void usb3_request_done(struct renesas_usb3_ep *usb3_ep,
-                             struct renesas_usb3_request *usb3_req, int status)
+static void __usb3_request_done(struct renesas_usb3_ep *usb3_ep,
+                               struct renesas_usb3_request *usb3_req,
+                               int status)
 {
        struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
-       unsigned long flags;
 
        dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n",
                usb3_ep->num, usb3_req->req.length, usb3_req->req.actual,
                status);
        usb3_req->req.status = status;
-       spin_lock_irqsave(&usb3->lock, flags);
        usb3_ep->started = false;
        list_del_init(&usb3_req->queue);
-       spin_unlock_irqrestore(&usb3->lock, flags);
+       spin_unlock(&usb3->lock);
        usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req);
+       spin_lock(&usb3->lock);
+}
+
+static void usb3_request_done(struct renesas_usb3_ep *usb3_ep,
+                             struct renesas_usb3_request *usb3_req, int status)
+{
+       struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
+       unsigned long flags;
+
+       spin_lock_irqsave(&usb3->lock, flags);
+       __usb3_request_done(usb3_ep, usb3_req, status);
+       spin_unlock_irqrestore(&usb3->lock, flags);
 }
 
 static void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3)
index 858fefd..c8f3864 100644 (file)
@@ -98,6 +98,7 @@ enum amd_chipset_gen {
        AMD_CHIPSET_HUDSON2,
        AMD_CHIPSET_BOLTON,
        AMD_CHIPSET_YANGTZE,
+       AMD_CHIPSET_TAISHAN,
        AMD_CHIPSET_UNKNOWN,
 };
 
@@ -141,6 +142,11 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo)
                        pinfo->sb_type.gen = AMD_CHIPSET_SB700;
                else if (rev >= 0x40 && rev <= 0x4f)
                        pinfo->sb_type.gen = AMD_CHIPSET_SB800;
+       }
+       pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
+                                         0x145c, NULL);
+       if (pinfo->smbus_dev) {
+               pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
        } else {
                pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
                                PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
@@ -260,11 +266,12 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
 {
        /* Make sure amd chipset type has already been initialized */
        usb_amd_find_chipset_info();
-       if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE)
-               return 0;
-
-       dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
-       return 1;
+       if (amd_chipset.sb_type.gen == AMD_CHIPSET_YANGTZE ||
+           amd_chipset.sb_type.gen == AMD_CHIPSET_TAISHAN) {
+               dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
+               return 1;
+       }
+       return 0;
 }
 EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk);
 
index 76decb8..3344ffd 100644 (file)
@@ -139,6 +139,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
                                "Could not flush host TX%d fifo: csr: %04x\n",
                                ep->epnum, csr))
                        return;
+               mdelay(1);
        }
 }
 
index 8fb86a5..3d0dd2f 100644 (file)
@@ -197,6 +197,7 @@ struct msm_otg {
        struct regulator *v3p3;
        struct regulator *v1p8;
        struct regulator *vddcx;
+       struct regulator_bulk_data supplies[3];
 
        struct reset_control *phy_rst;
        struct reset_control *link_rst;
@@ -1731,7 +1732,6 @@ static int msm_otg_reboot_notify(struct notifier_block *this,
 
 static int msm_otg_probe(struct platform_device *pdev)
 {
-       struct regulator_bulk_data regs[3];
        int ret = 0;
        struct device_node *np = pdev->dev.of_node;
        struct msm_otg_platform_data *pdata;
@@ -1817,17 +1817,18 @@ static int msm_otg_probe(struct platform_device *pdev)
                return motg->irq;
        }
 
-       regs[0].supply = "vddcx";
-       regs[1].supply = "v3p3";
-       regs[2].supply = "v1p8";
+       motg->supplies[0].supply = "vddcx";
+       motg->supplies[1].supply = "v3p3";
+       motg->supplies[2].supply = "v1p8";
 
-       ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs);
+       ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(motg->supplies),
+                                     motg->supplies);
        if (ret)
                return ret;
 
-       motg->vddcx = regs[0].consumer;
-       motg->v3p3  = regs[1].consumer;
-       motg->v1p8  = regs[2].consumer;
+       motg->vddcx = motg->supplies[0].consumer;
+       motg->v3p3  = motg->supplies[1].consumer;
+       motg->v1p8  = motg->supplies[2].consumer;
 
        clk_set_rate(motg->clk, 60000000);
 
index 93fba90..2c8161b 100644 (file)
@@ -639,14 +639,11 @@ static int usbhsg_ep_disable(struct usb_ep *ep)
        struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
        struct usbhs_pipe *pipe;
        unsigned long flags;
-       int ret = 0;
 
        spin_lock_irqsave(&uep->lock, flags);
        pipe = usbhsg_uep_to_pipe(uep);
-       if (!pipe) {
-               ret = -EINVAL;
+       if (!pipe)
                goto out;
-       }
 
        usbhsg_pipe_disable(uep);
        usbhs_pipe_free(pipe);
index d544b33..02b67ab 100644 (file)
 /* Low Power Status register (LPSTS) */
 #define LPSTS_SUSPM    0x4000
 
-/* USB General control register 2 (UGCTRL2), bit[31:6] should be 0 */
+/*
+ * USB General control register 2 (UGCTRL2)
+ * Remarks: bit[31:11] and bit[9:6] should be 0
+ */
 #define UGCTRL2_RESERVED_3     0x00000001      /* bit[3:0] should be B'0001 */
 #define UGCTRL2_USB0SEL_OTG    0x00000030
+#define UGCTRL2_VBUSSEL                0x00000400
 
 static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data)
 {
@@ -34,7 +38,8 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
 {
        struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
 
-       usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG);
+       usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG |
+                     UGCTRL2_VBUSSEL);
 
        if (enable) {
                usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
index f64e914..2d945c9 100644 (file)
@@ -142,6 +142,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
        { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
        { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
+       { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
index ebe51f1..fe12315 100644 (file)
@@ -2025,6 +2025,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) },                   /* D-Link DWM-158 */
        { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff),                     /* D-Link DWM-221 B1 */
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff),                     /* D-Link DWM-222 */
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
index c9ebefd..a585b47 100644 (file)
@@ -52,6 +52,8 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID),
                .driver_info = PL2303_QUIRK_ENDPOINT_HACK },
+       { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_UC485),
+               .driver_info = PL2303_QUIRK_ENDPOINT_HACK },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) },
        { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
        { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
index 09d9be8..3b5a15d 100644 (file)
@@ -27,6 +27,7 @@
 #define ATEN_VENDOR_ID         0x0557
 #define ATEN_VENDOR_ID2                0x0547
 #define ATEN_PRODUCT_ID                0x2008
+#define ATEN_PRODUCT_UC485     0x2021
 #define ATEN_PRODUCT_ID2       0x2118
 
 #define IODATA_VENDOR_ID       0x04bb
index cbea9f3..cde1153 100644 (file)
@@ -124,9 +124,9 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
 /* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
 UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
                "Initio Corporation",
-               "",
+               "INIC-3069",
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-               US_FL_NO_ATA_1X),
+               US_FL_NO_ATA_1X | US_FL_IGNORE_RESIDUE),
 
 /* Reported-by: Tom Arild Naess <tanaess@gmail.com> */
 UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999,
index 0661593..0dceb9f 100644 (file)
@@ -315,6 +315,7 @@ static int usb_stor_control_thread(void * __us)
 {
        struct us_data *us = (struct us_data *)__us;
        struct Scsi_Host *host = us_to_host(us);
+       struct scsi_cmnd *srb;
 
        for (;;) {
                usb_stor_dbg(us, "*** thread sleeping\n");
@@ -330,6 +331,7 @@ static int usb_stor_control_thread(void * __us)
                scsi_lock(host);
 
                /* When we are called with no command pending, we're done */
+               srb = us->srb;
                if (us->srb == NULL) {
                        scsi_unlock(host);
                        mutex_unlock(&us->dev_mutex);
@@ -398,14 +400,11 @@ static int usb_stor_control_thread(void * __us)
                /* lock access to the state */
                scsi_lock(host);
 
-               /* indicate that the command is done */
-               if (us->srb->result != DID_ABORT << 16) {
-                       usb_stor_dbg(us, "scsi cmd done, result=0x%x\n",
-                                    us->srb->result);
-                       us->srb->scsi_done(us->srb);
-               } else {
+               /* was the command aborted? */
+               if (us->srb->result == DID_ABORT << 16) {
 SkipForAbort:
                        usb_stor_dbg(us, "scsi command aborted\n");
+                       srb = NULL;     /* Don't call srb->scsi_done() */
                }
 
                /*
@@ -429,6 +428,13 @@ SkipForAbort:
 
                /* unlock the device pointers */
                mutex_unlock(&us->dev_mutex);
+
+               /* now that the locks are released, notify the SCSI core */
+               if (srb) {
+                       usb_stor_dbg(us, "scsi cmd done, result=0x%x\n",
+                                       srb->result);
+                       srb->scsi_done(srb);
+               }
        } /* for (;;) */
 
        /* Wait until we are told to stop */
index ff01bed..1e784ad 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/efi.h>
 
 static bool request_mem_succeeded = false;
+static bool nowc = false;
 
 static struct fb_var_screeninfo efifb_defined = {
        .activate               = FB_ACTIVATE_NOW,
@@ -99,6 +100,8 @@ static int efifb_setup(char *options)
                                screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
                        else if (!strncmp(this_opt, "width:", 6))
                                screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
+                       else if (!strcmp(this_opt, "nowc"))
+                               nowc = true;
                }
        }
 
@@ -255,7 +258,10 @@ static int efifb_probe(struct platform_device *dev)
        info->apertures->ranges[0].base = efifb_fix.smem_start;
        info->apertures->ranges[0].size = size_remap;
 
-       info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
+       if (nowc)
+               info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
+       else
+               info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
        if (!info->screen_base) {
                pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
                        efifb_fix.smem_len, efifb_fix.smem_start);
index c166e07..ba82f97 100644 (file)
@@ -1073,20 +1073,16 @@ static int imxfb_remove(struct platform_device *pdev)
        imxfb_disable_controller(fbi);
 
        unregister_framebuffer(info);
-
+       fb_dealloc_cmap(&info->cmap);
        pdata = dev_get_platdata(&pdev->dev);
        if (pdata && pdata->exit)
                pdata->exit(fbi->pdev);
-
-       fb_dealloc_cmap(&info->cmap);
-       kfree(info->pseudo_palette);
-       framebuffer_release(info);
-
        dma_free_wc(&pdev->dev, fbi->map_size, info->screen_base,
                    fbi->map_dma);
-
        iounmap(fbi->regs);
        release_mem_region(res->start, resource_size(res));
+       kfree(info->pseudo_palette);
+       framebuffer_release(info);
 
        return 0;
 }
index eecf695..09e5bb0 100644 (file)
@@ -193,7 +193,6 @@ static struct notifier_block omap_dss_pm_notif_block = {
 
 static int __init omap_dss_probe(struct platform_device *pdev)
 {
-       struct omap_dss_board_info *pdata = pdev->dev.platform_data;
        int r;
 
        core.pdev = pdev;
index 8feab81..7f188b8 100644 (file)
@@ -7,9 +7,6 @@ obj-y   += xenbus/
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_features.o                      := $(nostackp)
 
-CFLAGS_efi.o                           += -fshort-wchar
-LDFLAGS                                        += $(call ld-option, --no-wchar-size-warning)
-
 dom0-$(CONFIG_ARM64) += arm-device.o
 dom0-$(CONFIG_PCI) += pci.o
 dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
index 4da69db..1bdd02a 100644 (file)
@@ -10,8 +10,7 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
        unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
        unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
 
-       return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
-               ((bfn1 == bfn2) || ((bfn1+1) == bfn2));
+       return bfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == bfn2;
 #else
        /*
         * XXX: Add support for merging bio_vec when using different page
index bae1f5d..2d43118 100644 (file)
@@ -574,7 +574,7 @@ static void shutdown_pirq(struct irq_data *data)
 
 static void enable_pirq(struct irq_data *data)
 {
-       startup_pirq(data);
+       enable_dynirq(data);
 }
 
 static void disable_pirq(struct irq_data *data)
index e460802..3e59590 100644 (file)
@@ -857,6 +857,8 @@ static int xenwatch_thread(void *unused)
        struct list_head *ent;
        struct xs_watch_event *event;
 
+       xenwatch_pid = current->pid;
+
        for (;;) {
                wait_event_interruptible(watch_events_waitq,
                                         !list_empty(&watch_events));
@@ -925,7 +927,6 @@ int xs_init(void)
        task = kthread_run(xenwatch_thread, NULL, "xenwatch");
        if (IS_ERR(task))
                return PTR_ERR(task);
-       xenwatch_pid = task->pid;
 
        /* shutdown watches for kexec boot */
        xs_reset_watches();
index 879ff9c..6466153 100644 (file)
@@ -664,8 +664,7 @@ static unsigned long randomize_stack_top(unsigned long stack_top)
 {
        unsigned long random_variable = 0;
 
-       if ((current->flags & PF_RANDOMIZE) &&
-               !(current->personality & ADDR_NO_RANDOMIZE)) {
+       if (current->flags & PF_RANDOMIZE) {
                random_variable = get_random_long();
                random_variable &= STACK_RND_MASK;
                random_variable <<= PAGE_SHIFT;
index 080e2eb..f45b61f 100644 (file)
@@ -3516,7 +3516,7 @@ static blk_status_t wait_dev_flush(struct btrfs_device *device)
        struct bio *bio = device->flush_bio;
 
        if (!device->flush_bio_sent)
-               return 0;
+               return BLK_STS_OK;
 
        device->flush_bio_sent = 0;
        wait_for_completion_io(&device->flush_wait);
@@ -3563,7 +3563,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
                        continue;
 
                write_dev_flush(dev);
-               dev->last_flush_error = 0;
+               dev->last_flush_error = BLK_STS_OK;
        }
 
        /* wait for all the barriers */
index 95c2120..24bcd5c 100644 (file)
@@ -7924,11 +7924,12 @@ err:
        return ret;
 }
 
-static inline int submit_dio_repair_bio(struct inode *inode, struct bio *bio,
-                                       int mirror_num)
+static inline blk_status_t submit_dio_repair_bio(struct inode *inode,
+                                                struct bio *bio,
+                                                int mirror_num)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       int ret;
+       blk_status_t ret;
 
        BUG_ON(bio_op(bio) == REQ_OP_WRITE);
 
@@ -7980,10 +7981,10 @@ static int btrfs_check_dio_repairable(struct inode *inode,
        return 1;
 }
 
-static int dio_read_error(struct inode *inode, struct bio *failed_bio,
-                       struct page *page, unsigned int pgoff,
-                       u64 start, u64 end, int failed_mirror,
-                       bio_end_io_t *repair_endio, void *repair_arg)
+static blk_status_t dio_read_error(struct inode *inode, struct bio *failed_bio,
+                                  struct page *page, unsigned int pgoff,
+                                  u64 start, u64 end, int failed_mirror,
+                                  bio_end_io_t *repair_endio, void *repair_arg)
 {
        struct io_failure_record *failrec;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
@@ -7993,18 +7994,19 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
        int read_mode = 0;
        int segs;
        int ret;
+       blk_status_t status;
 
        BUG_ON(bio_op(failed_bio) == REQ_OP_WRITE);
 
        ret = btrfs_get_io_failure_record(inode, start, end, &failrec);
        if (ret)
-               return ret;
+               return errno_to_blk_status(ret);
 
        ret = btrfs_check_dio_repairable(inode, failed_bio, failrec,
                                         failed_mirror);
        if (!ret) {
                free_io_failure(failure_tree, io_tree, failrec);
-               return -EIO;
+               return BLK_STS_IOERR;
        }
 
        segs = bio_segments(failed_bio);
@@ -8022,13 +8024,13 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
                    "Repair DIO Read Error: submitting new dio read[%#x] to this_mirror=%d, in_validation=%d\n",
                    read_mode, failrec->this_mirror, failrec->in_validation);
 
-       ret = submit_dio_repair_bio(inode, bio, failrec->this_mirror);
-       if (ret) {
+       status = submit_dio_repair_bio(inode, bio, failrec->this_mirror);
+       if (status) {
                free_io_failure(failure_tree, io_tree, failrec);
                bio_put(bio);
        }
 
-       return ret;
+       return status;
 }
 
 struct btrfs_retry_complete {
@@ -8065,8 +8067,8 @@ end:
        bio_put(bio);
 }
 
-static int __btrfs_correct_data_nocsum(struct inode *inode,
-                                      struct btrfs_io_bio *io_bio)
+static blk_status_t __btrfs_correct_data_nocsum(struct inode *inode,
+                                               struct btrfs_io_bio *io_bio)
 {
        struct btrfs_fs_info *fs_info;
        struct bio_vec bvec;
@@ -8076,8 +8078,8 @@ static int __btrfs_correct_data_nocsum(struct inode *inode,
        unsigned int pgoff;
        u32 sectorsize;
        int nr_sectors;
-       int ret;
-       int err = 0;
+       blk_status_t ret;
+       blk_status_t err = BLK_STS_OK;
 
        fs_info = BTRFS_I(inode)->root->fs_info;
        sectorsize = fs_info->sectorsize;
@@ -8183,11 +8185,12 @@ static blk_status_t __btrfs_subio_endio_read(struct inode *inode,
        int csum_pos;
        bool uptodate = (err == 0);
        int ret;
+       blk_status_t status;
 
        fs_info = BTRFS_I(inode)->root->fs_info;
        sectorsize = fs_info->sectorsize;
 
-       err = 0;
+       err = BLK_STS_OK;
        start = io_bio->logical;
        done.inode = inode;
        io_bio->bio.bi_iter = io_bio->iter;
@@ -8209,12 +8212,12 @@ try_again:
                done.start = start;
                init_completion(&done.done);
 
-               ret = dio_read_error(inode, &io_bio->bio, bvec.bv_page,
-                               pgoff, start, start + sectorsize - 1,
-                               io_bio->mirror_num,
-                               btrfs_retry_endio, &done);
-               if (ret) {
-                       err = errno_to_blk_status(ret);
+               status = dio_read_error(inode, &io_bio->bio, bvec.bv_page,
+                                       pgoff, start, start + sectorsize - 1,
+                                       io_bio->mirror_num, btrfs_retry_endio,
+                                       &done);
+               if (status) {
+                       err = status;
                        goto next;
                }
 
@@ -8250,7 +8253,7 @@ static blk_status_t btrfs_subio_endio_read(struct inode *inode,
                if (unlikely(err))
                        return __btrfs_correct_data_nocsum(inode, io_bio);
                else
-                       return 0;
+                       return BLK_STS_OK;
        } else {
                return __btrfs_subio_endio_read(inode, io_bio, err);
        }
@@ -8423,9 +8426,9 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode,
        return 0;
 }
 
-static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
-                                        u64 file_offset, int skip_sum,
-                                        int async_submit)
+static inline blk_status_t
+__btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, u64 file_offset,
+                      int skip_sum, int async_submit)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_dio_private *dip = bio->bi_private;
@@ -8488,6 +8491,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip,
        int clone_offset = 0;
        int clone_len;
        int ret;
+       blk_status_t status;
 
        map_length = orig_bio->bi_iter.bi_size;
        submit_len = map_length;
@@ -8537,9 +8541,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip,
                 */
                atomic_inc(&dip->pending_bios);
 
-               ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum,
-                                            async_submit);
-               if (ret) {
+               status = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum,
+                                               async_submit);
+               if (status) {
                        bio_put(bio);
                        atomic_dec(&dip->pending_bios);
                        goto out_err;
@@ -8557,9 +8561,9 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip,
        } while (submit_len > 0);
 
 submit:
-       ret = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum,
-                                    async_submit);
-       if (!ret)
+       status = __btrfs_submit_dio_bio(bio, inode, file_offset, skip_sum,
+                                       async_submit);
+       if (!status)
                return 0;
 
        bio_put(bio);
index 2086383..2cf6ba4 100644 (file)
@@ -905,7 +905,7 @@ static void raid_write_end_io(struct bio *bio)
        if (!atomic_dec_and_test(&rbio->stripes_pending))
                return;
 
-       err = 0;
+       err = BLK_STS_OK;
 
        /* OK, we have read all the stripes we need to. */
        max_errors = (rbio->operation == BTRFS_RBIO_PARITY_SCRUB) ?
@@ -1324,7 +1324,7 @@ write_data:
        return;
 
 cleanup:
-       rbio_orig_end_io(rbio, -EIO);
+       rbio_orig_end_io(rbio, BLK_STS_IOERR);
 }
 
 /*
@@ -1475,7 +1475,7 @@ static void raid_rmw_end_io(struct bio *bio)
 
 cleanup:
 
-       rbio_orig_end_io(rbio, -EIO);
+       rbio_orig_end_io(rbio, BLK_STS_IOERR);
 }
 
 static void async_rmw_stripe(struct btrfs_raid_bio *rbio)
@@ -1579,7 +1579,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
        return 0;
 
 cleanup:
-       rbio_orig_end_io(rbio, -EIO);
+       rbio_orig_end_io(rbio, BLK_STS_IOERR);
        return -EIO;
 
 finish:
@@ -1795,12 +1795,12 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
        void **pointers;
        int faila = -1, failb = -1;
        struct page *page;
-       int err;
+       blk_status_t err;
        int i;
 
        pointers = kcalloc(rbio->real_stripes, sizeof(void *), GFP_NOFS);
        if (!pointers) {
-               err = -ENOMEM;
+               err = BLK_STS_RESOURCE;
                goto cleanup_io;
        }
 
@@ -1856,7 +1856,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
                                         * a bad data or Q stripe.
                                         * TODO, we should redo the xor here.
                                         */
-                                       err = -EIO;
+                                       err = BLK_STS_IOERR;
                                        goto cleanup;
                                }
                                /*
@@ -1882,7 +1882,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio)
                        if (rbio->bbio->raid_map[failb] == RAID6_Q_STRIPE) {
                                if (rbio->bbio->raid_map[faila] ==
                                    RAID5_P_STRIPE) {
-                                       err = -EIO;
+                                       err = BLK_STS_IOERR;
                                        goto cleanup;
                                }
                                /*
@@ -1954,13 +1954,13 @@ pstripe:
                }
        }
 
-       err = 0;
+       err = BLK_STS_OK;
 cleanup:
        kfree(pointers);
 
 cleanup_io:
        if (rbio->operation == BTRFS_RBIO_READ_REBUILD) {
-               if (err == 0)
+               if (err == BLK_STS_OK)
                        cache_rbio_pages(rbio);
                else
                        clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
@@ -1968,7 +1968,7 @@ cleanup_io:
                rbio_orig_end_io(rbio, err);
        } else if (rbio->operation == BTRFS_RBIO_REBUILD_MISSING) {
                rbio_orig_end_io(rbio, err);
-       } else if (err == 0) {
+       } else if (err == BLK_STS_OK) {
                rbio->faila = -1;
                rbio->failb = -1;
 
@@ -2005,7 +2005,7 @@ static void raid_recover_end_io(struct bio *bio)
                return;
 
        if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
-               rbio_orig_end_io(rbio, -EIO);
+               rbio_orig_end_io(rbio, BLK_STS_IOERR);
        else
                __raid_recover_end_io(rbio);
 }
@@ -2104,7 +2104,7 @@ out:
 cleanup:
        if (rbio->operation == BTRFS_RBIO_READ_REBUILD ||
            rbio->operation == BTRFS_RBIO_REBUILD_MISSING)
-               rbio_orig_end_io(rbio, -EIO);
+               rbio_orig_end_io(rbio, BLK_STS_IOERR);
        return -EIO;
 }
 
@@ -2431,7 +2431,7 @@ submit_write:
        nr_data = bio_list_size(&bio_list);
        if (!nr_data) {
                /* Every parity is right */
-               rbio_orig_end_io(rbio, 0);
+               rbio_orig_end_io(rbio, BLK_STS_OK);
                return;
        }
 
@@ -2451,7 +2451,7 @@ submit_write:
        return;
 
 cleanup:
-       rbio_orig_end_io(rbio, -EIO);
+       rbio_orig_end_io(rbio, BLK_STS_IOERR);
 }
 
 static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe)
@@ -2519,7 +2519,7 @@ static void validate_rbio_for_parity_scrub(struct btrfs_raid_bio *rbio)
        return;
 
 cleanup:
-       rbio_orig_end_io(rbio, -EIO);
+       rbio_orig_end_io(rbio, BLK_STS_IOERR);
 }
 
 /*
@@ -2633,7 +2633,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
        return;
 
 cleanup:
-       rbio_orig_end_io(rbio, -EIO);
+       rbio_orig_end_io(rbio, BLK_STS_IOERR);
        return;
 
 finish:
index e8b9a26..bd679bc 100644 (file)
@@ -6212,8 +6212,8 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
        }
 }
 
-int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
-                 int mirror_num, int async_submit)
+blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
+                          int mirror_num, int async_submit)
 {
        struct btrfs_device *dev;
        struct bio *first_bio = bio;
@@ -6233,7 +6233,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
                                &map_length, &bbio, mirror_num, 1);
        if (ret) {
                btrfs_bio_counter_dec(fs_info);
-               return ret;
+               return errno_to_blk_status(ret);
        }
 
        total_devs = bbio->num_stripes;
@@ -6256,7 +6256,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
                }
 
                btrfs_bio_counter_dec(fs_info);
-               return ret;
+               return errno_to_blk_status(ret);
        }
 
        if (map_length < length) {
@@ -6283,7 +6283,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
                                  dev_nr, async_submit);
        }
        btrfs_bio_counter_dec(fs_info);
-       return 0;
+       return BLK_STS_OK;
 }
 
 struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid,
index 6f45fd6..93277fc 100644 (file)
@@ -74,7 +74,7 @@ struct btrfs_device {
        int missing;
        int can_discard;
        int is_tgtdev_for_dev_replace;
-       int last_flush_error;
+       blk_status_t last_flush_error;
        int flush_bio_sent;
 
 #ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED
@@ -416,8 +416,8 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                      struct btrfs_fs_info *fs_info, u64 type);
 void btrfs_mapping_init(struct btrfs_mapping_tree *tree);
 void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree);
-int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
-                 int mirror_num, int async_submit);
+blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
+                          int mirror_num, int async_submit);
 int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                       fmode_t flags, void *holder);
 int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
index 108df2e..7eae33f 100644 (file)
@@ -133,6 +133,50 @@ static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb)
        return sb->s_fs_info;
 }
 
+static int devpts_ptmx_path(struct path *path)
+{
+       struct super_block *sb;
+       int err;
+
+       /* Has the devpts filesystem already been found? */
+       if (path->mnt->mnt_sb->s_magic == DEVPTS_SUPER_MAGIC)
+               return 0;
+
+       /* Is a devpts filesystem at "pts" in the same directory? */
+       err = path_pts(path);
+       if (err)
+               return err;
+
+       /* Is the path the root of a devpts filesystem? */
+       sb = path->mnt->mnt_sb;
+       if ((sb->s_magic != DEVPTS_SUPER_MAGIC) ||
+           (path->mnt->mnt_root != sb->s_root))
+               return -ENODEV;
+
+       return 0;
+}
+
+struct vfsmount *devpts_mntget(struct file *filp, struct pts_fs_info *fsi)
+{
+       struct path path;
+       int err;
+
+       path = filp->f_path;
+       path_get(&path);
+
+       err = devpts_ptmx_path(&path);
+       dput(path.dentry);
+       if (err) {
+               mntput(path.mnt);
+               path.mnt = ERR_PTR(err);
+       }
+       if (DEVPTS_SB(path.mnt->mnt_sb) != fsi) {
+               mntput(path.mnt);
+               path.mnt = ERR_PTR(-ENODEV);
+       }
+       return path.mnt;
+}
+
 struct pts_fs_info *devpts_acquire(struct file *filp)
 {
        struct pts_fs_info *result;
@@ -143,27 +187,16 @@ struct pts_fs_info *devpts_acquire(struct file *filp)
        path = filp->f_path;
        path_get(&path);
 
-       /* Has the devpts filesystem already been found? */
-       sb = path.mnt->mnt_sb;
-       if (sb->s_magic != DEVPTS_SUPER_MAGIC) {
-               /* Is a devpts filesystem at "pts" in the same directory? */
-               err = path_pts(&path);
-               if (err) {
-                       result = ERR_PTR(err);
-                       goto out;
-               }
-
-               /* Is the path the root of a devpts filesystem? */
-               result = ERR_PTR(-ENODEV);
-               sb = path.mnt->mnt_sb;
-               if ((sb->s_magic != DEVPTS_SUPER_MAGIC) ||
-                   (path.mnt->mnt_root != sb->s_root))
-                       goto out;
+       err = devpts_ptmx_path(&path);
+       if (err) {
+               result = ERR_PTR(err);
+               goto out;
        }
 
        /*
         * pty code needs to hold extra references in case of last /dev/tty close
         */
+       sb = path.mnt->mnt_sb;
        atomic_inc(&sb->s_active);
        result = DEVPTS_SB(sb);
 
index 5a10526..7010856 100644 (file)
@@ -2300,7 +2300,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
                                             EXT4_MAX_BLOCK_LOG_SIZE);
        struct sg {
                struct ext4_group_info info;
-               ext4_grpblk_t counters[blocksize_bits + 2];
+               ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2];
        } sg;
 
        group--;
@@ -2309,6 +2309,9 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
                              " 2^0   2^1   2^2   2^3   2^4   2^5   2^6  "
                              " 2^7   2^8   2^9   2^10  2^11  2^12  2^13  ]\n");
 
+       i = (blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) +
+               sizeof(struct ext4_group_info);
+
        grinfo = ext4_get_group_info(sb, group);
        /* Load the group info in memory only if not already loaded. */
        if (unlikely(EXT4_MB_GRP_NEED_INIT(grinfo))) {
@@ -2320,7 +2323,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
                buddy_loaded = 1;
        }
 
-       memcpy(&sg, ext4_get_group_info(sb, group), sizeof(sg));
+       memcpy(&sg, ext4_get_group_info(sb, group), i);
 
        if (buddy_loaded)
                ext4_mb_unload_buddy(&e4b);
index 82a5af9..3dd9701 100644 (file)
@@ -1543,7 +1543,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
                        /* Clear padding bytes. */
                        memset(val + i->value_len, 0, new_size - i->value_len);
                }
-               return 0;
+               goto update_hash;
        }
 
        /* Compute min_offs and last. */
@@ -1707,6 +1707,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
                here->e_value_size = cpu_to_le32(i->value_len);
        }
 
+update_hash:
        if (i->value) {
                __le32 hash = 0;
 
@@ -1725,7 +1726,8 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
                                                     here->e_name_len,
                                                     &crc32c_hash, 1);
                } else if (is_block) {
-                       __le32 *value = s->base + min_offs - new_size;
+                       __le32 *value = s->base + le16_to_cpu(
+                                                       here->e_value_offs);
 
                        hash = ext4_xattr_hash_entry(here->e_name,
                                                     here->e_name_len, value,
index 3ee4fdc..ab60051 100644 (file)
@@ -46,7 +46,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
 {
        struct fuse_file *ff;
 
-       ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+       ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL);
        if (unlikely(!ff))
                return NULL;
 
@@ -609,7 +609,7 @@ static void fuse_aio_complete_req(struct fuse_conn *fc, struct fuse_req *req)
        struct fuse_io_priv *io = req->io;
        ssize_t pos = -1;
 
-       fuse_release_user_pages(req, !io->write);
+       fuse_release_user_pages(req, io->should_dirty);
 
        if (io->write) {
                if (req->misc.write.in.size != req->misc.write.out.size)
@@ -1316,7 +1316,6 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                       loff_t *ppos, int flags)
 {
        int write = flags & FUSE_DIO_WRITE;
-       bool should_dirty = !write && iter_is_iovec(iter);
        int cuse = flags & FUSE_DIO_CUSE;
        struct file *file = io->file;
        struct inode *inode = file->f_mapping->host;
@@ -1346,6 +1345,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                        inode_unlock(inode);
        }
 
+       io->should_dirty = !write && iter_is_iovec(iter);
        while (count) {
                size_t nres;
                fl_owner_t owner = current->files;
@@ -1360,7 +1360,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                        nres = fuse_send_read(req, io, pos, nbytes, owner);
 
                if (!io->async)
-                       fuse_release_user_pages(req, should_dirty);
+                       fuse_release_user_pages(req, io->should_dirty);
                if (req->out.h.error) {
                        err = req->out.h.error;
                        break;
@@ -1669,6 +1669,7 @@ err_nofile:
 err_free:
        fuse_request_free(req);
 err:
+       mapping_set_error(page->mapping, error);
        end_page_writeback(page);
        return error;
 }
index 1bd7ffd..bd4d2a3 100644 (file)
@@ -249,6 +249,7 @@ struct fuse_io_priv {
        size_t size;
        __u64 offset;
        bool write;
+       bool should_dirty;
        int err;
        struct kiocb *iocb;
        struct file *file;
index 0392661..59cc98a 100644 (file)
@@ -278,7 +278,7 @@ iomap_dirty_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
                unsigned long bytes;    /* Bytes to write to page */
 
                offset = (pos & (PAGE_SIZE - 1));
-               bytes = min_t(unsigned long, PAGE_SIZE - offset, length);
+               bytes = min_t(loff_t, PAGE_SIZE - offset, length);
 
                rpage = __iomap_read_page(inode, pos);
                if (IS_ERR(rpage))
@@ -373,7 +373,7 @@ iomap_zero_range_actor(struct inode *inode, loff_t pos, loff_t count,
                unsigned offset, bytes;
 
                offset = pos & (PAGE_SIZE - 1); /* Within page */
-               bytes = min_t(unsigned, PAGE_SIZE - offset, count);
+               bytes = min_t(loff_t, PAGE_SIZE - offset, count);
 
                if (IS_DAX(inode))
                        status = iomap_dax_zero(pos, offset, bytes, iomap);
index 69d02cf..5f93cfa 100644 (file)
@@ -121,6 +121,7 @@ config PNFS_FILE_LAYOUT
 config PNFS_BLOCK
        tristate
        depends on NFS_V4_1 && BLK_DEV_DM
+       depends on 64BIT || LBDAF
        default NFS_V4
 
 config PNFS_FLEXFILE_LAYOUT
index 6df7a0c..f32c58b 100644 (file)
@@ -32,6 +32,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds)
 {
        nfs4_print_deviceid(&mirror_ds->id_node.deviceid);
        nfs4_pnfs_ds_put(mirror_ds->ds);
+       kfree(mirror_ds->ds_versions);
        kfree_rcu(mirror_ds, id_node.rcu);
 }
 
index ffd2e71..d901326 100644 (file)
@@ -2553,9 +2553,8 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
                clear_bit(NFS_O_RDWR_STATE, &state->flags);
                clear_bit(NFS_OPEN_STATE, &state->flags);
                stateid->type = NFS4_INVALID_STATEID_TYPE;
-       }
-       if (status != NFS_OK)
                return status;
+       }
        if (nfs_open_stateid_recover_openmode(state))
                return -NFS4ERR_OPENMODE;
        return NFS_OK;
index 53a1749..566e6ef 100644 (file)
@@ -1124,6 +1124,10 @@ void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
                WARN_ON_ONCE(1);
                dquot->dq_dqb.dqb_rsvspace = 0;
        }
+       if (dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace <=
+           dquot->dq_dqb.dqb_bsoftlimit)
+               dquot->dq_dqb.dqb_btime = (time64_t) 0;
+       clear_bit(DQ_BLKS_B, &dquot->dq_flags);
 }
 
 static void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
@@ -1145,7 +1149,8 @@ static void dquot_decr_space(struct dquot *dquot, qsize_t number)
                dquot->dq_dqb.dqb_curspace -= number;
        else
                dquot->dq_dqb.dqb_curspace = 0;
-       if (dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit)
+       if (dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace <=
+           dquot->dq_dqb.dqb_bsoftlimit)
                dquot->dq_dqb.dqb_btime = (time64_t) 0;
        clear_bit(DQ_BLKS_B, &dquot->dq_flags);
 }
@@ -1381,14 +1386,18 @@ static int info_idq_free(struct dquot *dquot, qsize_t inodes)
 
 static int info_bdq_free(struct dquot *dquot, qsize_t space)
 {
+       qsize_t tspace;
+
+       tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace;
+
        if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
-           dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit)
+           tspace <= dquot->dq_dqb.dqb_bsoftlimit)
                return QUOTA_NL_NOWARN;
 
-       if (dquot->dq_dqb.dqb_curspace - space <= dquot->dq_dqb.dqb_bsoftlimit)
+       if (tspace - space <= dquot->dq_dqb.dqb_bsoftlimit)
                return QUOTA_NL_BSOFTBELOW;
-       if (dquot->dq_dqb.dqb_curspace >= dquot->dq_dqb.dqb_bhardlimit &&
-           dquot->dq_dqb.dqb_curspace - space < dquot->dq_dqb.dqb_bhardlimit)
+       if (tspace >= dquot->dq_dqb.dqb_bhardlimit &&
+           tspace - space < dquot->dq_dqb.dqb_bhardlimit)
                return QUOTA_NL_BHARDBELOW;
        return QUOTA_NL_NOWARN;
 }
@@ -2681,7 +2690,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
 
        if (check_blim) {
                if (!dm->dqb_bsoftlimit ||
-                   dm->dqb_curspace < dm->dqb_bsoftlimit) {
+                   dm->dqb_curspace + dm->dqb_rsvspace < dm->dqb_bsoftlimit) {
                        dm->dqb_btime = 0;
                        clear_bit(DQ_BLKS_B, &dquot->dq_flags);
                } else if (!(di->d_fieldmask & QC_SPC_TIMER))
index ffd5a15..abf5bea 100644 (file)
@@ -1246,13 +1246,13 @@ xfs_dialloc_ag_inobt(
 
                        /* free inodes to the left? */
                        if (useleft && trec.ir_freecount) {
-                               rec = trec;
                                xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
                                cur = tcur;
 
                                pag->pagl_leftrec = trec.ir_startino;
                                pag->pagl_rightrec = rec.ir_startino;
                                pag->pagl_pagino = pagino;
+                               rec = trec;
                                goto alloc_inode;
                        }
 
index 0053bcf..4ebd0ba 100644 (file)
@@ -749,9 +749,20 @@ xfs_log_mount_finish(
                return 0;
        }
 
+       /*
+        * During the second phase of log recovery, we need iget and
+        * iput to behave like they do for an active filesystem.
+        * xfs_fs_drop_inode needs to be able to prevent the deletion
+        * of inodes before we're done replaying log items on those
+        * inodes.  Turn it off immediately after recovery finishes
+        * so that we don't leak the quota inodes if subsequent mount
+        * activities fail.
+        */
+       mp->m_super->s_flags |= MS_ACTIVE;
        error = xlog_recover_finish(mp->m_log);
        if (!error)
                xfs_log_work_queue(mp);
+       mp->m_super->s_flags &= ~MS_ACTIVE;
 
        return error;
 }
index 40d4e8b..ea7d4b4 100644 (file)
@@ -945,15 +945,6 @@ xfs_mountfs(
        }
 
        /*
-        * During the second phase of log recovery, we need iget and
-        * iput to behave like they do for an active filesystem.
-        * xfs_fs_drop_inode needs to be able to prevent the deletion
-        * of inodes before we're done replaying log items on those
-        * inodes.
-        */
-       mp->m_super->s_flags |= MS_ACTIVE;
-
-       /*
         * Finish recovering the file system.  This part needed to be delayed
         * until after the root and real-time bitmap inodes were consistently
         * read in.
@@ -1028,12 +1019,13 @@ xfs_mountfs(
  out_quota:
        xfs_qm_unmount_quotas(mp);
  out_rtunmount:
-       mp->m_super->s_flags &= ~MS_ACTIVE;
        xfs_rtunmount_inodes(mp);
  out_rele_rip:
        IRELE(rip);
        cancel_delayed_work_sync(&mp->m_reclaim_work);
        xfs_reclaim_inodes(mp, SYNC_WAIT);
+       /* Clean out dquots that might be in memory after quotacheck. */
+       xfs_qm_unmount(mp);
  out_log_dealloc:
        mp->m_flags |= XFS_MOUNT_UNMOUNTING;
        xfs_log_mount_cancel(mp);
index da0be9a..9623d78 100644 (file)
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
 /*
+ * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections, which
+ * generates .data.identifier sections, which need to be pulled in with
+ * .data. We don't want to pull in .data..other sections, which Linux
+ * has defined. Same for text and bss.
+ */
+#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
+#define TEXT_MAIN .text .text.[0-9a-zA-Z_]*
+#define DATA_MAIN .data .data.[0-9a-zA-Z_]*
+#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]*
+#else
+#define TEXT_MAIN .text
+#define DATA_MAIN .data
+#define BSS_MAIN .bss
+#endif
+
+/*
  * Align to a 32 byte boundary equal to the
  * alignment gcc 4.5 uses for a struct
  */
 
 /*
  * .data section
- * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections generates
- * .data.identifier which needs to be pulled in with .data, but don't want to
- * pull in .data..stuff which has its own requirements. Same for bss.
  */
 #define DATA_DATA                                                      \
-       *(.data .data.[0-9a-zA-Z_]*)                                    \
+       *(DATA_MAIN)                                                    \
        *(.ref.data)                                                    \
        *(.data..shared_aligned) /* percpu related */                   \
        MEM_KEEP(init.data)                                             \
                VMLINUX_SYMBOL(__security_initcall_end) = .;            \
        }
 
-/* .text section. Map to function alignment to avoid address changes
+/*
+ * .text section. Map to function alignment to avoid address changes
  * during second ld run in second ld pass when generating System.map
- * LD_DEAD_CODE_DATA_ELIMINATION option enables -ffunction-sections generates
- * .text.identifier which needs to be pulled in with .text , but some
- * architectures define .text.foo which is not intended to be pulled in here.
- * Those enabling LD_DEAD_CODE_DATA_ELIMINATION must ensure they don't have
- * conflicting section names, and must pull in .text.[0-9a-zA-Z_]* */
+ *
+ * TEXT_MAIN here will match .text.fixup and .text.unlikely if dead
+ * code elimination is enabled, so these sections should be converted
+ * to use ".." first.
+ */
 #define TEXT_TEXT                                                      \
                ALIGN_FUNCTION();                                       \
-               *(.text.hot .text .text.fixup .text.unlikely)           \
+               *(.text.hot TEXT_MAIN .text.fixup .text.unlikely)       \
                *(.ref.text)                                            \
        MEM_KEEP(init.text)                                             \
        MEM_KEEP(exit.text)                                             \
                BSS_FIRST_SECTIONS                                      \
                *(.bss..page_aligned)                                   \
                *(.dynbss)                                              \
-               *(.bss .bss.[0-9a-zA-Z_]*)                              \
+               *(BSS_MAIN)                                             \
                *(COMMON)                                               \
        }
 
index c749eef..27b4b66 100644 (file)
@@ -1209,6 +1209,7 @@ static inline bool acpi_has_watchdog(void) { return false; }
 #endif
 
 #ifdef CONFIG_ACPI_SPCR_TABLE
+extern bool qdf2400_e44_present;
 int parse_spcr(bool earlycon);
 #else
 static inline int parse_spcr(bool earlycon) { return 0; }
index 277ab9a..100cb43 100644 (file)
@@ -19,6 +19,7 @@
 
 struct pts_fs_info;
 
+struct vfsmount *devpts_mntget(struct file *, struct pts_fs_info *);
 struct pts_fs_info *devpts_acquire(struct file *);
 void devpts_release(struct pts_fs_info *);
 
@@ -32,6 +33,15 @@ void *devpts_get_priv(struct dentry *);
 /* unlink */
 void devpts_pty_kill(struct dentry *);
 
+/* in pty.c */
+int ptm_open_peer(struct file *master, struct tty_struct *tty, int flags);
+
+#else
+static inline int
+ptm_open_peer(struct file *master, struct tty_struct *tty, int flags)
+{
+       return -EIO;
+}
 #endif
 
 
index 497f2b3..97f1b46 100644 (file)
@@ -105,6 +105,11 @@ struct st_sensor_fullscale {
        struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
 };
 
+struct st_sensor_sim {
+       u8 addr;
+       u8 value;
+};
+
 /**
  * struct st_sensor_bdu - ST sensor device block data update
  * @addr: address of the register.
@@ -197,6 +202,7 @@ struct st_sensor_transfer_function {
  * @bdu: Block data update register.
  * @das: Data Alignment Selection register.
  * @drdy_irq: Data ready register of the sensor.
+ * @sim: SPI serial interface mode register of the sensor.
  * @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
  * @bootime: samples to discard when sensor passing from power-down to power-up.
  */
@@ -213,6 +219,7 @@ struct st_sensor_settings {
        struct st_sensor_bdu bdu;
        struct st_sensor_das das;
        struct st_sensor_data_ready_irq drdy_irq;
+       struct st_sensor_sim sim;
        bool multi_read_bit;
        unsigned int bootime;
 };
index 77d4279..bae11c7 100644 (file)
@@ -61,6 +61,7 @@ extern int memblock_debug;
 #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
 #define __init_memblock __meminit
 #define __initdata_memblock __meminitdata
+void memblock_discard(void);
 #else
 #define __init_memblock
 #define __initdata_memblock
@@ -74,8 +75,6 @@ phys_addr_t memblock_find_in_range_node(phys_addr_t size, phys_addr_t align,
                                        int nid, ulong flags);
 phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
                                   phys_addr_t size, phys_addr_t align);
-phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
-phys_addr_t get_allocated_memblock_memory_regions_info(phys_addr_t *addr);
 void memblock_allow_resize(void);
 int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
 int memblock_add(phys_addr_t base, phys_addr_t size);
@@ -110,6 +109,9 @@ void __next_mem_range_rev(u64 *idx, int nid, ulong flags,
 void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
                                phys_addr_t *out_end);
 
+void __memblock_free_early(phys_addr_t base, phys_addr_t size);
+void __memblock_free_late(phys_addr_t base, phys_addr_t size);
+
 /**
  * for_each_mem_range - iterate through memblock areas from type_a and not
  * included in type_b. Or just type_a if type_b is NULL.
index 3914e3d..9b15a4b 100644 (file)
@@ -484,7 +484,8 @@ bool mem_cgroup_oom_synchronize(bool wait);
 extern int do_swap_account;
 #endif
 
-void lock_page_memcg(struct page *page);
+struct mem_cgroup *lock_page_memcg(struct page *page);
+void __unlock_page_memcg(struct mem_cgroup *memcg);
 void unlock_page_memcg(struct page *page);
 
 static inline unsigned long memcg_page_state(struct mem_cgroup *memcg,
@@ -809,7 +810,12 @@ mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
 {
 }
 
-static inline void lock_page_memcg(struct page *page)
+static inline struct mem_cgroup *lock_page_memcg(struct page *page)
+{
+       return NULL;
+}
+
+static inline void __unlock_page_memcg(struct mem_cgroup *memcg)
 {
 }
 
index dda2cc9..ebeb48c 100644 (file)
@@ -37,7 +37,7 @@ struct net;
 
 /* Historically, SOCKWQ_ASYNC_NOSPACE & SOCKWQ_ASYNC_WAITDATA were located
  * in sock->flags, but moved into sk->sk_wq->flags to be RCU protected.
- * Eventually all flags will be in sk->sk_wq_flags.
+ * Eventually all flags will be in sk->sk_wq->flags.
  */
 #define SOCKWQ_ASYNC_NOSPACE   0
 #define SOCKWQ_ASYNC_WAITDATA  1
index 8aa01fd..a36abe2 100644 (file)
@@ -168,6 +168,14 @@ extern int sysctl_hardlockup_all_cpu_backtrace;
 #define sysctl_softlockup_all_cpu_backtrace 0
 #define sysctl_hardlockup_all_cpu_backtrace 0
 #endif
+
+#if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \
+    defined(CONFIG_HARDLOCKUP_DETECTOR)
+void watchdog_update_hrtimer_threshold(u64 period);
+#else
+static inline void watchdog_update_hrtimer_threshold(u64 period) { }
+#endif
+
 extern bool is_hardlockup(void);
 struct ctl_table;
 extern int proc_watchdog(struct ctl_table *, int ,
index 6c8c5d8..2591878 100644 (file)
@@ -346,6 +346,11 @@ struct nvme_fc_remote_port {
  *       indicating an FC transport Aborted status.
  *       Entrypoint is Mandatory.
  *
+ * @defer_rcv:  Called by the transport to signal the LLLD that it has
+ *       begun processing of a previously received NVME CMD IU. The LLDD
+ *       is now free to re-use the rcv buffer associated with the
+ *       nvmefc_tgt_fcp_req.
+ *
  * @max_hw_queues:  indicates the maximum number of hw queues the LLDD
  *       supports for cpu affinitization.
  *       Value is Mandatory. Must be at least 1.
@@ -846,6 +851,8 @@ struct nvmet_fc_target_template {
                                struct nvmefc_tgt_fcp_req *fcpreq);
        void (*fcp_req_release)(struct nvmet_fc_target_port *tgtport,
                                struct nvmefc_tgt_fcp_req *fcpreq);
+       void (*defer_rcv)(struct nvmet_fc_target_port *tgtport,
+                               struct nvmefc_tgt_fcp_req *fcpreq);
 
        u32     max_hw_queues;
        u16     max_sgl_segments;
index 8a266e2..76aac4c 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/types.h>
 #include <linux/nodemask.h>
 #include <uapi/linux/oom.h>
+#include <linux/sched/coredump.h> /* MMF_* */
+#include <linux/mm.h> /* VM_FAULT* */
 
 struct zonelist;
 struct notifier_block;
@@ -63,6 +65,26 @@ static inline bool tsk_is_oom_victim(struct task_struct * tsk)
        return tsk->signal->oom_mm;
 }
 
+/*
+ * Checks whether a page fault on the given mm is still reliable.
+ * This is no longer true if the oom reaper started to reap the
+ * address space which is reflected by MMF_UNSTABLE flag set in
+ * the mm. At that moment any !shared mapping would lose the content
+ * and could cause a memory corruption (zero pages instead of the
+ * original content).
+ *
+ * User should call this before establishing a page table entry for
+ * a !shared mapping and under the proper page table lock.
+ *
+ * Return 0 when the PF is safe VM_FAULT_SIGBUS otherwise.
+ */
+static inline int check_stable_address_space(struct mm_struct *mm)
+{
+       if (unlikely(test_bit(MMF_UNSTABLE, &mm->flags)))
+               return VM_FAULT_SIGBUS;
+       return 0;
+}
+
 extern unsigned long oom_badness(struct task_struct *p,
                struct mem_cgroup *memcg, const nodemask_t *nodemask,
                unsigned long totalpages);
index a75c136..f958d07 100644 (file)
@@ -188,6 +188,8 @@ enum pci_dev_flags {
         * the direct_complete optimization.
         */
        PCI_DEV_FLAGS_NEEDS_RESUME = (__force pci_dev_flags_t) (1 << 11),
+       /* Don't use Relaxed Ordering for TLPs directed at this device */
+       PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 12),
 };
 
 enum pci_irq_reroute_variant {
@@ -1126,6 +1128,7 @@ bool pci_check_pme_status(struct pci_dev *dev);
 void pci_pme_wakeup_bus(struct pci_bus *bus);
 void pci_d3cold_enable(struct pci_dev *dev);
 void pci_d3cold_disable(struct pci_dev *dev);
+bool pcie_relaxed_ordering_enabled(struct pci_dev *dev);
 
 /* PCI Virtual Channel */
 int pci_save_vc_state(struct pci_dev *dev);
index a3b873f..b14095b 100644 (file)
@@ -310,8 +310,8 @@ struct pmu {
         * Notification that the event was mapped or unmapped.  Called
         * in the context of the mapping task.
         */
-       void (*event_mapped)            (struct perf_event *event); /*optional*/
-       void (*event_unmapped)          (struct perf_event *event); /*optional*/
+       void (*event_mapped)            (struct perf_event *event, struct mm_struct *mm); /* optional */
+       void (*event_unmapped)          (struct perf_event *event, struct mm_struct *mm); /* optional */
 
        /*
         * Flags for ->add()/->del()/ ->start()/->stop(). There are
index 4d17931..7195827 100644 (file)
@@ -8,7 +8,9 @@ enum pid_type
        PIDTYPE_PID,
        PIDTYPE_PGID,
        PIDTYPE_SID,
-       PIDTYPE_MAX
+       PIDTYPE_MAX,
+       /* only valid to __task_pid_nr_ns() */
+       __PIDTYPE_TGID
 };
 
 /*
index 79b0e4c..f8274b0 100644 (file)
  *     Available only for accelerometer and pressure sensors.
  *     Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet).
  * @open_drain: set the interrupt line to be open drain if possible.
+ * @spi_3wire: enable spi-3wire mode.
  */
 struct st_sensors_platform_data {
        u8 drdy_int_pin;
        bool open_drain;
+       bool spi_3wire;
 };
 
 #endif /* ST_SENSORS_PDATA_H */
index d8c97ec..37b4bb2 100644 (file)
@@ -436,9 +436,9 @@ static inline int ptr_ring_consume_batched_bh(struct ptr_ring *r,
        __PTR_RING_PEEK_CALL_v; \
 })
 
-static inline void **__ptr_ring_init_queue_alloc(int size, gfp_t gfp)
+static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp)
 {
-       return kzalloc(ALIGN(size * sizeof(void *), SMP_CACHE_BYTES), gfp);
+       return kcalloc(size, sizeof(void *), gfp);
 }
 
 static inline void __ptr_ring_set_size(struct ptr_ring *r, int size)
@@ -582,7 +582,8 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
  * In particular if you consume ring in interrupt or BH context, you must
  * disable interrupts/BH when doing so.
  */
-static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings,
+static inline int ptr_ring_resize_multiple(struct ptr_ring **rings,
+                                          unsigned int nrings,
                                           int size,
                                           gfp_t gfp, void (*destroy)(void *))
 {
@@ -590,7 +591,7 @@ static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings,
        void ***queues;
        int i;
 
-       queues = kmalloc(nrings * sizeof *queues, gfp);
+       queues = kmalloc_array(nrings, sizeof(*queues), gfp);
        if (!queues)
                goto noqueues;
 
index 772c5f6..93be319 100644 (file)
@@ -1173,13 +1173,6 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk)
        return tsk->tgid;
 }
 
-extern pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
-
-static inline pid_t task_tgid_vnr(struct task_struct *tsk)
-{
-       return pid_vnr(task_tgid(tsk));
-}
-
 /**
  * pid_alive - check that a task structure is not stale
  * @p: Task structure to be checked.
@@ -1195,23 +1188,6 @@ static inline int pid_alive(const struct task_struct *p)
        return p->pids[PIDTYPE_PID].pid != NULL;
 }
 
-static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
-{
-       pid_t pid = 0;
-
-       rcu_read_lock();
-       if (pid_alive(tsk))
-               pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
-       rcu_read_unlock();
-
-       return pid;
-}
-
-static inline pid_t task_ppid_nr(const struct task_struct *tsk)
-{
-       return task_ppid_nr_ns(tsk, &init_pid_ns);
-}
-
 static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
 {
        return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns);
@@ -1233,6 +1209,33 @@ static inline pid_t task_session_vnr(struct task_struct *tsk)
        return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL);
 }
 
+static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+       return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns);
+}
+
+static inline pid_t task_tgid_vnr(struct task_struct *tsk)
+{
+       return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL);
+}
+
+static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
+{
+       pid_t pid = 0;
+
+       rcu_read_lock();
+       if (pid_alive(tsk))
+               pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
+       rcu_read_unlock();
+
+       return pid;
+}
+
+static inline pid_t task_ppid_nr(const struct task_struct *tsk)
+{
+       return task_ppid_nr_ns(tsk, &init_pid_ns);
+}
+
 /* Obsolete, do not use: */
 static inline pid_t task_pgrp_nr(struct task_struct *tsk)
 {
index 35226cd..8621ffd 100644 (file)
@@ -193,7 +193,8 @@ static inline int skb_array_resize(struct skb_array *a, int size, gfp_t gfp)
 }
 
 static inline int skb_array_resize_multiple(struct skb_array **rings,
-                                           int nrings, int size, gfp_t gfp)
+                                           int nrings, unsigned int size,
+                                           gfp_t gfp)
 {
        BUILD_BUG_ON(offsetof(struct skb_array, ring));
        return ptr_ring_resize_multiple((struct ptr_ring **)rings,
index 5b74e36..dc19880 100644 (file)
@@ -757,6 +757,43 @@ extern int do_wait_intr_irq(wait_queue_head_t *, wait_queue_entry_t *);
        __ret;                                                                  \
 })
 
+#define __wait_event_killable_timeout(wq_head, condition, timeout)             \
+       ___wait_event(wq_head, ___wait_cond_timeout(condition),                 \
+                     TASK_KILLABLE, 0, timeout,                                \
+                     __ret = schedule_timeout(__ret))
+
+/**
+ * wait_event_killable_timeout - sleep until a condition gets true or a timeout elapses
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @timeout: timeout, in jiffies
+ *
+ * The process is put to sleep (TASK_KILLABLE) until the
+ * @condition evaluates to true or a kill signal is received.
+ * The @condition is checked each time the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * Returns:
+ * 0 if the @condition evaluated to %false after the @timeout elapsed,
+ * 1 if the @condition evaluated to %true after the @timeout elapsed,
+ * the remaining jiffies (at least 1) if the @condition evaluated
+ * to %true before the @timeout elapsed, or -%ERESTARTSYS if it was
+ * interrupted by a kill signal.
+ *
+ * Only kill signals interrupt this process.
+ */
+#define wait_event_killable_timeout(wq_head, condition, timeout)               \
+({                                                                             \
+       long __ret = timeout;                                                   \
+       might_sleep();                                                          \
+       if (!___wait_cond_timeout(condition))                                   \
+               __ret = __wait_event_killable_timeout(wq_head,                  \
+                                               condition, timeout);            \
+       __ret;                                                                  \
+})
+
 
 #define __wait_event_lock_irq(wq_head, condition, lock, cmd)                   \
        (void)___wait_event(wq_head, condition, TASK_UNINTERRUPTIBLE, 0, 0,     \
index 6df79e9..f44ff24 100644 (file)
@@ -336,6 +336,16 @@ static inline void in6_dev_put(struct inet6_dev *idev)
                in6_dev_finish_destroy(idev);
 }
 
+static inline void in6_dev_put_clear(struct inet6_dev **pidev)
+{
+       struct inet6_dev *idev = *pidev;
+
+       if (idev) {
+               in6_dev_put(idev);
+               *pidev = NULL;
+       }
+}
+
 static inline void __in6_dev_put(struct inet6_dev *idev)
 {
        refcount_dec(&idev->refcnt);
index b00508d..b2e6865 100644 (file)
@@ -277,6 +277,11 @@ static inline bool bond_is_lb(const struct bonding *bond)
               BOND_MODE(bond) == BOND_MODE_ALB;
 }
 
+static inline bool bond_needs_speed_duplex(const struct bonding *bond)
+{
+       return BOND_MODE(bond) == BOND_MODE_8023AD || bond_is_lb(bond);
+}
+
 static inline bool bond_is_nondyn_tlb(const struct bonding *bond)
 {
        return (BOND_MODE(bond) == BOND_MODE_TLB)  &&
index 8ffd434..71c72a9 100644 (file)
 #include <linux/sched/signal.h>
 #include <net/ip.h>
 
-#ifdef CONFIG_NET_RX_BUSY_POLL
-
-struct napi_struct;
-extern unsigned int sysctl_net_busy_read __read_mostly;
-extern unsigned int sysctl_net_busy_poll __read_mostly;
-
 /*             0 - Reserved to indicate value not set
  *     1..NR_CPUS - Reserved for sender_cpu
  *  NR_CPUS+1..~0 - Region available for NAPI IDs
  */
 #define MIN_NAPI_ID ((unsigned int)(NR_CPUS + 1))
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+
+struct napi_struct;
+extern unsigned int sysctl_net_busy_read __read_mostly;
+extern unsigned int sysctl_net_busy_poll __read_mostly;
+
 static inline bool net_busy_loop_on(void)
 {
        return sysctl_net_busy_poll;
index 821cedc..0cf7f5a 100644 (file)
@@ -352,7 +352,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
            !forwarding)
                return dst_mtu(dst);
 
-       return min(dst->dev->mtu, IP_MAX_MTU);
+       return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU);
 }
 
 static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
@@ -364,7 +364,7 @@ static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
                return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding);
        }
 
-       return min(skb_dst(skb)->dev->mtu, IP_MAX_MTU);
+       return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
 }
 
 u32 ip_idents_reserve(u32 hash, int segs);
index b2b5419..f8149ca 100644 (file)
@@ -5499,6 +5499,21 @@ static inline void ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif,
        ieee80211_manage_rx_ba_offl(vif, addr, tid + IEEE80211_NUM_TIDS);
 }
 
+/**
+ * ieee80211_rx_ba_timer_expired - stop a Rx BA session due to timeout
+ *
+ * Some device drivers do not offload AddBa/DelBa negotiation, but handle rx
+ * buffer reording internally, and therefore also handle the session timer.
+ *
+ * Trigger the timeout flow, which sends a DelBa.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback
+ * @addr: station mac address
+ * @tid: the rx tid
+ */
+void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
+                                  const u8 *addr, unsigned int tid);
+
 /* Rate control API */
 
 /**
index 1c123e2..67f815e 100644 (file)
@@ -806,8 +806,11 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
        old = *pold;
        *pold = new;
        if (old != NULL) {
-               qdisc_tree_reduce_backlog(old, old->q.qlen, old->qstats.backlog);
+               unsigned int qlen = old->q.qlen;
+               unsigned int backlog = old->qstats.backlog;
+
                qdisc_reset(old);
+               qdisc_tree_reduce_backlog(old, qlen, backlog);
        }
        sch_tree_unlock(sch);
 
index 7c0632c..aeeec62 100644 (file)
@@ -507,9 +507,7 @@ int sk_set_peek_off(struct sock *sk, int val);
 static inline int sk_peek_offset(struct sock *sk, int flags)
 {
        if (unlikely(flags & MSG_PEEK)) {
-               s32 off = READ_ONCE(sk->sk_peek_off);
-               if (off >= 0)
-                       return off;
+               return READ_ONCE(sk->sk_peek_off);
        }
 
        return 0;
index cc80369..586de4b 100644 (file)
@@ -366,12 +366,13 @@ static inline bool udp_skb_is_linear(struct sk_buff *skb)
 static inline int copy_linear_skb(struct sk_buff *skb, int len, int off,
                                  struct iov_iter *to)
 {
-       int n, copy = len - off;
+       int n;
 
-       n = copy_to_iter(skb->data + off, copy, to);
-       if (n == copy)
+       n = copy_to_iter(skb->data + off, len, to);
+       if (n == len)
                return 0;
 
+       iov_iter_revert(to, n);
        return -EFAULT;
 }
 
index b573243..88c32ab 100644 (file)
@@ -1683,6 +1683,7 @@ struct ib_qp {
        enum ib_qp_type         qp_type;
        struct ib_rwq_ind_table *rwq_ind_tbl;
        struct ib_qp_security  *qp_sec;
+       u8                      port;
 };
 
 struct ib_mr {
index a1266d3..6af198d 100644 (file)
@@ -57,6 +57,7 @@ struct scsi_pointer {
 /* for scmd->flags */
 #define SCMD_TAGGED            (1 << 0)
 #define SCMD_UNCHECKED_ISA_DMA (1 << 1)
+#define SCMD_ZONE_WRITE_LOCK   (1 << 2)
 
 struct scsi_cmnd {
        struct scsi_request req;
index 0ca1fb0..fb87d32 100644 (file)
@@ -786,6 +786,7 @@ struct iscsi_np {
        int                     np_sock_type;
        enum np_thread_state_table np_thread_state;
        bool                    enabled;
+       atomic_t                np_reset_count;
        enum iscsi_timer_flags_table np_login_timer_flags;
        u32                     np_exports;
        enum np_flags_table     np_flags;
index 62d686d..9eb8b35 100644 (file)
@@ -66,7 +66,7 @@ static struct fsnotify_group *audit_watch_group;
 
 /* fsnotify events we care about. */
 #define AUDIT_FS_WATCH (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\
-                       FS_MOVE_SELF | FS_EVENT_ON_CHILD)
+                       FS_MOVE_SELF | FS_EVENT_ON_CHILD | FS_UNMOUNT)
 
 static void audit_free_parent(struct audit_parent *parent)
 {
@@ -457,13 +457,15 @@ void audit_remove_watch_rule(struct audit_krule *krule)
        list_del(&krule->rlist);
 
        if (list_empty(&watch->rules)) {
+               /*
+                * audit_remove_watch() drops our reference to 'parent' which
+                * can get freed. Grab our own reference to be safe.
+                */
+               audit_get_parent(parent);
                audit_remove_watch(watch);
-
-               if (list_empty(&parent->watches)) {
-                       audit_get_parent(parent);
+               if (list_empty(&parent->watches))
                        fsnotify_destroy_mark(&parent->mark, audit_watch_group);
-                       audit_put_parent(parent);
-               }
+               audit_put_parent(parent);
        }
 }
 
index 426c2ff..ee20d4c 100644 (file)
@@ -2217,6 +2217,33 @@ static int group_can_go_on(struct perf_event *event,
        return can_add_hw;
 }
 
+/*
+ * Complement to update_event_times(). This computes the tstamp_* values to
+ * continue 'enabled' state from @now, and effectively discards the time
+ * between the prior tstamp_stopped and now (as we were in the OFF state, or
+ * just switched (context) time base).
+ *
+ * This further assumes '@event->state == INACTIVE' (we just came from OFF) and
+ * cannot have been scheduled in yet. And going into INACTIVE state means
+ * '@event->tstamp_stopped = @now'.
+ *
+ * Thus given the rules of update_event_times():
+ *
+ *   total_time_enabled = tstamp_stopped - tstamp_enabled
+ *   total_time_running = tstamp_stopped - tstamp_running
+ *
+ * We can insert 'tstamp_stopped == now' and reverse them to compute new
+ * tstamp_* values.
+ */
+static void __perf_event_enable_time(struct perf_event *event, u64 now)
+{
+       WARN_ON_ONCE(event->state != PERF_EVENT_STATE_INACTIVE);
+
+       event->tstamp_stopped = now;
+       event->tstamp_enabled = now - event->total_time_enabled;
+       event->tstamp_running = now - event->total_time_running;
+}
+
 static void add_event_to_ctx(struct perf_event *event,
                               struct perf_event_context *ctx)
 {
@@ -2224,9 +2251,12 @@ static void add_event_to_ctx(struct perf_event *event,
 
        list_add_event(event, ctx);
        perf_group_attach(event);
-       event->tstamp_enabled = tstamp;
-       event->tstamp_running = tstamp;
-       event->tstamp_stopped = tstamp;
+       /*
+        * We can be called with event->state == STATE_OFF when we create with
+        * .disabled = 1. In that case the IOC_ENABLE will call this function.
+        */
+       if (event->state == PERF_EVENT_STATE_INACTIVE)
+               __perf_event_enable_time(event, tstamp);
 }
 
 static void ctx_sched_out(struct perf_event_context *ctx,
@@ -2471,10 +2501,11 @@ static void __perf_event_mark_enabled(struct perf_event *event)
        u64 tstamp = perf_event_time(event);
 
        event->state = PERF_EVENT_STATE_INACTIVE;
-       event->tstamp_enabled = tstamp - event->total_time_enabled;
+       __perf_event_enable_time(event, tstamp);
        list_for_each_entry(sub, &event->sibling_list, group_entry) {
+               /* XXX should not be > INACTIVE if event isn't */
                if (sub->state >= PERF_EVENT_STATE_INACTIVE)
-                       sub->tstamp_enabled = tstamp - sub->total_time_enabled;
+                       __perf_event_enable_time(sub, tstamp);
        }
 }
 
@@ -5090,7 +5121,7 @@ static void perf_mmap_open(struct vm_area_struct *vma)
                atomic_inc(&event->rb->aux_mmap_count);
 
        if (event->pmu->event_mapped)
-               event->pmu->event_mapped(event);
+               event->pmu->event_mapped(event, vma->vm_mm);
 }
 
 static void perf_pmu_output_stop(struct perf_event *event);
@@ -5113,7 +5144,7 @@ static void perf_mmap_close(struct vm_area_struct *vma)
        unsigned long size = perf_data_size(rb);
 
        if (event->pmu->event_unmapped)
-               event->pmu->event_unmapped(event);
+               event->pmu->event_unmapped(event, vma->vm_mm);
 
        /*
         * rb->aux_mmap_count will always drop before rb->mmap_count and
@@ -5411,7 +5442,7 @@ aux_unlock:
        vma->vm_ops = &perf_mmap_vmops;
 
        if (event->pmu->event_mapped)
-               event->pmu->event_mapped(event);
+               event->pmu->event_mapped(event, vma->vm_mm);
 
        return ret;
 }
index a3cc37c..3675c60 100644 (file)
@@ -1000,7 +1000,7 @@ EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name);
 
 void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
 {
-       unsigned long flags;
+       unsigned long flags, trigger, tmp;
        struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
 
        if (!desc)
@@ -1014,6 +1014,8 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
 
        irq_settings_clr_and_set(desc, clr, set);
 
+       trigger = irqd_get_trigger_type(&desc->irq_data);
+
        irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
                   IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT);
        if (irq_settings_has_no_balance_set(desc))
@@ -1025,7 +1027,11 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
        if (irq_settings_is_level(desc))
                irqd_set(&desc->irq_data, IRQD_LEVEL);
 
-       irqd_set(&desc->irq_data, irq_settings_get_trigger_mask(desc));
+       tmp = irq_settings_get_trigger_mask(desc);
+       if (tmp != IRQ_TYPE_NONE)
+               trigger = tmp;
+
+       irqd_set(&desc->irq_data, trigger);
 
        irq_put_desc_unlock(desc, flags);
 }
index 1a9abc1..259a22a 100644 (file)
@@ -165,7 +165,7 @@ irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu)
        struct irq_data *data = irq_get_irq_data(irq);
        struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL;
 
-       if (!data || !ipimask || cpu > nr_cpu_ids)
+       if (!data || !ipimask || cpu >= nr_cpu_ids)
                return INVALID_HWIRQ;
 
        if (!cpumask_test_cpu(cpu, ipimask))
@@ -195,7 +195,7 @@ static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data,
        if (!chip->ipi_send_single && !chip->ipi_send_mask)
                return -EINVAL;
 
-       if (cpu > nr_cpu_ids)
+       if (cpu >= nr_cpu_ids)
                return -EINVAL;
 
        if (dest) {
index 6d016c5..2f37acd 100644 (file)
@@ -71,6 +71,18 @@ static atomic_t kmod_concurrent_max = ATOMIC_INIT(MAX_KMOD_CONCURRENT);
 static DECLARE_WAIT_QUEUE_HEAD(kmod_wq);
 
 /*
+ * This is a restriction on having *all* MAX_KMOD_CONCURRENT threads
+ * running at the same time without returning. When this happens we
+ * believe you've somehow ended up with a recursive module dependency
+ * creating a loop.
+ *
+ * We have no option but to fail.
+ *
+ * Userspace should proactively try to detect and prevent these.
+ */
+#define MAX_KMOD_ALL_BUSY_TIMEOUT 5
+
+/*
        modprobe_path is set via /proc/sys.
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
@@ -167,8 +179,17 @@ int __request_module(bool wait, const char *fmt, ...)
                pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...",
                                    atomic_read(&kmod_concurrent_max),
                                    MAX_KMOD_CONCURRENT, module_name);
-               wait_event_interruptible(kmod_wq,
-                                        atomic_dec_if_positive(&kmod_concurrent_max) >= 0);
+               ret = wait_event_killable_timeout(kmod_wq,
+                                                 atomic_dec_if_positive(&kmod_concurrent_max) >= 0,
+                                                 MAX_KMOD_ALL_BUSY_TIMEOUT * HZ);
+               if (!ret) {
+                       pr_warn_ratelimited("request_module: modprobe %s cannot be processed, kmod busy with %d threads for more than %d seconds now",
+                                           module_name, MAX_KMOD_CONCURRENT, MAX_KMOD_ALL_BUSY_TIMEOUT);
+                       return -ETIME;
+               } else if (ret == -ERESTARTSYS) {
+                       pr_warn_ratelimited("request_module: sigkill sent for modprobe %s, giving up", module_name);
+                       return ret;
+               }
        }
 
        trace_module_request(module_name, wait, _RET_IP_);
index c69c30d..020dedb 100644 (file)
@@ -527,8 +527,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
        if (!ns)
                ns = task_active_pid_ns(current);
        if (likely(pid_alive(task))) {
-               if (type != PIDTYPE_PID)
+               if (type != PIDTYPE_PID) {
+                       if (type == __PIDTYPE_TGID)
+                               type = PIDTYPE_PID;
                        task = task->group_leader;
+               }
                nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns);
        }
        rcu_read_unlock();
@@ -537,12 +540,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
 }
 EXPORT_SYMBOL(__task_pid_nr_ns);
 
-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
-{
-       return pid_nr_ns(task_tgid(tsk), ns);
-}
-EXPORT_SYMBOL(task_tgid_nr_ns);
-
 struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
 {
        return ns_of_pid(task_pid(tsk));
index 7e33f8c..ed804a4 100644 (file)
@@ -1194,7 +1194,11 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
                        recalc_sigpending_and_wake(t);
                }
        }
-       if (action->sa.sa_handler == SIG_DFL)
+       /*
+        * Don't clear SIGNAL_UNKILLABLE for traced tasks, users won't expect
+        * debugging to leave init killable.
+        */
+       if (action->sa.sa_handler == SIG_DFL && !t->ptrace)
                t->signal->flags &= ~SIGNAL_UNKILLABLE;
        ret = specific_send_sig_info(sig, info, t);
        spin_unlock_irqrestore(&t->sighand->siglock, flags);
index 3738519..dc498b6 100644 (file)
@@ -204,10 +204,36 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1,
                fmt_cnt++;
        }
 
-       return __trace_printk(1/* fake ip will not be printed */, fmt,
-                             mod[0] == 2 ? arg1 : mod[0] == 1 ? (long) arg1 : (u32) arg1,
-                             mod[1] == 2 ? arg2 : mod[1] == 1 ? (long) arg2 : (u32) arg2,
-                             mod[2] == 2 ? arg3 : mod[2] == 1 ? (long) arg3 : (u32) arg3);
+/* Horrid workaround for getting va_list handling working with different
+ * argument type combinations generically for 32 and 64 bit archs.
+ */
+#define __BPF_TP_EMIT()        __BPF_ARG3_TP()
+#define __BPF_TP(...)                                                  \
+       __trace_printk(1 /* Fake ip will not be printed. */,            \
+                      fmt, ##__VA_ARGS__)
+
+#define __BPF_ARG1_TP(...)                                             \
+       ((mod[0] == 2 || (mod[0] == 1 && __BITS_PER_LONG == 64))        \
+         ? __BPF_TP(arg1, ##__VA_ARGS__)                               \
+         : ((mod[0] == 1 || (mod[0] == 0 && __BITS_PER_LONG == 32))    \
+             ? __BPF_TP((long)arg1, ##__VA_ARGS__)                     \
+             : __BPF_TP((u32)arg1, ##__VA_ARGS__)))
+
+#define __BPF_ARG2_TP(...)                                             \
+       ((mod[1] == 2 || (mod[1] == 1 && __BITS_PER_LONG == 64))        \
+         ? __BPF_ARG1_TP(arg2, ##__VA_ARGS__)                          \
+         : ((mod[1] == 1 || (mod[1] == 0 && __BITS_PER_LONG == 32))    \
+             ? __BPF_ARG1_TP((long)arg2, ##__VA_ARGS__)                \
+             : __BPF_ARG1_TP((u32)arg2, ##__VA_ARGS__)))
+
+#define __BPF_ARG3_TP(...)                                             \
+       ((mod[2] == 2 || (mod[2] == 1 && __BITS_PER_LONG == 64))        \
+         ? __BPF_ARG2_TP(arg3, ##__VA_ARGS__)                          \
+         : ((mod[2] == 1 || (mod[2] == 0 && __BITS_PER_LONG == 32))    \
+             ? __BPF_ARG2_TP((long)arg3, ##__VA_ARGS__)                \
+             : __BPF_ARG2_TP((u32)arg3, ##__VA_ARGS__)))
+
+       return __BPF_TP_EMIT();
 }
 
 static const struct bpf_func_proto bpf_trace_printk_proto = {
index 02004ae..96cea88 100644 (file)
@@ -889,6 +889,10 @@ static int profile_graph_entry(struct ftrace_graph_ent *trace)
 
        function_profile_call(trace->func, 0, NULL, NULL);
 
+       /* If function graph is shutting down, ret_stack can be NULL */
+       if (!current->ret_stack)
+               return 0;
+
        if (index >= 0 && index < FTRACE_RETFUNC_DEPTH)
                current->ret_stack[index].subtime = 0;
 
index 529cc50..81279c6 100644 (file)
@@ -4386,15 +4386,19 @@ EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu);
  * the page that was allocated, with the read page of the buffer.
  *
  * Returns:
- *  The page allocated, or NULL on error.
+ *  The page allocated, or ERR_PTR
  */
 void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu)
 {
-       struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
+       struct ring_buffer_per_cpu *cpu_buffer;
        struct buffer_data_page *bpage = NULL;
        unsigned long flags;
        struct page *page;
 
+       if (!cpumask_test_cpu(cpu, buffer->cpumask))
+               return ERR_PTR(-ENODEV);
+
+       cpu_buffer = buffer->buffers[cpu];
        local_irq_save(flags);
        arch_spin_lock(&cpu_buffer->lock);
 
@@ -4412,7 +4416,7 @@ void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu)
        page = alloc_pages_node(cpu_to_node(cpu),
                                GFP_KERNEL | __GFP_NORETRY, 0);
        if (!page)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        bpage = page_address(page);
 
@@ -4467,8 +4471,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);
  *
  * for example:
  *     rpage = ring_buffer_alloc_read_page(buffer, cpu);
- *     if (!rpage)
- *             return error;
+ *     if (IS_ERR(rpage))
+ *             return PTR_ERR(rpage);
  *     ret = ring_buffer_read_page(buffer, &rpage, len, cpu, 0);
  *     if (ret >= 0)
  *             process_page(rpage, ret);
index 9fbcaf5..68ee79a 100644 (file)
@@ -113,7 +113,7 @@ static enum event_status read_page(int cpu)
        int i;
 
        bpage = ring_buffer_alloc_read_page(buffer, cpu);
-       if (!bpage)
+       if (IS_ERR(bpage))
                return EVENT_DROPPED;
 
        ret = ring_buffer_read_page(buffer, &bpage, PAGE_SIZE, cpu, 1);
index 42b9355..44004d8 100644 (file)
@@ -6598,7 +6598,7 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
 {
        struct ftrace_buffer_info *info = filp->private_data;
        struct trace_iterator *iter = &info->iter;
-       ssize_t ret;
+       ssize_t ret = 0;
        ssize_t size;
 
        if (!count)
@@ -6612,10 +6612,15 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
        if (!info->spare) {
                info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer,
                                                          iter->cpu_file);
-               info->spare_cpu = iter->cpu_file;
+               if (IS_ERR(info->spare)) {
+                       ret = PTR_ERR(info->spare);
+                       info->spare = NULL;
+               } else {
+                       info->spare_cpu = iter->cpu_file;
+               }
        }
        if (!info->spare)
-               return -ENOMEM;
+               return ret;
 
        /* Do we have previous read data to read? */
        if (info->read < PAGE_SIZE)
@@ -6790,8 +6795,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                ref->ref = 1;
                ref->buffer = iter->trace_buffer->buffer;
                ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
-               if (!ref->page) {
-                       ret = -ENOMEM;
+               if (IS_ERR(ref->page)) {
+                       ret = PTR_ERR(ref->page);
+                       ref->page = NULL;
                        kfree(ref);
                        break;
                }
@@ -8293,6 +8299,7 @@ __init static int tracer_alloc_buffers(void)
        if (ret < 0)
                goto out_free_cpumask;
        /* Used for event triggers */
+       ret = -ENOMEM;
        temp_buffer = ring_buffer_alloc(PAGE_SIZE, RB_FL_OVERWRITE);
        if (!temp_buffer)
                goto out_rm_hp_state;
@@ -8407,4 +8414,4 @@ __init static int clear_boot_tracer(void)
 }
 
 fs_initcall(tracer_init_tracefs);
-late_initcall(clear_boot_tracer);
+late_initcall_sync(clear_boot_tracer);
index 59a411f..181e139 100644 (file)
@@ -1959,6 +1959,10 @@ static int create_filter(struct trace_event_call *call,
                if (err && set_str)
                        append_filter_err(ps, filter);
        }
+       if (err && !set_str) {
+               free_event_filter(filter);
+               filter = NULL;
+       }
        create_filter_finish(ps);
 
        *filterp = filter;
index 0a689bb..305039b 100644 (file)
@@ -221,16 +221,19 @@ void tracing_map_array_free(struct tracing_map_array *a)
        if (!a)
                return;
 
-       if (!a->pages) {
-               kfree(a);
-               return;
-       }
+       if (!a->pages)
+               goto free;
 
        for (i = 0; i < a->n_pages; i++) {
                if (!a->pages[i])
                        break;
                free_page((unsigned long)a->pages[i]);
        }
+
+       kfree(a->pages);
+
+ free:
+       kfree(a);
 }
 
 struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts,
index 06d3389..f5d5202 100644 (file)
@@ -240,6 +240,7 @@ static void set_sample_period(void)
         * hardlockup detector generates a warning
         */
        sample_period = get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5);
+       watchdog_update_hrtimer_threshold(sample_period);
 }
 
 /* Commands for resetting the watchdog */
index 295a0d8..3a09ea1 100644 (file)
@@ -37,6 +37,62 @@ void arch_touch_nmi_watchdog(void)
 }
 EXPORT_SYMBOL(arch_touch_nmi_watchdog);
 
+#ifdef CONFIG_HARDLOCKUP_CHECK_TIMESTAMP
+static DEFINE_PER_CPU(ktime_t, last_timestamp);
+static DEFINE_PER_CPU(unsigned int, nmi_rearmed);
+static ktime_t watchdog_hrtimer_sample_threshold __read_mostly;
+
+void watchdog_update_hrtimer_threshold(u64 period)
+{
+       /*
+        * The hrtimer runs with a period of (watchdog_threshold * 2) / 5
+        *
+        * So it runs effectively with 2.5 times the rate of the NMI
+        * watchdog. That means the hrtimer should fire 2-3 times before
+        * the NMI watchdog expires. The NMI watchdog on x86 is based on
+        * unhalted CPU cycles, so if Turbo-Mode is enabled the CPU cycles
+        * might run way faster than expected and the NMI fires in a
+        * smaller period than the one deduced from the nominal CPU
+        * frequency. Depending on the Turbo-Mode factor this might be fast
+        * enough to get the NMI period smaller than the hrtimer watchdog
+        * period and trigger false positives.
+        *
+        * The sample threshold is used to check in the NMI handler whether
+        * the minimum time between two NMI samples has elapsed. That
+        * prevents false positives.
+        *
+        * Set this to 4/5 of the actual watchdog threshold period so the
+        * hrtimer is guaranteed to fire at least once within the real
+        * watchdog threshold.
+        */
+       watchdog_hrtimer_sample_threshold = period * 2;
+}
+
+static bool watchdog_check_timestamp(void)
+{
+       ktime_t delta, now = ktime_get_mono_fast_ns();
+
+       delta = now - __this_cpu_read(last_timestamp);
+       if (delta < watchdog_hrtimer_sample_threshold) {
+               /*
+                * If ktime is jiffies based, a stalled timer would prevent
+                * jiffies from being incremented and the filter would look
+                * at a stale timestamp and never trigger.
+                */
+               if (__this_cpu_inc_return(nmi_rearmed) < 10)
+                       return false;
+       }
+       __this_cpu_write(nmi_rearmed, 0);
+       __this_cpu_write(last_timestamp, now);
+       return true;
+}
+#else
+static inline bool watchdog_check_timestamp(void)
+{
+       return true;
+}
+#endif
+
 static struct perf_event_attr wd_hw_attr = {
        .type           = PERF_TYPE_HARDWARE,
        .config         = PERF_COUNT_HW_CPU_CYCLES,
@@ -61,6 +117,9 @@ static void watchdog_overflow_callback(struct perf_event *event,
                return;
        }
 
+       if (!watchdog_check_timestamp())
+               return;
+
        /* check for a hardlockup
         * This is done by making sure our timer interrupt
         * is incrementing.  The timer interrupt should have
index eb0f316..e718df3 100644 (file)
@@ -798,6 +798,13 @@ config HARDLOCKUP_DETECTOR_PERF
        select SOFTLOCKUP_DETECTOR
 
 #
+# Enables a timestamp based low pass filter to compensate for perf based
+# hard lockup detection which runs too fast due to turbo modes.
+#
+config HARDLOCKUP_CHECK_TIMESTAMP
+       bool
+
+#
 # arch/ can define HAVE_HARDLOCKUP_DETECTOR_ARCH to provide their own hard
 # lockup detector rather than the perf based detector.
 #
index 595b757..c03ccbc 100644 (file)
@@ -167,7 +167,7 @@ static void cma_debugfs_add_one(struct cma *cma, int idx)
        char name[16];
        int u32s;
 
-       sprintf(name, "cma-%s", cma->name);
+       scnprintf(name, sizeof(name), "cma-%s", cma->name);
 
        tmp = debugfs_create_dir(name, cma_debugfs_root);
 
index 08f6c19..3644ff9 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/userfaultfd_k.h>
 #include <linux/page_idle.h>
 #include <linux/shmem_fs.h>
+#include <linux/oom.h>
 
 #include <asm/tlb.h>
 #include <asm/pgalloc.h>
@@ -550,6 +551,7 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page,
        struct mem_cgroup *memcg;
        pgtable_t pgtable;
        unsigned long haddr = vmf->address & HPAGE_PMD_MASK;
+       int ret = 0;
 
        VM_BUG_ON_PAGE(!PageCompound(page), page);
 
@@ -561,9 +563,8 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page,
 
        pgtable = pte_alloc_one(vma->vm_mm, haddr);
        if (unlikely(!pgtable)) {
-               mem_cgroup_cancel_charge(page, memcg, true);
-               put_page(page);
-               return VM_FAULT_OOM;
+               ret = VM_FAULT_OOM;
+               goto release;
        }
 
        clear_huge_page(page, haddr, HPAGE_PMD_NR);
@@ -576,13 +577,14 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page,
 
        vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
        if (unlikely(!pmd_none(*vmf->pmd))) {
-               spin_unlock(vmf->ptl);
-               mem_cgroup_cancel_charge(page, memcg, true);
-               put_page(page);
-               pte_free(vma->vm_mm, pgtable);
+               goto unlock_release;
        } else {
                pmd_t entry;
 
+               ret = check_stable_address_space(vma->vm_mm);
+               if (ret)
+                       goto unlock_release;
+
                /* Deliver the page fault to userland */
                if (userfaultfd_missing(vma)) {
                        int ret;
@@ -610,6 +612,15 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page,
        }
 
        return 0;
+unlock_release:
+       spin_unlock(vmf->ptl);
+release:
+       if (pgtable)
+               pte_free(vma->vm_mm, pgtable);
+       mem_cgroup_cancel_charge(page, memcg, true);
+       put_page(page);
+       return ret;
+
 }
 
 /*
@@ -688,7 +699,10 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf)
                ret = 0;
                set = false;
                if (pmd_none(*vmf->pmd)) {
-                       if (userfaultfd_missing(vma)) {
+                       ret = check_stable_address_space(vma->vm_mm);
+                       if (ret) {
+                               spin_unlock(vmf->ptl);
+                       } else if (userfaultfd_missing(vma)) {
                                spin_unlock(vmf->ptl);
                                ret = handle_userfault(vmf, VM_UFFD_MISSING);
                                VM_BUG_ON(ret & VM_FAULT_FALLBACK);
index 2cb25fe..bf14aea 100644 (file)
@@ -285,31 +285,27 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u
 }
 
 #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
-
-phys_addr_t __init_memblock get_allocated_memblock_reserved_regions_info(
-                                       phys_addr_t *addr)
-{
-       if (memblock.reserved.regions == memblock_reserved_init_regions)
-               return 0;
-
-       *addr = __pa(memblock.reserved.regions);
-
-       return PAGE_ALIGN(sizeof(struct memblock_region) *
-                         memblock.reserved.max);
-}
-
-phys_addr_t __init_memblock get_allocated_memblock_memory_regions_info(
-                                       phys_addr_t *addr)
+/**
+ * Discard memory and reserved arrays if they were allocated
+ */
+void __init memblock_discard(void)
 {
-       if (memblock.memory.regions == memblock_memory_init_regions)
-               return 0;
+       phys_addr_t addr, size;
 
-       *addr = __pa(memblock.memory.regions);
+       if (memblock.reserved.regions != memblock_reserved_init_regions) {
+               addr = __pa(memblock.reserved.regions);
+               size = PAGE_ALIGN(sizeof(struct memblock_region) *
+                                 memblock.reserved.max);
+               __memblock_free_late(addr, size);
+       }
 
-       return PAGE_ALIGN(sizeof(struct memblock_region) *
-                         memblock.memory.max);
+       if (memblock.memory.regions == memblock_memory_init_regions) {
+               addr = __pa(memblock.memory.regions);
+               size = PAGE_ALIGN(sizeof(struct memblock_region) *
+                                 memblock.memory.max);
+               __memblock_free_late(addr, size);
+       }
 }
-
 #endif
 
 /**
index 3df3c04..e09741a 100644 (file)
@@ -1611,9 +1611,13 @@ cleanup:
  * @page: the page
  *
  * This function protects unlocked LRU pages from being moved to
- * another cgroup and stabilizes their page->mem_cgroup binding.
+ * another cgroup.
+ *
+ * It ensures lifetime of the returned memcg. Caller is responsible
+ * for the lifetime of the page; __unlock_page_memcg() is available
+ * when @page might get freed inside the locked section.
  */
-void lock_page_memcg(struct page *page)
+struct mem_cgroup *lock_page_memcg(struct page *page)
 {
        struct mem_cgroup *memcg;
        unsigned long flags;
@@ -1622,18 +1626,24 @@ void lock_page_memcg(struct page *page)
         * The RCU lock is held throughout the transaction.  The fast
         * path can get away without acquiring the memcg->move_lock
         * because page moving starts with an RCU grace period.
-        */
+        *
+        * The RCU lock also protects the memcg from being freed when
+        * the page state that is going to change is the only thing
+        * preventing the page itself from being freed. E.g. writeback
+        * doesn't hold a page reference and relies on PG_writeback to
+        * keep off truncation, migration and so forth.
+         */
        rcu_read_lock();
 
        if (mem_cgroup_disabled())
-               return;
+               return NULL;
 again:
        memcg = page->mem_cgroup;
        if (unlikely(!memcg))
-               return;
+               return NULL;
 
        if (atomic_read(&memcg->moving_account) <= 0)
-               return;
+               return memcg;
 
        spin_lock_irqsave(&memcg->move_lock, flags);
        if (memcg != page->mem_cgroup) {
@@ -1649,18 +1659,18 @@ again:
        memcg->move_lock_task = current;
        memcg->move_lock_flags = flags;
 
-       return;
+       return memcg;
 }
 EXPORT_SYMBOL(lock_page_memcg);
 
 /**
- * unlock_page_memcg - unlock a page->mem_cgroup binding
- * @page: the page
+ * __unlock_page_memcg - unlock and unpin a memcg
+ * @memcg: the memcg
+ *
+ * Unlock and unpin a memcg returned by lock_page_memcg().
  */
-void unlock_page_memcg(struct page *page)
+void __unlock_page_memcg(struct mem_cgroup *memcg)
 {
-       struct mem_cgroup *memcg = page->mem_cgroup;
-
        if (memcg && memcg->move_lock_task == current) {
                unsigned long flags = memcg->move_lock_flags;
 
@@ -1672,6 +1682,15 @@ void unlock_page_memcg(struct page *page)
 
        rcu_read_unlock();
 }
+
+/**
+ * unlock_page_memcg - unlock a page->mem_cgroup binding
+ * @page: the page
+ */
+void unlock_page_memcg(struct page *page)
+{
+       __unlock_page_memcg(page->mem_cgroup);
+}
 EXPORT_SYMBOL(unlock_page_memcg);
 
 /*
index e158f7a..fe2fba2 100644 (file)
@@ -68,6 +68,7 @@
 #include <linux/debugfs.h>
 #include <linux/userfaultfd_k.h>
 #include <linux/dax.h>
+#include <linux/oom.h>
 
 #include <asm/io.h>
 #include <asm/mmu_context.h>
@@ -2893,6 +2894,7 @@ static int do_anonymous_page(struct vm_fault *vmf)
        struct vm_area_struct *vma = vmf->vma;
        struct mem_cgroup *memcg;
        struct page *page;
+       int ret = 0;
        pte_t entry;
 
        /* File mapping without ->vm_ops ? */
@@ -2925,6 +2927,9 @@ static int do_anonymous_page(struct vm_fault *vmf)
                                vmf->address, &vmf->ptl);
                if (!pte_none(*vmf->pte))
                        goto unlock;
+               ret = check_stable_address_space(vma->vm_mm);
+               if (ret)
+                       goto unlock;
                /* Deliver the page fault to userland, check inside PT lock */
                if (userfaultfd_missing(vma)) {
                        pte_unmap_unlock(vmf->pte, vmf->ptl);
@@ -2959,6 +2964,10 @@ static int do_anonymous_page(struct vm_fault *vmf)
        if (!pte_none(*vmf->pte))
                goto release;
 
+       ret = check_stable_address_space(vma->vm_mm);
+       if (ret)
+               goto release;
+
        /* Deliver the page fault to userland, check inside PT lock */
        if (userfaultfd_missing(vma)) {
                pte_unmap_unlock(vmf->pte, vmf->ptl);
@@ -2978,7 +2987,7 @@ setpte:
        update_mmu_cache(vma, vmf->address, vmf->pte);
 unlock:
        pte_unmap_unlock(vmf->pte, vmf->ptl);
-       return 0;
+       return ret;
 release:
        mem_cgroup_cancel_charge(page, memcg, false);
        put_page(page);
@@ -3252,7 +3261,7 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
 int finish_fault(struct vm_fault *vmf)
 {
        struct page *page;
-       int ret;
+       int ret = 0;
 
        /* Did we COW the page? */
        if ((vmf->flags & FAULT_FLAG_WRITE) &&
@@ -3260,7 +3269,15 @@ int finish_fault(struct vm_fault *vmf)
                page = vmf->cow_page;
        else
                page = vmf->page;
-       ret = alloc_set_pte(vmf, vmf->memcg, page);
+
+       /*
+        * check even for read faults because we might have lost our CoWed
+        * page
+        */
+       if (!(vmf->vma->vm_flags & VM_SHARED))
+               ret = check_stable_address_space(vmf->vma->vm_mm);
+       if (!ret)
+               ret = alloc_set_pte(vmf, vmf->memcg, page);
        if (vmf->pte)
                pte_unmap_unlock(vmf->pte, vmf->ptl);
        return ret;
@@ -3900,19 +3917,6 @@ int handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
                        mem_cgroup_oom_synchronize(false);
        }
 
-       /*
-        * This mm has been already reaped by the oom reaper and so the
-        * refault cannot be trusted in general. Anonymous refaults would
-        * lose data and give a zero page instead e.g. This is especially
-        * problem for use_mm() because regular tasks will just die and
-        * the corrupted data will not be visible anywhere while kthread
-        * will outlive the oom victim and potentially propagate the date
-        * further.
-        */
-       if (unlikely((current->flags & PF_KTHREAD) && !(ret & VM_FAULT_ERROR)
-                               && test_bit(MMF_UNSTABLE, &vma->vm_mm->flags)))
-               ret = VM_FAULT_SIGBUS;
-
        return ret;
 }
 EXPORT_SYMBOL_GPL(handle_mm_fault);
index d911fa5..618ab12 100644 (file)
@@ -861,11 +861,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
                *policy |= (pol->flags & MPOL_MODE_FLAGS);
        }
 
-       if (vma) {
-               up_read(&current->mm->mmap_sem);
-               vma = NULL;
-       }
-
        err = 0;
        if (nmask) {
                if (mpol_store_user_nodemask(pol)) {
index d68a41d..e84eeb4 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/page_idle.h>
 #include <linux/page_owner.h>
 #include <linux/sched/mm.h>
+#include <linux/ptrace.h>
 
 #include <asm/tlbflush.h>
 
@@ -1652,7 +1653,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
                const int __user *, nodes,
                int __user *, status, int, flags)
 {
-       const struct cred *cred = current_cred(), *tcred;
        struct task_struct *task;
        struct mm_struct *mm;
        int err;
@@ -1676,14 +1676,9 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
 
        /*
         * Check if this process has the right to modify the specified
-        * process. The right exists if the process has administrative
-        * capabilities, superuser privileges or the same
-        * userid as the target process.
+        * process. Use the regular "ptrace_may_access()" checks.
         */
-       tcred = __task_cred(task);
-       if (!uid_eq(cred->euid, tcred->suid) && !uid_eq(cred->euid, tcred->uid) &&
-           !uid_eq(cred->uid,  tcred->suid) && !uid_eq(cred->uid,  tcred->uid) &&
-           !capable(CAP_SYS_NICE)) {
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
                rcu_read_unlock();
                err = -EPERM;
                goto out;
index 36454d0..3637809 100644 (file)
@@ -146,22 +146,6 @@ static unsigned long __init free_low_memory_core_early(void)
                                NULL)
                count += __free_memory_core(start, end);
 
-#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
-       {
-               phys_addr_t size;
-
-               /* Free memblock.reserved array if it was allocated */
-               size = get_allocated_memblock_reserved_regions_info(&start);
-               if (size)
-                       count += __free_memory_core(start, start + size);
-
-               /* Free memblock.memory array if it was allocated */
-               size = get_allocated_memblock_memory_regions_info(&start);
-               if (size)
-                       count += __free_memory_core(start, start + size);
-       }
-#endif
-
        return count;
 }
 
index 96e93b2..bf050ab 100644 (file)
@@ -2724,9 +2724,12 @@ EXPORT_SYMBOL(clear_page_dirty_for_io);
 int test_clear_page_writeback(struct page *page)
 {
        struct address_space *mapping = page_mapping(page);
+       struct mem_cgroup *memcg;
+       struct lruvec *lruvec;
        int ret;
 
-       lock_page_memcg(page);
+       memcg = lock_page_memcg(page);
+       lruvec = mem_cgroup_page_lruvec(page, page_pgdat(page));
        if (mapping && mapping_use_writeback_tags(mapping)) {
                struct inode *inode = mapping->host;
                struct backing_dev_info *bdi = inode_to_bdi(inode);
@@ -2754,12 +2757,18 @@ int test_clear_page_writeback(struct page *page)
        } else {
                ret = TestClearPageWriteback(page);
        }
+       /*
+        * NOTE: Page might be free now! Writeback doesn't hold a page
+        * reference on its own, it relies on truncation to wait for
+        * the clearing of PG_writeback. The below can only access
+        * page state that is static across allocation cycles.
+        */
        if (ret) {
-               dec_lruvec_page_state(page, NR_WRITEBACK);
+               dec_lruvec_state(lruvec, NR_WRITEBACK);
                dec_zone_page_state(page, NR_ZONE_WRITE_PENDING);
                inc_node_page_state(page, NR_WRITTEN);
        }
-       unlock_page_memcg(page);
+       __unlock_page_memcg(memcg);
        return ret;
 }
 
index 6acf612..471b052 100644 (file)
@@ -1585,6 +1585,10 @@ void __init page_alloc_init_late(void)
        /* Reinit limits that are based on free pages after the kernel is up */
        files_maxfiles_init();
 #endif
+#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
+       /* Discard memblock private memory */
+       memblock_discard();
+#endif
 
        for_each_populated_zone(zone)
                set_zone_contiguous(zone);
index 1d3f983..e8b4e31 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5642,13 +5642,14 @@ static void sysfs_slab_remove_workfn(struct work_struct *work)
                 * A cache is never shut down before deactivation is
                 * complete, so no need to worry about synchronization.
                 */
-               return;
+               goto out;
 
 #ifdef CONFIG_MEMCG
        kset_unregister(s->memcg_kset);
 #endif
        kobject_uevent(&s->kobj, KOBJ_REMOVE);
        kobject_del(&s->kobj);
+out:
        kobject_put(&s->kobj);
 }
 
index 8698c1c..a47e389 100644 (file)
@@ -1671,7 +1671,10 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
        struct page **pages;
        unsigned int nr_pages, array_size, i;
        const gfp_t nested_gfp = (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO;
-       const gfp_t alloc_mask = gfp_mask | __GFP_HIGHMEM | __GFP_NOWARN;
+       const gfp_t alloc_mask = gfp_mask | __GFP_NOWARN;
+       const gfp_t highmem_mask = (gfp_mask & (GFP_DMA | GFP_DMA32)) ?
+                                       0 :
+                                       __GFP_HIGHMEM;
 
        nr_pages = get_vm_area_size(area) >> PAGE_SHIFT;
        array_size = (nr_pages * sizeof(struct page *));
@@ -1679,7 +1682,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
        area->nr_pages = nr_pages;
        /* Please note that the recursion is strictly bounded. */
        if (array_size > PAGE_SIZE) {
-               pages = __vmalloc_node(array_size, 1, nested_gfp|__GFP_HIGHMEM,
+               pages = __vmalloc_node(array_size, 1, nested_gfp|highmem_mask,
                                PAGE_KERNEL, node, area->caller);
        } else {
                pages = kmalloc_node(array_size, nested_gfp, node);
@@ -1700,9 +1703,9 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
                }
 
                if (node == NUMA_NO_NODE)
-                       page = alloc_page(alloc_mask);
+                       page = alloc_page(alloc_mask|highmem_mask);
                else
-                       page = alloc_pages_node(node, alloc_mask, 0);
+                       page = alloc_pages_node(node, alloc_mask|highmem_mask, 0);
 
                if (unlikely(!page)) {
                        /* Successfully allocated i pages, free them in __vunmap() */
@@ -1710,7 +1713,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
                        goto fail;
                }
                area->pages[i] = page;
-               if (gfpflags_allow_blocking(gfp_mask))
+               if (gfpflags_allow_blocking(gfp_mask|highmem_mask))
                        cond_resched();
        }
 
index ee5647b..a21ca8d 100644 (file)
@@ -169,14 +169,20 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
                                          int *peeked, int *off, int *err,
                                          struct sk_buff **last)
 {
+       bool peek_at_off = false;
        struct sk_buff *skb;
-       int _off = *off;
+       int _off = 0;
+
+       if (unlikely(flags & MSG_PEEK && *off >= 0)) {
+               peek_at_off = true;
+               _off = *off;
+       }
 
        *last = queue->prev;
        skb_queue_walk(queue, skb) {
                if (flags & MSG_PEEK) {
-                       if (_off >= skb->len && (skb->len || _off ||
-                                                skb->peeked)) {
+                       if (peek_at_off && _off >= skb->len &&
+                           (_off || skb->peeked)) {
                                _off -= skb->len;
                                continue;
                        }
index f44fc22..6280a60 100644 (file)
@@ -3505,6 +3505,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                                              bpf_target_off(struct sk_buff, tc_index, 2,
                                                             target_size));
 #else
+               *target_size = 2;
                if (type == BPF_WRITE)
                        *insn++ = BPF_MOV64_REG(si->dst_reg, si->dst_reg);
                else
@@ -3520,6 +3521,7 @@ static u32 bpf_convert_ctx_access(enum bpf_access_type type,
                *insn++ = BPF_JMP_IMM(BPF_JGE, si->dst_reg, MIN_NAPI_ID, 1);
                *insn++ = BPF_MOV64_IMM(si->dst_reg, 0);
 #else
+               *target_size = 4;
                *insn++ = BPF_MOV64_IMM(si->dst_reg, 0);
 #endif
                break;
index 9fe25bf..b68168f 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/checksum.h>
 
 #include <net/inet_sock.h>
+#include <net/inet_common.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
 
@@ -170,6 +171,15 @@ const char *dccp_packet_name(const int type)
 
 EXPORT_SYMBOL_GPL(dccp_packet_name);
 
+static void dccp_sk_destruct(struct sock *sk)
+{
+       struct dccp_sock *dp = dccp_sk(sk);
+
+       ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
+       dp->dccps_hc_tx_ccid = NULL;
+       inet_sock_destruct(sk);
+}
+
 int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
 {
        struct dccp_sock *dp = dccp_sk(sk);
@@ -179,6 +189,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
        icsk->icsk_syn_retries  = sysctl_dccp_request_retries;
        sk->sk_state            = DCCP_CLOSED;
        sk->sk_write_space      = dccp_write_space;
+       sk->sk_destruct         = dccp_sk_destruct;
        icsk->icsk_sync_mss     = dccp_sync_mss;
        dp->dccps_mss_cache     = 536;
        dp->dccps_rate_last     = jiffies;
@@ -201,10 +212,7 @@ void dccp_destroy_sock(struct sock *sk)
 {
        struct dccp_sock *dp = dccp_sk(sk);
 
-       /*
-        * DCCP doesn't use sk_write_queue, just sk_send_head
-        * for retransmissions
-        */
+       __skb_queue_purge(&sk->sk_write_queue);
        if (sk->sk_send_head != NULL) {
                kfree_skb(sk->sk_send_head);
                sk->sk_send_head = NULL;
@@ -222,8 +230,7 @@ void dccp_destroy_sock(struct sock *sk)
                dp->dccps_hc_rx_ackvec = NULL;
        }
        ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
-       ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
-       dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
+       dp->dccps_hc_rx_ccid = NULL;
 
        /* clean up feature negotiation state */
        dccp_feat_list_purge(&dp->dccps_featneg);
index fab41de..de66ca8 100644 (file)
@@ -42,6 +42,9 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
        padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len;
 
        if (skb_tailroom(skb) >= padlen + KSZ_INGRESS_TAG_LEN) {
+               if (skb_put_padto(skb, skb->len + padlen))
+                       return NULL;
+
                nskb = skb;
        } else {
                nskb = alloc_skb(NET_IP_ALIGN + skb->len +
@@ -56,13 +59,15 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
                skb_set_transport_header(nskb,
                                         skb_transport_header(skb) - skb->head);
                skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len));
+
+               if (skb_put_padto(nskb, nskb->len + padlen)) {
+                       kfree_skb(nskb);
+                       return NULL;
+               }
+
                kfree_skb(skb);
        }
 
-       /* skb is freed when it fails */
-       if (skb_put_padto(nskb, nskb->len + padlen))
-               return NULL;
-
        tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN);
        tag[0] = 0;
        tag[1] = 1 << p->dp->index; /* destination port */
index b8d1817..ec3a9ce 100644 (file)
@@ -1083,15 +1083,17 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
        fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
        if (!fi)
                goto failure;
-       fib_info_cnt++;
        if (cfg->fc_mx) {
                fi->fib_metrics = kzalloc(sizeof(*fi->fib_metrics), GFP_KERNEL);
-               if (!fi->fib_metrics)
-                       goto failure;
+               if (unlikely(!fi->fib_metrics)) {
+                       kfree(fi);
+                       return ERR_PTR(err);
+               }
                atomic_set(&fi->fib_metrics->refcnt, 1);
-       } else
+       } else {
                fi->fib_metrics = (struct dst_metrics *)&dst_default_metrics;
-
+       }
+       fib_info_cnt++;
        fi->fib_net = net;
        fi->fib_protocol = cfg->fc_protocol;
        fi->fib_scope = cfg->fc_scope;
index 498706b..caf2f11 100644 (file)
@@ -1007,10 +1007,18 @@ int igmp_rcv(struct sk_buff *skb)
 {
        /* This basically follows the spec line by line -- see RFC1112 */
        struct igmphdr *ih;
-       struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
+       struct net_device *dev = skb->dev;
+       struct in_device *in_dev;
        int len = skb->len;
        bool dropped = true;
 
+       if (netif_is_l3_master(dev)) {
+               dev = dev_get_by_index_rcu(dev_net(dev), IPCB(skb)->iif);
+               if (!dev)
+                       goto drop;
+       }
+
+       in_dev = __in_dev_get_rcu(dev);
        if (!in_dev)
                goto drop;
 
index 0383e66..2331de2 100644 (file)
@@ -1267,7 +1267,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
        if (mtu)
                return mtu;
 
-       mtu = dst->dev->mtu;
+       mtu = READ_ONCE(dst->dev->mtu);
 
        if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
                if (rt->rt_uses_gateway && mtu > 576)
@@ -2750,26 +2750,34 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
                err = 0;
                if (IS_ERR(rt))
                        err = PTR_ERR(rt);
+               else
+                       skb_dst_set(skb, &rt->dst);
        }
 
        if (err)
                goto errout_free;
 
-       skb_dst_set(skb, &rt->dst);
        if (rtm->rtm_flags & RTM_F_NOTIFY)
                rt->rt_flags |= RTCF_NOTIFY;
 
        if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
                table_id = rt->rt_table_id;
 
-       if (rtm->rtm_flags & RTM_F_FIB_MATCH)
+       if (rtm->rtm_flags & RTM_F_FIB_MATCH) {
+               if (!res.fi) {
+                       err = fib_props[res.type].error;
+                       if (!err)
+                               err = -EHOSTUNREACH;
+                       goto errout_free;
+               }
                err = fib_dump_info(skb, NETLINK_CB(in_skb).portid,
                                    nlh->nlmsg_seq, RTM_NEWROUTE, table_id,
                                    rt->rt_type, res.prefix, res.prefixlen,
                                    fl4.flowi4_tos, res.fi, 0);
-       else
+       } else {
                err = rt_fill_info(net, dst, src, table_id, &fl4, skb,
                                   NETLINK_CB(in_skb).portid, nlh->nlmsg_seq);
+       }
        if (err < 0)
                goto errout_free;
 
index 53de142..bab7f04 100644 (file)
@@ -3009,8 +3009,7 @@ void tcp_rearm_rto(struct sock *sk)
                        /* delta_us may not be positive if the socket is locked
                         * when the retrans timer fires and is rescheduled.
                         */
-                       if (delta_us > 0)
-                               rto = usecs_to_jiffies(delta_us);
+                       rto = usecs_to_jiffies(max_t(int, delta_us, 1));
                }
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto,
                                          TCP_RTO_MAX);
index a20e7f0..e9252c7 100644 (file)
@@ -1722,6 +1722,8 @@ process:
                 */
                sock_hold(sk);
                refcounted = true;
+               if (tcp_filter(sk, skb))
+                       goto discard_and_relse;
                nsk = tcp_check_req(sk, skb, req, false);
                if (!nsk) {
                        reqsk_put(req);
@@ -1729,8 +1731,6 @@ process:
                }
                if (nsk == sk) {
                        reqsk_put(req);
-               } else if (tcp_filter(sk, skb)) {
-                       goto discard_and_relse;
                } else if (tcp_child_process(sk, nsk, skb)) {
                        tcp_v4_send_reset(nsk, skb);
                        goto discard_and_relse;
index 2417f55..6bb9e14 100644 (file)
@@ -122,14 +122,14 @@ int tcp_set_ulp(struct sock *sk, const char *name)
 
        ulp_ops = __tcp_ulp_find_autoload(name);
        if (!ulp_ops)
-               err = -ENOENT;
-       else
-               err = ulp_ops->init(sk);
+               return -ENOENT;
 
-       if (err)
-               goto out;
+       err = ulp_ops->init(sk);
+       if (err) {
+               module_put(ulp_ops->owner);
+               return err;
+       }
 
        icsk->icsk_ulp_ops = ulp_ops;
- out:
-       return err;
+       return 0;
 }
index b34f09b..ebe46ed 100644 (file)
@@ -1574,7 +1574,8 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
                return ip_recv_error(sk, msg, len, addr_len);
 
 try_again:
-       peeking = off = sk_peek_offset(sk, flags);
+       peeking = flags & MSG_PEEK;
+       off = sk_peek_offset(sk, flags);
        skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
        if (!skb)
                return err;
index ebb299c..5cc0ea0 100644 (file)
@@ -914,6 +914,8 @@ add:
                }
                nsiblings = iter->rt6i_nsiblings;
                fib6_purge_rt(iter, fn, info->nl_net);
+               if (fn->rr_ptr == iter)
+                       fn->rr_ptr = NULL;
                rt6_release(iter);
 
                if (nsiblings) {
@@ -926,6 +928,8 @@ add:
                                if (rt6_qualify_for_ecmp(iter)) {
                                        *ins = iter->dst.rt6_next;
                                        fib6_purge_rt(iter, fn, info->nl_net);
+                                       if (fn->rr_ptr == iter)
+                                               fn->rr_ptr = NULL;
                                        rt6_release(iter);
                                        nsiblings--;
                                } else {
@@ -1014,7 +1018,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
                        /* Create subtree root node */
                        sfn = node_alloc();
                        if (!sfn)
-                               goto st_failure;
+                               goto failure;
 
                        sfn->leaf = info->nl_net->ipv6.ip6_null_entry;
                        atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref);
@@ -1031,12 +1035,12 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
 
                        if (IS_ERR(sn)) {
                                /* If it is failed, discard just allocated
-                                  root, and then (in st_failure) stale node
+                                  root, and then (in failure) stale node
                                   in main tree.
                                 */
                                node_free(sfn);
                                err = PTR_ERR(sn);
-                               goto st_failure;
+                               goto failure;
                        }
 
                        /* Now link new subtree to main tree */
@@ -1051,7 +1055,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
 
                        if (IS_ERR(sn)) {
                                err = PTR_ERR(sn);
-                               goto st_failure;
+                               goto failure;
                        }
                }
 
@@ -1092,18 +1096,17 @@ out:
                        atomic_inc(&pn->leaf->rt6i_ref);
                }
 #endif
-               /* Always release dst as dst->__refcnt is guaranteed
-                * to be taken before entering this function
-                */
-               dst_release_immediate(&rt->dst);
+               goto failure;
        }
        return err;
 
-#ifdef CONFIG_IPV6_SUBTREES
-       /* Subtree creation failed, probably main tree node
-          is orphan. If it is, shoot it.
+failure:
+       /* fn->leaf could be NULL if fn is an intermediate node and we
+        * failed to add the new route to it in both subtree creation
+        * failure and fib6_add_rt2node() failure case.
+        * In both cases, fib6_repair_tree() should be called to fix
+        * fn->leaf.
         */
-st_failure:
        if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)))
                fib6_repair_tree(info->nl_net, fn);
        /* Always release dst as dst->__refcnt is guaranteed
@@ -1111,7 +1114,6 @@ st_failure:
         */
        dst_release_immediate(&rt->dst);
        return err;
-#endif
 }
 
 /*
index a640fbc..94d6a13 100644 (file)
@@ -417,14 +417,11 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
        struct net_device *loopback_dev =
                dev_net(dev)->loopback_dev;
 
-       if (dev != loopback_dev) {
-               if (idev && idev->dev == dev) {
-                       struct inet6_dev *loopback_idev =
-                               in6_dev_get(loopback_dev);
-                       if (loopback_idev) {
-                               rt->rt6i_idev = loopback_idev;
-                               in6_dev_put(idev);
-                       }
+       if (idev && idev->dev != loopback_dev) {
+               struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev);
+               if (loopback_idev) {
+                       rt->rt6i_idev = loopback_idev;
+                       in6_dev_put(idev);
                }
        }
 }
@@ -3724,10 +3721,10 @@ static int ip6_route_dev_notify(struct notifier_block *this,
                /* NETDEV_UNREGISTER could be fired for multiple times by
                 * netdev_wait_allrefs(). Make sure we only call this once.
                 */
-               in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev);
+               in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
-               in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev);
-               in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev);
+               in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
+               in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
 #endif
        }
 
index 2521690..2062101 100644 (file)
@@ -1456,6 +1456,8 @@ process:
                }
                sock_hold(sk);
                refcounted = true;
+               if (tcp_filter(sk, skb))
+                       goto discard_and_relse;
                nsk = tcp_check_req(sk, skb, req, false);
                if (!nsk) {
                        reqsk_put(req);
@@ -1464,8 +1466,6 @@ process:
                if (nsk == sk) {
                        reqsk_put(req);
                        tcp_v6_restore_cb(skb);
-               } else if (tcp_filter(sk, skb)) {
-                       goto discard_and_relse;
                } else if (tcp_child_process(sk, nsk, skb)) {
                        tcp_v6_send_reset(nsk, skb);
                        goto discard_and_relse;
index 96d2407..8cd9b62 100644 (file)
@@ -362,7 +362,8 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
 
 try_again:
-       peeking = off = sk_peek_offset(sk, flags);
+       peeking = flags & MSG_PEEK;
+       off = sk_peek_offset(sk, flags);
        skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
        if (!skb)
                return err;
index 2e6990f..23fa7c8 100644 (file)
@@ -2213,7 +2213,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
 {
        struct sock *sk = sock->sk;
        struct irda_sock *self = irda_sk(sk);
-       struct irda_device_list list;
+       struct irda_device_list list = { 0 };
        struct irda_device_info *discoveries;
        struct irda_ias_set *   ias_opt;        /* IAS get/query params */
        struct ias_object *     ias_obj;        /* Object in IAS */
index ca9d3ae..98f4d82 100644 (file)
@@ -228,7 +228,7 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
 #define BROADCAST_ONE          1
 #define BROADCAST_REGISTERED   2
 #define BROADCAST_PROMISC_ONLY 4
-static int pfkey_broadcast(struct sk_buff *skb,
+static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
                           int broadcast_flags, struct sock *one_sk,
                           struct net *net)
 {
@@ -278,7 +278,7 @@ static int pfkey_broadcast(struct sk_buff *skb,
        rcu_read_unlock();
 
        if (one_sk != NULL)
-               err = pfkey_broadcast_one(skb, &skb2, GFP_KERNEL, one_sk);
+               err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk);
 
        kfree_skb(skb2);
        kfree_skb(skb);
@@ -311,7 +311,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk)
                hdr = (struct sadb_msg *) pfk->dump.skb->data;
                hdr->sadb_msg_seq = 0;
                hdr->sadb_msg_errno = rc;
-               pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+               pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
                                &pfk->sk, sock_net(&pfk->sk));
                pfk->dump.skb = NULL;
        }
@@ -355,7 +355,7 @@ static int pfkey_error(const struct sadb_msg *orig, int err, struct sock *sk)
        hdr->sadb_msg_len = (sizeof(struct sadb_msg) /
                             sizeof(uint64_t));
 
-       pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk));
+       pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk));
 
        return 0;
 }
@@ -1389,7 +1389,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, const struct sadb_
 
        xfrm_state_put(x);
 
-       pfkey_broadcast(resp_skb, BROADCAST_ONE, sk, net);
+       pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net);
 
        return 0;
 }
@@ -1476,7 +1476,7 @@ static int key_notify_sa(struct xfrm_state *x, const struct km_event *c)
        hdr->sadb_msg_seq = c->seq;
        hdr->sadb_msg_pid = c->portid;
 
-       pfkey_broadcast(skb, BROADCAST_ALL, NULL, xs_net(x));
+       pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x));
 
        return 0;
 }
@@ -1589,7 +1589,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, const struct sadb_msg
        out_hdr->sadb_msg_reserved = 0;
        out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
        out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-       pfkey_broadcast(out_skb, BROADCAST_ONE, sk, sock_net(sk));
+       pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk));
 
        return 0;
 }
@@ -1694,8 +1694,8 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad
                return -ENOBUFS;
        }
 
-       pfkey_broadcast(supp_skb, BROADCAST_REGISTERED, sk, sock_net(sk));
-
+       pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk,
+                       sock_net(sk));
        return 0;
 }
 
@@ -1712,7 +1712,8 @@ static int unicast_flush_resp(struct sock *sk, const struct sadb_msg *ihdr)
        hdr->sadb_msg_errno = (uint8_t) 0;
        hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
 
-       return pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk));
+       return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk,
+                              sock_net(sk));
 }
 
 static int key_notify_sa_flush(const struct km_event *c)
@@ -1733,7 +1734,7 @@ static int key_notify_sa_flush(const struct km_event *c)
        hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
        hdr->sadb_msg_reserved = 0;
 
-       pfkey_broadcast(skb, BROADCAST_ALL, NULL, c->net);
+       pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
 
        return 0;
 }
@@ -1790,7 +1791,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
        out_hdr->sadb_msg_pid = pfk->dump.msg_portid;
 
        if (pfk->dump.skb)
-               pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+               pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
                                &pfk->sk, sock_net(&pfk->sk));
        pfk->dump.skb = out_skb;
 
@@ -1878,7 +1879,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, const struct sadb
                new_hdr->sadb_msg_errno = 0;
        }
 
-       pfkey_broadcast(skb, BROADCAST_ALL, NULL, sock_net(sk));
+       pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk));
        return 0;
 }
 
@@ -2206,7 +2207,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, const struct km_ev
        out_hdr->sadb_msg_errno = 0;
        out_hdr->sadb_msg_seq = c->seq;
        out_hdr->sadb_msg_pid = c->portid;
-       pfkey_broadcast(out_skb, BROADCAST_ALL, NULL, xp_net(xp));
+       pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp));
        return 0;
 
 }
@@ -2426,7 +2427,7 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, const struc
        out_hdr->sadb_msg_errno = 0;
        out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
        out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-       pfkey_broadcast(out_skb, BROADCAST_ONE, sk, xp_net(xp));
+       pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp));
        err = 0;
 
 out:
@@ -2682,7 +2683,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
        out_hdr->sadb_msg_pid = pfk->dump.msg_portid;
 
        if (pfk->dump.skb)
-               pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+               pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
                                &pfk->sk, sock_net(&pfk->sk));
        pfk->dump.skb = out_skb;
 
@@ -2739,7 +2740,7 @@ static int key_notify_policy_flush(const struct km_event *c)
        hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
        hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
        hdr->sadb_msg_reserved = 0;
-       pfkey_broadcast(skb_out, BROADCAST_ALL, NULL, c->net);
+       pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
        return 0;
 
 }
@@ -2803,7 +2804,7 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, const struct sadb
        void *ext_hdrs[SADB_EXT_MAX];
        int err;
 
-       pfkey_broadcast(skb_clone(skb, GFP_KERNEL),
+       pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,
                        BROADCAST_PROMISC_ONLY, NULL, sock_net(sk));
 
        memset(ext_hdrs, 0, sizeof(ext_hdrs));
@@ -3024,7 +3025,8 @@ static int key_notify_sa_expire(struct xfrm_state *x, const struct km_event *c)
        out_hdr->sadb_msg_seq = 0;
        out_hdr->sadb_msg_pid = 0;
 
-       pfkey_broadcast(out_skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+       pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+                       xs_net(x));
        return 0;
 }
 
@@ -3212,7 +3214,8 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
                       xfrm_ctx->ctx_len);
        }
 
-       return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+       return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+                              xs_net(x));
 }
 
 static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
@@ -3408,7 +3411,8 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
        n_port->sadb_x_nat_t_port_port = sport;
        n_port->sadb_x_nat_t_port_reserved = 0;
 
-       return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+       return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+                              xs_net(x));
 }
 
 #ifdef CONFIG_NET_KEY_MIGRATE
@@ -3599,7 +3603,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
        }
 
        /* broadcast migrate message to sockets */
-       pfkey_broadcast(skb, BROADCAST_ALL, NULL, &init_net);
+       pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net);
 
        return 0;
 
index 8708cbe..2b36eff 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015-2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -466,3 +466,23 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
        rcu_read_unlock();
 }
 EXPORT_SYMBOL(ieee80211_manage_rx_ba_offl);
+
+void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
+                                  const u8 *addr, unsigned int tid)
+{
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       struct ieee80211_local *local = sdata->local;
+       struct sta_info *sta;
+
+       rcu_read_lock();
+       sta = sta_info_get_bss(sdata, addr);
+       if (!sta)
+               goto unlock;
+
+       set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired);
+       ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
+
+ unlock:
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL(ieee80211_rx_ba_timer_expired);
index e461067..a54a556 100644 (file)
@@ -1337,6 +1337,7 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
                goto out;
        }
 
+       OVS_CB(skb)->acts_origlen = acts->orig_len;
        err = do_execute_actions(dp, skb, key,
                                 acts->actions, acts->actions_len);
 
index 45fe8c8..6b44fe4 100644 (file)
@@ -381,7 +381,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
 }
 
 static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
-                             unsigned int hdrlen)
+                             unsigned int hdrlen, int actions_attrlen)
 {
        size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
                + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
@@ -398,7 +398,7 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
 
        /* OVS_PACKET_ATTR_ACTIONS */
        if (upcall_info->actions_len)
-               size += nla_total_size(upcall_info->actions_len);
+               size += nla_total_size(actions_attrlen);
 
        /* OVS_PACKET_ATTR_MRU */
        if (upcall_info->mru)
@@ -465,7 +465,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
        else
                hlen = skb->len;
 
-       len = upcall_msg_size(upcall_info, hlen - cutlen);
+       len = upcall_msg_size(upcall_info, hlen - cutlen,
+                             OVS_CB(skb)->acts_origlen);
        user_skb = genlmsg_new(len, GFP_ATOMIC);
        if (!user_skb) {
                err = -ENOMEM;
index 5d8dcd8..4806006 100644 (file)
@@ -99,11 +99,13 @@ struct datapath {
  * when a packet is received by OVS.
  * @mru: The maximum received fragement size; 0 if the packet is not
  * fragmented.
+ * @acts_origlen: The netlink size of the flow actions applied to this skb.
  * @cutlen: The number of bytes from the packet end to be removed.
  */
 struct ovs_skb_cb {
        struct vport            *input_vport;
        u16                     mru;
+       u16                     acts_origlen;
        u32                     cutlen;
 };
 #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
index dd30d74..ec3383f 100644 (file)
@@ -223,6 +223,7 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx)
        tail = b->call_backlog_tail;
        while (CIRC_CNT(head, tail, size) > 0) {
                struct rxrpc_call *call = b->call_backlog[tail];
+               call->socket = rx;
                if (rx->discard_new_call) {
                        _debug("discard %lx", call->user_call_ID);
                        rx->discard_new_call(call, call->user_call_ID);
index d516ba8..5417078 100644 (file)
@@ -41,6 +41,7 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
 {
        struct xt_tgchk_param par;
        struct xt_target *target;
+       struct ipt_entry e = {};
        int ret = 0;
 
        target = xt_request_find_target(AF_INET, t->u.user.name,
@@ -52,6 +53,7 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
        memset(&par, 0, sizeof(par));
        par.net       = net;
        par.table     = table;
+       par.entryinfo = &e;
        par.target    = target;
        par.targinfo  = t->data;
        par.hook_mask = hook;
index 39da0c5..9fd44c2 100644 (file)
@@ -205,7 +205,7 @@ static void tcf_chain_flush(struct tcf_chain *chain)
 {
        struct tcf_proto *tp;
 
-       if (*chain->p_filter_chain)
+       if (chain->p_filter_chain)
                RCU_INIT_POINTER(*chain->p_filter_chain, NULL);
        while ((tp = rtnl_dereference(chain->filter_chain)) != NULL) {
                RCU_INIT_POINTER(chain->filter_chain, tp->next);
index bd24a55..a3fa144 100644 (file)
@@ -286,9 +286,6 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
 void qdisc_hash_add(struct Qdisc *q, bool invisible)
 {
        if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
-               struct Qdisc *root = qdisc_dev(q)->qdisc;
-
-               WARN_ON_ONCE(root == &noop_qdisc);
                ASSERT_RTNL();
                hash_add_rcu(qdisc_dev(q)->qdisc_hash, &q->hash, q->handle);
                if (invisible)
index 572fe25..c403c87 100644 (file)
@@ -572,8 +572,10 @@ static void atm_tc_destroy(struct Qdisc *sch)
        struct atm_flow_data *flow, *tmp;
 
        pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
-       list_for_each_entry(flow, &p->flows, list)
+       list_for_each_entry(flow, &p->flows, list) {
                tcf_block_put(flow->block);
+               flow->block = NULL;
+       }
 
        list_for_each_entry_safe(flow, tmp, &p->flows, list) {
                if (flow->ref > 1)
index 481036f..780db43 100644 (file)
@@ -1431,8 +1431,10 @@ static void cbq_destroy(struct Qdisc *sch)
         * be bound to classes which have been destroyed already. --TGR '04
         */
        for (h = 0; h < q->clhash.hashsize; h++) {
-               hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode)
+               hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) {
                        tcf_block_put(cl->block);
+                       cl->block = NULL;
+               }
        }
        for (h = 0; h < q->clhash.hashsize; h++) {
                hlist_for_each_entry_safe(cl, next, &q->clhash.hash[h],
index b52f746..fd15200 100644 (file)
@@ -1428,6 +1428,10 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
                return err;
        q->eligible = RB_ROOT;
 
+       err = tcf_block_get(&q->root.block, &q->root.filter_list);
+       if (err)
+               goto err_tcf;
+
        q->root.cl_common.classid = sch->handle;
        q->root.refcnt  = 1;
        q->root.sched   = q;
@@ -1447,6 +1451,10 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
        qdisc_watchdog_init(&q->watchdog, sch);
 
        return 0;
+
+err_tcf:
+       qdisc_class_hash_destroy(&q->clhash);
+       return err;
 }
 
 static int
@@ -1522,8 +1530,10 @@ hfsc_destroy_qdisc(struct Qdisc *sch)
        unsigned int i;
 
        for (i = 0; i < q->clhash.hashsize; i++) {
-               hlist_for_each_entry(cl, &q->clhash.hash[i], cl_common.hnode)
+               hlist_for_each_entry(cl, &q->clhash.hash[i], cl_common.hnode) {
                        tcf_block_put(cl->block);
+                       cl->block = NULL;
+               }
        }
        for (i = 0; i < q->clhash.hashsize; i++) {
                hlist_for_each_entry_safe(cl, next, &q->clhash.hash[i],
index 203286a..5d65ec5 100644 (file)
@@ -1258,8 +1258,10 @@ static void htb_destroy(struct Qdisc *sch)
        tcf_block_put(q->block);
 
        for (i = 0; i < q->clhash.hashsize; i++) {
-               hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode)
+               hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) {
                        tcf_block_put(cl->block);
+                       cl->block = NULL;
+               }
        }
        for (i = 0; i < q->clhash.hashsize; i++) {
                hlist_for_each_entry_safe(cl, next, &q->clhash.hash[i],
index f80ea2c..82469ef 100644 (file)
@@ -437,6 +437,7 @@ congestion_drop:
                qdisc_drop(head, sch, to_free);
 
                slot_queue_add(slot, skb);
+               qdisc_tree_reduce_backlog(sch, 0, delta);
                return NET_XMIT_CN;
        }
 
@@ -468,8 +469,10 @@ enqueue:
        /* Return Congestion Notification only if we dropped a packet
         * from this flow.
         */
-       if (qlen != slot->qlen)
+       if (qlen != slot->qlen) {
+               qdisc_tree_reduce_backlog(sch, 0, dropped - qdisc_pkt_len(skb));
                return NET_XMIT_CN;
+       }
 
        /* As we dropped a packet, better let upper stack know this */
        qdisc_tree_reduce_backlog(sch, 1, dropped);
index 2a186b2..a4b6ffb 100644 (file)
@@ -512,7 +512,9 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
 {
        addr->sa.sa_family = AF_INET6;
        addr->v6.sin6_port = port;
+       addr->v6.sin6_flowinfo = 0;
        addr->v6.sin6_addr = *saddr;
+       addr->v6.sin6_scope_id = 0;
 }
 
 /* Compare addresses exactly.
index d174ee3..767e053 100644 (file)
@@ -596,7 +596,7 @@ static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
        rcu_read_lock();
        b = rcu_dereference_rtnl(dev->tipc_ptr);
        if (likely(b && test_bit(0, &b->up) &&
-                  (skb->pkt_type <= PACKET_BROADCAST))) {
+                  (skb->pkt_type <= PACKET_MULTICAST))) {
                skb->next = NULL;
                tipc_rcv(dev_net(dev), skb, b);
                rcu_read_unlock();
index ab30876..dcd90e6 100644 (file)
@@ -513,6 +513,7 @@ bool tipc_msg_reverse(u32 own_node,  struct sk_buff **skb, int err)
 
        /* Now reverse the concerned fields */
        msg_set_errcode(hdr, err);
+       msg_set_non_seq(hdr, 0);
        msg_set_origport(hdr, msg_destport(&ohdr));
        msg_set_destport(hdr, msg_origport(&ohdr));
        msg_set_destnode(hdr, msg_prevnode(&ohdr));
index 9bfe886..750949d 100644 (file)
@@ -258,13 +258,15 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
        arg = nlmsg_new(0, GFP_KERNEL);
        if (!arg) {
                kfree_skb(msg->rep);
+               msg->rep = NULL;
                return -ENOMEM;
        }
 
        err = __tipc_nl_compat_dumpit(cmd, msg, arg);
-       if (err)
+       if (err) {
                kfree_skb(msg->rep);
-
+               msg->rep = NULL;
+       }
        kfree_skb(arg);
 
        return err;
index 7b52a38..be8982b 100644 (file)
@@ -2304,10 +2304,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
         */
        mutex_lock(&u->iolock);
 
-       if (flags & MSG_PEEK)
-               skip = sk_peek_offset(sk, flags);
-       else
-               skip = 0;
+       skip = max(sk_peek_offset(sk, flags), 0);
 
        do {
                int chunk;
index dd8e2dd..9ffd3dd 100644 (file)
@@ -85,8 +85,8 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
 
 # try-run
 # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
-# Exit code chooses option. "$$TMP" is can be used as temporary file and
-# is automatically cleaned up.
+# Exit code chooses option. "$$TMP" serves as a temporary file and is
+# automatically cleaned up.
 try-run = $(shell set -e;              \
        TMP="$(TMPOUT).$$$$.tmp";       \
        TMPO="$(TMPOUT).$$$$.o";        \
@@ -261,7 +261,6 @@ make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1)))))
 any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
 
 # Execute command if command has changed or prerequisite(s) are updated.
-#
 if_changed = $(if $(strip $(any-prereq) $(arg-check)),                       \
        @set -e;                                                             \
        $(echo-cmd) $(cmd_$(1));                                             \
@@ -315,7 +314,7 @@ if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ),                 \
        $(rule_$(1)), @:)
 
 ###
-# why - tell why a a target got build
+# why - tell why a target got built
 #       enabled by make V=2
 #       Output (listed in the order they are checked):
 #          (1) - due to target is PHONY
index 95f7d80..a6c8c17 100644 (file)
@@ -1,9 +1,9 @@
 # include/asm-generic contains a lot of files that are used
 # verbatim by several architectures.
 #
-# This Makefile reads the file arch/$(SRCARCH)/include/asm/Kbuild
+# This Makefile reads the file arch/$(SRCARCH)/include/$(src)/Kbuild
 # and for each file listed in this file with generic-y creates
-# a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/asm)
+# a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/$(src))
 
 kbuild-file := $(srctree)/arch/$(SRCARCH)/include/$(src)/Kbuild
 -include $(kbuild-file)
index 854608d..a18cb44 100644 (file)
@@ -229,8 +229,8 @@ ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
 endif
 # Due to recursion, we must skip empty.o.
 # The empty.o file is created in the make process in order to determine
-#  the target endianness and word size. It is made before all other C
-#  files, including recordmcount.
+# the target endianness and word size. It is made before all other C
+# files, including recordmcount.
 sub_cmd_record_mcount =                                        \
        if [ $(@) != "scripts/mod/empty.o" ]; then      \
                $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)";   \
@@ -245,13 +245,13 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH
        "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
        "$(if $(part-of-module),1,0)" "$(@)";
 recordmcount_source := $(srctree)/scripts/recordmcount.pl
-endif
+endif # BUILD_C_RECORDMCOUNT
 cmd_record_mcount =                                            \
        if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" =   \
             "$(CC_FLAGS_FTRACE)" ]; then                       \
                $(sub_cmd_record_mcount)                        \
        fi;
-endif
+endif # CONFIG_FTRACE_MCOUNT_RECORD
 
 ifdef CONFIG_STACK_VALIDATION
 ifneq ($(SKIP_STACK_VALIDATION),1)
index 34614a4..993fb85 100644 (file)
@@ -14,7 +14,7 @@ src := $(obj)
 PHONY := __dtbs_install
 __dtbs_install:
 
-export dtbinst-root ?= $(obj)
+export dtbinst_root ?= $(obj)
 
 include include/config/auto.conf
 include scripts/Kbuild.include
@@ -27,7 +27,7 @@ dtbinst-dirs  := $(dts-dirs)
 quiet_cmd_dtb_install =        INSTALL $<
       cmd_dtb_install =        mkdir -p $(2); cp $< $(2)
 
-install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj))
+install-dir = $(patsubst $(dtbinst_root)%,$(INSTALL_DTBS_PATH)%,$(obj))
 
 $(dtbinst-files): %.dtb: $(obj)/%.dtb
        $(call cmd,dtb_install,$(install-dir))
index ec10d93..0372b33 100644 (file)
@@ -1,5 +1,5 @@
 ###
-# Makefile.basic lists the most basic programs used during the build process.
+# This Makefile lists the most basic programs used during the build process.
 # The programs listed herein are what are needed to do the basic stuff,
 # such as fix file dependencies.
 # This initial step is needed to avoid files to be recompiled
index fff818b..bbf62cb 100644 (file)
@@ -25,7 +25,7 @@
  *
  * So we play the same trick that "mkdep" played before. We replace
  * the dependency on autoconf.h by a dependency on every config
- * option which is mentioned in any of the listed prequisites.
+ * option which is mentioned in any of the listed prerequisites.
  *
  * kconfig populates a tree in include/config/ with an empty file
  * for each config symbol and when the configuration is updated
@@ -34,7 +34,7 @@
  * the config symbols are rebuilt.
  *
  * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
- * which depend on "include/linux/config/his/driver.h" will be rebuilt,
+ * which depend on "include/config/his/driver.h" will be rebuilt,
  * so most likely only his driver ;-)
  *
  * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
@@ -75,7 +75,7 @@
  * and then basically copies the .<target>.d file to stdout, in the
  * process filtering out the dependency on autoconf.h and adding
  * dependencies on include/config/my/option.h for every
- * CONFIG_MY_OPTION encountered in any of the prequisites.
+ * CONFIG_MY_OPTION encountered in any of the prerequisites.
  *
  * It will also filter out all the dependencies on *.ver. We need
  * to make sure that the generated version checksum are globally up
index a536760..45c1336 100644 (file)
@@ -47,10 +47,10 @@ config SND_SEQ_HRTIMER_DEFAULT
          timer.
 
 config SND_SEQ_MIDI_EVENT
-       def_tristate SND_RAWMIDI
+       tristate
 
 config SND_SEQ_MIDI
-       tristate
+       def_tristate SND_RAWMIDI
        select SND_SEQ_MIDI_EVENT
 
 config SND_SEQ_MIDI_EMUL
index 272c55f..ea2d0ae 100644 (file)
@@ -1502,16 +1502,11 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
 static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
 {
        struct snd_seq_queue_info *info = arg;
-       int result;
        struct snd_seq_queue *q;
 
-       result = snd_seq_queue_alloc(client->number, info->locked, info->flags);
-       if (result < 0)
-               return result;
-
-       q = queueptr(result);
-       if (q == NULL)
-               return -EINVAL;
+       q = snd_seq_queue_alloc(client->number, info->locked, info->flags);
+       if (IS_ERR(q))
+               return PTR_ERR(q);
 
        info->queue = q->queue;
        info->locked = q->locked;
@@ -1521,7 +1516,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
        if (!info->name[0])
                snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue);
        strlcpy(q->name, info->name, sizeof(q->name));
-       queuefree(q);
+       snd_use_lock_free(&q->use_lock);
 
        return 0;
 }
index 450c518..79e0c56 100644 (file)
@@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void)
 static void queue_use(struct snd_seq_queue *queue, int client, int use);
 
 /* allocate a new queue -
- * return queue index value or negative value for error
+ * return pointer to new queue or ERR_PTR(-errno) for error
+ * The new queue's use_lock is set to 1. It is the caller's responsibility to
+ * call snd_use_lock_free(&q->use_lock).
  */
-int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
+struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
 {
        struct snd_seq_queue *q;
 
        q = queue_new(client, locked);
        if (q == NULL)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
        q->info_flags = info_flags;
        queue_use(q, client, 1);
+       snd_use_lock_use(&q->use_lock);
        if (queue_list_add(q) < 0) {
+               snd_use_lock_free(&q->use_lock);
                queue_delete(q);
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
        }
-       return q->queue;
+       return q;
 }
 
 /* delete a queue - queue must be owned by the client */
index 30c8111..7190934 100644 (file)
@@ -71,7 +71,7 @@ void snd_seq_queues_delete(void);
 
 
 /* create new queue (constructor) */
-int snd_seq_queue_alloc(int client, int locked, unsigned int flags);
+struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags);
 
 /* delete queue (destructor) */
 int snd_seq_queue_delete(int client, int queueid);
index dc58595..a2b56b1 100644 (file)
@@ -698,10 +698,18 @@ static int copy_gctl(struct snd_emu10k1 *emu,
 {
        struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
 
-       if (emu->support_tlv)
-               return copy_from_user(gctl, &_gctl[idx], sizeof(*gctl));
+       if (emu->support_tlv) {
+               if (in_kernel)
+                       memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl));
+               else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)))
+                       return -EFAULT;
+               return 0;
+       }
+
        octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
-       if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
+       if (in_kernel)
+               memcpy(gctl, (void *)&octl[idx], sizeof(*octl));
+       else if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
                return -EFAULT;
        gctl->tlv = NULL;
        return 0;
index a91a9ef..217bb58 100644 (file)
@@ -6647,7 +6647,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
        SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
                ALC225_STANDARD_PINS,
                {0x12, 0xb7a60130},
-               {0x13, 0xb8a61140},
                {0x17, 0x90170110}),
        {}
 };
index 082736c..e630813 100644 (file)
@@ -542,6 +542,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 
        if (size < sizeof(scale))
                return -ENOMEM;
+       if (cval->min_mute)
+               scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
        scale[2] = cval->dBmin;
        scale[3] = cval->dBmax;
        if (copy_to_user(_tlv, scale, sizeof(scale)))
index 3417ef3..2b4b067 100644 (file)
@@ -64,6 +64,7 @@ struct usb_mixer_elem_info {
        int cached;
        int cache_val[MAX_CHANNELS];
        u8 initialized;
+       u8 min_mute;
        void *private_data;
 };
 
index e3d1dec..e1e7ce9 100644 (file)
@@ -1878,6 +1878,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
                if (unitid == 7 && cval->control == UAC_FU_VOLUME)
                        snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
                break;
+       /* lowest playback value is muted on C-Media devices */
+       case USB_ID(0x0d8c, 0x000c):
+       case USB_ID(0x0d8c, 0x0014):
+               if (strstr(kctl->id.name, "Playback"))
+                       cval->min_mute = 1;
+               break;
        }
 }
 
index d7b0b0a..6a03f96 100644 (file)
@@ -1142,6 +1142,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
        case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
        case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
        case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
+       case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
        case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
        case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
        case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
@@ -1374,6 +1375,10 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
                        }
                }
                break;
+       case USB_ID(0x16d0, 0x0a23):
+               if (fp->altsetting == 2)
+                       return SNDRV_PCM_FMTBIT_DSD_U32_BE;
+               break;
 
        default:
                break;
index 1a2c07e..8c67a90 100644 (file)
@@ -879,7 +879,8 @@ bpf_object__create_maps(struct bpf_object *obj)
                        size_t j;
                        int err = *pfd;
 
-                       pr_warning("failed to create map: %s\n",
+                       pr_warning("failed to create map (name: '%s'): %s\n",
+                                  obj->maps[i].name,
                                   strerror(errno));
                        for (j = 0; j < i; j++)
                                zclose(obj->maps[j].fd);
index e2fbb89..7c647f6 100644 (file)
@@ -14,7 +14,7 @@ all:
        done
 
 override define RUN_TESTS
-       @if [ `dirname $(OUTPUT)` = $(PWD) ]; then ./run.sh; fi
+       $(OUTPUT)/run.sh
 endef
 
 override define INSTALL_RULE
old mode 100644 (file)
new mode 100755 (executable)
index 8cecae9..7956ea3
@@ -473,8 +473,8 @@ usage()
        echo "    all     Runs all tests (default)"
        echo "    -t      Run test ID the number amount of times is recommended"
        echo "    -w      Watch test ID run until it runs into an error"
-       echo "    -c      Run test ID once"
-       echo "    -s      Run test ID x test-count number of times"
+       echo "    -s      Run test ID once"
+       echo "    -c      Run test ID x test-count number of times"
        echo "    -l      List all test ID list"
        echo " -h|--help  Help"
        echo
old mode 100644 (file)
new mode 100755 (executable)
index e8c6183..22312eb 100644 (file)
@@ -229,10 +229,9 @@ static void init_test(void)
        printf("CLOCK_MONOTONIC_RAW+CLOCK_MONOTONIC precision: %.0f ns\t\t",
               1e9 * precision);
 
-       if (precision > MAX_PRECISION) {
-               printf("[SKIP]\n");
-               ksft_exit_skip();
-       }
+       if (precision > MAX_PRECISION)
+               ksft_exit_skip("precision: %.0f ns > MAX_PRECISION: %.0f ns\n",
+                               1e9 * precision, 1e9 * MAX_PRECISION);
 
        printf("[OK]\n");
        srand(ts.tv_sec ^ ts.tv_nsec);