Merge tag 'trace-v4.17-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rosted...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 May 2018 03:38:37 +0000 (17:38 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 May 2018 03:38:37 +0000 (17:38 -1000)
Pull tracing fixes from Steven Rostedt:
 "Various fixes in tracing:

   - Tracepoints should not give warning on OOM failures

   - Use special field for function pointer in trace event

   - Fix igrab issues in uprobes

   - Fixes to the new histogram triggers"

* tag 'trace-v4.17-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tracepoint: Do not warn on ENOMEM
  tracing: Add field modifier parsing hist error for hist triggers
  tracing: Add field parsing hist error for hist triggers
  tracing: Restore proper field flag printing when displaying triggers
  tracing: initcall: Ordered comparison of function pointers
  tracing: Remove igrab() iput() call from uprobes.c
  tracing: Fix bad use of igrab in trace_uprobe.c

705 files changed:
Documentation/core-api/kernel-api.rst
Documentation/devicetree/bindings/input/atmel,maxtouch.txt
Documentation/devicetree/bindings/serial/amlogic,meson-uart.txt
Documentation/devicetree/bindings/serial/mvebu-uart.txt
Documentation/devicetree/bindings/serial/renesas,sci-serial.txt
Documentation/devicetree/bindings/thermal/exynos-thermal.txt
Documentation/devicetree/bindings/thermal/thermal.txt
Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt [new file with mode: 0644]
Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt
Documentation/devicetree/bindings/usb/usb-xhci.txt
Documentation/driver-api/firmware/request_firmware.rst
Documentation/driver-api/infrastructure.rst
Documentation/driver-api/usb/typec.rst
Documentation/i2c/dev-interface
Documentation/ioctl/ioctl-number.txt
Documentation/livepatch/shadow-vars.txt
Documentation/networking/filter.txt
Documentation/networking/ip-sysctl.txt
Documentation/power/suspend-and-cpuhotplug.txt
Documentation/process/magic-number.rst
Documentation/trace/ftrace.rst
Documentation/virtual/kvm/api.txt
Documentation/virtual/kvm/arm/psci.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/arm/boot/dts/gemini-nas4220b.dts
arch/arm/boot/dts/omap4.dtsi
arch/arm/configs/gemini_defconfig
arch/arm/configs/socfpga_defconfig
arch/arm/include/asm/kvm_host.h
arch/arm/include/uapi/asm/kvm.h
arch/arm/kvm/guest.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/pm-asm-offsets.c
arch/arm/mach-omap2/sleep33xx.S
arch/arm/mach-omap2/sleep43xx.S
arch/arm/mach-s3c24xx/mach-jive.c
arch/arm64/Makefile
arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
arch/arm64/boot/dts/arm/juno-motherboard.dtsi
arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/module.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/uapi/asm/kvm.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/module-plts.c
arch/arm64/kernel/module.c
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/traps.c
arch/arm64/kvm/guest.c
arch/arm64/kvm/sys_regs.c
arch/arm64/lib/Makefile
arch/arm64/mm/flush.c
arch/arm64/mm/kasan_init.c
arch/hexagon/include/asm/io.h
arch/hexagon/lib/checksum.c
arch/mips/boot/dts/img/boston.dts
arch/mips/include/asm/io.h
arch/mips/include/asm/uaccess.h
arch/mips/lib/memset.S
arch/parisc/kernel/Makefile
arch/powerpc/include/asm/powernv.h
arch/powerpc/kernel/eeh_pe.c
arch/powerpc/kernel/idle_book3s.S
arch/powerpc/kernel/mce_power.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kvm/booke.c
arch/powerpc/lib/feature-fixups.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/powernv/memtrace.c
arch/powerpc/platforms/powernv/npu-dma.c
arch/powerpc/platforms/powernv/opal-rtc.c
arch/powerpc/sysdev/xive/native.c
arch/riscv/Kconfig
arch/riscv/include/asm/Kbuild
arch/riscv/kernel/vdso/Makefile
arch/s390/Kbuild
arch/s390/Kconfig
arch/s390/boot/Makefile
arch/s390/boot/compressed/.gitignore
arch/s390/configs/debug_defconfig [new file with mode: 0644]
arch/s390/configs/default_defconfig [deleted file]
arch/s390/configs/gcov_defconfig [deleted file]
arch/s390/configs/performance_defconfig
arch/s390/defconfig
arch/s390/hypfs/inode.c
arch/s390/include/asm/kexec.h
arch/s390/include/asm/purgatory.h [new file with mode: 0644]
arch/s390/include/asm/setup.h
arch/s390/include/asm/thread_info.h
arch/s390/include/uapi/asm/signal.h
arch/s390/kernel/Makefile
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/compat_wrapper.c
arch/s390/kernel/kexec_elf.c [new file with mode: 0644]
arch/s390/kernel/kexec_image.c [new file with mode: 0644]
arch/s390/kernel/machine_kexec_file.c [new file with mode: 0644]
arch/s390/kernel/module.c
arch/s390/kernel/nospec-branch.c
arch/s390/kernel/perf_cpum_cf_events.c
arch/s390/kernel/process.c
arch/s390/kernel/setup.c
arch/s390/kernel/syscalls/syscall.tbl
arch/s390/kernel/uprobes.c
arch/s390/purgatory/.gitignore [new file with mode: 0644]
arch/s390/purgatory/Makefile [new file with mode: 0644]
arch/s390/purgatory/head.S [new file with mode: 0644]
arch/s390/purgatory/purgatory.c [new file with mode: 0644]
arch/sparc/include/uapi/asm/oradax.h
arch/sparc/kernel/vio.c
arch/x86/Kconfig
arch/x86/entry/entry_64_compat.S
arch/x86/events/intel/core.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/include/asm/asm.h
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/irq_vectors.h
arch/x86/include/asm/jailhouse_para.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/pgtable_64_types.h
arch/x86/include/asm/processor.h
arch/x86/include/uapi/asm/msgbuf.h
arch/x86/include/uapi/asm/shmbuf.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/microcode/intel.c
arch/x86/kernel/jailhouse.c
arch/x86/kernel/kexec-bzimage64.c
arch/x86/kernel/ldt.c
arch/x86/kernel/pci-nommu.c [deleted file]
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/tsc.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/mm/dump_pagetables.c
arch/x86/mm/pageattr.c
arch/x86/mm/pti.c
arch/x86/power/hibernate_64.c
block/bfq-iosched.c
block/blk-cgroup.c
block/blk-core.c
block/blk-mq.c
block/blk-mq.h
crypto/api.c
crypto/drbg.c
drivers/acpi/acpi_video.c
drivers/acpi/acpi_watchdog.c
drivers/acpi/button.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/amba/bus.c
drivers/android/binder.c
drivers/atm/iphase.c
drivers/base/dma-coherent.c
drivers/base/dma-mapping.c
drivers/base/firmware_loader/fallback.c
drivers/base/firmware_loader/fallback.h
drivers/block/loop.c
drivers/block/loop.h
drivers/block/rbd.c
drivers/block/swim.c
drivers/block/swim3.c
drivers/bus/Kconfig
drivers/cdrom/cdrom.c
drivers/char/random.c
drivers/char/virtio_console.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/timer-imx-tpm.c
drivers/clocksource/timer-npcm7xx.c [new file with mode: 0644]
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/brcmstb-avs-cpufreq.c
drivers/cpufreq/powernv-cpufreq.c
drivers/dax/device.c
drivers/firmware/arm_scmi/clock.c
drivers/fpga/altera-ps-spi.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdkfd/Kconfig
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h
drivers/gpu/drm/drm_dp_dual_mode_helper.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/exynos/exynos_drm_fb.c
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/display.c
drivers/gpu/drm/i915/gvt/dmabuf.c
drivers/gpu/drm/i915/gvt/fb_decoder.c
drivers/gpu/drm/i915/gvt/gtt.c
drivers/gpu/drm/i915/gvt/gtt.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/kvmgt.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
drivers/gpu/drm/msm/disp/mdp_format.c
drivers/gpu/drm/msm/disp/mdp_kms.h
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
drivers/gpu/drm/msm/msm_fb.c
drivers/gpu/drm/msm/msm_fbdev.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/msm/msm_kms.h
drivers/gpu/drm/qxl/qxl_cmd.c
drivers/gpu/drm/qxl/qxl_drv.h
drivers/gpu/drm/qxl/qxl_ioctl.c
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/sun4i/sun4i_lvds.c
drivers/gpu/drm/vc4/vc4_bo.c
drivers/gpu/drm/vc4/vc4_validate_shaders.c
drivers/gpu/drm/virtio/virtgpu_vq.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hidraw.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/wacom_wac.c
drivers/hwmon/k10temp.c
drivers/hwmon/nct6683.c
drivers/hwmon/scmi-hwmon.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-sprd.c
drivers/i2c/i2c-dev.c
drivers/input/evdev.c
drivers/input/input-leds.c
drivers/input/mouse/alps.c
drivers/input/rmi4/rmi_spi.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/isdn/mISDN/dsp_hwec.c
drivers/isdn/mISDN/l1oip_core.c
drivers/md/md.c
drivers/md/raid1.c
drivers/memory/emif-asm-offsets.c
drivers/message/fusion/mptsas.c
drivers/mmc/host/renesas_sdhi_internal_dmac.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/nand/core.c
drivers/mtd/nand/raw/marvell_nand.c
drivers/mtd/nand/raw/tango_nand.c
drivers/mtd/spi-nor/cadence-quadspi.c
drivers/net/bonding/bond_main.c
drivers/net/dsa/mv88e6xxx/hwtstamp.c
drivers/net/ethernet/amd/xgbe/xgbe-common.h
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
drivers/net/ethernet/amd/xgbe/xgbe-main.c
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
drivers/net/ethernet/amd/xgbe/xgbe-pci.c
drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
drivers/net/ethernet/amd/xgbe/xgbe.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h
drivers/net/ethernet/hisilicon/hns/hnae.h
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/ibm/ibmvnic.h
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_sched.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/marvell/mvpp2.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.h
drivers/net/ethernet/netronome/nfp/flower/main.c
drivers/net/ethernet/netronome/nfp/flower/main.h
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx.h
drivers/net/ethernet/sfc/farch.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/stmicro/stmmac/dwmac4.h
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/macsec.c
drivers/net/phy/marvell.c
drivers/net/phy/microchip.c
drivers/net/ppp/pppoe.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/usb/qmi_wwan.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/nvdimm/Kconfig
drivers/nvdimm/dimm_devs.c
drivers/nvdimm/of_pmem.c
drivers/of/fdt.c
drivers/pci/dwc/pcie-kirin.c
drivers/pci/host/pci-aardvark.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/rapidio/devices/rio_mport_cdev.c
drivers/rtc/rtc-opal.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_diag.c
drivers/s390/char/sclp_early_core.c
drivers/s390/cio/chsc.c
drivers/s390/cio/vfio_ccw_fsm.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_core_mpc.h
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/smsgiucv.c
drivers/sbus/char/oradax.c
drivers/scsi/fnic/fnic_trace.c
drivers/scsi/isci/port_config.c
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sd.c
drivers/scsi/sd_zbc.c
drivers/scsi/storvsc_drv.c
drivers/scsi/ufs/ufshcd.c
drivers/slimbus/messaging.c
drivers/soc/bcm/raspberrypi-power.c
drivers/staging/wilc1000/host_interface.c
drivers/target/target_core_iblock.c
drivers/target/target_core_pscsi.c
drivers/tty/n_gsm.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/imx.c
drivers/tty/serial/mvebu-uart.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/tty_io.c
drivers/tty/tty_ldisc.c
drivers/uio/uio_hv_generic.c
drivers/usb/Kconfig
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/phy.c
drivers/usb/core/phy.h
drivers/usb/core/quirks.c
drivers/usb/host/xhci-dbgtty.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/musb_host.c
drivers/usb/serial/Kconfig
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/usb-serial-simple.c
drivers/usb/typec/ucsi/Makefile
drivers/usb/typec/ucsi/ucsi.c
drivers/usb/usbip/stub_main.c
drivers/usb/usbip/usbip_common.h
drivers/usb/usbip/usbip_event.c
drivers/usb/usbip/vhci_hcd.c
drivers/virt/vboxguest/vboxguest_core.c
drivers/virt/vboxguest/vboxguest_core.h
drivers/virt/vboxguest/vboxguest_linux.c
drivers/virt/vboxguest/vboxguest_utils.c
drivers/watchdog/aspeed_wdt.c
drivers/watchdog/renesas_wdt.c
drivers/watchdog/sch311x_wdt.c
drivers/watchdog/w83977f_wdt.c
drivers/watchdog/wafer5823wdt.c
drivers/xen/xen-pciback/conf_space_quirks.c
drivers/xen/xen-pciback/pci_stub.c
drivers/xen/xenbus/xenbus_dev_frontend.c
fs/afs/server.c
fs/autofs4/root.c
fs/binfmt_elf.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/delayed-ref.c
fs/btrfs/delayed-ref.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/print-tree.c
fs/btrfs/print-tree.h
fs/btrfs/qgroup.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/ceph/inode.c
fs/ceph/xattr.c
fs/cifs/cifs_debug.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smbdirect.c
fs/cifs/transport.c
fs/ecryptfs/crypto.c
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ext2/file.c
fs/ext4/balloc.c
fs/ext4/extents.c
fs/ext4/super.c
fs/fs-writeback.c
fs/isofs/compress.c
fs/isofs/inode.c
fs/jbd2/transaction.c
fs/jffs2/super.c
fs/namespace.c
fs/notify/fanotify/fanotify.c
fs/notify/fsnotify.c
fs/orangefs/super.c
fs/proc/base.c
fs/proc/loadavg.c
fs/proc/task_mmu.c
fs/quota/dquot.c
fs/super.c
fs/udf/unicode.c
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_inode_buf.c
fs/xfs/xfs_file.c
include/asm-generic/vmlinux.lds.h
include/drm/drm_hdcp.h
include/kvm/arm_psci.h
include/linux/backing-dev-defs.h
include/linux/backing-dev.h
include/linux/blk-mq.h
include/linux/blkdev.h
include/linux/bpf.h
include/linux/compiler-clang.h
include/linux/coresight-pmu.h
include/linux/device.h
include/linux/ethtool.h
include/linux/fsnotify_backend.h
include/linux/hid.h
include/linux/hrtimer.h
include/linux/if_vlan.h
include/linux/livepatch.h
include/linux/microchipphy.h
include/linux/mtd/flashchip.h
include/linux/serial_core.h
include/linux/shrinker.h
include/linux/stringhash.h
include/linux/textsearch.h
include/linux/thread_info.h
include/linux/ti-emif-sram.h
include/linux/timekeeper_internal.h
include/linux/timekeeping.h
include/linux/timekeeping32.h
include/linux/timer.h
include/linux/tty.h
include/linux/vbox_utils.h
include/linux/virtio.h
include/net/ife.h
include/net/llc_conn.h
include/scsi/scsi_dbg.h
include/soc/bcm2835/raspberrypi-firmware.h
include/sound/control.h
include/trace/events/ufs.h
include/uapi/linux/kvm.h
include/uapi/linux/perf_event.h
include/uapi/linux/random.h
include/uapi/linux/sysctl.h
include/uapi/linux/time.h
include/uapi/linux/virtio_balloon.h
include/xen/interface/io/sndif.h
kernel/bpf/core.c
kernel/bpf/sockmap.c
kernel/events/callchain.c
kernel/events/core.c
kernel/fork.c
kernel/livepatch/shadow.c
kernel/module.c
kernel/sysctl_binary.c
kernel/time/hrtimer.c
kernel/time/posix-cpu-timers.c
kernel/time/posix-stubs.c
kernel/time/posix-timers.c
kernel/time/tick-common.c
kernel/time/tick-internal.h
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/timekeeping.c
kernel/time/timekeeping.h
kernel/trace/bpf_trace.c
kernel/trace/trace.c
kernel/trace/trace_kprobe.c
lib/dma-direct.c
lib/errseq.c
lib/kobject.c
lib/textsearch.c
mm/filemap.c
mm/huge_memory.c
mm/memcontrol.c
mm/migrate.c
mm/mmap.c
mm/page-writeback.c
mm/rmap.c
mm/vmscan.c
net/bridge/netfilter/ebtables.c
net/caif/chnl_net.c
net/ceph/messenger.c
net/ceph/mon_client.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/neighbour.c
net/dns_resolver/dns_key.c
net/ife/ife.c
net/ipv4/ip_output.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv6/netfilter/Kconfig
net/ipv6/route.c
net/ipv6/seg6_iptunnel.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_debugfs.c
net/l2tp/l2tp_netlink.c
net/l2tp/l2tp_ppp.c
net/llc/af_llc.c
net/llc/llc_c_ac.c
net/llc/llc_conn.c
net/netfilter/Kconfig
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_sync.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_extend.c
net/netfilter/nf_conntrack_sip.c
net/netfilter/nf_tables_api.c
net/netfilter/xt_connmark.c
net/packet/af_packet.c
net/packet/internal.h
net/qrtr/qrtr.c
net/sched/act_ife.c
net/sctp/ipv6.c
net/smc/af_smc.c
net/strparser/strparser.c
net/sunrpc/rpc_pipe.c
net/tipc/monitor.c
net/tipc/name_table.c
net/tipc/name_table.h
net/tipc/net.c
net/tipc/netlink.c
net/tipc/node.c
net/tipc/socket.c
net/tipc/subscr.c
net/tls/tls_sw.c
net/vmw_vsock/af_vsock.c
samples/livepatch/livepatch-shadow-fix1.c
samples/livepatch/livepatch-shadow-fix2.c
security/commoncap.c
sound/core/control.c
sound/core/pcm_compat.c
sound/core/pcm_native.c
sound/core/rawmidi_compat.c
sound/core/seq/oss/seq_oss_event.c
sound/core/seq/oss/seq_oss_midi.c
sound/core/seq/oss/seq_oss_synth.c
sound/core/seq/oss/seq_oss_synth.h
sound/drivers/opl3/opl3_synth.c
sound/firewire/dice/dice-stream.c
sound/firewire/dice/dice.c
sound/pci/asihpi/hpimsginit.c
sound/pci/asihpi/hpioctl.c
sound/pci/hda/hda_hwdep.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/rme9652/hdspm.c
sound/pci/rme9652/rme9652.c
sound/soc/amd/acp-da7219-max98357a.c
sound/soc/codecs/adau17x1.c
sound/soc/codecs/adau17x1.h
sound/soc/codecs/msm8916-wcd-analog.c
sound/soc/codecs/rt5514.c
sound/soc/fsl/fsl_esai.c
sound/soc/fsl/fsl_ssi.c
sound/soc/intel/Kconfig
sound/soc/omap/omap-dmic.c
sound/soc/sh/rcar/core.c
sound/soc/soc-topology.c
sound/usb/line6/midi.c
sound/usb/mixer.c
sound/usb/mixer_maps.c
sound/usb/stream.c
sound/usb/usx2y/us122l.c
sound/usb/usx2y/usX2Yhwdep.c
sound/usb/usx2y/usx2yhwdeppcm.c
tools/arch/arm/include/uapi/asm/kvm.h
tools/arch/x86/include/asm/required-features.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/include/linux/compiler.h
tools/include/linux/coresight-pmu.h
tools/include/uapi/asm-generic/mman-common.h
tools/include/uapi/linux/bpf.h
tools/include/uapi/linux/if_link.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/perf_event.h
tools/include/uapi/sound/asound.h
tools/lib/subcmd/parse-options.c
tools/objtool/Makefile
tools/perf/Documentation/perf-config.txt
tools/perf/Documentation/perf-mem.txt
tools/perf/Documentation/perf-sched.txt
tools/perf/Documentation/perf-script.txt
tools/perf/Documentation/perf-stat.txt
tools/perf/Makefile.config
tools/perf/arch/arm/include/arch-tests.h [new file with mode: 0644]
tools/perf/arch/arm/tests/Build
tools/perf/arch/arm/tests/arch-tests.c [new file with mode: 0644]
tools/perf/arch/arm/util/auxtrace.c
tools/perf/arch/arm/util/cs-etm.c
tools/perf/arch/arm/util/cs-etm.h
tools/perf/arch/arm/util/pmu.c
tools/perf/arch/s390/util/auxtrace.c
tools/perf/arch/s390/util/header.c
tools/perf/arch/x86/Makefile
tools/perf/arch/x86/annotate/instructions.c
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
tools/perf/builtin-help.c
tools/perf/builtin-mem.c
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/builtin-version.c
tools/perf/perf.c
tools/perf/pmu-events/arch/s390/mapfile.csv
tools/perf/tests/attr/test-record-group-sampling
tools/perf/tests/bpf-script-example.c
tools/perf/tests/bpf-script-test-kbuild.c
tools/perf/tests/builtin-test.c
tools/perf/tests/mmap-basic.c
tools/perf/tests/shell/record+probe_libc_inet_pton.sh
tools/perf/trace/beauty/mmap.c
tools/perf/ui/browsers/annotate.c
tools/perf/ui/browsers/hists.c
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
tools/perf/util/cs-etm.c
tools/perf/util/cs-etm.h
tools/perf/util/event.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/generate-cmdlist.sh
tools/perf/util/header.c
tools/perf/util/machine.c
tools/perf/util/parse-events.y
tools/perf/util/pmu.c
tools/perf/util/symbol.c
tools/perf/util/syscalltbl.c
tools/perf/util/trace-event-scripting.c
tools/testing/nvdimm/test/nfit.c
tools/testing/selftests/bpf/.gitignore
tools/testing/selftests/bpf/test_sock.c
tools/testing/selftests/bpf/test_sock_addr.c
tools/testing/selftests/bpf/test_sock_addr.sh
tools/testing/selftests/filesystems/Makefile
tools/testing/selftests/firmware/Makefile
tools/testing/selftests/firmware/fw_lib.sh
tools/testing/selftests/firmware/fw_run_tests.sh
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/include/vmx.h [new file with mode: 0644]
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/sparsebit.c
tools/testing/selftests/kvm/lib/vmx.c [new file with mode: 0644]
tools/testing/selftests/kvm/vmx_tsc_adjust_test.c [new file with mode: 0644]
tools/testing/selftests/net/Makefile
tools/testing/selftests/x86/test_syscall_vdso.c
virt/kvm/arm/arm.c
virt/kvm/arm/psci.c
virt/kvm/arm/vgic/vgic-mmio-v2.c
virt/kvm/arm/vgic/vgic.c

index ff335f8aeb39e2c461b4326392bee3ea1b3cd4ad..92f30006adae48846ab89684e8d5c3449ccbe341 100644 (file)
@@ -136,6 +136,19 @@ Sorting
 .. kernel-doc:: lib/list_sort.c
    :export:
 
+Text Searching
+--------------
+
+.. kernel-doc:: lib/textsearch.c
+   :doc: ts_intro
+
+.. kernel-doc:: lib/textsearch.c
+   :export:
+
+.. kernel-doc:: include/linux/textsearch.h
+   :functions: textsearch_find textsearch_next \
+               textsearch_get_pattern textsearch_get_pattern_len
+
 UUID/GUID
 ---------
 
index 23e3abc3fdef0c084ed61a78d15c49597f075c72..c88919480d373ea373be6cdff30e9206224603db 100644 (file)
@@ -4,6 +4,13 @@ Required properties:
 - compatible:
     atmel,maxtouch
 
+    The following compatibles have been used in various products but are
+    deprecated:
+       atmel,qt602240_ts
+       atmel,atmel_mxt_ts
+       atmel,atmel_mxt_tp
+       atmel,mXT224
+
 - reg: The I2C address of the device
 
 - interrupts: The sink for the touchpad's IRQ output
index 8ff65fa632fdedd739b005027e198051f62c8c34..c06c045126fc9070ca8f4faefc18b17a8de85ee6 100644 (file)
@@ -21,7 +21,7 @@ Required properties:
 - interrupts : identifier to the device interrupt
 - clocks : a list of phandle + clock-specifier pairs, one for each
           entry in clock names.
-- clocks-names :
+- clock-names :
    * "xtal" for external xtal clock identifier
    * "pclk" for the bus core clock, either the clk81 clock or the gate clock
    * "baud" for the source of the baudrate generator, can be either the xtal
index 2ae2fee7e023c01375f7fa09b9b21f7f812293c1..b7e0e32b9ac62c1029ba93998b8257ce71478de4 100644 (file)
@@ -24,7 +24,7 @@ Required properties:
     - Must contain two elements for the extended variant of the IP
       (marvell,armada-3700-uart-ext): "uart-tx" and "uart-rx",
       respectively the UART TX interrupt and the UART RX interrupt. A
-      corresponding interrupts-names property must be defined.
+      corresponding interrupt-names property must be defined.
     - For backward compatibility reasons, a single element interrupts
       property is also supported for the standard variant of the IP,
       containing only the UART sum interrupt. This form is deprecated
index ad962f4ec3aaffe73991118aabd78b9da3d5cb87..a006ea4d065f7cdd0781ef2ef1ab1ee35827c5da 100644 (file)
@@ -17,6 +17,8 @@ Required properties:
     - "renesas,scifa-r8a7745" for R8A7745 (RZ/G1E) SCIFA compatible UART.
     - "renesas,scifb-r8a7745" for R8A7745 (RZ/G1E) SCIFB compatible UART.
     - "renesas,hscif-r8a7745" for R8A7745 (RZ/G1E) HSCIF compatible UART.
+    - "renesas,scif-r8a77470" for R8A77470 (RZ/G1C) SCIF compatible UART.
+    - "renesas,hscif-r8a77470" for R8A77470 (RZ/G1C) HSCIF compatible UART.
     - "renesas,scif-r8a7778" for R8A7778 (R-Car M1) SCIF compatible UART.
     - "renesas,scif-r8a7779" for R8A7779 (R-Car H1) SCIF compatible UART.
     - "renesas,scif-r8a7790" for R8A7790 (R-Car H2) SCIF compatible UART.
index 1b596fd38dc4a4ed506b4c0c2417107154be1f3a..b957acff57aa448071e0deda91a3e11eb78ca184 100644 (file)
@@ -49,19 +49,6 @@ on the SoC (only first trip points defined in DT will be configured):
  - samsung,exynos5433-tmu: 8
  - samsung,exynos7-tmu: 8
 
-Following properties are mandatory (depending on SoC):
-- samsung,tmu_gain: Gain value for internal TMU operation.
-- samsung,tmu_reference_voltage: Value of TMU IP block's reference voltage
-- samsung,tmu_noise_cancel_mode: Mode for noise cancellation
-- samsung,tmu_efuse_value: Default level of temperature - it is needed when
-                          in factory fusing produced wrong value
-- samsung,tmu_min_efuse_value: Minimum temperature fused value
-- samsung,tmu_max_efuse_value: Maximum temperature fused value
-- samsung,tmu_first_point_trim: First point trimming value
-- samsung,tmu_second_point_trim: Second point trimming value
-- samsung,tmu_default_temp_offset: Default temperature offset
-- samsung,tmu_cal_type: Callibration type
-
 ** Optional properties:
 
 - vtmu-supply: This entry is optional and provides the regulator node supplying
@@ -78,7 +65,7 @@ Example 1):
                clocks = <&clock 383>;
                clock-names = "tmu_apbif";
                vtmu-supply = <&tmu_regulator_node>;
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
 Example 2):
@@ -89,7 +76,7 @@ Example 2):
                interrupts = <0 58 0>;
                clocks = <&clock 21>;
                clock-names = "tmu_apbif";
-               #include "exynos5440-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
 Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
@@ -99,7 +86,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
                interrupts = <0 184 0>;
                clocks = <&clock 318>, <&clock 318>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
        tmu_cpu3: tmu@1006c000 {
@@ -108,7 +95,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
                interrupts = <0 185 0>;
                clocks = <&clock 318>, <&clock 319>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
        tmu_gpu: tmu@100a0000 {
@@ -117,7 +104,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
                interrupts = <0 215 0>;
                clocks = <&clock 319>, <&clock 318>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
 Note: For multi-instance tmu each instance should have an alias correctly
index 1719d47a5e2fdb8434cdd9d09b83d1cba2c1ae63..cc553f0952c5a5e6b68da0121f9da34b19b6114a 100644 (file)
@@ -55,8 +55,7 @@ of heat dissipation). For example a fan's cooling states correspond to
 the different fan speeds possible. Cooling states are referred to by
 single unsigned integers, where larger numbers mean greater heat
 dissipation. The precise set of cooling states associated with a device
-(as referred to by the cooling-min-level and cooling-max-level
-properties) should be defined in a particular device's binding.
+should be defined in a particular device's binding.
 For more examples of cooling devices, refer to the example sections below.
 
 Required properties:
@@ -69,15 +68,6 @@ Required properties:
                        See Cooling device maps section below for more details
                        on how consumers refer to cooling devices.
 
-Optional properties:
-- cooling-min-level:   An integer indicating the smallest
-  Type: unsigned       cooling state accepted. Typically 0.
-  Size: one cell
-
-- cooling-max-level:   An integer indicating the largest
-  Type: unsigned       cooling state accepted.
-  Size: one cell
-
 * Trip points
 
 The trip node is a node to describe a point in the temperature domain
@@ -226,8 +216,6 @@ cpus {
                        396000  950000
                        198000  850000
                >;
-               cooling-min-level = <0>;
-               cooling-max-level = <3>;
                #cooling-cells = <2>; /* min followed by max */
        };
        ...
@@ -241,8 +229,6 @@ cpus {
         */
        fan0: fan@48 {
                ...
-               cooling-min-level = <0>;
-               cooling-max-level = <9>;
                #cooling-cells = <2>; /* min followed by max */
        };
 };
diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
new file mode 100644 (file)
index 0000000..ea22dfe
--- /dev/null
@@ -0,0 +1,21 @@
+Nuvoton NPCM7xx timer
+
+Nuvoton NPCM7xx have three timer modules, each timer module provides five 24-bit
+timer counters.
+
+Required properties:
+- compatible      : "nuvoton,npcm750-timer" for Poleg NPCM750.
+- reg             : Offset and length of the register set for the device.
+- interrupts      : Contain the timer interrupt with flags for
+                    falling edge.
+- clocks          : phandle of timer reference clock (usually a 25 MHz clock).
+
+Example:
+
+timer@f0008000 {
+    compatible = "nuvoton,npcm750-timer";
+    interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+    reg = <0xf0008000 0x50>;
+    clocks = <&clk NPCM7XX_CLK_TIMER>;
+};
+
index b4aa7ddb5b134d9b8accdf625c18807ec4f13928..f82087b220f415976754db8b30c9297da8da3303 100644 (file)
@@ -15,7 +15,7 @@ Required properties:
 - interrupts : Should be the clock event device interrupt.
 - clocks :     The clocks provided by the SoC to drive the timer, must contain
                an entry for each entry in clock-names.
-- clock-names : Must include the following entries: "igp" and "per".
+- clock-names : Must include the following entries: "ipg" and "per".
 
 Example:
 tpm5: tpm@40260000 {
index c4c00dff4b569f94821a184784895a7aed1d315b..bd1dd316fb231f84d02a6125d566e881600df387 100644 (file)
@@ -28,7 +28,10 @@ Required properties:
   - interrupts: one XHCI interrupt should be described here.
 
 Optional properties:
-  - clocks: reference to a clock
+  - clocks: reference to the clocks
+  - clock-names: mandatory if there is a second clock, in this case
+    the name must be "core" for the first clock and "reg" for the
+    second one
   - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
   - usb3-lpm-capable: determines if platform is USB3 LPM capable
   - quirk-broken-port-ped: set if the controller has broken port disable mechanism
index cf4516dfbf964b0ada60136fc49579df6c113823..d5ec95a7195bf001f6fa855dc6d7fa922ba40ed7 100644 (file)
@@ -17,17 +17,17 @@ an error is returned.
 
 request_firmware
 ----------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware
 
 request_firmware_direct
 -----------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware_direct
 
 request_firmware_into_buf
 -------------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware_into_buf
 
 Asynchronous firmware requests
@@ -41,7 +41,7 @@ in atomic contexts.
 
 request_firmware_nowait
 -----------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware_nowait
 
 Special optimizations on reboot
@@ -50,12 +50,12 @@ Special optimizations on reboot
 Some devices have an optimization in place to enable the firmware to be
 retained during system reboot. When such optimizations are used the driver
 author must ensure the firmware is still available on resume from suspend,
-this can be done with firmware_request_cache() insted of requesting for the
-firmare to be loaded.
+this can be done with firmware_request_cache() instead of requesting for the
+firmware to be loaded.
 
 firmware_request_cache()
------------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+------------------------
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: firmware_request_cache
 
 request firmware API expected driver use
index 6d9ff316b608db48b46de6413d9503e23b51536a..bee1b9a1702f1cc6c89811aff6b8bdbc1eefb0b0 100644 (file)
@@ -28,7 +28,7 @@ Device Drivers Base
 .. kernel-doc:: drivers/base/node.c
    :internal:
 
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :export:
 
 .. kernel-doc:: drivers/base/transport_class.c
index feb31946490b01c13106e2f9f43d1d28fd918ea0..48ff58095f115ae5c1d0c25e6987d187937dd365 100644 (file)
@@ -210,7 +210,7 @@ If the connector is dual-role capable, there may also be a switch for the data
 role. USB Type-C Connector Class does not supply separate API for them. The
 port drivers can use USB Role Class API with those.
 
-Illustration of the muxes behind a connector that supports an alternate mode:
+Illustration of the muxes behind a connector that supports an alternate mode::
 
                      ------------------------
                      |       Connector      |
index d04e6e4964ee7f88387f2e0e9ce3803b96d4ae18..fbed645ccd7563e90e86796d13cae7cfa7329748 100644 (file)
@@ -9,8 +9,8 @@ i2c adapters present on your system at a given time. i2cdetect is part of
 the i2c-tools package.
 
 I2C device files are character device files with major device number 89
-and a minor device number corresponding to the number assigned as 
-explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., 
+and a minor device number corresponding to the number assigned as
+explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ...,
 i2c-10, ...). All 256 minor device numbers are reserved for i2c.
 
 
@@ -23,11 +23,6 @@ First, you need to include these two headers:
   #include <linux/i2c-dev.h>
   #include <i2c/smbus.h>
 
-(Please note that there are two files named "i2c-dev.h" out there. One is
-distributed with the Linux kernel and the other one is included in the
-source tree of i2c-tools. They used to be different in content but since 2012
-they're identical. You should use "linux/i2c-dev.h").
-
 Now, you have to decide which adapter you want to access. You should
 inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this.
 Adapter numbers are assigned somewhat dynamically, so you can not
@@ -38,7 +33,7 @@ Next thing, open the device file, as follows:
   int file;
   int adapter_nr = 2; /* probably dynamically determined */
   char filename[20];
-  
+
   snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
   file = open(filename, O_RDWR);
   if (file < 0) {
@@ -72,8 +67,10 @@ the device supports them. Both are illustrated below.
     /* res contains the read word */
   }
 
-  /* Using I2C Write, equivalent of 
-     i2c_smbus_write_word_data(file, reg, 0x6543) */
+  /*
+   * Using I2C Write, equivalent of
+   * i2c_smbus_write_word_data(file, reg, 0x6543)
+   */
   buf[0] = reg;
   buf[1] = 0x43;
   buf[2] = 0x65;
@@ -140,14 +137,14 @@ ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
   set in each message, overriding the values set with the above ioctl's.
 
 ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)
-  Not meant to be called  directly; instead, use the access functions
-  below.
+  If possible, use the provided i2c_smbus_* methods described below instead
+  of issuing direct ioctls.
 
 You can do plain i2c transactions by using read(2) and write(2) calls.
 You do not need to pass the address byte; instead, set it through
 ioctl I2C_SLAVE before you try to access the device.
 
-You can do SMBus level transactions (see documentation file smbus-protocol 
+You can do SMBus level transactions (see documentation file smbus-protocol
 for details) through the following functions:
   __s32 i2c_smbus_write_quick(int file, __u8 value);
   __s32 i2c_smbus_read_byte(int file);
@@ -158,7 +155,7 @@ for details) through the following functions:
   __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
   __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
   __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
-  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, 
+  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
                                    __u8 *values);
 All these transactions return -1 on failure; you can read errno to see
 what happened. The 'write' transactions return 0 on success; the
@@ -166,10 +163,9 @@ what happened. The 'write' transactions return 0 on success; the
 returns the number of values read. The block buffers need not be longer
 than 32 bytes.
 
-The above functions are all inline functions, that resolve to calls to
-the i2c_smbus_access function, that on its turn calls a specific ioctl
-with the data in a specific format. Read the source code if you
-want to know what happens behind the screens.
+The above functions are made available by linking against the libi2c library,
+which is provided by the i2c-tools project.  See:
+https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/.
 
 
 Implementation details
index 84bb74dcae12e95acc4a2aa888462520422f693d..7f7413e597f3886ad046b9ca527b7d5fe19ecf56 100644 (file)
@@ -217,7 +217,6 @@ Code  Seq#(hex)     Include File            Comments
 'd'    02-40   pcmcia/ds.h             conflict!
 'd'    F0-FF   linux/digi1.h
 'e'    all     linux/digi1.h           conflict!
-'e'    00-1F   drivers/net/irda/irtty-sir.h    conflict!
 'f'    00-1F   linux/ext2_fs.h         conflict!
 'f'    00-1F   linux/ext3_fs.h         conflict!
 'f'    00-0F   fs/jfs/jfs_dinode.h     conflict!
@@ -247,7 +246,6 @@ Code  Seq#(hex)     Include File            Comments
 'm'    all     linux/synclink.h        conflict!
 'm'    00-19   drivers/message/fusion/mptctl.h conflict!
 'm'    00      drivers/scsi/megaraid/megaraid_ioctl.h  conflict!
-'m'    00-1F   net/irda/irmod.h        conflict!
 'n'    00-7F   linux/ncp_fs.h and fs/ncpfs/ioctl.c
 'n'    80-8F   uapi/linux/nilfs2_api.h NILFS2
 'n'    E0-FF   linux/matroxfb.h        matroxfb
index 89c66634d600c2753c1b4b68db8dafa7a2b5b106..ecc09a7be5dd61cb52e390fde145883bf7b51848 100644 (file)
@@ -34,9 +34,13 @@ meta-data and shadow-data:
   - data[] - storage for shadow data
 
 It is important to note that the klp_shadow_alloc() and
-klp_shadow_get_or_alloc() calls, described below, store a *copy* of the
-data that the functions are provided.  Callers should provide whatever
-mutual exclusion is required of the shadow data.
+klp_shadow_get_or_alloc() are zeroing the variable by default.
+They also allow to call a custom constructor function when a non-zero
+value is needed. Callers should provide whatever mutual exclusion
+is required.
+
+Note that the constructor is called under klp_shadow_lock spinlock. It allows
+to do actions that can be done only once when a new variable is allocated.
 
 * klp_shadow_get() - retrieve a shadow variable data pointer
   - search hashtable for <obj, id> pair
@@ -47,7 +51,7 @@ mutual exclusion is required of the shadow data.
     - WARN and return NULL
   - if <obj, id> doesn't already exist
     - allocate a new shadow variable
-    - copy data into the new shadow variable
+    - initialize the variable using a custom constructor and data when provided
     - add <obj, id> to the global hashtable
 
 * klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
@@ -56,16 +60,20 @@ mutual exclusion is required of the shadow data.
     - return existing shadow variable
   - if <obj, id> doesn't already exist
     - allocate a new shadow variable
-    - copy data into the new shadow variable
+    - initialize the variable using a custom constructor and data when provided
     - add <obj, id> pair to the global hashtable
 
 * klp_shadow_free() - detach and free a <obj, id> shadow variable
   - find and remove a <obj, id> reference from global hashtable
-    - if found, free shadow variable
+    - if found
+      - call destructor function if defined
+      - free shadow variable
 
 * klp_shadow_free_all() - detach and free all <*, id> shadow variables
   - find and remove any <*, id> references from global hashtable
-    - if found, free shadow variable
+    - if found
+      - call destructor function if defined
+      - free shadow variable
 
 
 2. Use cases
@@ -107,7 +115,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
 
        /* Attach a corresponding shadow variable, then initialize it */
-       ps_lock = klp_shadow_alloc(sta, PS_LOCK, NULL, sizeof(*ps_lock), gfp);
+       ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp,
+                                  NULL, NULL);
        if (!ps_lock)
                goto shadow_fail;
        spin_lock_init(ps_lock);
@@ -131,7 +140,7 @@ variable:
 
 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
 {
-       klp_shadow_free(sta, PS_LOCK);
+       klp_shadow_free(sta, PS_LOCK, NULL);
        kfree(sta);
        ...
 
@@ -148,16 +157,24 @@ shadow variables to parents already in-flight.
 For commit 1d147bfa6429, a good spot to allocate a shadow spinlock is
 inside ieee80211_sta_ps_deliver_wakeup():
 
+int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
+{
+       spinlock_t *lock = shadow_data;
+
+       spin_lock_init(lock);
+       return 0;
+}
+
 #define PS_LOCK 1
 void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 {
-       DEFINE_SPINLOCK(ps_lock_fallback);
        spinlock_t *ps_lock;
 
        /* sync with ieee80211_tx_h_unicast_ps_buf */
        ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK,
-                       &ps_lock_fallback, sizeof(ps_lock_fallback),
-                       GFP_ATOMIC);
+                       sizeof(*ps_lock), GFP_ATOMIC,
+                       ps_lock_shadow_ctor, NULL);
+
        if (ps_lock)
                spin_lock(ps_lock);
        ...
index a4508ec1816b4dc7e1985b8371b004542735b3ba..fd55c7de99910628a68b545d606bd38b9020a6b8 100644 (file)
@@ -169,7 +169,7 @@ access to BPF code as well.
 BPF engine and instruction set
 ------------------------------
 
-Under tools/net/ there's a small helper tool called bpf_asm which can
+Under tools/bpf/ there's a small helper tool called bpf_asm which can
 be used to write low-level filters for example scenarios mentioned in the
 previous section. Asm-like syntax mentioned here has been implemented in
 bpf_asm and will be used for further explanations (instead of dealing with
@@ -359,7 +359,7 @@ $ ./bpf_asm -c foo
 In particular, as usage with xt_bpf or cls_bpf can result in more complex BPF
 filters that might not be obvious at first, it's good to test filters before
 attaching to a live system. For that purpose, there's a small tool called
-bpf_dbg under tools/net/ in the kernel source directory. This debugger allows
+bpf_dbg under tools/bpf/ in the kernel source directory. This debugger allows
 for testing BPF filters against given pcap files, single stepping through the
 BPF code on the pcap's packets and to do BPF machine register dumps.
 
@@ -483,7 +483,7 @@ Example output from dmesg:
 [ 3389.935851] JIT code: 00000030: 00 e8 28 94 ff e0 83 f8 01 75 07 b8 ff ff 00 00
 [ 3389.935852] JIT code: 00000040: eb 02 31 c0 c9 c3
 
-In the kernel source tree under tools/net/, there's bpf_jit_disasm for
+In the kernel source tree under tools/bpf/, there's bpf_jit_disasm for
 generating disassembly out of the kernel log's hexdump:
 
 # ./bpf_jit_disasm
index 5dc1a040a2f1db610873de26c2d79bc57ac5a1a2..35ffaa281b269f9856c93c20344968e511ac175a 100644 (file)
@@ -1390,26 +1390,26 @@ mld_qrv - INTEGER
        Default: 2 (as specified by RFC3810 9.1)
        Minimum: 1 (as specified by RFC6636 4.5)
 
-max_dst_opts_cnt - INTEGER
+max_dst_opts_number - INTEGER
        Maximum number of non-padding TLVs allowed in a Destination
        options extension header. If this value is less than zero
        then unknown options are disallowed and the number of known
        TLVs allowed is the absolute value of this number.
        Default: 8
 
-max_hbh_opts_cnt - INTEGER
+max_hbh_opts_number - INTEGER
        Maximum number of non-padding TLVs allowed in a Hop-by-Hop
        options extension header. If this value is less than zero
        then unknown options are disallowed and the number of known
        TLVs allowed is the absolute value of this number.
        Default: 8
 
-max dst_opts_len - INTEGER
+max_dst_opts_length - INTEGER
        Maximum length allowed for a Destination options extension
        header.
        Default: INT_MAX (unlimited)
 
-max hbh_opts_len - INTEGER
+max_hbh_length - INTEGER
        Maximum length allowed for a Hop-by-Hop options extension
        header.
        Default: INT_MAX (unlimited)
@@ -2126,18 +2126,3 @@ max_dgram_qlen - INTEGER
 
        Default: 10
 
-
-UNDOCUMENTED:
-
-/proc/sys/net/irda/*
-       fast_poll_increase FIXME
-       warn_noreply_time FIXME
-       discovery_slots FIXME
-       slot_timeout FIXME
-       max_baud_rate FIXME
-       discovery_timeout FIXME
-       lap_keepalive_time FIXME
-       max_noreply_time FIXME
-       max_tx_data_size FIXME
-       max_tx_window FIXME
-       min_tx_turn_time FIXME
index 31abd04b957284f55697be1aa226e906c981196c..6f55eb960a6dc642159cb8b027c000c764d554a5 100644 (file)
@@ -168,7 +168,7 @@ update on the CPUs, as discussed below:
 
 [Please bear in mind that the kernel requests the microcode images from
 userspace, using the request_firmware() function defined in
-drivers/base/firmware_class.c]
+drivers/base/firmware_loader/main.c]
 
 
 a. When all the CPUs are identical:
index 00cecf1fcba9f34808cf27053afc0543d852ef2a..633be1043690dde2bbd45a09387843cdb5e13b84 100644 (file)
@@ -157,8 +157,5 @@ memory management. See ``include/sound/sndmagic.h`` for complete list of them. M
 OSS sound drivers have their magic numbers constructed from the soundcard PCI
 ID - these are not listed here as well.
 
-IrDA subsystem also uses large number of own magic numbers, see
-``include/net/irda/irda.h`` for a complete list of them.
-
 HFS is another larger user of magic numbers - you can find them in
 ``fs/hfs/hfs.h``.
index e45f0786f3f9ef29bb1da2f9c2b3c8d7430adc85..67d9c38e95eb54d2855bf356b6fccc0cace8442a 100644 (file)
@@ -461,9 +461,17 @@ of ftrace. Here is a list of some of the key files:
                and ticks at the same rate as the hardware clocksource.
 
        boot:
-               Same as mono. Used to be a separate clock which accounted
-               for the time spent in suspend while CLOCK_MONOTONIC did
-               not.
+               This is the boot clock (CLOCK_BOOTTIME) and is based on the
+               fast monotonic clock, but also accounts for time spent in
+               suspend. Since the clock access is designed for use in
+               tracing in the suspend path, some side effects are possible
+               if clock is accessed after the suspend time is accounted before
+               the fast mono clock is updated. In this case, the clock update
+               appears to happen slightly sooner than it normally would have.
+               Also on 32-bit systems, it's possible that the 64-bit boot offset
+               sees a partial update. These effects are rare and post
+               processing should be able to handle them. See comments in the
+               ktime_get_boot_fast_ns() function for more information.
 
        To set a clock, simply echo the clock name into this file::
 
index 1c7958b57fe9fd52d337862fa9b6b5d46ca2e9f8..758bf403a169dac0db8ec259bc611986aea69cfd 100644 (file)
@@ -1960,6 +1960,9 @@ ARM 32-bit VFP control registers have the following id bit patterns:
 ARM 64-bit FP registers have the following id bit patterns:
   0x4030 0000 0012 0 <regno:12>
 
+ARM firmware pseudo-registers have the following bit pattern:
+  0x4030 0000 0014 <regno:16>
+
 
 arm64 registers are mapped using the lower 32 bits. The upper 16 of
 that is the register group type, or coprocessor number:
@@ -1976,6 +1979,9 @@ arm64 CCSIDR registers are demultiplexed by CSSELR value:
 arm64 system registers have the following id bit patterns:
   0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3>
 
+arm64 firmware pseudo-registers have the following bit pattern:
+  0x6030 0000 0014 <regno:16>
+
 
 MIPS registers are mapped using the lower 32 bits.  The upper 16 of that is
 the register group type:
@@ -2510,7 +2516,8 @@ Possible features:
          and execute guest code when KVM_RUN is called.
        - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode.
          Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
-       - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU.
+       - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 (or a future revision
+          backward compatible with v0.2) for the CPU.
          Depends on KVM_CAP_ARM_PSCI_0_2.
        - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU.
          Depends on KVM_CAP_ARM_PMU_V3.
diff --git a/Documentation/virtual/kvm/arm/psci.txt b/Documentation/virtual/kvm/arm/psci.txt
new file mode 100644 (file)
index 0000000..aafdab8
--- /dev/null
@@ -0,0 +1,30 @@
+KVM implements the PSCI (Power State Coordination Interface)
+specification in order to provide services such as CPU on/off, reset
+and power-off to the guest.
+
+The PSCI specification is regularly updated to provide new features,
+and KVM implements these updates if they make sense from a virtualization
+point of view.
+
+This means that a guest booted on two different versions of KVM can
+observe two different "firmware" revisions. This could cause issues if
+a given guest is tied to a particular PSCI revision (unlikely), or if
+a migration causes a different PSCI version to be exposed out of the
+blue to an unsuspecting guest.
+
+In order to remedy this situation, KVM exposes a set of "firmware
+pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
+interface. These registers can be saved/restored by userspace, and set
+to a convenient value if required.
+
+The following register is defined:
+
+* KVM_REG_ARM_PSCI_VERSION:
+
+  - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set
+    (and thus has already been initialized)
+  - Returns the current PSCI version on GET_ONE_REG (defaulting to the
+    highest PSCI version implemented by KVM and compatible with v0.2)
+  - Allows any PSCI version implemented by KVM and compatible with
+    v0.2 to be set with SET_ONE_REG
+  - Affects the whole VM (even if the register view is per-vcpu)
index 0a1410d5a621835ded529ac2d6ade31c306e086f..eab763f17aab8d1bcfb00e88d077689d7034c32d 100644 (file)
@@ -564,8 +564,9 @@ S:  Maintained
 F:     drivers/media/dvb-frontends/af9033*
 
 AFFS FILE SYSTEM
+M:     David Sterba <dsterba@suse.com>
 L:     linux-fsdevel@vger.kernel.org
-S:     Orphan
+S:     Odd Fixes
 F:     Documentation/filesystems/affs.txt
 F:     fs/affs/
 
@@ -905,6 +906,8 @@ ANDROID ION DRIVER
 M:     Laura Abbott <labbott@redhat.com>
 M:     Sumit Semwal <sumit.semwal@linaro.org>
 L:     devel@driverdev.osuosl.org
+L:     dri-devel@lists.freedesktop.org
+L:     linaro-mm-sig@lists.linaro.org (moderated for non-subscribers)
 S:     Supported
 F:     drivers/staging/android/ion
 F:     drivers/staging/android/uapi/ion.h
@@ -1208,7 +1211,6 @@ F:        drivers/*/*alpine*
 ARM/ARTPEC MACHINE SUPPORT
 M:     Jesper Nilsson <jesper.nilsson@axis.com>
 M:     Lars Persson <lars.persson@axis.com>
-M:     Niklas Cassel <niklas.cassel@axis.com>
 S:     Maintained
 L:     linux-arm-kernel@axis.com
 F:     arch/arm/mach-artpec
@@ -1373,7 +1375,8 @@ F:        arch/arm/mach-ebsa110/
 F:     drivers/net/ethernet/amd/am79c961a.*
 
 ARM/ENERGY MICRO (SILICON LABS) EFM32 SUPPORT
-M:     Uwe Kleine-König <kernel@pengutronix.de>
+M:     Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 N:     efm32
@@ -1401,7 +1404,8 @@ F:        arch/arm/mach-footbridge/
 
 ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
 M:     Shawn Guo <shawnguo@kernel.org>
-M:     Sascha Hauer <kernel@pengutronix.de>
+M:     Sascha Hauer <s.hauer@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 R:     Fabio Estevam <fabio.estevam@nxp.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -1416,7 +1420,8 @@ F:        include/soc/imx/
 
 ARM/FREESCALE VYBRID ARM ARCHITECTURE
 M:     Shawn Guo <shawnguo@kernel.org>
-M:     Sascha Hauer <kernel@pengutronix.de>
+M:     Sascha Hauer <s.hauer@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 R:     Stefan Agner <stefan@agner.ch>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -2614,7 +2619,7 @@ S:        Maintained
 F:     drivers/net/hamradio/baycom*
 
 BCACHE (BLOCK LAYER CACHE)
-M:     Michael Lyle <mlyle@lyle.org>
+M:     Coly Li <colyli@suse.de>
 M:     Kent Overstreet <kent.overstreet@gmail.com>
 L:     linux-bcache@vger.kernel.org
 W:     http://bcache.evilpiepirate.org
@@ -4245,6 +4250,9 @@ F:        include/trace/events/fs_dax.h
 
 DEVICE DIRECT ACCESS (DAX)
 M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
+M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
 L:     linux-nvdimm@lists.01.org
 S:     Supported
 F:     drivers/dax/
@@ -5652,7 +5660,8 @@ F:        drivers/net/ethernet/freescale/fec.h
 F:     Documentation/devicetree/bindings/net/fsl-fec.txt
 
 FREESCALE IMX / MXC FRAMEBUFFER DRIVER
-M:     Sascha Hauer <kernel@pengutronix.de>
+M:     Sascha Hauer <s.hauer@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 L:     linux-fbdev@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -5784,6 +5793,14 @@ F:       fs/crypto/
 F:     include/linux/fscrypt*.h
 F:     Documentation/filesystems/fscrypt.rst
 
+FSNOTIFY: FILESYSTEM NOTIFICATION INFRASTRUCTURE
+M:     Jan Kara <jack@suse.cz>
+R:     Amir Goldstein <amir73il@gmail.com>
+L:     linux-fsdevel@vger.kernel.org
+S:     Maintained
+F:     fs/notify/
+F:     include/linux/fsnotify*.h
+
 FUJITSU LAPTOP EXTRAS
 M:     Jonathan Woithe <jwoithe@just42.net>
 L:     platform-driver-x86@vger.kernel.org
@@ -6256,7 +6273,7 @@ S:        Odd Fixes
 F:     drivers/media/usb/hdpvr/
 
 HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER
-M:     Jimmy Vance <jimmy.vance@hpe.com>
+M:     Jerry Hoemann <jerry.hoemann@hpe.com>
 S:     Supported
 F:     Documentation/watchdog/hpwdt.txt
 F:     drivers/watchdog/hpwdt.c
@@ -7396,16 +7413,6 @@ S:       Obsolete
 F:     include/uapi/linux/ipx.h
 F:     drivers/staging/ipx/
 
-IRDA SUBSYSTEM
-M:     Samuel Ortiz <samuel@sortiz.org>
-L:     irda-users@lists.sourceforge.net (subscribers-only)
-L:     netdev@vger.kernel.org
-W:     http://irda.sourceforge.net/
-S:     Obsolete
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git
-F:     Documentation/networking/irda.txt
-F:     drivers/staging/irda/
-
 IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
 M:     Marc Zyngier <marc.zyngier@arm.com>
 S:     Maintained
@@ -7738,7 +7745,7 @@ F:        arch/x86/include/asm/svm.h
 F:     arch/x86/kvm/svm.c
 
 KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm)
-M:     Christoffer Dall <christoffer.dall@linaro.org>
+M:     Christoffer Dall <christoffer.dall@arm.com>
 M:     Marc Zyngier <marc.zyngier@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     kvmarm@lists.cs.columbia.edu
@@ -7752,7 +7759,7 @@ F:        virt/kvm/arm/
 F:     include/kvm/arm_*
 
 KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
-M:     Christoffer Dall <christoffer.dall@linaro.org>
+M:     Christoffer Dall <christoffer.dall@arm.com>
 M:     Marc Zyngier <marc.zyngier@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     kvmarm@lists.cs.columbia.edu
@@ -8048,6 +8055,9 @@ F:        tools/lib/lockdep/
 
 LIBNVDIMM BLK: MMIO-APERTURE DRIVER
 M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Dan Williams <dan.j.williams@intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 S:     Supported
@@ -8056,6 +8066,9 @@ F:        drivers/nvdimm/region_devs.c
 
 LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
 M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dan Williams <dan.j.williams@intel.com>
+M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 S:     Supported
@@ -8063,6 +8076,9 @@ F:        drivers/nvdimm/btt*
 
 LIBNVDIMM PMEM: PERSISTENT MEMORY DRIVER
 M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Dan Williams <dan.j.williams@intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 S:     Supported
@@ -8078,6 +8094,9 @@ F:        Documentation/devicetree/bindings/pmem/pmem-region.txt
 
 LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
 M:     Dan Williams <dan.j.williams@intel.com>
+M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
@@ -9765,6 +9784,7 @@ F:        include/uapi/linux/net_namespace.h
 F:     tools/testing/selftests/net/
 F:     lib/net_utils.c
 F:     lib/random32.c
+F:     Documentation/networking/
 
 NETWORKING [IPSEC]
 M:     Steffen Klassert <steffen.klassert@secunet.com>
@@ -10881,7 +10901,6 @@ F:      drivers/pci/host/
 F:     drivers/pci/dwc/
 
 PCIE DRIVER FOR AXIS ARTPEC
-M:     Niklas Cassel <niklas.cassel@axis.com>
 M:     Jesper Nilsson <jesper.nilsson@axis.com>
 L:     linux-arm-kernel@axis.com
 L:     linux-pci@vger.kernel.org
@@ -12816,7 +12835,8 @@ F:      include/linux/siphash.h
 
 SIOX
 M:     Gavin Schenk <g.schenk@eckelmann.de>
-M:     Uwe Kleine-König <kernel@pengutronix.de>
+M:     Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 S:     Supported
 F:     drivers/siox/*
 F:     include/trace/events/siox.h
@@ -13833,7 +13853,6 @@ S:      Supported
 F:     drivers/iommu/tegra*
 
 TEGRA KBC DRIVER
-M:     Rakesh Iyer <riyer@nvidia.com>
 M:     Laxman Dewangan <ldewangan@nvidia.com>
 S:     Supported
 F:     drivers/input/keyboard/tegra-kbc.c
@@ -13936,7 +13955,7 @@ THUNDERBOLT DRIVER
 M:     Andreas Noever <andreas.noever@gmail.com>
 M:     Michael Jamet <michael.jamet@intel.com>
 M:     Mika Westerberg <mika.westerberg@linux.intel.com>
-M:     Yehezkel Bernat <yehezkel.bernat@intel.com>
+M:     Yehezkel Bernat <YehezkelShB@gmail.com>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git
 S:     Maintained
 F:     Documentation/admin-guide/thunderbolt.rst
@@ -13946,7 +13965,7 @@ F:      include/linux/thunderbolt.h
 THUNDERBOLT NETWORK DRIVER
 M:     Michael Jamet <michael.jamet@intel.com>
 M:     Mika Westerberg <mika.westerberg@linux.intel.com>
-M:     Yehezkel Bernat <yehezkel.bernat@intel.com>
+M:     Yehezkel Bernat <YehezkelShB@gmail.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/thunderbolt.c
index e811e0c509c5b90add1c607bc664c2bc8cb0d6dc..619a85ad716b43e2aafa080eb5e85da9516d5459 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 17
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
index 8bbb6f85d1618b3743bed54612ffe769141c850b..4785fbcc41ed840f0e72507163d2374532925395 100644 (file)
                                                function = "gmii";
                                                groups = "gmii_gmac0_grp";
                                        };
-                                       /* Settings come from OpenWRT */
+                                       /* Settings come from OpenWRT, pins on SL3516 */
                                        conf0 {
-                                               pins = "R8 GMAC0 RXDV", "U11 GMAC1 RXDV";
+                                               pins = "V8 GMAC0 RXDV", "T10 GMAC1 RXDV";
                                                skew-delay = <0>;
                                        };
                                        conf1 {
-                                               pins = "T8 GMAC0 RXC", "T11 GMAC1 RXC";
+                                               pins = "Y7 GMAC0 RXC", "Y11 GMAC1 RXC";
                                                skew-delay = <15>;
                                        };
                                        conf2 {
-                                               pins = "P8 GMAC0 TXEN", "V11 GMAC1 TXEN";
+                                               pins = "T8 GMAC0 TXEN", "W11 GMAC1 TXEN";
                                                skew-delay = <7>;
                                        };
                                        conf3 {
-                                               pins = "V7 GMAC0 TXC";
+                                               pins = "U8 GMAC0 TXC";
                                                skew-delay = <11>;
                                        };
                                        conf4 {
-                                               pins = "P10 GMAC1 TXC";
+                                               pins = "V11 GMAC1 TXC";
                                                skew-delay = <10>;
                                        };
                                        conf5 {
                                                /* The data lines all have default skew */
-                                               pins = "U8 GMAC0 RXD0", "V8 GMAC0 RXD1",
-                                                      "P9 GMAC0 RXD2", "R9 GMAC0 RXD3",
-                                                      "U7 GMAC0 TXD0", "T7 GMAC0 TXD1",
-                                                      "R7 GMAC0 TXD2", "P7 GMAC0 TXD3",
-                                                      "R11 GMAC1 RXD0", "P11 GMAC1 RXD1",
-                                                      "V12 GMAC1 RXD2", "U12 GMAC1 RXD3",
-                                                      "R10 GMAC1 TXD0", "T10 GMAC1 TXD1",
-                                                      "U10 GMAC1 TXD2", "V10 GMAC1 TXD3";
+                                               pins = "W8 GMAC0 RXD0", "V9 GMAC0 RXD1",
+                                                      "Y8 GMAC0 RXD2", "U9 GMAC0 RXD3",
+                                                      "T7 GMAC0 TXD0", "U6 GMAC0 TXD1",
+                                                      "V7 GMAC0 TXD2", "U7 GMAC0 TXD3",
+                                                      "Y12 GMAC1 RXD0", "V12 GMAC1 RXD1",
+                                                      "T11 GMAC1 RXD2", "W12 GMAC1 RXD3",
+                                                      "U10 GMAC1 TXD0", "Y10 GMAC1 TXD1",
+                                                      "W10 GMAC1 TXD2", "T9 GMAC1 TXD3";
                                                skew-delay = <7>;
                                        };
                                        /* Set up drive strength on GMAC0 to 16 mA */
index 475904894b8633464173b1b76f85e378c13ff4cb..e554b6e039f32fe396386bd6f7c32e9b4869ecf8 100644 (file)
 
                        cm2: cm2@8000 {
                                compatible = "ti,omap4-cm2", "simple-bus";
-                               reg = <0x8000 0x3000>;
+                               reg = <0x8000 0x2000>;
                                #address-cells = <1>;
                                #size-cells = <1>;
-                               ranges = <0 0x8000 0x3000>;
+                               ranges = <0 0x8000 0x2000>;
 
                                cm2_clocks: clocks {
                                        #address-cells = <1>;
 
                                prm: prm@6000 {
                                        compatible = "ti,omap4-prm";
-                                       reg = <0x6000 0x3000>;
+                                       reg = <0x6000 0x2000>;
                                        interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                        #address-cells = <1>;
                                        #size-cells = <1>;
-                                       ranges = <0 0x6000 0x3000>;
+                                       ranges = <0 0x6000 0x2000>;
 
                                        prm_clocks: clocks {
                                                #address-cells = <1>;
index 2a63fa10c813042bf2b98261964c7b6cd9f03790..553777ac28146f053983a1903ddf568a5bdd3c31 100644 (file)
@@ -1,6 +1,7 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_USER_NS=y
 CONFIG_RELAY=y
@@ -12,15 +13,21 @@ CONFIG_ARCH_GEMINI=y
 CONFIG_PCI=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
 CONFIG_CMDLINE="console=ttyS0,115200n8"
 CONFIG_KEXEC=y
 CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
@@ -33,6 +40,11 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_ATA=y
 CONFIG_PATA_FTIDE010=y
+CONFIG_NETDEVICES=y
+CONFIG_GEMINI_ETHERNET=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_REALTEK_PHY=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
@@ -43,9 +55,19 @@ CONFIG_SERIAL_8250_NR_UARTS=1
 CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=y
+CONFIG_THERMAL=y
 CONFIG_WATCHDOG=y
-CONFIG_GEMINI_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_ILITEK_IL9322=y
+CONFIG_DRM_TVE200=y
+CONFIG_LOGO=y
 CONFIG_USB=y
 CONFIG_USB_MON=y
 CONFIG_USB_FOTG210_HCD=y
@@ -54,6 +76,7 @@ CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_DISK=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
 CONFIG_DMADEVICES=y
index 2620ce790db0afaa18ed4d51eca2d886a21b00a8..371fca4e1ab7deafe2d8aed06ac5fd4092c7a8e4 100644 (file)
@@ -57,6 +57,7 @@ CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
 CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_OF_OVERLAY=y
 CONFIG_OF_CONFIGFS=y
index c6a749568dd6c413603ef3b7554561f356b33cc9..c7c28c885a1946de9a012311cbca7861d93a67da 100644 (file)
@@ -77,6 +77,9 @@ struct kvm_arch {
        /* Interrupt controller */
        struct vgic_dist        vgic;
        int max_vcpus;
+
+       /* Mandated version of PSCI */
+       u32 psci_version;
 };
 
 #define KVM_NR_MEM_OBJS     40
index 2ba95d6fe852d7bed7460b022f1ed5b8409caacd..caae4843cb7001fbee1fa9b222850df7006850fb 100644 (file)
@@ -195,6 +195,12 @@ struct kvm_arch_memory_slot {
 #define KVM_REG_ARM_VFP_FPINST         0x1009
 #define KVM_REG_ARM_VFP_FPINST2                0x100A
 
+/* KVM-as-firmware specific pseudo-registers */
+#define KVM_REG_ARM_FW                 (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_FW_REG(r)          (KVM_REG_ARM | KVM_REG_SIZE_U64 | \
+                                        KVM_REG_ARM_FW | ((r) & 0xffff))
+#define KVM_REG_ARM_PSCI_VERSION       KVM_REG_ARM_FW_REG(0)
+
 /* Device Control API: ARM VGIC */
 #define KVM_DEV_ARM_VGIC_GRP_ADDR      0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
index 1e0784ebbfd6db77595652961ad3c48c41fceabe..a18f33edc471a92fcf6194dbe6601bc4b94f1988 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
+#include <kvm/arm_psci.h>
 #include <asm/cputype.h>
 #include <linux/uaccess.h>
 #include <asm/kvm.h>
@@ -176,6 +177,7 @@ static unsigned long num_core_regs(void)
 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
 {
        return num_core_regs() + kvm_arm_num_coproc_regs(vcpu)
+               + kvm_arm_get_fw_num_regs(vcpu)
                + NUM_TIMER_REGS;
 }
 
@@ -196,6 +198,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
                uindices++;
        }
 
+       ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices);
+       if (ret)
+               return ret;
+       uindices += kvm_arm_get_fw_num_regs(vcpu);
+
        ret = copy_timer_indices(vcpu, uindices);
        if (ret)
                return ret;
@@ -214,6 +221,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return get_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_get_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return get_timer_reg(vcpu, reg);
 
@@ -230,6 +240,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return set_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_set_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return set_timer_reg(vcpu, reg);
 
index 4603c30fef73a721b8564ed74ffe63ce21b5966c..0d9ce58bc464a87249f1551a0882c18d5009bc5d 100644 (file)
@@ -243,8 +243,4 @@ arch/arm/mach-omap2/pm-asm-offsets.s: arch/arm/mach-omap2/pm-asm-offsets.c
 include/generated/ti-pm-asm-offsets.h: arch/arm/mach-omap2/pm-asm-offsets.s FORCE
        $(call filechk,offsets,__TI_PM_ASM_OFFSETS_H__)
 
-# For rule to generate ti-emif-asm-offsets.h dependency
-include drivers/memory/Makefile.asm-offsets
-
-arch/arm/mach-omap2/sleep33xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h
-arch/arm/mach-omap2/sleep43xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h
+$(obj)/sleep33xx.o $(obj)/sleep43xx.o: include/generated/ti-pm-asm-offsets.h
index 6d4392da7c11008dcc2f2c6eb762e1c850b22190..b9846b19e5e2c7b9737085e23c56d83e0d0a6f67 100644 (file)
@@ -7,9 +7,12 @@
 
 #include <linux/kbuild.h>
 #include <linux/platform_data/pm33xx.h>
+#include <linux/ti-emif-sram.h>
 
 int main(void)
 {
+       ti_emif_asm_offsets();
+
        DEFINE(AMX3_PM_WFI_FLAGS_OFFSET,
               offsetof(struct am33xx_pm_sram_data, wfi_flags));
        DEFINE(AMX3_PM_L2_AUX_CTRL_VAL_OFFSET,
index 218d79930b04623c24af79aa75468186a1b39f67..322b3bb868b49766f53ac807674ced65b5b42bc9 100644 (file)
@@ -6,7 +6,6 @@
  *     Dave Gerlach, Vaibhav Bedia
  */
 
-#include <generated/ti-emif-asm-offsets.h>
 #include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
 #include <linux/ti-emif-sram.h>
index b24be624e8b993d12ad7768cb2ed1ecea4676734..8903814a6677d327579f9410f9b9b641e23ed97a 100644 (file)
@@ -6,7 +6,6 @@
  *     Dave Gerlach, Vaibhav Bedia
  */
 
-#include <generated/ti-emif-asm-offsets.h>
 #include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
 #include <linux/ti-emif-sram.h>
index 59589a4a0d4b2023b628e9485aec98849c0f4c76..885e8f12e4b911bfaaf74ce8a8f9767b95bd08e7 100644 (file)
@@ -427,9 +427,9 @@ static struct gpiod_lookup_table jive_wm8750_gpiod_table = {
        .dev_id         = "spi_gpio",
        .table          = {
                GPIO_LOOKUP("GPIOB", 4,
-                           "gpio-sck", GPIO_ACTIVE_HIGH),
+                           "sck", GPIO_ACTIVE_HIGH),
                GPIO_LOOKUP("GPIOB", 9,
-                           "gpio-mosi", GPIO_ACTIVE_HIGH),
+                           "mosi", GPIO_ACTIVE_HIGH),
                GPIO_LOOKUP("GPIOH", 10,
                            "cs", GPIO_ACTIVE_HIGH),
                { },
index 15402861bb59eb9377682e56453965e7713592ca..87f7d2f9f17c266fee66973f29b6efd6c0590a71 100644 (file)
@@ -56,7 +56,11 @@ KBUILD_AFLAGS        += $(lseinstr) $(brokengasinst)
 KBUILD_CFLAGS  += $(call cc-option,-mabi=lp64)
 KBUILD_AFLAGS  += $(call cc-option,-mabi=lp64)
 
+ifeq ($(cc-name),clang)
+KBUILD_CFLAGS  += -DCONFIG_ARCH_SUPPORTS_INT128
+else
 KBUILD_CFLAGS  += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128)
+endif
 
 ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
 KBUILD_CPPFLAGS        += -mbig-endian
index 4eef36b2253865833a659be0ca5b3f2ab1b34cb7..88e712ea757a238152c06f932dfecfeb5b36b843 100644 (file)
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
index 22bf37404ff1b41ba74b96702d523a517e978c9c..3e3eb31748a35a7790a9dc90e56971f004660298 100644 (file)
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
+
+&usb2_phy0 {
+       /*
+        * even though the schematics don't show it:
+        * HDMI_5V is also used as supply for the USB VBUS.
+        */
+       phy-supply = <&hdmi_5v>;
+};
index 69c721a70e44b7c377040c2428833fc141f0ddf0..6739697be1defd72693e1e867c172a85cfe643ba 100644 (file)
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
index 0a0953fbc7d42b776a6b4d64f8da6a041ae30cb3..0cfd701809dec578ac31f5f68a7fcfbc21822619 100644 (file)
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
index e1a39cbed8c9c18abf90c521ba09dbd5356b7502..dba365ed4bd5f903e34f4c6fdf1b14d539db0d89 100644 (file)
                        no-map;
                };
        };
+
+       soc {
+               usb0: usb@c9000000 {
+                       status = "disabled";
+                       compatible = "amlogic,meson-gxl-dwc3";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       clocks = <&clkc CLKID_USB>;
+                       clock-names = "usb_general";
+                       resets = <&reset RESET_USB_OTG>;
+                       reset-names = "usb_otg";
+
+                       dwc3: dwc3@c9000000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x0 0xc9000000 0x0 0x100000>;
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               dr_mode = "host";
+                               maximum-speed = "high-speed";
+                               snps,dis_u2_susphy_quirk;
+                               phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>;
+                       };
+               };
+       };
+};
+
+&apb {
+       usb2_phy0: phy@78000 {
+               compatible = "amlogic,meson-gxl-usb2-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78000 0x0 0x20>;
+               clocks = <&clkc CLKID_USB>;
+               clock-names = "phy";
+               resets = <&reset RESET_USB_OTG>;
+               reset-names = "phy";
+               status = "okay";
+       };
+
+       usb2_phy1: phy@78020 {
+               compatible = "amlogic,meson-gxl-usb2-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78020 0x0 0x20>;
+               clocks = <&clkc CLKID_USB>;
+               clock-names = "phy";
+               resets = <&reset RESET_USB_OTG>;
+               reset-names = "phy";
+               status = "okay";
+       };
+
+       usb3_phy: phy@78080 {
+               compatible = "amlogic,meson-gxl-usb3-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78080 0x0 0x20>;
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&clkc CLKID_USB>, <&clkc_AO CLKID_AO_CEC_32K>;
+               clock-names = "phy", "peripheral";
+               resets = <&reset RESET_USB_OTG>, <&reset RESET_USB_OTG>;
+               reset-names = "phy", "peripheral";
+               status = "okay";
+       };
 };
 
 &ethmac {
index 4fd46c1546a7e5a82ec63dc50e15a2e0ae65d3e3..0868da476e41ff1a81aa40be378a13737c2a2c4a 100644 (file)
        status = "okay";
        vref-supply = <&vddio_ao18>;
 };
+
+&usb0 {
+       status = "okay";
+};
index d076a7c425dddd683ed81a9cfcb45fc7f2df682a..247888d68a3aabe06e8841a8d93cbfe8afe12960 100644 (file)
        };
 };
 
+&apb {
+       usb2_phy2: phy@78040 {
+               compatible = "amlogic,meson-gxl-usb2-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78040 0x0 0x20>;
+               clocks = <&clkc CLKID_USB>;
+               clock-names = "phy";
+               resets = <&reset RESET_USB_OTG>;
+               reset-names = "phy";
+               status = "okay";
+       };
+};
+
 &clkc_AO {
        compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc";
 };
 &hdmi_tx {
        compatible = "amlogic,meson-gxm-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
 };
+
+&dwc3 {
+       phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>;
+};
index 2ac43221ddb680acafd1507a866da58514a53370..69804c5f1197caac2815199edde847a547a0ae03 100644 (file)
@@ -56,8 +56,6 @@
 
                        gpio_keys {
                                compatible = "gpio-keys";
-                               #address-cells = <1>;
-                               #size-cells = <0>;
 
                                power-button {
                                        debounce_interval = <50>;
index 4b5465da81d8e29ac616fc18de3f1351e81321ed..8c68e0c26f1b281c0259fd0f5cca18d2eebcb8a4 100644 (file)
                #size-cells = <1>;
                ranges = <0x0 0x0 0x67d00000 0x00800000>;
 
-               sata0: ahci@210000 {
+               sata0: ahci@0 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00210000 0x1000>;
+                       reg = <0x00000000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -52,9 +52,9 @@
                        };
                };
 
-               sata_phy0: sata_phy@212100 {
+               sata_phy0: sata_phy@2100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00212100 0x1000>;
+                       reg = <0x00002100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               sata1: ahci@310000 {
+               sata1: ahci@10000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00310000 0x1000>;
+                       reg = <0x00010000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -82,9 +82,9 @@
                        };
                };
 
-               sata_phy1: sata_phy@312100 {
+               sata_phy1: sata_phy@12100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00312100 0x1000>;
+                       reg = <0x00012100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               sata2: ahci@120000 {
+               sata2: ahci@20000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00120000 0x1000>;
+                       reg = <0x00020000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        };
                };
 
-               sata_phy2: sata_phy@122100 {
+               sata_phy2: sata_phy@22100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00122100 0x1000>;
+                       reg = <0x00022100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               sata3: ahci@130000 {
+               sata3: ahci@30000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00130000 0x1000>;
+                       reg = <0x00030000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        };
                };
 
-               sata_phy3: sata_phy@132100 {
+               sata_phy3: sata_phy@32100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00132100 0x1000>;
+                       reg = <0x00032100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               sata4: ahci@330000 {
+               sata4: ahci@100000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00330000 0x1000>;
+                       reg = <0x00100000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        };
                };
 
-               sata_phy4: sata_phy@332100 {
+               sata_phy4: sata_phy@102100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00332100 0x1000>;
+                       reg = <0x00102100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               sata5: ahci@400000 {
+               sata5: ahci@110000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00400000 0x1000>;
+                       reg = <0x00110000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        };
                };
 
-               sata_phy5: sata_phy@402100 {
+               sata_phy5: sata_phy@112100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00402100 0x1000>;
+                       reg = <0x00112100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               sata6: ahci@410000 {
+               sata6: ahci@120000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00410000 0x1000>;
+                       reg = <0x00120000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        };
                };
 
-               sata_phy6: sata_phy@412100 {
+               sata_phy6: sata_phy@122100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00412100 0x1000>;
+                       reg = <0x00122100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               sata7: ahci@420000 {
+               sata7: ahci@130000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00420000 0x1000>;
+                       reg = <0x00130000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        };
                };
 
-               sata_phy7: sata_phy@422100 {
+               sata_phy7: sata_phy@132100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00422100 0x1000>;
+                       reg = <0x00132100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
index ab46bc70add636e0793f32083f800ff06bf80353..469de8acd06f5fa4103d9f55d0fb4c4c97d853a9 100644 (file)
@@ -75,6 +75,9 @@ struct kvm_arch {
 
        /* Interrupt controller */
        struct vgic_dist        vgic;
+
+       /* Mandated version of PSCI */
+       u32 psci_version;
 };
 
 #define KVM_NR_MEM_OBJS     40
index b6dbbe3123a9a9f8308a07b9257bfe968c184804..97d0ef12e2ff561938acdf96196a1a213664c522 100644 (file)
@@ -39,7 +39,7 @@ struct mod_arch_specific {
 u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela,
                          Elf64_Sym *sym);
 
-u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val);
+u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val);
 
 #ifdef CONFIG_RANDOMIZE_BASE
 extern u64 module_alloc_base;
index 7e2c27e63cd894371655a569046faaa67cfc1837..7c4c8f318ba999afdac0b41300c9613fe161e91d 100644 (file)
@@ -230,7 +230,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
        }
 }
 
-extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
+extern void __sync_icache_dcache(pte_t pteval);
 
 /*
  * PTE bits configuration in the presence of hardware Dirty Bit Management
@@ -253,7 +253,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
        pte_t old_pte;
 
        if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
-               __sync_icache_dcache(pte, addr);
+               __sync_icache_dcache(pte);
 
        /*
         * If the existing pte is valid, check for potential race with
index 9abbf30446545a0668083b0891461f015563bcb1..04b3256f8e6d5f8e3e368b043f0fdcfeb7c23164 100644 (file)
@@ -206,6 +206,12 @@ struct kvm_arch_memory_slot {
 #define KVM_REG_ARM_TIMER_CNT          ARM64_SYS_REG(3, 3, 14, 3, 2)
 #define KVM_REG_ARM_TIMER_CVAL         ARM64_SYS_REG(3, 3, 14, 0, 2)
 
+/* KVM-as-firmware specific pseudo-registers */
+#define KVM_REG_ARM_FW                 (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_FW_REG(r)          (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
+                                        KVM_REG_ARM_FW | ((r) & 0xffff))
+#define KVM_REG_ARM_PSCI_VERSION       KVM_REG_ARM_FW_REG(0)
+
 /* Device Control API: ARM VGIC */
 #define KVM_DEV_ARM_VGIC_GRP_ADDR      0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
index 536d572e55967286b65457631251c842c1951353..9d1b06d67c53d4addacf97dd96207aa91d2ba04b 100644 (file)
@@ -868,6 +868,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
        static const struct midr_range kpti_safe_list[] = {
                MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
                MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
+               { /* sentinel */ }
        };
        char const *str = "command line option";
 
index fa3637284a3d8f4c7dbfe4b7e107af9af94f2685..f0690c2ca3e0f2f27f761a1568e6b3cc637779a4 100644 (file)
@@ -43,7 +43,7 @@ u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela,
 }
 
 #ifdef CONFIG_ARM64_ERRATUM_843419
-u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val)
+u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val)
 {
        struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
                                                          &mod->arch.init;
index 719fde8dcc19042b38164ddcaa7da429cd2180b2..155fd91e78f4a62180e7577355ca4a6b0eb283f4 100644 (file)
@@ -215,7 +215,7 @@ static int reloc_insn_adrp(struct module *mod, __le32 *place, u64 val)
                insn &= ~BIT(31);
        } else {
                /* out of range for ADR -> emit a veneer */
-               val = module_emit_adrp_veneer(mod, place, val & ~0xfff);
+               val = module_emit_veneer_for_adrp(mod, place, val & ~0xfff);
                if (!val)
                        return -ENOEXEC;
                insn = aarch64_insn_gen_branch_imm((u64)place, val,
index 71d99af24ef20852a18deea4d29a25c0197cf651..7ff81fed46e1ebeebfdd58eddc5c718af5f3d565 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/sched/signal.h>
 #include <linux/sched/task_stack.h>
 #include <linux/mm.h>
+#include <linux/nospec.h>
 #include <linux/smp.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
@@ -249,15 +250,20 @@ static struct perf_event *ptrace_hbp_get_event(unsigned int note_type,
 
        switch (note_type) {
        case NT_ARM_HW_BREAK:
-               if (idx < ARM_MAX_BRP)
-                       bp = tsk->thread.debug.hbp_break[idx];
+               if (idx >= ARM_MAX_BRP)
+                       goto out;
+               idx = array_index_nospec(idx, ARM_MAX_BRP);
+               bp = tsk->thread.debug.hbp_break[idx];
                break;
        case NT_ARM_HW_WATCH:
-               if (idx < ARM_MAX_WRP)
-                       bp = tsk->thread.debug.hbp_watch[idx];
+               if (idx >= ARM_MAX_WRP)
+                       goto out;
+               idx = array_index_nospec(idx, ARM_MAX_WRP);
+               bp = tsk->thread.debug.hbp_watch[idx];
                break;
        }
 
+out:
        return bp;
 }
 
@@ -1458,9 +1464,7 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
 {
        int ret;
        u32 kdata;
-       mm_segment_t old_fs = get_fs();
 
-       set_fs(KERNEL_DS);
        /* Watchpoint */
        if (num < 0) {
                ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata);
@@ -1471,7 +1475,6 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
        } else {
                ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata);
        }
-       set_fs(old_fs);
 
        if (!ret)
                ret = put_user(kdata, data);
@@ -1484,7 +1487,6 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
 {
        int ret;
        u32 kdata = 0;
-       mm_segment_t old_fs = get_fs();
 
        if (num == 0)
                return 0;
@@ -1493,12 +1495,10 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
        if (ret)
                return ret;
 
-       set_fs(KERNEL_DS);
        if (num < 0)
                ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata);
        else
                ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata);
-       set_fs(old_fs);
 
        return ret;
 }
index ba964da31a252dd2ea517b2b7a4dcef06daa0f7b..8bbdc17e49df79cab3e8576783216e91aef6c746 100644 (file)
@@ -277,7 +277,8 @@ void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size)
         * If we were single stepping, we want to get the step exception after
         * we return from the trap.
         */
-       user_fastforward_single_step(current);
+       if (user_mode(regs))
+               user_fastforward_single_step(current);
 }
 
 static LIST_HEAD(undef_hook);
@@ -366,7 +367,7 @@ void force_signal_inject(int signal, int code, unsigned long address)
        }
 
        /* Force signals we don't understand to SIGKILL */
-       if (WARN_ON(signal != SIGKILL ||
+       if (WARN_ON(signal != SIGKILL &&
                    siginfo_layout(signal, code) != SIL_FAULT)) {
                signal = SIGKILL;
        }
index 959e50d2588c0f14b9eb9230522c3f12c3f7daf9..56a0260ceb11a95258099f0f19356b8989ff6afa 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
+#include <kvm/arm_psci.h>
 #include <asm/cputype.h>
 #include <linux/uaccess.h>
 #include <asm/kvm.h>
@@ -205,7 +206,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
 {
        return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu)
-                + NUM_TIMER_REGS;
+               + kvm_arm_get_fw_num_regs(vcpu) + NUM_TIMER_REGS;
 }
 
 /**
@@ -225,6 +226,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
                uindices++;
        }
 
+       ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices);
+       if (ret)
+               return ret;
+       uindices += kvm_arm_get_fw_num_regs(vcpu);
+
        ret = copy_timer_indices(vcpu, uindices);
        if (ret)
                return ret;
@@ -243,6 +249,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return get_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_get_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return get_timer_reg(vcpu, reg);
 
@@ -259,6 +268,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return set_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_set_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return set_timer_reg(vcpu, reg);
 
index 806b0b126a644dbc4e2f80db451370b63c63c6a5..6e3b969391fdbb853f621fa60f7c8760d79caa78 100644 (file)
@@ -996,14 +996,12 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz)
 
        if (id == SYS_ID_AA64PFR0_EL1) {
                if (val & (0xfUL << ID_AA64PFR0_SVE_SHIFT))
-                       pr_err_once("kvm [%i]: SVE unsupported for guests, suppressing\n",
-                                   task_pid_nr(current));
+                       kvm_debug("SVE unsupported for guests, suppressing\n");
 
                val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
        } else if (id == SYS_ID_AA64MMFR1_EL1) {
                if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))
-                       pr_err_once("kvm [%i]: LORegions unsupported for guests, suppressing\n",
-                                   task_pid_nr(current));
+                       kvm_debug("LORegions unsupported for guests, suppressing\n");
 
                val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT);
        }
index 0ead8a1d167956193f5666dfa9a5365e0e94ebc8..137710f4dac30ac01c5c17856b730a996628a2e3 100644 (file)
@@ -19,5 +19,9 @@ CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2         \
                   -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15   \
                   -fcall-saved-x18 -fomit-frame-pointer
 CFLAGS_REMOVE_atomic_ll_sc.o := -pg
+GCOV_PROFILE_atomic_ll_sc.o    := n
+KASAN_SANITIZE_atomic_ll_sc.o  := n
+KCOV_INSTRUMENT_atomic_ll_sc.o := n
+UBSAN_SANITIZE_atomic_ll_sc.o  := n
 
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
index e36ed5087b5cbba3f71c57937af82b1b00cb88e4..1059884f9a6f35231be04b2930c7ecf5c10b4105 100644 (file)
@@ -58,7 +58,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
        flush_ptrace_access(vma, page, uaddr, dst, len);
 }
 
-void __sync_icache_dcache(pte_t pte, unsigned long addr)
+void __sync_icache_dcache(pte_t pte)
 {
        struct page *page = pte_page(pte);
 
index dabfc1ecda3d3a9d57a430f1641eca05c1114703..12145874c02b8c8a3f82b4dac954e73521085dd7 100644 (file)
@@ -204,7 +204,7 @@ void __init kasan_init(void)
        clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
        kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
-                          pfn_to_nid(virt_to_pfn(lm_alias(_text))));
+                          early_pfn_to_nid(virt_to_pfn(lm_alias(_text))));
 
        kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
                                   (void *)mod_shadow_start);
@@ -224,7 +224,7 @@ void __init kasan_init(void)
 
                kasan_map_populate((unsigned long)kasan_mem_to_shadow(start),
                                   (unsigned long)kasan_mem_to_shadow(end),
-                                  pfn_to_nid(virt_to_pfn(start)));
+                                  early_pfn_to_nid(virt_to_pfn(start)));
        }
 
        /*
index 9e8621d94ee9c0ecece44aa76f93810fea1e70fb..e17262ad125e7ee0c48be297dfff08dc50f2d5e6 100644 (file)
@@ -216,6 +216,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
        memcpy((void *) dst, src, count);
 }
 
+static inline void memset_io(volatile void __iomem *addr, int value,
+                            size_t size)
+{
+       memset((void __force *)addr, value, size);
+}
+
 #define PCI_IO_ADDR    (volatile void __iomem *)
 
 /*
index 617506d1a5596679b19b27af252c3199e61ab1f1..7cd0a2259269659b2b90222c074d06d18bc5b907 100644 (file)
@@ -199,3 +199,4 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
        memcpy(dst, src, len);
        return csum_partial(dst, len, sum);
 }
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
index 1bd105428f61421eec2f5df8e470e7e056fb8598..65af3f6ba81c3a6515e4e9a199916c9eff131d87 100644 (file)
@@ -51,6 +51,8 @@
                ranges = <0x02000000 0 0x40000000
                          0x40000000 0 0x40000000>;
 
+               bus-range = <0x00 0xff>;
+
                interrupt-map-mask = <0 0 0 7>;
                interrupt-map = <0 0 0 1 &pci0_intc 1>,
                                <0 0 0 2 &pci0_intc 2>,
@@ -79,6 +81,8 @@
                ranges = <0x02000000 0 0x20000000
                          0x20000000 0 0x20000000>;
 
+               bus-range = <0x00 0xff>;
+
                interrupt-map-mask = <0 0 0 7>;
                interrupt-map = <0 0 0 1 &pci1_intc 1>,
                                <0 0 0 2 &pci1_intc 2>,
                ranges = <0x02000000 0 0x16000000
                          0x16000000 0 0x100000>;
 
+               bus-range = <0x00 0xff>;
+
                interrupt-map-mask = <0 0 0 7>;
                interrupt-map = <0 0 0 1 &pci2_intc 1>,
                                <0 0 0 2 &pci2_intc 2>,
index 0cbf3af37ecad9d195847c49ddffb15a6165fc4d..a7d0b836f2f7dd9c8bf7897759aed6b9f59ade39 100644 (file)
@@ -307,7 +307,7 @@ static inline void iounmap(const volatile void __iomem *addr)
 #if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT)
 #define war_io_reorder_wmb()           wmb()
 #else
-#define war_io_reorder_wmb()           do { } while (0)
+#define war_io_reorder_wmb()           barrier()
 #endif
 
 #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq)                    \
@@ -377,6 +377,8 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem)        \
                BUG();                                                  \
        }                                                               \
                                                                        \
+       /* prevent prefetching of coherent DMA data prematurely */      \
+       rmb();                                                          \
        return pfx##ioswab##bwlq(__mem, __val);                         \
 }
 
index b713069472903c26f21c11424113765a5156d955..06629011a4342f490bf4bcabd9e4fe06ed0952ac 100644 (file)
@@ -654,6 +654,13 @@ __clear_user(void __user *addr, __kernel_size_t size)
 {
        __kernel_size_t res;
 
+#ifdef CONFIG_CPU_MICROMIPS
+/* micromips memset / bzero also clobbers t7 & t8 */
+#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$15", "$24", "$31"
+#else
+#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"
+#endif /* CONFIG_CPU_MICROMIPS */
+
        if (eva_kernel_access()) {
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
@@ -663,7 +670,7 @@ __clear_user(void __user *addr, __kernel_size_t size)
                        "move\t%0, $6"
                        : "=r" (res)
                        : "r" (addr), "r" (size)
-                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+                       : bzero_clobbers);
        } else {
                might_fault();
                __asm__ __volatile__(
@@ -674,7 +681,7 @@ __clear_user(void __user *addr, __kernel_size_t size)
                        "move\t%0, $6"
                        : "=r" (res)
                        : "r" (addr), "r" (size)
-                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+                       : bzero_clobbers);
        }
 
        return res;
index a1456664d6c28c9ccc8f837e341fe1a760b3c2d6..f7327979a8f8e163547dafe4302d12caab809fbd 100644 (file)
 1:     PTR_ADDIU       a0, 1                   /* fill bytewise */
        R10KCBARRIER(0(ra))
        bne             t1, a0, 1b
-       sb              a1, -1(a0)
+        EX(sb, a1, -1(a0), .Lsmall_fixup\@)
 
 2:     jr              ra                      /* done */
        move            a2, zero
        PTR_L           t0, TI_TASK($28)
        andi            a2, STORMASK
        LONG_L          t0, THREAD_BUADDR(t0)
-       LONG_ADDU       a2, t1
+       LONG_ADDU       a2, a0
        jr              ra
        LONG_SUBU       a2, t0
 
 .Llast_fixup\@:
        jr              ra
-       andi            v1, a2, STORMASK
+        nop
+
+.Lsmall_fixup\@:
+       PTR_SUBU        a2, t1, a0
+       jr              ra
+        PTR_ADDIU      a2, 1
 
        .endm
 
index eafd06ab59ef8db3b21aabccc5021a05877e38f7..e5de34d00b1adad3409bd11b07fae826167e59c5 100644 (file)
@@ -23,7 +23,7 @@ obj-$(CONFIG_SMP)     += smp.o
 obj-$(CONFIG_PA11)     += pci-dma.o
 obj-$(CONFIG_PCI)      += pci.o
 obj-$(CONFIG_MODULES)  += module.o
-obj-$(CONFIG_64BIT)    += binfmt_elf32.o sys_parisc32.o signal32.o
+obj-$(CONFIG_64BIT)    += sys_parisc32.o signal32.o
 obj-$(CONFIG_STACKTRACE)+= stacktrace.o
 obj-$(CONFIG_AUDIT)    += audit.o
 obj64-$(CONFIG_AUDIT)  += compat_audit.o
index d1c2d2e658cf4d5b1d3c3718a377efa345067128..2f3ff7a278815a131f9ebec73bffcdaedf0abab3 100644 (file)
@@ -15,7 +15,7 @@
 extern void powernv_set_nmmu_ptcr(unsigned long ptcr);
 extern struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
                        unsigned long flags,
-                       struct npu_context *(*cb)(struct npu_context *, void *),
+                       void (*cb)(struct npu_context *, void *),
                        void *priv);
 extern void pnv_npu2_destroy_context(struct npu_context *context,
                                struct pci_dev *gpdev);
index 2d4956e97aa9812fd93863322e1a1808e5a54cd7..ee5a67d57aab8ff3153071c7a4c07574aa6f8adf 100644 (file)
@@ -807,7 +807,8 @@ static void eeh_restore_bridge_bars(struct eeh_dev *edev)
        eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]);
 
        /* PCI Command: 0x4 */
-       eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1]);
+       eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1] |
+                             PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 
        /* Check the PCIe link is ready */
        eeh_bridge_check_link(edev);
index 79d005445c6c996fa9a4cff42f3d52d557f91177..e734f6e45abc1ecb64cc8fe68b88054210e30bd3 100644 (file)
@@ -553,12 +553,12 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
        lbz     r0,HSTATE_HWTHREAD_STATE(r13)
        cmpwi   r0,KVM_HWTHREAD_IN_KERNEL
-       beq     1f
+       beq     0f
        li      r0,KVM_HWTHREAD_IN_KERNEL
        stb     r0,HSTATE_HWTHREAD_STATE(r13)
        /* Order setting hwthread_state vs. testing hwthread_req */
        sync
-       lbz     r0,HSTATE_HWTHREAD_REQ(r13)
+0:     lbz     r0,HSTATE_HWTHREAD_REQ(r13)
        cmpwi   r0,0
        beq     1f
        b       kvm_start_guest
index fe6fc63251fec70e7cf2dee7f6deab47fe8ab256..38c5b4764bfed0e0aeb647418f53875bb0f7b2a0 100644 (file)
@@ -441,7 +441,6 @@ static int mce_handle_ierror(struct pt_regs *regs,
                                        if (pfn != ULONG_MAX) {
                                                *phys_addr =
                                                        (pfn << PAGE_SHIFT);
-                                               handled = 1;
                                        }
                                }
                        }
@@ -532,9 +531,7 @@ static int mce_handle_derror(struct pt_regs *regs,
                         * kernel/exception-64s.h
                         */
                        if (get_paca()->in_mce < MAX_MCE_DEPTH)
-                               if (!mce_find_instr_ea_and_pfn(regs, addr,
-                                                               phys_addr))
-                                       handled = 1;
+                               mce_find_instr_ea_and_pfn(regs, addr, phys_addr);
                }
                found = 1;
        }
@@ -572,7 +569,7 @@ static long mce_handle_error(struct pt_regs *regs,
                const struct mce_ierror_table itable[])
 {
        struct mce_error_info mce_err = { 0 };
-       uint64_t addr, phys_addr;
+       uint64_t addr, phys_addr = ULONG_MAX;
        uint64_t srr1 = regs->msr;
        long handled;
 
index 44c30dd380670ff0f5d3114522829190d0662990..b78f142a41488e1a91833112d5f3d1fe0c3bb4d0 100644 (file)
@@ -890,6 +890,17 @@ static void __ref init_fallback_flush(void)
                return;
 
        l1d_size = ppc64_caches.l1d.size;
+
+       /*
+        * If there is no d-cache-size property in the device tree, l1d_size
+        * could be zero. That leads to the loop in the asm wrapping around to
+        * 2^64-1, and then walking off the end of the fallback area and
+        * eventually causing a page fault which is fatal. Just default to
+        * something vaguely sane.
+        */
+       if (!l1d_size)
+               l1d_size = (64 * 1024);
+
        limit = min(ppc64_bolted_size(), ppc64_rma_size);
 
        /*
index e16ec7b3b427ea2d2ce2ca0a1229b16df51dc0e1..9ca7148b5881a098abf7bf0a3eff99536f99a7ec 100644 (file)
@@ -566,10 +566,35 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
 #endif
 
 #ifdef CONFIG_NMI_IPI
-static void stop_this_cpu(struct pt_regs *regs)
-#else
+static void nmi_stop_this_cpu(struct pt_regs *regs)
+{
+       /*
+        * This is a special case because it never returns, so the NMI IPI
+        * handling would never mark it as done, which makes any later
+        * smp_send_nmi_ipi() call spin forever. Mark it done now.
+        *
+        * IRQs are already hard disabled by the smp_handle_nmi_ipi.
+        */
+       nmi_ipi_lock();
+       nmi_ipi_busy_count--;
+       nmi_ipi_unlock();
+
+       /* Remove this CPU */
+       set_cpu_online(smp_processor_id(), false);
+
+       spin_begin();
+       while (1)
+               spin_cpu_relax();
+}
+
+void smp_send_stop(void)
+{
+       smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, nmi_stop_this_cpu, 1000000);
+}
+
+#else /* CONFIG_NMI_IPI */
+
 static void stop_this_cpu(void *dummy)
-#endif
 {
        /* Remove this CPU */
        set_cpu_online(smp_processor_id(), false);
@@ -582,12 +607,22 @@ static void stop_this_cpu(void *dummy)
 
 void smp_send_stop(void)
 {
-#ifdef CONFIG_NMI_IPI
-       smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, stop_this_cpu, 1000000);
-#else
+       static bool stopped = false;
+
+       /*
+        * Prevent waiting on csd lock from a previous smp_send_stop.
+        * This is racy, but in general callers try to do the right
+        * thing and only fire off one smp_send_stop (e.g., see
+        * kernel/panic.c)
+        */
+       if (stopped)
+               return;
+
+       stopped = true;
+
        smp_call_function(stop_this_cpu, NULL, 0);
-#endif
 }
+#endif /* CONFIG_NMI_IPI */
 
 struct thread_info *current_set[NR_CPUS];
 
index 6038e2e7aee03c2b29edb65624be370f01a6c928..876d4f294fdd89fc160439073a3c04c9c8e81174 100644 (file)
@@ -305,6 +305,13 @@ void kvmppc_core_queue_fpunavail(struct kvm_vcpu *vcpu)
        kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_FP_UNAVAIL);
 }
 
+#ifdef CONFIG_ALTIVEC
+void kvmppc_core_queue_vec_unavail(struct kvm_vcpu *vcpu)
+{
+       kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ALTIVEC_UNAVAIL);
+}
+#endif
+
 void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
 {
        kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DECREMENTER);
index 35f80ab7cbd83c6fbd7eca53955d4e14839ff837..288fe4f0db4ea326321915e1904da3771380978d 100644 (file)
@@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
                unsigned int *target = (unsigned int *)branch_target(src);
 
                /* Branch within the section doesn't need translating */
-               if (target < alt_start || target >= alt_end) {
+               if (target < alt_start || target > alt_end) {
                        instr = translate_branch(dest, src);
                        if (!instr)
                                return 1;
index 737f8a4632ccc68abfdd61a1900380834b125340..c3c39b02b2ba7b0ae58df5bf293103b382b2b708 100644 (file)
@@ -133,6 +133,7 @@ int __meminit arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *
                        start, start + size, rc);
                return -EFAULT;
        }
+       flush_inval_dcache_range(start, start + size);
 
        return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 }
@@ -159,6 +160,7 @@ int __meminit arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap
 
        /* Remove htab bolted mappings for this section of memory */
        start = (unsigned long)__va(start);
+       flush_inval_dcache_range(start, start + size);
        ret = remove_section_mapping(start, start + size);
 
        /* Ensure all vmalloc mappings are flushed in case they also
index 9033c8194eda5d7d39db99af0af9e6f33811a272..ccc42150336394ca0fa8a7263b5d408e59c30552 100644 (file)
@@ -1093,7 +1093,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private)
                LOAD_INT(c), LOAD_FRAC(c),
                count_active_contexts(),
                atomic_read(&nr_spu_contexts),
-               idr_get_cursor(&task_active_pid_ns(current)->idr));
+               idr_get_cursor(&task_active_pid_ns(current)->idr) - 1);
        return 0;
 }
 
index de470caf07848e28864cbb8ff0129e4ed7aaf021..fc222a0c2ac46b06095ed831827d40e84994e3ca 100644 (file)
@@ -82,19 +82,6 @@ static const struct file_operations memtrace_fops = {
        .open   = simple_open,
 };
 
-static void flush_memory_region(u64 base, u64 size)
-{
-       unsigned long line_size = ppc64_caches.l1d.size;
-       u64 end = base + size;
-       u64 addr;
-
-       base = round_down(base, line_size);
-       end = round_up(end, line_size);
-
-       for (addr = base; addr < end; addr += line_size)
-               asm volatile("dcbf 0,%0" : "=r" (addr) :: "memory");
-}
-
 static int check_memblock_online(struct memory_block *mem, void *arg)
 {
        if (mem->state != MEM_ONLINE)
@@ -132,10 +119,6 @@ static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages)
        walk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE,
                          change_memblock_state);
 
-       /* RCU grace period? */
-       flush_memory_region((u64)__va(start_pfn << PAGE_SHIFT),
-                           nr_pages << PAGE_SHIFT);
-
        lock_device_hotplug();
        remove_memory(nid, start_pfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
        unlock_device_hotplug();
index 69a4f9e8bd554f137dd01b930b1b3d87e204fd47..525e966dce3418cef4a82f494da331793b628668 100644 (file)
 
 #define npu_to_phb(x) container_of(x, struct pnv_phb, npu)
 
+/*
+ * spinlock to protect initialisation of an npu_context for a particular
+ * mm_struct.
+ */
+static DEFINE_SPINLOCK(npu_context_lock);
+
+/*
+ * When an address shootdown range exceeds this threshold we invalidate the
+ * entire TLB on the GPU for the given PID rather than each specific address in
+ * the range.
+ */
+#define ATSD_THRESHOLD (2*1024*1024)
+
 /*
  * Other types of TCE cache invalidation are not functional in the
  * hardware.
@@ -401,7 +414,7 @@ struct npu_context {
        bool nmmu_flush;
 
        /* Callback to stop translation requests on a given GPU */
-       struct npu_context *(*release_cb)(struct npu_context *, void *);
+       void (*release_cb)(struct npu_context *context, void *priv);
 
        /*
         * Private pointer passed to the above callback for usage by
@@ -671,11 +684,19 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
        struct npu_context *npu_context = mn_to_npu_context(mn);
        unsigned long address;
 
-       for (address = start; address < end; address += PAGE_SIZE)
-               mmio_invalidate(npu_context, 1, address, false);
+       if (end - start > ATSD_THRESHOLD) {
+               /*
+                * Just invalidate the entire PID if the address range is too
+                * large.
+                */
+               mmio_invalidate(npu_context, 0, 0, true);
+       } else {
+               for (address = start; address < end; address += PAGE_SIZE)
+                       mmio_invalidate(npu_context, 1, address, false);
 
-       /* Do the flush only on the final addess == end */
-       mmio_invalidate(npu_context, 1, address, true);
+               /* Do the flush only on the final addess == end */
+               mmio_invalidate(npu_context, 1, address, true);
+       }
 }
 
 static const struct mmu_notifier_ops nv_nmmu_notifier_ops = {
@@ -696,11 +717,12 @@ static const struct mmu_notifier_ops nv_nmmu_notifier_ops = {
  * Returns an error if there no contexts are currently available or a
  * npu_context which should be passed to pnv_npu2_handle_fault().
  *
- * mmap_sem must be held in write mode.
+ * mmap_sem must be held in write mode and must not be called from interrupt
+ * context.
  */
 struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
                        unsigned long flags,
-                       struct npu_context *(*cb)(struct npu_context *, void *),
+                       void (*cb)(struct npu_context *, void *),
                        void *priv)
 {
        int rc;
@@ -743,7 +765,9 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
        /*
         * Setup the NPU context table for a particular GPU. These need to be
         * per-GPU as we need the tables to filter ATSDs when there are no
-        * active contexts on a particular GPU.
+        * active contexts on a particular GPU. It is safe for these to be
+        * called concurrently with destroy as the OPAL call takes appropriate
+        * locks and refcounts on init/destroy.
         */
        rc = opal_npu_init_context(nphb->opal_id, mm->context.id, flags,
                                PCI_DEVID(gpdev->bus->number, gpdev->devfn));
@@ -754,8 +778,29 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
         * We store the npu pci device so we can more easily get at the
         * associated npus.
         */
+       spin_lock(&npu_context_lock);
        npu_context = mm->context.npu_context;
+       if (npu_context) {
+               if (npu_context->release_cb != cb ||
+                       npu_context->priv != priv) {
+                       spin_unlock(&npu_context_lock);
+                       opal_npu_destroy_context(nphb->opal_id, mm->context.id,
+                                               PCI_DEVID(gpdev->bus->number,
+                                                       gpdev->devfn));
+                       return ERR_PTR(-EINVAL);
+               }
+
+               WARN_ON(!kref_get_unless_zero(&npu_context->kref));
+       }
+       spin_unlock(&npu_context_lock);
+
        if (!npu_context) {
+               /*
+                * We can set up these fields without holding the
+                * npu_context_lock as the npu_context hasn't been returned to
+                * the caller meaning it can't be destroyed. Parallel allocation
+                * is protected against by mmap_sem.
+                */
                rc = -ENOMEM;
                npu_context = kzalloc(sizeof(struct npu_context), GFP_KERNEL);
                if (npu_context) {
@@ -774,8 +819,6 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
                }
 
                mm->context.npu_context = npu_context;
-       } else {
-               WARN_ON(!kref_get_unless_zero(&npu_context->kref));
        }
 
        npu_context->release_cb = cb;
@@ -814,15 +857,16 @@ static void pnv_npu2_release_context(struct kref *kref)
                mm_context_remove_copro(npu_context->mm);
 
        npu_context->mm->context.npu_context = NULL;
-       mmu_notifier_unregister(&npu_context->mn,
-                               npu_context->mm);
-
-       kfree(npu_context);
 }
 
+/*
+ * Destroy a context on the given GPU. May free the npu_context if it is no
+ * longer active on any GPUs. Must not be called from interrupt context.
+ */
 void pnv_npu2_destroy_context(struct npu_context *npu_context,
                        struct pci_dev *gpdev)
 {
+       int removed;
        struct pnv_phb *nphb;
        struct npu *npu;
        struct pci_dev *npdev = pnv_pci_get_npu_dev(gpdev, 0);
@@ -844,7 +888,21 @@ void pnv_npu2_destroy_context(struct npu_context *npu_context,
        WRITE_ONCE(npu_context->npdev[npu->index][nvlink_index], NULL);
        opal_npu_destroy_context(nphb->opal_id, npu_context->mm->context.id,
                                PCI_DEVID(gpdev->bus->number, gpdev->devfn));
-       kref_put(&npu_context->kref, pnv_npu2_release_context);
+       spin_lock(&npu_context_lock);
+       removed = kref_put(&npu_context->kref, pnv_npu2_release_context);
+       spin_unlock(&npu_context_lock);
+
+       /*
+        * We need to do this outside of pnv_npu2_release_context so that it is
+        * outside the spinlock as mmu_notifier_destroy uses SRCU.
+        */
+       if (removed) {
+               mmu_notifier_unregister(&npu_context->mn,
+                                       npu_context->mm);
+
+               kfree(npu_context);
+       }
+
 }
 EXPORT_SYMBOL(pnv_npu2_destroy_context);
 
index f8868864f373ed5eecba333a5b1a2b83e38e0ec6..aa2a5139462ea5f6c81f51c8f025c9af84ce0be2 100644 (file)
@@ -48,10 +48,12 @@ unsigned long __init opal_get_boot_time(void)
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       mdelay(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else if (rc == OPAL_BUSY)
-                       mdelay(10);
+               } else if (rc == OPAL_BUSY) {
+                       mdelay(OPAL_BUSY_DELAY_MS);
+               }
        }
        if (rc != OPAL_SUCCESS)
                return 0;
index d22aeb0b69e107636e94e7811785e573f60880ce..b48454be5b9822fdd1ac75452edf20a988745e5b 100644 (file)
@@ -389,6 +389,10 @@ static void xive_native_setup_cpu(unsigned int cpu, struct xive_cpu *xc)
        if (xive_pool_vps == XIVE_INVALID_VP)
                return;
 
+       /* Check if pool VP already active, if it is, pull it */
+       if (in_be32(xive_tima + TM_QW2_HV_POOL + TM_WORD2) & TM_QW2W2_VP)
+               in_be64(xive_tima + TM_SPC_PULL_POOL_CTX);
+
        /* Enable the pool VP */
        vp = xive_pool_vps + cpu;
        pr_debug("CPU %d setting up pool VP 0x%x\n", cpu, vp);
index 23d8acca5c9038a184df62d24ccb2112cb92a7c0..cd4fd85fde84e76fa205737076c5a721b9f4c6f4 100644 (file)
@@ -11,6 +11,7 @@ config RISCV
        select ARCH_WANT_FRAME_POINTERS
        select CLONE_BACKWARDS
        select COMMON_CLK
+       select DMA_DIRECT_OPS
        select GENERIC_CLOCKEVENTS
        select GENERIC_CPU_DEVICES
        select GENERIC_IRQ_SHOW
@@ -89,9 +90,6 @@ config PGTABLE_LEVELS
 config HAVE_KPROBES
        def_bool n
 
-config DMA_DIRECT_OPS
-       def_bool y
-
 menu "Platform type"
 
 choice
index 1e5fd280fb4d150ebc5a593b7f249af0330a7228..4286a5f838760c7ad4d922ddd2b49286c374df56 100644 (file)
@@ -15,7 +15,6 @@ generic-y += fcntl.h
 generic-y += futex.h
 generic-y += hardirq.h
 generic-y += hash.h
-generic-y += handle_irq.h
 generic-y += hw_irq.h
 generic-y += ioctl.h
 generic-y += ioctls.h
index 324568d3392130fe5beba7bd03928a762848d377..f6561b783b619282c014ac62230b2a029c4ef226 100644 (file)
@@ -52,7 +52,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
 # Add -lgcc so rv32 gets static muldi3 and lshrdi3 definitions.
 # Make sure only to export the intended __vdso_xxx symbol offsets.
 quiet_cmd_vdsold = VDSOLD  $@
-      cmd_vdsold = $(CC) $(KCFLAGS) -nostdlib $(SYSCFLAGS_$(@F)) \
+      cmd_vdsold = $(CC) $(KCFLAGS) $(call cc-option, -no-pie) -nostdlib $(SYSCFLAGS_$(@F)) \
                            -Wl,-T,$(filter-out FORCE,$^) -o $@.tmp -lgcc && \
                    $(CROSS_COMPILE)objcopy \
                            $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@
index 9fdff3fe1a42aac7414c06ccea3018399906fd42..e63940bb57cd4f9fc28e433be49babbf47e9973e 100644 (file)
@@ -8,3 +8,4 @@ obj-$(CONFIG_APPLDATA_BASE)     += appldata/
 obj-y                          += net/
 obj-$(CONFIG_PCI)              += pci/
 obj-$(CONFIG_NUMA)             += numa/
+obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += purgatory/
index 32a0d5b958bf5c320d8e22f2e2fb167b443fe632..199ac3e4da1d9008a4a6abcdd5bec55e41354b19 100644 (file)
@@ -47,10 +47,6 @@ config PGSTE
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
        def_bool y
 
-config KEXEC
-       def_bool y
-       select KEXEC_CORE
-
 config AUDIT_ARCH
        def_bool y
 
@@ -290,12 +286,12 @@ config MARCH_Z13
          older machines.
 
 config MARCH_Z14
-       bool "IBM z14"
+       bool "IBM z14 ZR1 and z14"
        select HAVE_MARCH_Z14_FEATURES
        help
-         Select this to enable optimizations for IBM z14 (3906 series).
-         The kernel will be slightly faster but will not work on older
-         machines.
+         Select this to enable optimizations for IBM z14 ZR1 and z14 (3907
+         and 3906 series). The kernel will be slightly faster but will not
+         work on older machines.
 
 endchoice
 
@@ -525,6 +521,26 @@ source kernel/Kconfig.preempt
 
 source kernel/Kconfig.hz
 
+config KEXEC
+       def_bool y
+       select KEXEC_CORE
+
+config KEXEC_FILE
+       bool "kexec file based system call"
+       select KEXEC_CORE
+       select BUILD_BIN2C
+       depends on CRYPTO
+       depends on CRYPTO_SHA256
+       depends on CRYPTO_SHA256_S390
+       help
+         Enable the kexec file based system call. In contrast to the normal
+         kexec system call this system call takes file descriptors for the
+         kernel and initramfs as arguments.
+
+config ARCH_HAS_KEXEC_PURGATORY
+       def_bool y
+       depends on KEXEC_FILE
+
 config ARCH_RANDOM
        def_bool y
        prompt "s390 architectural random number generation API"
index da9dad35c28e54e0f211bd3cfc2b0c66b51d983b..d1fa37fcce833887850d5891970e23f0e65375a1 100644 (file)
@@ -3,12 +3,6 @@
 # Makefile for the linux s390-specific parts of the memory manager.
 #
 
-COMPILE_VERSION := __linux_compile_version_id__`hostname |  \
-                       tr -c '[0-9A-Za-z]' '_'`__`date | \
-                       tr -c '[0-9A-Za-z]' '_'`_t
-
-ccflags-y  := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
-
 targets := image
 targets += bzImage
 subdir- := compressed
index ae06b9b4c02f79a7f6bc188dad222d20f5bd0bcf..2088cc14062911752b034486ce2712bdd930b6b4 100644 (file)
@@ -1,3 +1,4 @@
 sizes.h
 vmlinux
 vmlinux.lds
+vmlinux.bin.full
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
new file mode 100644 (file)
index 0000000..6176fe9
--- /dev/null
@@ -0,0 +1,731 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_USERFAULTFD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_STATIC_KEYS_SELFTEST=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_WBT_SQ=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_LIVEPATCH=y
+CONFIG_TUNE_ZEC12=y
+CONFIG_NR_CPUS=512
+CONFIG_NUMA=y
+CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
+CONFIG_KEXEC_FILE=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_CLEANCACHE=y
+CONFIG_FRONTSWAP=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_DEBUGFS=y
+CONFIG_MEM_SOFT_DIRTY=y
+CONFIG_ZSWAP=y
+CONFIG_ZBUD=m
+CONFIG_ZSMALLOC=m
+CONFIG_ZSMALLOC_STAT=y
+CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
+CONFIG_IDLE_PAGE_TRACKING=y
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_S390=y
+CONFIG_CHSC_SCH=y
+CONFIG_CRASH_DUMP=y
+CONFIG_BINFMT_MISC=m
+CONFIG_HIBERNATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_SMC=m
+CONFIG_SMC_DIAG=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_VTI=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_GRE=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NF_TABLES=m
+CONFIG_NFT_EXTHDR=m
+CONFIG_NFT_META=m
+CONFIG_NFT_CT=m
+CONFIG_NFT_COUNTER=m
+CONFIG_NFT_LOG=m
+CONFIG_NFT_LIMIT=m
+CONFIG_NFT_NAT=m
+CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NETPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETNET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_PE_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_TABLES_IPV4=m
+CONFIG_NFT_CHAIN_ROUTE_IPV4=m
+CONFIG_NF_TABLES_ARP=m
+CONFIG_NFT_CHAIN_NAT_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_NF_TABLES_IPV6=m
+CONFIG_NFT_CHAIN_ROUTE_IPV6=m
+CONFIG_NFT_CHAIN_NAT_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_RDS=m
+CONFIG_RDS_RDMA=m
+CONFIG_RDS_TCP=m
+CONFIG_RDS_DEBUG=y
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_BPF=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+CONFIG_DNS_RESOLVER=y
+CONFIG_OPENVSWITCH=m
+CONFIG_NETLINK_DIAG=m
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_BPF_JIT=y
+CONFIG_NET_PKTGEN=m
+CONFIG_DEVTMPFS=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=0
+CONFIG_CONNECTOR=y
+CONFIG_ZRAM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_RBD=m
+CONFIG_BLK_DEV_NVME=m
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_GENWQE=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_ZFCP=y
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_RAID=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_DM_FLAKEY=m
+CONFIG_DM_VERITY=m
+CONFIG_DM_SWITCH=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_EQUALIZER=m
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_MLX4_EN=m
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_CORE_EN=y
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_RAW_DRIVER=m
+CONFIG_HANGCHECK_TIMER=m
+CONFIG_TN3270_FS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_DIAG288_WATCHDOG=m
+CONFIG_DRM=y
+CONFIG_DRM_VIRTIO_GPU=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_MLX5_INFINIBAND=m
+CONFIG_VFIO=m
+CONFIG_VFIO_PCI=m
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_INPUT=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_JBD2_DEBUG=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_JFS_STATISTICS=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_XFS_DEBUG=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=y
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_BTRFS_DEBUG=y
+CONFIG_NILFS2_FS=m
+CONFIG_FS_DAX=y
+CONFIG_EXPORTFS_BLOCK_OPS=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QUOTA_DEBUG=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_OVERLAY_FS=m
+CONFIG_FSCACHE=m
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+CONFIG_NFS_SWAP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_V4_SECURITY_LABEL=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG is not set
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
+CONFIG_FRAME_WARN=1024
+CONFIG_READABLE_ASM=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_RODATA_TEST=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_SELFTEST=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_WORK=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
+CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_SLUB_STATS=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_VM_VMACACHE=y
+CONFIG_DEBUG_VM_RB=y
+CONFIG_DEBUG_VM_PGFLAGS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
+CONFIG_DEBUG_PER_CPU_MAPS=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCK_STAT=y
+CONFIG_DEBUG_LOCKDEP=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_DEBUG_CREDENTIALS=y
+CONFIG_RCU_TORTURE_TEST=m
+CONFIG_RCU_CPU_STALL_TIMEOUT=300
+CONFIG_NOTIFIER_ERROR_INJECTION=m
+CONFIG_PM_NOTIFIER_ERROR_INJECT=m
+CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAILSLAB=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAIL_MAKE_REQUEST=y
+CONFIG_FAIL_IO_TIMEOUT=y
+CONFIG_FAIL_FUTEX=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_LATENCYTOP=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_SCHED_TRACER=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_STACK_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_HIST_TRIGGERS=y
+CONFIG_DMA_API_DEBUG=y
+CONFIG_LKDTM=m
+CONFIG_TEST_LIST_SORT=y
+CONFIG_TEST_SORT=y
+CONFIG_KPROBES_SANITY_TEST=y
+CONFIG_RBTREE_TEST=y
+CONFIG_INTERVAL_TREE_TEST=m
+CONFIG_PERCPU_TEST=m
+CONFIG_ATOMIC64_SELFTEST=y
+CONFIG_TEST_BPF=m
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_S390_PTDUMP=y
+CONFIG_PERSISTENT_KEYRINGS=y
+CONFIG_BIG_KEYS=y
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_INTEGRITY_SIGNATURE=y
+CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
+CONFIG_IMA=y
+CONFIG_IMA_DEFAULT_HASH_SHA256=y
+CONFIG_IMA_WRITE_POLICY=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_CRYPTO_DH=m
+CONFIG_CRYPTO_ECDH=m
+CONFIG_CRYPTO_USER=m
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_PCRYPT=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_MCRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CHACHA20POLY1305=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_SHA3=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_842=m
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_USER_API_AEAD=m
+CONFIG_ZCRYPT=m
+CONFIG_PKEY=m
+CONFIG_CRYPTO_PAES_S390=m
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256_S390=m
+CONFIG_CRYPTO_SHA512_S390=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_GHASH_S390=m
+CONFIG_CRYPTO_CRC32_S390=y
+CONFIG_PKCS7_MESSAGE_PARSER=y
+CONFIG_SYSTEM_TRUSTED_KEYRING=y
+CONFIG_CRC7=m
+CONFIG_CRC8=m
+CONFIG_RANDOM32_SELFTEST=y
+CONFIG_CORDIC=m
+CONFIG_CMM=m
+CONFIG_APPLDATA_BASE=y
+CONFIG_KVM=m
+CONFIG_KVM_S390_UCONTROL=y
+CONFIG_VHOST_NET=m
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig
deleted file mode 100644 (file)
index 5af8458..0000000
+++ /dev/null
@@ -1,721 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_AUDIT=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_NUMA_BALANCING=y
-CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
-CONFIG_BLK_CGROUP=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_CGROUP_PIDS=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_HUGETLB=y
-CONFIG_CPUSETS=y
-CONFIG_CGROUP_DEVICE=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_NAMESPACES=y
-CONFIG_USER_NS=y
-CONFIG_SCHED_AUTOGROUP=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSFS_SYSCALL is not set
-CONFIG_BPF_SYSCALL=y
-CONFIG_USERFAULTFD=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_KPROBES=y
-CONFIG_JUMP_LABEL=y
-CONFIG_STATIC_KEYS_SELFTEST=y
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_BLK_DEV_THROTTLING=y
-CONFIG_BLK_WBT=y
-CONFIG_BLK_WBT_SQ=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_CFQ_GROUP_IOSCHED=y
-CONFIG_DEFAULT_DEADLINE=y
-CONFIG_LIVEPATCH=y
-CONFIG_TUNE_ZEC12=y
-CONFIG_NR_CPUS=256
-CONFIG_NUMA=y
-CONFIG_PREEMPT=y
-CONFIG_HZ_100=y
-CONFIG_MEMORY_HOTPLUG=y
-CONFIG_MEMORY_HOTREMOVE=y
-CONFIG_KSM=y
-CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_CLEANCACHE=y
-CONFIG_FRONTSWAP=y
-CONFIG_CMA_DEBUG=y
-CONFIG_CMA_DEBUGFS=y
-CONFIG_MEM_SOFT_DIRTY=y
-CONFIG_ZSWAP=y
-CONFIG_ZBUD=m
-CONFIG_ZSMALLOC=m
-CONFIG_ZSMALLOC_STAT=y
-CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
-CONFIG_IDLE_PAGE_TRACKING=y
-CONFIG_PCI=y
-CONFIG_PCI_DEBUG=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_S390=y
-CONFIG_CHSC_SCH=y
-CONFIG_CRASH_DUMP=y
-CONFIG_BINFMT_MISC=m
-CONFIG_HIBERNATION=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_PACKET_DIAG=m
-CONFIG_UNIX=y
-CONFIG_UNIX_DIAG=m
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_SMC=m
-CONFIG_SMC_DIAG=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE_DEMUX=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_NET_IPVTI=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-CONFIG_INET_UDP_DIAG=m
-CONFIG_TCP_CONG_ADVANCED=y
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_SCALABLE=m
-CONFIG_TCP_CONG_LP=m
-CONFIG_TCP_CONG_VENO=m
-CONFIG_TCP_CONG_YEAH=m
-CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_VTI=m
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_GRE=m
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CONNTRACK_TIMEOUT=y
-CONFIG_NF_CONNTRACK_TIMESTAMP=y
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_SNMP=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SANE=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NF_CT_NETLINK_TIMEOUT=m
-CONFIG_NF_TABLES=m
-CONFIG_NFT_EXTHDR=m
-CONFIG_NFT_META=m
-CONFIG_NFT_CT=m
-CONFIG_NFT_COUNTER=m
-CONFIG_NFT_LOG=m
-CONFIG_NFT_LIMIT=m
-CONFIG_NFT_NAT=m
-CONFIG_NFT_COMPAT=m
-CONFIG_NFT_HASH=m
-CONFIG_NETFILTER_XT_SET=m
-CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CT=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_HMARK=m
-CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
-CONFIG_NETFILTER_XT_TARGET_LOG=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TEE=m
-CONFIG_NETFILTER_XT_TARGET_TPROXY=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
-CONFIG_NETFILTER_XT_MATCH_BPF=m
-CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_CPU=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_IPVS=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_NFACCT=m
-CONFIG_NETFILTER_XT_MATCH_OSF=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_IP_SET=m
-CONFIG_IP_SET_BITMAP_IP=m
-CONFIG_IP_SET_BITMAP_IPMAC=m
-CONFIG_IP_SET_BITMAP_PORT=m
-CONFIG_IP_SET_HASH_IP=m
-CONFIG_IP_SET_HASH_IPPORT=m
-CONFIG_IP_SET_HASH_IPPORTIP=m
-CONFIG_IP_SET_HASH_IPPORTNET=m
-CONFIG_IP_SET_HASH_NETPORTNET=m
-CONFIG_IP_SET_HASH_NET=m
-CONFIG_IP_SET_HASH_NETNET=m
-CONFIG_IP_SET_HASH_NETPORT=m
-CONFIG_IP_SET_HASH_NETIFACE=m
-CONFIG_IP_SET_LIST_SET=m
-CONFIG_IP_VS=m
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-CONFIG_IP_VS_FTP=m
-CONFIG_IP_VS_PE_SIP=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_TABLES_IPV4=m
-CONFIG_NFT_CHAIN_ROUTE_IPV4=m
-CONFIG_NF_TABLES_ARP=m
-CONFIG_NFT_CHAIN_NAT_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_RPFILTER=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_SECURITY=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_NF_TABLES_IPV6=m
-CONFIG_NFT_CHAIN_ROUTE_IPV6=m
-CONFIG_NFT_CHAIN_NAT_IPV6=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_AH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_MH=m
-CONFIG_IP6_NF_MATCH_RPFILTER=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_IP6_NF_SECURITY=m
-CONFIG_IP6_NF_NAT=m
-CONFIG_IP6_NF_TARGET_MASQUERADE=m
-CONFIG_NF_TABLES_BRIDGE=m
-CONFIG_NET_SCTPPROBE=m
-CONFIG_RDS=m
-CONFIG_RDS_RDMA=m
-CONFIG_RDS_TCP=m
-CONFIG_RDS_DEBUG=y
-CONFIG_L2TP=m
-CONFIG_L2TP_DEBUGFS=m
-CONFIG_L2TP_V3=y
-CONFIG_L2TP_IP=m
-CONFIG_L2TP_ETH=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_MULTIQ=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFB=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_DRR=m
-CONFIG_NET_SCH_MQPRIO=m
-CONFIG_NET_SCH_CHOKE=m
-CONFIG_NET_SCH_QFQ=m
-CONFIG_NET_SCH_CODEL=m
-CONFIG_NET_SCH_FQ_CODEL=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_SCH_PLUG=m
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_FLOW=m
-CONFIG_NET_CLS_CGROUP=y
-CONFIG_NET_CLS_BPF=m
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=m
-CONFIG_NET_ACT_GACT=m
-CONFIG_GACT_PROB=y
-CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
-CONFIG_NET_ACT_NAT=m
-CONFIG_NET_ACT_PEDIT=m
-CONFIG_NET_ACT_SIMP=m
-CONFIG_NET_ACT_SKBEDIT=m
-CONFIG_NET_ACT_CSUM=m
-CONFIG_DNS_RESOLVER=y
-CONFIG_NETLINK_DIAG=m
-CONFIG_CGROUP_NET_PRIO=y
-CONFIG_BPF_JIT=y
-CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
-CONFIG_DEVTMPFS=y
-CONFIG_DMA_CMA=y
-CONFIG_CMA_SIZE_MBYTES=0
-CONFIG_CONNECTOR=y
-CONFIG_ZRAM=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_DRBD=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_RAM_DAX=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_BLK_DEV_RBD=m
-CONFIG_ENCLOSURE_SERVICES=m
-CONFIG_GENWQE=m
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_ENCLOSURE=m
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_ISCSI_TCP=m
-CONFIG_SCSI_DEBUG=m
-CONFIG_ZFCP=y
-CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=y
-CONFIG_SCSI_DH_RDAC=m
-CONFIG_SCSI_DH_HP_SW=m
-CONFIG_SCSI_DH_EMC=m
-CONFIG_SCSI_DH_ALUA=m
-CONFIG_SCSI_OSD_INITIATOR=m
-CONFIG_SCSI_OSD_ULD=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_THIN_PROVISIONING=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_LOG_USERSPACE=m
-CONFIG_DM_RAID=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_QL=m
-CONFIG_DM_MULTIPATH_ST=m
-CONFIG_DM_DELAY=m
-CONFIG_DM_UEVENT=y
-CONFIG_DM_FLAKEY=m
-CONFIG_DM_VERITY=m
-CONFIG_DM_SWITCH=m
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_EQUALIZER=m
-CONFIG_IFB=m
-CONFIG_MACVLAN=m
-CONFIG_MACVTAP=m
-CONFIG_VXLAN=m
-CONFIG_TUN=m
-CONFIG_VETH=m
-CONFIG_VIRTIO_NET=m
-CONFIG_NLMON=m
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-CONFIG_MLX4_EN=m
-CONFIG_MLX5_CORE=m
-CONFIG_MLX5_CORE_EN=y
-# CONFIG_NET_VENDOR_NATSEMI is not set
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPTP=m
-CONFIG_PPPOL2TP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_LEGACY_PTY_COUNT=0
-CONFIG_HW_RANDOM_VIRTIO=m
-CONFIG_RAW_DRIVER=m
-CONFIG_HANGCHECK_TIMER=m
-CONFIG_TN3270_FS=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_DIAG288_WATCHDOG=m
-# CONFIG_HID is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_ACCESS=m
-CONFIG_MLX4_INFINIBAND=m
-CONFIG_MLX5_INFINIBAND=m
-CONFIG_VFIO=m
-CONFIG_VFIO_PCI=m
-CONFIG_VIRTIO_BALLOON=m
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
-CONFIG_JBD2_DEBUG=y
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-CONFIG_JFS_STATISTICS=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
-CONFIG_XFS_DEBUG=y
-CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=y
-CONFIG_OCFS2_FS=m
-CONFIG_BTRFS_FS=y
-CONFIG_BTRFS_FS_POSIX_ACL=y
-CONFIG_BTRFS_DEBUG=y
-CONFIG_NILFS2_FS=m
-CONFIG_FS_DAX=y
-CONFIG_EXPORTFS_BLOCK_OPS=y
-CONFIG_FANOTIFY=y
-CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
-CONFIG_QUOTA_NETLINK_INTERFACE=y
-CONFIG_QUOTA_DEBUG=y
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=y
-CONFIG_CUSE=m
-CONFIG_OVERLAY_FS=m
-CONFIG_FSCACHE=m
-CONFIG_CACHEFILES=m
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_HUGETLBFS=y
-CONFIG_CONFIGFS_FS=m
-CONFIG_ECRYPT_FS=m
-CONFIG_CRAMFS=m
-CONFIG_SQUASHFS=m
-CONFIG_SQUASHFS_XATTR=y
-CONFIG_SQUASHFS_LZO=y
-CONFIG_SQUASHFS_XZ=y
-CONFIG_ROMFS_FS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=m
-CONFIG_NFS_SWAP=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_V4_SECURITY_LABEL=y
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-CONFIG_CIFS_STATS2=y
-CONFIG_CIFS_WEAK_PW_HASH=y
-CONFIG_CIFS_UPCALL=y
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_DEBUG is not set
-CONFIG_CIFS_DFS_UPCALL=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_DLM=m
-CONFIG_PRINTK_TIME=y
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_INFO_DWARF4=y
-CONFIG_GDB_SCRIPTS=y
-CONFIG_FRAME_WARN=1024
-CONFIG_READABLE_ASM=y
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_HEADERS_CHECK=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_PAGEALLOC=y
-CONFIG_DEBUG_RODATA_TEST=y
-CONFIG_DEBUG_OBJECTS=y
-CONFIG_DEBUG_OBJECTS_SELFTEST=y
-CONFIG_DEBUG_OBJECTS_FREE=y
-CONFIG_DEBUG_OBJECTS_TIMERS=y
-CONFIG_DEBUG_OBJECTS_WORK=y
-CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
-CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
-CONFIG_SLUB_DEBUG_ON=y
-CONFIG_SLUB_STATS=y
-CONFIG_DEBUG_STACK_USAGE=y
-CONFIG_DEBUG_VM=y
-CONFIG_DEBUG_VM_VMACACHE=y
-CONFIG_DEBUG_VM_RB=y
-CONFIG_DEBUG_VM_PGFLAGS=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
-CONFIG_DEBUG_PER_CPU_MAPS=y
-CONFIG_DEBUG_SHIRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_WQ_WATCHDOG=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_DEBUG_TIMEKEEPING=y
-CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
-CONFIG_PROVE_LOCKING=y
-CONFIG_LOCK_STAT=y
-CONFIG_DEBUG_LOCKDEP=y
-CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
-CONFIG_DEBUG_SG=y
-CONFIG_DEBUG_NOTIFIERS=y
-CONFIG_DEBUG_CREDENTIALS=y
-CONFIG_RCU_TORTURE_TEST=m
-CONFIG_RCU_CPU_STALL_TIMEOUT=300
-CONFIG_NOTIFIER_ERROR_INJECTION=m
-CONFIG_PM_NOTIFIER_ERROR_INJECT=m
-CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
-CONFIG_FAULT_INJECTION=y
-CONFIG_FAILSLAB=y
-CONFIG_FAIL_PAGE_ALLOC=y
-CONFIG_FAIL_MAKE_REQUEST=y
-CONFIG_FAIL_IO_TIMEOUT=y
-CONFIG_FAIL_FUTEX=y
-CONFIG_FAULT_INJECTION_DEBUG_FS=y
-CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
-CONFIG_LATENCYTOP=y
-CONFIG_IRQSOFF_TRACER=y
-CONFIG_PREEMPT_TRACER=y
-CONFIG_SCHED_TRACER=y
-CONFIG_FTRACE_SYSCALLS=y
-CONFIG_STACK_TRACER=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_FUNCTION_PROFILER=y
-CONFIG_HIST_TRIGGERS=y
-CONFIG_DMA_API_DEBUG=y
-CONFIG_LKDTM=m
-CONFIG_TEST_LIST_SORT=y
-CONFIG_TEST_SORT=y
-CONFIG_KPROBES_SANITY_TEST=y
-CONFIG_RBTREE_TEST=y
-CONFIG_INTERVAL_TREE_TEST=m
-CONFIG_PERCPU_TEST=m
-CONFIG_ATOMIC64_SELFTEST=y
-CONFIG_TEST_BPF=m
-CONFIG_BUG_ON_DATA_CORRUPTION=y
-CONFIG_S390_PTDUMP=y
-CONFIG_ENCRYPTED_KEYS=m
-CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
-CONFIG_FORTIFY_SOURCE=y
-CONFIG_SECURITY_SELINUX=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
-CONFIG_SECURITY_SELINUX_DISABLE=y
-CONFIG_IMA=y
-CONFIG_IMA_APPRAISE=y
-CONFIG_CRYPTO_RSA=m
-CONFIG_CRYPTO_DH=m
-CONFIG_CRYPTO_ECDH=m
-CONFIG_CRYPTO_USER=m
-CONFIG_CRYPTO_PCRYPT=m
-CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_MCRYPTD=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_GCM=m
-CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_KEYWRAP=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_VMAC=m
-CONFIG_CRYPTO_CRC32=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD128=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_SHA3=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES_TI=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SALSA20=m
-CONFIG_CRYPTO_SEED=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_842=m
-CONFIG_CRYPTO_LZ4=m
-CONFIG_CRYPTO_LZ4HC=m
-CONFIG_CRYPTO_ANSI_CPRNG=m
-CONFIG_CRYPTO_USER_API_HASH=m
-CONFIG_CRYPTO_USER_API_SKCIPHER=m
-CONFIG_CRYPTO_USER_API_RNG=m
-CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_ZCRYPT=m
-CONFIG_PKEY=m
-CONFIG_CRYPTO_PAES_S390=m
-CONFIG_CRYPTO_SHA1_S390=m
-CONFIG_CRYPTO_SHA256_S390=m
-CONFIG_CRYPTO_SHA512_S390=m
-CONFIG_CRYPTO_DES_S390=m
-CONFIG_CRYPTO_AES_S390=m
-CONFIG_CRYPTO_GHASH_S390=m
-CONFIG_CRYPTO_CRC32_S390=y
-CONFIG_ASYMMETRIC_KEY_TYPE=y
-CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
-CONFIG_X509_CERTIFICATE_PARSER=m
-CONFIG_CRC7=m
-CONFIG_CRC8=m
-CONFIG_RANDOM32_SELFTEST=y
-CONFIG_CORDIC=m
-CONFIG_CMM=m
-CONFIG_APPLDATA_BASE=y
-CONFIG_KVM=m
-CONFIG_KVM_S390_UCONTROL=y
-CONFIG_VHOST_NET=m
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig
deleted file mode 100644 (file)
index d52eafe..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_AUDIT=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_NUMA_BALANCING=y
-# CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set
-CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
-CONFIG_BLK_CGROUP=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_CGROUP_PIDS=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_HUGETLB=y
-CONFIG_CPUSETS=y
-CONFIG_CGROUP_DEVICE=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_NAMESPACES=y
-CONFIG_USER_NS=y
-CONFIG_SCHED_AUTOGROUP=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSFS_SYSCALL is not set
-CONFIG_BPF_SYSCALL=y
-CONFIG_USERFAULTFD=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_KPROBES=y
-CONFIG_JUMP_LABEL=y
-CONFIG_GCOV_KERNEL=y
-CONFIG_GCOV_PROFILE_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_BLK_DEV_THROTTLING=y
-CONFIG_BLK_WBT=y
-CONFIG_BLK_WBT_SQ=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_CFQ_GROUP_IOSCHED=y
-CONFIG_DEFAULT_DEADLINE=y
-CONFIG_LIVEPATCH=y
-CONFIG_TUNE_ZEC12=y
-CONFIG_NR_CPUS=512
-CONFIG_NUMA=y
-CONFIG_HZ_100=y
-CONFIG_MEMORY_HOTPLUG=y
-CONFIG_MEMORY_HOTREMOVE=y
-CONFIG_KSM=y
-CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_CLEANCACHE=y
-CONFIG_FRONTSWAP=y
-CONFIG_MEM_SOFT_DIRTY=y
-CONFIG_ZSWAP=y
-CONFIG_ZBUD=m
-CONFIG_ZSMALLOC=m
-CONFIG_ZSMALLOC_STAT=y
-CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
-CONFIG_IDLE_PAGE_TRACKING=y
-CONFIG_PCI=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_S390=y
-CONFIG_CHSC_SCH=y
-CONFIG_CRASH_DUMP=y
-CONFIG_BINFMT_MISC=m
-CONFIG_HIBERNATION=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_PACKET_DIAG=m
-CONFIG_UNIX=y
-CONFIG_UNIX_DIAG=m
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_SMC=m
-CONFIG_SMC_DIAG=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE_DEMUX=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_NET_IPVTI=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-CONFIG_INET_UDP_DIAG=m
-CONFIG_TCP_CONG_ADVANCED=y
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_SCALABLE=m
-CONFIG_TCP_CONG_LP=m
-CONFIG_TCP_CONG_VENO=m
-CONFIG_TCP_CONG_YEAH=m
-CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_VTI=m
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_GRE=m
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CONNTRACK_TIMEOUT=y
-CONFIG_NF_CONNTRACK_TIMESTAMP=y
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_SNMP=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SANE=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NF_CT_NETLINK_TIMEOUT=m
-CONFIG_NF_TABLES=m
-CONFIG_NFT_EXTHDR=m
-CONFIG_NFT_META=m
-CONFIG_NFT_CT=m
-CONFIG_NFT_COUNTER=m
-CONFIG_NFT_LOG=m
-CONFIG_NFT_LIMIT=m
-CONFIG_NFT_NAT=m
-CONFIG_NFT_COMPAT=m
-CONFIG_NFT_HASH=m
-CONFIG_NETFILTER_XT_SET=m
-CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CT=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_HMARK=m
-CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
-CONFIG_NETFILTER_XT_TARGET_LOG=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TEE=m
-CONFIG_NETFILTER_XT_TARGET_TPROXY=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
-CONFIG_NETFILTER_XT_MATCH_BPF=m
-CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_CPU=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_IPVS=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_NFACCT=m
-CONFIG_NETFILTER_XT_MATCH_OSF=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_IP_SET=m
-CONFIG_IP_SET_BITMAP_IP=m
-CONFIG_IP_SET_BITMAP_IPMAC=m
-CONFIG_IP_SET_BITMAP_PORT=m
-CONFIG_IP_SET_HASH_IP=m
-CONFIG_IP_SET_HASH_IPPORT=m
-CONFIG_IP_SET_HASH_IPPORTIP=m
-CONFIG_IP_SET_HASH_IPPORTNET=m
-CONFIG_IP_SET_HASH_NETPORTNET=m
-CONFIG_IP_SET_HASH_NET=m
-CONFIG_IP_SET_HASH_NETNET=m
-CONFIG_IP_SET_HASH_NETPORT=m
-CONFIG_IP_SET_HASH_NETIFACE=m
-CONFIG_IP_SET_LIST_SET=m
-CONFIG_IP_VS=m
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-CONFIG_IP_VS_FTP=m
-CONFIG_IP_VS_PE_SIP=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_TABLES_IPV4=m
-CONFIG_NFT_CHAIN_ROUTE_IPV4=m
-CONFIG_NF_TABLES_ARP=m
-CONFIG_NFT_CHAIN_NAT_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_RPFILTER=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_SECURITY=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_NF_TABLES_IPV6=m
-CONFIG_NFT_CHAIN_ROUTE_IPV6=m
-CONFIG_NFT_CHAIN_NAT_IPV6=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_AH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_MH=m
-CONFIG_IP6_NF_MATCH_RPFILTER=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_IP6_NF_SECURITY=m
-CONFIG_IP6_NF_NAT=m
-CONFIG_IP6_NF_TARGET_MASQUERADE=m
-CONFIG_NF_TABLES_BRIDGE=m
-CONFIG_NET_SCTPPROBE=m
-CONFIG_RDS=m
-CONFIG_RDS_RDMA=m
-CONFIG_RDS_TCP=m
-CONFIG_L2TP=m
-CONFIG_L2TP_DEBUGFS=m
-CONFIG_L2TP_V3=y
-CONFIG_L2TP_IP=m
-CONFIG_L2TP_ETH=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_MULTIQ=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFB=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_DRR=m
-CONFIG_NET_SCH_MQPRIO=m
-CONFIG_NET_SCH_CHOKE=m
-CONFIG_NET_SCH_QFQ=m
-CONFIG_NET_SCH_CODEL=m
-CONFIG_NET_SCH_FQ_CODEL=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_SCH_PLUG=m
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_FLOW=m
-CONFIG_NET_CLS_CGROUP=y
-CONFIG_NET_CLS_BPF=m
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=m
-CONFIG_NET_ACT_GACT=m
-CONFIG_GACT_PROB=y
-CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
-CONFIG_NET_ACT_NAT=m
-CONFIG_NET_ACT_PEDIT=m
-CONFIG_NET_ACT_SIMP=m
-CONFIG_NET_ACT_SKBEDIT=m
-CONFIG_NET_ACT_CSUM=m
-CONFIG_DNS_RESOLVER=y
-CONFIG_NETLINK_DIAG=m
-CONFIG_CGROUP_NET_PRIO=y
-CONFIG_BPF_JIT=y
-CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
-CONFIG_DEVTMPFS=y
-CONFIG_DMA_CMA=y
-CONFIG_CMA_SIZE_MBYTES=0
-CONFIG_CONNECTOR=y
-CONFIG_ZRAM=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_DRBD=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_RAM_DAX=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_ENCLOSURE_SERVICES=m
-CONFIG_GENWQE=m
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_ENCLOSURE=m
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_ISCSI_TCP=m
-CONFIG_SCSI_DEBUG=m
-CONFIG_ZFCP=y
-CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=y
-CONFIG_SCSI_DH_RDAC=m
-CONFIG_SCSI_DH_HP_SW=m
-CONFIG_SCSI_DH_EMC=m
-CONFIG_SCSI_DH_ALUA=m
-CONFIG_SCSI_OSD_INITIATOR=m
-CONFIG_SCSI_OSD_ULD=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_THIN_PROVISIONING=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_LOG_USERSPACE=m
-CONFIG_DM_RAID=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_QL=m
-CONFIG_DM_MULTIPATH_ST=m
-CONFIG_DM_DELAY=m
-CONFIG_DM_UEVENT=y
-CONFIG_DM_FLAKEY=m
-CONFIG_DM_VERITY=m
-CONFIG_DM_SWITCH=m
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_EQUALIZER=m
-CONFIG_IFB=m
-CONFIG_MACVLAN=m
-CONFIG_MACVTAP=m
-CONFIG_VXLAN=m
-CONFIG_TUN=m
-CONFIG_VETH=m
-CONFIG_VIRTIO_NET=m
-CONFIG_NLMON=m
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-CONFIG_MLX4_EN=m
-CONFIG_MLX5_CORE=m
-CONFIG_MLX5_CORE_EN=y
-# CONFIG_NET_VENDOR_NATSEMI is not set
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPTP=m
-CONFIG_PPPOL2TP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_LEGACY_PTY_COUNT=0
-CONFIG_HW_RANDOM_VIRTIO=m
-CONFIG_RAW_DRIVER=m
-CONFIG_HANGCHECK_TIMER=m
-CONFIG_TN3270_FS=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_DIAG288_WATCHDOG=m
-# CONFIG_HID is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_ACCESS=m
-CONFIG_MLX4_INFINIBAND=m
-CONFIG_MLX5_INFINIBAND=m
-CONFIG_VFIO=m
-CONFIG_VFIO_PCI=m
-CONFIG_VIRTIO_BALLOON=m
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
-CONFIG_JBD2_DEBUG=y
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-CONFIG_JFS_STATISTICS=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
-CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=y
-CONFIG_OCFS2_FS=m
-CONFIG_BTRFS_FS=y
-CONFIG_BTRFS_FS_POSIX_ACL=y
-CONFIG_NILFS2_FS=m
-CONFIG_FS_DAX=y
-CONFIG_EXPORTFS_BLOCK_OPS=y
-CONFIG_FANOTIFY=y
-CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
-CONFIG_QUOTA_NETLINK_INTERFACE=y
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=y
-CONFIG_CUSE=m
-CONFIG_OVERLAY_FS=m
-CONFIG_OVERLAY_FS_REDIRECT_DIR=y
-CONFIG_FSCACHE=m
-CONFIG_CACHEFILES=m
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_HUGETLBFS=y
-CONFIG_CONFIGFS_FS=m
-CONFIG_ECRYPT_FS=m
-CONFIG_CRAMFS=m
-CONFIG_SQUASHFS=m
-CONFIG_SQUASHFS_XATTR=y
-CONFIG_SQUASHFS_LZO=y
-CONFIG_SQUASHFS_XZ=y
-CONFIG_ROMFS_FS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=m
-CONFIG_NFS_SWAP=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_V4_SECURITY_LABEL=y
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-CONFIG_CIFS_STATS2=y
-CONFIG_CIFS_WEAK_PW_HASH=y
-CONFIG_CIFS_UPCALL=y
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_DEBUG is not set
-CONFIG_CIFS_DFS_UPCALL=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_DLM=m
-CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_INFO_DWARF4=y
-CONFIG_GDB_SCRIPTS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_RCU_TORTURE_TEST=m
-CONFIG_RCU_CPU_STALL_TIMEOUT=60
-CONFIG_LATENCYTOP=y
-CONFIG_SCHED_TRACER=y
-CONFIG_FTRACE_SYSCALLS=y
-CONFIG_STACK_TRACER=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_FUNCTION_PROFILER=y
-CONFIG_HIST_TRIGGERS=y
-CONFIG_LKDTM=m
-CONFIG_PERCPU_TEST=m
-CONFIG_ATOMIC64_SELFTEST=y
-CONFIG_TEST_BPF=m
-CONFIG_BUG_ON_DATA_CORRUPTION=y
-CONFIG_S390_PTDUMP=y
-CONFIG_PERSISTENT_KEYRINGS=y
-CONFIG_BIG_KEYS=y
-CONFIG_ENCRYPTED_KEYS=m
-CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
-CONFIG_SECURITY_SELINUX=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
-CONFIG_SECURITY_SELINUX_DISABLE=y
-CONFIG_INTEGRITY_SIGNATURE=y
-CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
-CONFIG_IMA=y
-CONFIG_IMA_WRITE_POLICY=y
-CONFIG_IMA_APPRAISE=y
-CONFIG_CRYPTO_DH=m
-CONFIG_CRYPTO_ECDH=m
-CONFIG_CRYPTO_USER=m
-# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
-CONFIG_CRYPTO_PCRYPT=m
-CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_MCRYPTD=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_KEYWRAP=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_VMAC=m
-CONFIG_CRYPTO_CRC32=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD128=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_SHA3=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES_TI=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SALSA20=m
-CONFIG_CRYPTO_SEED=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_842=m
-CONFIG_CRYPTO_LZ4=m
-CONFIG_CRYPTO_LZ4HC=m
-CONFIG_CRYPTO_ANSI_CPRNG=m
-CONFIG_CRYPTO_USER_API_HASH=m
-CONFIG_CRYPTO_USER_API_SKCIPHER=m
-CONFIG_CRYPTO_USER_API_RNG=m
-CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_ZCRYPT=m
-CONFIG_PKEY=m
-CONFIG_CRYPTO_PAES_S390=m
-CONFIG_CRYPTO_SHA1_S390=m
-CONFIG_CRYPTO_SHA256_S390=m
-CONFIG_CRYPTO_SHA512_S390=m
-CONFIG_CRYPTO_DES_S390=m
-CONFIG_CRYPTO_AES_S390=m
-CONFIG_CRYPTO_GHASH_S390=m
-CONFIG_CRYPTO_CRC32_S390=y
-CONFIG_CRC7=m
-CONFIG_CRC8=m
-CONFIG_CORDIC=m
-CONFIG_CMM=m
-CONFIG_APPLDATA_BASE=y
-CONFIG_KVM=m
-CONFIG_KVM_S390_UCONTROL=y
-CONFIG_VHOST_NET=m
index 20ed149e113739afd64c6f016c2384b4aa03411a..c105bcc6d7a6fc0f932ba7537f85fe6e1a171b1a 100644 (file)
@@ -25,13 +25,13 @@ CONFIG_CPUSETS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_SYSFS_SYSCALL is not set
+CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -45,6 +45,8 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_SHA256=y
 CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_BLK_DEV_THROTTLING=y
 CONFIG_BLK_WBT=y
@@ -62,6 +64,7 @@ CONFIG_TUNE_ZEC12=y
 CONFIG_NR_CPUS=512
 CONFIG_NUMA=y
 CONFIG_HZ_100=y
+CONFIG_KEXEC_FILE=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
@@ -301,7 +304,6 @@ CONFIG_IP6_NF_SECURITY=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_NF_TABLES_BRIDGE=m
-CONFIG_NET_SCTPPROBE=m
 CONFIG_RDS=m
 CONFIG_RDS_RDMA=m
 CONFIG_RDS_TCP=m
@@ -359,11 +361,11 @@ CONFIG_NET_ACT_SIMP=m
 CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_NET_ACT_CSUM=m
 CONFIG_DNS_RESOLVER=y
+CONFIG_OPENVSWITCH=m
 CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
 CONFIG_DEVTMPFS=y
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=0
@@ -375,8 +377,9 @@ CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_RAM_DAX=y
 CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_RBD=m
+CONFIG_BLK_DEV_NVME=m
 CONFIG_ENCLOSURE_SERVICES=m
 CONFIG_GENWQE=m
 CONFIG_RAID_ATTRS=m
@@ -455,6 +458,7 @@ CONFIG_PPTP=m
 CONFIG_PPPOL2TP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
+CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
@@ -468,6 +472,9 @@ CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_WATCHDOG=m
 CONFIG_DIAG288_WATCHDOG=m
+CONFIG_DRM=y
+CONFIG_DRM_VIRTIO_GPU=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_INFINIBAND=m
@@ -476,7 +483,9 @@ CONFIG_MLX4_INFINIBAND=m
 CONFIG_MLX5_INFINIBAND=m
 CONFIG_VFIO=m
 CONFIG_VFIO_PCI=m
+CONFIG_VIRTIO_PCI=m
 CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_INPUT=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
@@ -507,7 +516,6 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=m
 CONFIG_OVERLAY_FS=m
-CONFIG_OVERLAY_FS_REDIRECT_DIR=y
 CONFIG_FSCACHE=m
 CONFIG_CACHEFILES=m
 CONFIG_ISO9660_FS=y
@@ -592,8 +600,10 @@ CONFIG_SECURITY_SELINUX_DISABLE=y
 CONFIG_INTEGRITY_SIGNATURE=y
 CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
 CONFIG_IMA=y
+CONFIG_IMA_DEFAULT_HASH_SHA256=y
 CONFIG_IMA_WRITE_POLICY=y
 CONFIG_IMA_APPRAISE=y
+CONFIG_CRYPTO_FIPS=y
 CONFIG_CRYPTO_DH=m
 CONFIG_CRYPTO_ECDH=m
 CONFIG_CRYPTO_USER=m
index 46a3178d8bc6e6860b898bd8377d62dd2e5b6260..f40600eb17628cbeaa44857a479544b60c1a2068 100644 (file)
@@ -8,6 +8,7 @@ CONFIG_TASKSTATS=y
 CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_CPU_ISOLATION is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -23,12 +24,12 @@ CONFIG_CPUSETS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_SYSFS_SYSCALL is not set
+CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -47,6 +48,7 @@ CONFIG_LIVEPATCH=y
 CONFIG_NR_CPUS=256
 CONFIG_NUMA=y
 CONFIG_HZ_100=y
+CONFIG_KEXEC_FILE=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
@@ -129,10 +131,13 @@ CONFIG_EQUALIZER=m
 CONFIG_TUN=m
 CONFIG_VIRTIO_NET=y
 # CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
 # CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
+# CONFIG_VT is not set
 CONFIG_DEVKMEM=y
 CONFIG_RAW_DRIVER=m
 CONFIG_VIRTIO_BALLOON=y
@@ -177,13 +182,15 @@ CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
 CONFIG_STACK_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_FUNCTION_PROFILER=y
-CONFIG_KPROBES_SANITY_TEST=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_S390_PTDUMP=y
 CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CFB=m
 CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
@@ -213,6 +220,8 @@ CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_SALSA20=m
 CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_SM4=m
+CONFIG_CRYPTO_SPECK=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_DEFLATE=m
index 43bbe63e2992c1ef525597bf4475b5f4c26d134b..06b513d192b9bc5cd3e589a7a220d126744cadf4 100644 (file)
@@ -320,7 +320,7 @@ static void hypfs_kill_super(struct super_block *sb)
 
        if (sb->s_root)
                hypfs_delete_tree(sb->s_root);
-       if (sb_info->update_file)
+       if (sb_info && sb_info->update_file)
                hypfs_remove(sb_info->update_file);
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
index 1d708a419326eaf8e400e8be3e430301c3e0035e..825dd0f7f2211863a5b127c193220f4c6556dfa4 100644 (file)
 static inline void crash_setup_regs(struct pt_regs *newregs,
                                        struct pt_regs *oldregs) { }
 
+struct kimage;
+struct s390_load_data {
+       /* Pointer to the kernel buffer. Used to register cmdline etc.. */
+       void *kernel_buf;
+
+       /* Total size of loaded segments in memory. Used as an offset. */
+       size_t memsz;
+
+       /* Load address of initrd. Used to register INITRD_START in kernel. */
+       unsigned long initrd_load_addr;
+};
+
+int kexec_file_add_purgatory(struct kimage *image,
+                            struct s390_load_data *data);
+int kexec_file_add_initrd(struct kimage *image,
+                         struct s390_load_data *data,
+                         char *initrd, unsigned long initrd_len);
+int *kexec_file_update_kernel(struct kimage *iamge,
+                             struct s390_load_data *data);
+
+extern const struct kexec_file_ops s390_kexec_image_ops;
+extern const struct kexec_file_ops s390_kexec_elf_ops;
+
 #endif /*_S390_KEXEC_H */
diff --git a/arch/s390/include/asm/purgatory.h b/arch/s390/include/asm/purgatory.h
new file mode 100644 (file)
index 0000000..e297bcf
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#ifndef _S390_PURGATORY_H_
+#define _S390_PURGATORY_H_
+#ifndef __ASSEMBLY__
+
+#include <linux/purgatory.h>
+
+int verify_sha256_digest(void);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _S390_PURGATORY_H_ */
index 124154fdfc9722d34f84ed293a9b6fc31fff370f..9c30ebe046f3ec5787f33be17e83fdfa646bbe03 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  *  S390 version
- *    Copyright IBM Corp. 1999, 2010
+ *    Copyright IBM Corp. 1999, 2017
  */
 #ifndef _ASM_S390_SETUP_H
 #define _ASM_S390_SETUP_H
 #define LPP_MAGIC              _BITUL(31)
 #define LPP_PID_MASK           _AC(0xffffffff, UL)
 
+/* Offsets to entry points in kernel/head.S  */
+
+#define STARTUP_NORMAL_OFFSET  0x10000
+#define STARTUP_KDUMP_OFFSET   0x10010
+
+/* Offsets to parameters in kernel/head.S  */
+
+#define IPL_DEVICE_OFFSET      0x10400
+#define INITRD_START_OFFSET    0x10408
+#define INITRD_SIZE_OFFSET     0x10410
+#define OLDMEM_BASE_OFFSET     0x10418
+#define OLDMEM_SIZE_OFFSET     0x10420
+#define COMMAND_LINE_OFFSET    0x10480
+
 #ifndef __ASSEMBLY__
 
 #include <asm/lowcore.h>
 #include <asm/types.h>
 
-#define IPL_DEVICE        (*(unsigned long *)  (0x10400))
-#define INITRD_START      (*(unsigned long *)  (0x10408))
-#define INITRD_SIZE       (*(unsigned long *)  (0x10410))
-#define OLDMEM_BASE      (*(unsigned long *)  (0x10418))
-#define OLDMEM_SIZE      (*(unsigned long *)  (0x10420))
-#define COMMAND_LINE      ((char *)            (0x10480))
+#define IPL_DEVICE     (*(unsigned long *)  (IPL_DEVICE_OFFSET))
+#define INITRD_START   (*(unsigned long *)  (INITRD_START_OFFSET))
+#define INITRD_SIZE    (*(unsigned long *)  (INITRD_SIZE_OFFSET))
+#define OLDMEM_BASE    (*(unsigned long *)  (OLDMEM_BASE_OFFSET))
+#define OLDMEM_SIZE    (*(unsigned long *)  (OLDMEM_SIZE_OFFSET))
+#define COMMAND_LINE   ((char *)            (COMMAND_LINE_OFFSET))
 
 extern int memory_end_set;
 extern unsigned long memory_end;
@@ -121,12 +135,12 @@ extern void (*_machine_power_off)(void);
 
 #else /* __ASSEMBLY__ */
 
-#define IPL_DEVICE        0x10400
-#define INITRD_START      0x10408
-#define INITRD_SIZE       0x10410
-#define OLDMEM_BASE      0x10418
-#define OLDMEM_SIZE      0x10420
-#define COMMAND_LINE      0x10480
+#define IPL_DEVICE     (IPL_DEVICE_OFFSET)
+#define INITRD_START   (INITRD_START_OFFSET)
+#define INITRD_SIZE    (INITRD_SIZE_OFFSET)
+#define OLDMEM_BASE    (OLDMEM_BASE_OFFSET)
+#define OLDMEM_SIZE    (OLDMEM_SIZE_OFFSET)
+#define COMMAND_LINE   (COMMAND_LINE_OFFSET)
 
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_S390_SETUP_H */
index 83ba57533ce6fb63887d06046758a409fd58b1f3..3c883c368eb0587daef70a03c74010b6579f9084 100644 (file)
@@ -45,6 +45,9 @@ struct thread_info {
 void arch_release_task_struct(struct task_struct *tsk);
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
 
+void arch_setup_new_exec(void);
+#define arch_setup_new_exec arch_setup_new_exec
+
 #endif
 
 /*
index c57f9d28d8940e8691328bb8eaf5af877541651b..9a14a611ed822e70cde1ef86d14bbd979a16eb39 100644 (file)
@@ -97,22 +97,31 @@ typedef unsigned long sigset_t;
 #include <asm-generic/signal-defs.h>
 
 #ifndef __KERNEL__
-/* Here we must cater to libcs that poke about in kernel headers.  */
 
+/*
+ * There are two system calls in regard to sigaction, sys_rt_sigaction
+ * and sys_sigaction. Internally the kernel uses the struct old_sigaction
+ * for the older sys_sigaction system call, and the kernel version of the
+ * struct sigaction for the newer sys_rt_sigaction.
+ *
+ * The uapi definition for struct sigaction has made a strange distinction
+ * between 31-bit and 64-bit in the past. For 64-bit the uapi structure
+ * looks like the kernel struct sigaction, but for 31-bit it used to
+ * look like the kernel struct old_sigaction. That practically made the
+ * structure unusable for either system call. To get around this problem
+ * the glibc always had its own definitions for the sigaction structures.
+ *
+ * The current struct sigaction uapi definition below is suitable for the
+ * sys_rt_sigaction system call only.
+ */
 struct sigaction {
         union {
           __sighandler_t _sa_handler;
           void (*_sa_sigaction)(int, struct siginfo *, void *);
         } _u;
-#ifndef __s390x__ /* lovely */
-        sigset_t sa_mask;
-        unsigned long sa_flags;
-        void (*sa_restorer)(void);
-#else  /* __s390x__ */
         unsigned long sa_flags;
         void (*sa_restorer)(void);
        sigset_t sa_mask;
-#endif /* __s390x__ */
 };
 
 #define sa_handler      _u._sa_handler
index b06a6f79c1ec3b3dba230e6c7a3eadf8e935beea..84ea6225efb4be999ca6c92343d69f0b138447d6 100644 (file)
@@ -82,6 +82,9 @@ obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_UPROBES)          += uprobes.o
 
+obj-$(CONFIG_KEXEC_FILE)       += machine_kexec_file.o kexec_image.o
+obj-$(CONFIG_KEXEC_FILE)       += kexec_elf.o
+
 obj-$(CONFIG_PERF_EVENTS)      += perf_event.o perf_cpum_cf.o perf_cpum_sf.o
 obj-$(CONFIG_PERF_EVENTS)      += perf_cpum_cf_events.o perf_regs.o
 
index cfe2c45c518039e2128c115e1cb98fceba271cf2..eb2a5c0443cd9c4fb6e0cfd4aa71ebdf14e163fa 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kbuild.h>
 #include <linux/kvm_host.h>
 #include <linux/sched.h>
+#include <linux/purgatory.h>
 #include <asm/idle.h>
 #include <asm/vdso.h>
 #include <asm/pgtable.h>
@@ -204,5 +205,9 @@ int main(void)
        OFFSET(__GMAP_ASCE, gmap, asce);
        OFFSET(__SIE_PROG0C, kvm_s390_sie_block, prog0c);
        OFFSET(__SIE_PROG20, kvm_s390_sie_block, prog20);
+       /* kexec_sha_region */
+       OFFSET(__KEXEC_SHA_REGION_START, kexec_sha_region, start);
+       OFFSET(__KEXEC_SHA_REGION_LEN, kexec_sha_region, len);
+       DEFINE(__KEXEC_SHA_REGION_SIZE, sizeof(struct kexec_sha_region));
        return 0;
 }
index 11e9d8b5c1b0633ba4eb41eb26c73fc9e78a3a78..607c5e9fba3ddcdfe762c347c8441c447fc529f5 100644 (file)
@@ -182,3 +182,4 @@ COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int,
 COMPAT_SYSCALL_WRAP2(s390_guarded_storage, int, command, struct gs_cb *, gs_cb);
 COMPAT_SYSCALL_WRAP5(statx, int, dfd, const char __user *, path, unsigned, flags, unsigned, mask, struct statx __user *, buffer);
 COMPAT_SYSCALL_WRAP4(s390_sthyi, unsigned long, code, void __user *, info, u64 __user *, rc, unsigned long, flags);
+COMPAT_SYSCALL_WRAP5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags)
diff --git a/arch/s390/kernel/kexec_elf.c b/arch/s390/kernel/kexec_elf.c
new file mode 100644 (file)
index 0000000..5a286b0
--- /dev/null
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ELF loader for kexec_file_load system call.
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
+#include <asm/setup.h>
+
+static int kexec_file_add_elf_kernel(struct kimage *image,
+                                    struct s390_load_data *data,
+                                    char *kernel, unsigned long kernel_len)
+{
+       struct kexec_buf buf;
+       const Elf_Ehdr *ehdr;
+       const Elf_Phdr *phdr;
+       int i, ret;
+
+       ehdr = (Elf_Ehdr *)kernel;
+       buf.image = image;
+
+       phdr = (void *)ehdr + ehdr->e_phoff;
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+               if (phdr->p_type != PT_LOAD)
+                       continue;
+
+               buf.buffer = kernel + phdr->p_offset;
+               buf.bufsz = phdr->p_filesz;
+
+               buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
+               buf.memsz = phdr->p_memsz;
+
+               if (phdr->p_paddr == 0) {
+                       data->kernel_buf = buf.buffer;
+                       data->memsz += STARTUP_NORMAL_OFFSET;
+
+                       buf.buffer += STARTUP_NORMAL_OFFSET;
+                       buf.bufsz -= STARTUP_NORMAL_OFFSET;
+
+                       buf.mem += STARTUP_NORMAL_OFFSET;
+                       buf.memsz -= STARTUP_NORMAL_OFFSET;
+               }
+
+               if (image->type == KEXEC_TYPE_CRASH)
+                       buf.mem += crashk_res.start;
+
+               ret = kexec_add_buffer(&buf);
+               if (ret)
+                       return ret;
+
+               data->memsz += buf.memsz;
+       }
+
+       return 0;
+}
+
+static void *s390_elf_load(struct kimage *image,
+                          char *kernel, unsigned long kernel_len,
+                          char *initrd, unsigned long initrd_len,
+                          char *cmdline, unsigned long cmdline_len)
+{
+       struct s390_load_data data = {0};
+       const Elf_Ehdr *ehdr;
+       const Elf_Phdr *phdr;
+       size_t size;
+       int i, ret;
+
+       /* image->fobs->probe already checked for valid ELF magic number. */
+       ehdr = (Elf_Ehdr *)kernel;
+
+       if (ehdr->e_type != ET_EXEC ||
+           ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
+           !elf_check_arch(ehdr))
+               return ERR_PTR(-EINVAL);
+
+       if (!ehdr->e_phnum || ehdr->e_phentsize != sizeof(Elf_Phdr))
+               return ERR_PTR(-EINVAL);
+
+       size = ehdr->e_ehsize + ehdr->e_phoff;
+       size += ehdr->e_phentsize * ehdr->e_phnum;
+       if (size > kernel_len)
+               return ERR_PTR(-EINVAL);
+
+       phdr = (void *)ehdr + ehdr->e_phoff;
+       size = ALIGN(size, phdr->p_align);
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+               if (phdr->p_type == PT_INTERP)
+                       return ERR_PTR(-EINVAL);
+
+               if (phdr->p_offset > kernel_len)
+                       return ERR_PTR(-EINVAL);
+
+               size += ALIGN(phdr->p_filesz, phdr->p_align);
+       }
+
+       if (size > kernel_len)
+               return ERR_PTR(-EINVAL);
+
+       ret = kexec_file_add_elf_kernel(image, &data, kernel, kernel_len);
+       if (ret)
+               return ERR_PTR(ret);
+
+       if (!data.memsz)
+               return ERR_PTR(-EINVAL);
+
+       if (initrd) {
+               ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
+       ret = kexec_file_add_purgatory(image, &data);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return kexec_file_update_kernel(image, &data);
+}
+
+static int s390_elf_probe(const char *buf, unsigned long len)
+{
+       const Elf_Ehdr *ehdr;
+
+       if (len < sizeof(Elf_Ehdr))
+               return -ENOEXEC;
+
+       ehdr = (Elf_Ehdr *)buf;
+
+       /* Only check the ELF magic number here and do proper validity check
+        * in the loader. Any check here that fails would send the erroneous
+        * ELF file to the image loader that does not care what it gets.
+        * (Most likely) causing behavior not intended by the user.
+        */
+       if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0)
+               return -ENOEXEC;
+
+       return 0;
+}
+
+const struct kexec_file_ops s390_kexec_elf_ops = {
+       .probe = s390_elf_probe,
+       .load = s390_elf_load,
+};
diff --git a/arch/s390/kernel/kexec_image.c b/arch/s390/kernel/kexec_image.c
new file mode 100644 (file)
index 0000000..3800852
--- /dev/null
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Image loader for kexec_file_load system call.
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
+#include <asm/setup.h>
+
+static int kexec_file_add_image_kernel(struct kimage *image,
+                                      struct s390_load_data *data,
+                                      char *kernel, unsigned long kernel_len)
+{
+       struct kexec_buf buf;
+       int ret;
+
+       buf.image = image;
+
+       buf.buffer = kernel + STARTUP_NORMAL_OFFSET;
+       buf.bufsz = kernel_len - STARTUP_NORMAL_OFFSET;
+
+       buf.mem = STARTUP_NORMAL_OFFSET;
+       if (image->type == KEXEC_TYPE_CRASH)
+               buf.mem += crashk_res.start;
+       buf.memsz = buf.bufsz;
+
+       ret = kexec_add_buffer(&buf);
+
+       data->kernel_buf = kernel;
+       data->memsz += buf.memsz + STARTUP_NORMAL_OFFSET;
+
+       return ret;
+}
+
+static void *s390_image_load(struct kimage *image,
+                            char *kernel, unsigned long kernel_len,
+                            char *initrd, unsigned long initrd_len,
+                            char *cmdline, unsigned long cmdline_len)
+{
+       struct s390_load_data data = {0};
+       int ret;
+
+       ret = kexec_file_add_image_kernel(image, &data, kernel, kernel_len);
+       if (ret)
+               return ERR_PTR(ret);
+
+       if (initrd) {
+               ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
+       ret = kexec_file_add_purgatory(image, &data);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return kexec_file_update_kernel(image, &data);
+}
+
+static int s390_image_probe(const char *buf, unsigned long len)
+{
+       /* Can't reliably tell if an image is valid.  Therefore give the
+        * user whatever he wants.
+        */
+       return 0;
+}
+
+const struct kexec_file_ops s390_kexec_image_ops = {
+       .probe = s390_image_probe,
+       .load = s390_image_load,
+};
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
new file mode 100644 (file)
index 0000000..f413f57
--- /dev/null
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * s390 code for kexec_file_load system call
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/elf.h>
+#include <linux/kexec.h>
+#include <asm/setup.h>
+
+const struct kexec_file_ops * const kexec_file_loaders[] = {
+       &s390_kexec_elf_ops,
+       &s390_kexec_image_ops,
+       NULL,
+};
+
+int *kexec_file_update_kernel(struct kimage *image,
+                             struct s390_load_data *data)
+{
+       unsigned long *loc;
+
+       if (image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE)
+               return ERR_PTR(-EINVAL);
+
+       if (image->cmdline_buf_len)
+               memcpy(data->kernel_buf + COMMAND_LINE_OFFSET,
+                      image->cmdline_buf, image->cmdline_buf_len);
+
+       if (image->type == KEXEC_TYPE_CRASH) {
+               loc = (unsigned long *)(data->kernel_buf + OLDMEM_BASE_OFFSET);
+               *loc = crashk_res.start;
+
+               loc = (unsigned long *)(data->kernel_buf + OLDMEM_SIZE_OFFSET);
+               *loc = crashk_res.end - crashk_res.start + 1;
+       }
+
+       if (image->initrd_buf) {
+               loc = (unsigned long *)(data->kernel_buf + INITRD_START_OFFSET);
+               *loc = data->initrd_load_addr;
+
+               loc = (unsigned long *)(data->kernel_buf + INITRD_SIZE_OFFSET);
+               *loc = image->initrd_buf_len;
+       }
+
+       return NULL;
+}
+
+static int kexec_file_update_purgatory(struct kimage *image)
+{
+       u64 entry, type;
+       int ret;
+
+       if (image->type == KEXEC_TYPE_CRASH) {
+               entry = STARTUP_KDUMP_OFFSET;
+               type = KEXEC_TYPE_CRASH;
+       } else {
+               entry = STARTUP_NORMAL_OFFSET;
+               type = KEXEC_TYPE_DEFAULT;
+       }
+
+       ret = kexec_purgatory_get_set_symbol(image, "kernel_entry", &entry,
+                                            sizeof(entry), false);
+       if (ret)
+               return ret;
+
+       ret = kexec_purgatory_get_set_symbol(image, "kernel_type", &type,
+                                            sizeof(type), false);
+       if (ret)
+               return ret;
+
+       if (image->type == KEXEC_TYPE_CRASH) {
+               u64 crash_size;
+
+               ret = kexec_purgatory_get_set_symbol(image, "crash_start",
+                                                    &crashk_res.start,
+                                                    sizeof(crashk_res.start),
+                                                    false);
+               if (ret)
+                       return ret;
+
+               crash_size = crashk_res.end - crashk_res.start + 1;
+               ret = kexec_purgatory_get_set_symbol(image, "crash_size",
+                                                    &crash_size,
+                                                    sizeof(crash_size),
+                                                    false);
+       }
+       return ret;
+}
+
+int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data)
+{
+       struct kexec_buf buf;
+       int ret;
+
+       buf.image = image;
+
+       data->memsz = ALIGN(data->memsz, PAGE_SIZE);
+       buf.mem = data->memsz;
+       if (image->type == KEXEC_TYPE_CRASH)
+               buf.mem += crashk_res.start;
+
+       ret = kexec_load_purgatory(image, &buf);
+       if (ret)
+               return ret;
+
+       ret = kexec_file_update_purgatory(image);
+       return ret;
+}
+
+int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data,
+                         char *initrd, unsigned long initrd_len)
+{
+       struct kexec_buf buf;
+       int ret;
+
+       buf.image = image;
+
+       buf.buffer = initrd;
+       buf.bufsz = initrd_len;
+
+       data->memsz = ALIGN(data->memsz, PAGE_SIZE);
+       buf.mem = data->memsz;
+       if (image->type == KEXEC_TYPE_CRASH)
+               buf.mem += crashk_res.start;
+       buf.memsz = buf.bufsz;
+
+       data->initrd_load_addr = buf.mem;
+       data->memsz += buf.memsz;
+
+       ret = kexec_add_buffer(&buf);
+       return ret;
+}
+
+/*
+ * The kernel is loaded to a fixed location. Turn off kexec_locate_mem_hole
+ * and provide kbuf->mem by hand.
+ */
+int arch_kexec_walk_mem(struct kexec_buf *kbuf,
+                       int (*func)(struct resource *, void *))
+{
+       return 1;
+}
+
+int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
+                                    Elf_Shdr *section,
+                                    const Elf_Shdr *relsec,
+                                    const Elf_Shdr *symtab)
+{
+       Elf_Rela *relas;
+       int i;
+
+       relas = (void *)pi->ehdr + relsec->sh_offset;
+
+       for (i = 0; i < relsec->sh_size / sizeof(*relas); i++) {
+               const Elf_Sym *sym;     /* symbol to relocate */
+               unsigned long addr;     /* final location after relocation */
+               unsigned long val;      /* relocated symbol value */
+               void *loc;              /* tmp location to modify */
+
+               sym = (void *)pi->ehdr + symtab->sh_offset;
+               sym += ELF64_R_SYM(relas[i].r_info);
+
+               if (sym->st_shndx == SHN_UNDEF)
+                       return -ENOEXEC;
+
+               if (sym->st_shndx == SHN_COMMON)
+                       return -ENOEXEC;
+
+               if (sym->st_shndx >= pi->ehdr->e_shnum &&
+                   sym->st_shndx != SHN_ABS)
+                       return -ENOEXEC;
+
+               loc = pi->purgatory_buf;
+               loc += section->sh_offset;
+               loc += relas[i].r_offset;
+
+               val = sym->st_value;
+               if (sym->st_shndx != SHN_ABS)
+                       val += pi->sechdrs[sym->st_shndx].sh_addr;
+               val += relas[i].r_addend;
+
+               addr = section->sh_addr + relas[i].r_offset;
+
+               switch (ELF64_R_TYPE(relas[i].r_info)) {
+               case R_390_8:           /* Direct 8 bit.   */
+                       *(u8 *)loc = val;
+                       break;
+               case R_390_12:          /* Direct 12 bit.  */
+                       *(u16 *)loc &= 0xf000;
+                       *(u16 *)loc |= val & 0xfff;
+                       break;
+               case R_390_16:          /* Direct 16 bit.  */
+                       *(u16 *)loc = val;
+                       break;
+               case R_390_20:          /* Direct 20 bit.  */
+                       *(u32 *)loc &= 0xf00000ff;
+                       *(u32 *)loc |= (val & 0xfff) << 16;     /* DL */
+                       *(u32 *)loc |= (val & 0xff000) >> 4;    /* DH */
+                       break;
+               case R_390_32:          /* Direct 32 bit.  */
+                       *(u32 *)loc = val;
+                       break;
+               case R_390_64:          /* Direct 64 bit.  */
+                       *(u64 *)loc = val;
+                       break;
+               case R_390_PC16:        /* PC relative 16 bit.  */
+                       *(u16 *)loc = (val - addr);
+                       break;
+               case R_390_PC16DBL:     /* PC relative 16 bit shifted by 1.  */
+                       *(u16 *)loc = (val - addr) >> 1;
+                       break;
+               case R_390_PC32DBL:     /* PC relative 32 bit shifted by 1.  */
+                       *(u32 *)loc = (val - addr) >> 1;
+                       break;
+               case R_390_PC32:        /* PC relative 32 bit.  */
+                       *(u32 *)loc = (val - addr);
+                       break;
+               case R_390_PC64:        /* PC relative 64 bit.  */
+                       *(u64 *)loc = (val - addr);
+                       break;
+               default:
+                       break;
+               }
+       }
+       return 0;
+}
+
+int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
+                                 unsigned long buf_len)
+{
+       /* A kernel must be at least large enough to contain head.S. During
+        * load memory in head.S will be accessed, e.g. to register the next
+        * command line. If the next kernel were smaller the current kernel
+        * will panic at load.
+        *
+        * 0x11000 = sizeof(head.S)
+        */
+       if (buf_len < 0x11000)
+               return -ENOEXEC;
+
+       return kexec_image_probe_default(image, buf, buf_len);
+}
index 5a83be955c70ed8f9a378ec6a47c61933c2968d9..0dc8ac8548ee3f32904038b41b5b30517516bf41 100644 (file)
@@ -465,11 +465,11 @@ int module_finalize(const Elf_Ehdr *hdr,
                        apply_alternatives(aseg, aseg + s->sh_size);
 
                if (IS_ENABLED(CONFIG_EXPOLINE) &&
-                   (!strcmp(".nospec_call_table", secname)))
+                   (!strncmp(".s390_indirect", secname, 14)))
                        nospec_revert(aseg, aseg + s->sh_size);
 
                if (IS_ENABLED(CONFIG_EXPOLINE) &&
-                   (!strcmp(".nospec_return_table", secname)))
+                   (!strncmp(".s390_return", secname, 12)))
                        nospec_revert(aseg, aseg + s->sh_size);
        }
 
index f236ce8757e8d4e0334859ebc59e53c2fafff727..46d49a11663f5915753c42ece6c0f56870889b80 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/cpu.h>
 #include <asm/nospec-branch.h>
 
 static int __init nobp_setup_early(char *str)
index c5bc3f209652eca50763f1f3ca4a03f7aa373b5c..feebb294488203b77899f5415f841e12cefedf29 100644 (file)
@@ -123,7 +123,7 @@ CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES_IV, 0x00a1);
 CPUMF_EVENT_ATTR(cf_zec12, TX_NC_TABORT, 0x00b1);
 CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_NO_SPECIAL, 0x00b2);
 CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_SPECIAL, 0x00b3);
-CPUMF_EVENT_ATTR(cf_z13, L1D_WRITES_RO_EXCL, 0x0080);
+CPUMF_EVENT_ATTR(cf_z13, L1D_RO_EXCL_WRITES, 0x0080);
 CPUMF_EVENT_ATTR(cf_z13, DTLB1_WRITES, 0x0081);
 CPUMF_EVENT_ATTR(cf_z13, DTLB1_MISSES, 0x0082);
 CPUMF_EVENT_ATTR(cf_z13, DTLB1_HPAGE_WRITES, 0x0083);
@@ -179,7 +179,7 @@ CPUMF_EVENT_ATTR(cf_z13, TX_C_TABORT_NO_SPECIAL, 0x00db);
 CPUMF_EVENT_ATTR(cf_z13, TX_C_TABORT_SPECIAL, 0x00dc);
 CPUMF_EVENT_ATTR(cf_z13, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0);
 CPUMF_EVENT_ATTR(cf_z13, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1);
-CPUMF_EVENT_ATTR(cf_z14, L1D_WRITES_RO_EXCL, 0x0080);
+CPUMF_EVENT_ATTR(cf_z14, L1D_RO_EXCL_WRITES, 0x0080);
 CPUMF_EVENT_ATTR(cf_z14, DTLB2_WRITES, 0x0081);
 CPUMF_EVENT_ATTR(cf_z14, DTLB2_MISSES, 0x0082);
 CPUMF_EVENT_ATTR(cf_z14, DTLB2_HPAGE_WRITES, 0x0083);
@@ -371,7 +371,7 @@ static struct attribute *cpumcf_zec12_pmu_event_attr[] __initdata = {
 };
 
 static struct attribute *cpumcf_z13_pmu_event_attr[] __initdata = {
-       CPUMF_EVENT_PTR(cf_z13, L1D_WRITES_RO_EXCL),
+       CPUMF_EVENT_PTR(cf_z13, L1D_RO_EXCL_WRITES),
        CPUMF_EVENT_PTR(cf_z13, DTLB1_WRITES),
        CPUMF_EVENT_PTR(cf_z13, DTLB1_MISSES),
        CPUMF_EVENT_PTR(cf_z13, DTLB1_HPAGE_WRITES),
@@ -431,7 +431,7 @@ static struct attribute *cpumcf_z13_pmu_event_attr[] __initdata = {
 };
 
 static struct attribute *cpumcf_z14_pmu_event_attr[] __initdata = {
-       CPUMF_EVENT_PTR(cf_z14, L1D_WRITES_RO_EXCL),
+       CPUMF_EVENT_PTR(cf_z14, L1D_RO_EXCL_WRITES),
        CPUMF_EVENT_PTR(cf_z14, DTLB2_WRITES),
        CPUMF_EVENT_PTR(cf_z14, DTLB2_MISSES),
        CPUMF_EVENT_PTR(cf_z14, DTLB2_HPAGE_WRITES),
@@ -583,6 +583,7 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
                model = cpumcf_z13_pmu_event_attr;
                break;
        case 0x3906:
+       case 0x3907:
                model = cpumcf_z14_pmu_event_attr;
                break;
        default:
index 70576a2f69cf6851ea2917197ed418de1459bf44..6e758bb6cd29b70821bec49fd69b6d8d76111d2e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/random.h>
 #include <linux/export.h>
 #include <linux/init_task.h>
+#include <asm/cpu_mf.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/vtimer.h>
@@ -48,6 +49,15 @@ void flush_thread(void)
 {
 }
 
+void arch_setup_new_exec(void)
+{
+       if (S390_lowcore.current_pid != current->pid) {
+               S390_lowcore.current_pid = current->pid;
+               if (test_facility(40))
+                       lpp(&S390_lowcore.lpp);
+       }
+}
+
 void arch_release_task_struct(struct task_struct *tsk)
 {
        runtime_instr_release(tsk);
index fc3b4aa185cc93895d43fc947e7c0fcec498c045..d82a9ec64ea9712b2f33572b7baffcbe679ff6bd 100644 (file)
@@ -821,6 +821,7 @@ static int __init setup_hwcaps(void)
                strcpy(elf_platform, "z13");
                break;
        case 0x3906:
+       case 0x3907:
                strcpy(elf_platform, "z14");
                break;
        }
index b38d48464368dc5fe102f58e109a68ab80004d84..8b210ead79569413ab74e3a1c03b506f48a1622f 100644 (file)
 378  common    s390_guarded_storage    sys_s390_guarded_storage        compat_sys_s390_guarded_storage
 379  common    statx                   sys_statx                       compat_sys_statx
 380  common    s390_sthyi              sys_s390_sthyi                  compat_sys_s390_sthyi
+381  common    kexec_file_load         sys_kexec_file_load             compat_sys_kexec_file_load
index d9d1f512f019415ed36912e7afd81156fbd284ae..5007fac01bb5e215392362768898cc829cc121d0 100644 (file)
@@ -150,6 +150,15 @@ unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline,
        return orig;
 }
 
+bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
+                            struct pt_regs *regs)
+{
+       if (ctx == RP_CHECK_CHAIN_CALL)
+               return user_stack_pointer(regs) <= ret->stack;
+       else
+               return user_stack_pointer(regs) < ret->stack;
+}
+
 /* Instruction Emulation */
 
 static void adjust_psw_addr(psw_t *psw, unsigned long len)
diff --git a/arch/s390/purgatory/.gitignore b/arch/s390/purgatory/.gitignore
new file mode 100644 (file)
index 0000000..e9e66f1
--- /dev/null
@@ -0,0 +1,2 @@
+kexec-purgatory.c
+purgatory.ro
diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile
new file mode 100644 (file)
index 0000000..e9525bc
--- /dev/null
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0
+
+OBJECT_FILES_NON_STANDARD := y
+
+purgatory-y := head.o purgatory.o string.o sha256.o mem.o
+
+targets += $(purgatory-y) purgatory.ro kexec-purgatory.c
+PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
+
+$(obj)/sha256.o: $(srctree)/lib/sha256.c
+       $(call if_changed_rule,cc_o_c)
+
+$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S
+       $(call if_changed_rule,as_o_S)
+
+$(obj)/string.o: $(srctree)/arch/s390/lib/string.c
+       $(call if_changed_rule,cc_o_c)
+
+LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib
+LDFLAGS_purgatory.ro += -z nodefaultlib
+KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes
+KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
+KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding
+KBUILD_CFLAGS += -c -MD -Os -m64
+KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
+
+$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
+               $(call if_changed,ld)
+
+CMD_BIN2C = $(objtree)/scripts/basic/bin2c
+quiet_cmd_bin2c = BIN2C   $@
+      cmd_bin2c = $(CMD_BIN2C) kexec_purgatory < $< > $@
+
+$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
+       $(call if_changed,bin2c)
+
+obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += kexec-purgatory.o
diff --git a/arch/s390/purgatory/head.S b/arch/s390/purgatory/head.S
new file mode 100644 (file)
index 0000000..660c96a
--- /dev/null
@@ -0,0 +1,279 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Purgatory setup code
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/sigp.h>
+
+/* The purgatory is the code running between two kernels. It's main purpose
+ * is to verify that the next kernel was not corrupted after load and to
+ * start it.
+ *
+ * If the next kernel is a crash kernel there are some peculiarities to
+ * consider:
+ *
+ * First the purgatory is called twice. Once only to verify the
+ * sha digest. So if the crash kernel got corrupted the old kernel can try
+ * to trigger a stand-alone dumper. And once to actually load the crash kernel.
+ *
+ * Second the purgatory also has to swap the crash memory region with its
+ * destination at address 0. As the purgatory is part of crash memory this
+ * requires some finesse. The tactic here is that the purgatory first copies
+ * itself to the end of the destination and then swaps the rest of the
+ * memory running from there.
+ */
+
+#define bufsz purgatory_end-stack
+
+.macro MEMCPY dst,src,len
+       lgr     %r0,\dst
+       lgr     %r1,\len
+       lgr     %r2,\src
+       lgr     %r3,\len
+
+20:    mvcle   %r0,%r2,0
+       jo      20b
+.endm
+
+.macro MEMSWAP dst,src,buf,len
+10:    cghi    \len,bufsz
+       jh      11f
+       lgr     %r4,\len
+       j       12f
+11:    lghi    %r4,bufsz
+
+12:    MEMCPY  \buf,\dst,%r4
+       MEMCPY  \dst,\src,%r4
+       MEMCPY  \src,\buf,%r4
+
+       agr     \dst,%r4
+       agr     \src,%r4
+       sgr     \len,%r4
+
+       cghi    \len,0
+       jh      10b
+.endm
+
+.macro START_NEXT_KERNEL base
+       lg      %r4,kernel_entry-\base(%r13)
+       lg      %r5,load_psw_mask-\base(%r13)
+       ogr     %r4,%r5
+       stg     %r4,0(%r0)
+
+       xgr     %r0,%r0
+       diag    %r0,%r0,0x308
+.endm
+
+.text
+.align PAGE_SIZE
+ENTRY(purgatory_start)
+       /* The purgatory might be called after a diag308 so better set
+        * architecture and addressing mode.
+        */
+       lhi     %r1,1
+       sigp    %r1,%r0,SIGP_SET_ARCHITECTURE
+       sam64
+
+       larl    %r5,gprregs
+       stmg    %r6,%r15,0(%r5)
+
+       basr    %r13,0
+.base_crash:
+
+       /* Setup stack */
+       larl    %r15,purgatory_end
+       aghi    %r15,-160
+
+       /* If the next kernel is KEXEC_TYPE_CRASH the purgatory is called
+        * directly with a flag passed in %r2 whether the purgatory shall do
+        * checksum verification only (%r2 = 0 -> verification only).
+        *
+        * Check now and preserve over C function call by storing in
+        * %r10 whith
+        *      1 -> checksum verification only
+        *      0 -> load new kernel
+        */
+       lghi    %r10,0
+       lg      %r11,kernel_type-.base_crash(%r13)
+       cghi    %r11,1          /* KEXEC_TYPE_CRASH */
+       jne     .do_checksum_verification
+       cghi    %r2,0           /* checksum verification only */
+       jne     .do_checksum_verification
+       lghi    %r10,1
+
+.do_checksum_verification:
+       brasl   %r14,verify_sha256_digest
+
+       cghi    %r10,1          /* checksum verification only */
+       je      .return_old_kernel
+       cghi    %r2,0           /* checksum match */
+       jne     .disabled_wait
+
+       /* If the next kernel is a crash kernel the purgatory has to swap
+        * the mem regions first.
+        */
+       cghi    %r11,1 /* KEXEC_TYPE_CRASH */
+       je      .start_crash_kernel
+
+       /* start normal kernel */
+       START_NEXT_KERNEL .base_crash
+
+.return_old_kernel:
+       lmg     %r6,%r15,gprregs-.base_crash(%r13)
+       br      %r14
+
+.disabled_wait:
+       lpswe   disabled_wait_psw-.base_crash(%r13)
+
+.start_crash_kernel:
+       /* Location of purgatory_start in crash memory */
+       lgr     %r8,%r13
+       aghi    %r8,-(.base_crash-purgatory_start)
+
+       /* Destination for this code i.e. end of memory to be swapped. */
+       lg      %r9,crash_size-.base_crash(%r13)
+       aghi    %r9,-(purgatory_end-purgatory_start)
+
+       /* Destination in crash memory, i.e. same as r9 but in crash memory. */
+       lg      %r10,crash_start-.base_crash(%r13)
+       agr     %r10,%r9
+
+       /* Buffer location (in crash memory) and size. As the purgatory is
+        * behind the point of no return it can re-use the stack as buffer.
+        */
+       lghi    %r11,bufsz
+       larl    %r12,stack
+
+       MEMCPY  %r12,%r9,%r11   /* dst  -> (crash) buf */
+       MEMCPY  %r9,%r8,%r11    /* self -> dst */
+
+       /* Jump to new location. */
+       lgr     %r7,%r9
+       aghi    %r7,.jump_to_dst-purgatory_start
+       br      %r7
+
+.jump_to_dst:
+       basr    %r13,0
+.base_dst:
+
+       /* clear buffer */
+       MEMCPY  %r12,%r10,%r11  /* (crash) buf -> (crash) dst */
+
+       /* Load new buffer location after jump */
+       larl    %r7,stack
+       aghi    %r10,stack-purgatory_start
+       MEMCPY  %r10,%r7,%r11   /* (new) buf -> (crash) buf */
+
+       /* Now the code is set up to run from its designated location. Start
+        * swapping the rest of crash memory now.
+        *
+        * The registers will be used as follow:
+        *
+        *      %r0-%r4 reserved for macros defined above
+        *      %r5-%r6 tmp registers
+        *      %r7     pointer to current struct sha region
+        *      %r8     index to iterate over all sha regions
+        *      %r9     pointer in crash memory
+        *      %r10    pointer in old kernel
+        *      %r11    total size (still) to be moved
+        *      %r12    pointer to buffer
+        */
+       lgr     %r12,%r7
+       lgr     %r11,%r9
+       lghi    %r10,0
+       lg      %r9,crash_start-.base_dst(%r13)
+       lghi    %r8,16  /* KEXEC_SEGMENTS_MAX */
+       larl    %r7,purgatory_sha_regions
+
+       j .loop_first
+
+       /* Loop over all purgatory_sha_regions. */
+.loop_next:
+       aghi    %r8,-1
+       cghi    %r8,0
+       je      .loop_out
+
+       aghi    %r7,__KEXEC_SHA_REGION_SIZE
+
+.loop_first:
+       lg      %r5,__KEXEC_SHA_REGION_START(%r7)
+       cghi    %r5,0
+       je      .loop_next
+
+       /* Copy [end last sha region, start current sha region) */
+       /* Note: kexec_sha_region->start points in crash memory */
+       sgr     %r5,%r9
+       MEMCPY  %r9,%r10,%r5
+
+       agr     %r9,%r5
+       agr     %r10,%r5
+       sgr     %r11,%r5
+
+       /* Swap sha region */
+       lg      %r6,__KEXEC_SHA_REGION_LEN(%r7)
+       MEMSWAP %r9,%r10,%r12,%r6
+       sg      %r11,__KEXEC_SHA_REGION_LEN(%r7)
+       j       .loop_next
+
+.loop_out:
+       /* Copy rest of crash memory */
+       MEMCPY  %r9,%r10,%r11
+
+       /* start crash kernel */
+       START_NEXT_KERNEL .base_dst
+
+
+load_psw_mask:
+       .long   0x00080000,0x80000000
+
+       .align  8
+disabled_wait_psw:
+       .quad   0x0002000180000000
+       .quad   0x0000000000000000 + .do_checksum_verification
+
+gprregs:
+       .rept   10
+       .quad   0
+       .endr
+
+purgatory_sha256_digest:
+       .global purgatory_sha256_digest
+       .rept   32      /* SHA256_DIGEST_SIZE */
+       .byte   0
+       .endr
+
+purgatory_sha_regions:
+       .global purgatory_sha_regions
+       .rept   16 * __KEXEC_SHA_REGION_SIZE    /* KEXEC_SEGMENTS_MAX */
+       .byte   0
+       .endr
+
+kernel_entry:
+       .global kernel_entry
+       .quad   0
+
+kernel_type:
+       .global kernel_type
+       .quad   0
+
+crash_start:
+       .global crash_start
+       .quad   0
+
+crash_size:
+       .global crash_size
+       .quad   0
+
+       .align  PAGE_SIZE
+stack:
+       /* The buffer to move this code must be as big as the code. */
+       .skip   stack-purgatory_start
+       .align  PAGE_SIZE
+purgatory_end:
diff --git a/arch/s390/purgatory/purgatory.c b/arch/s390/purgatory/purgatory.c
new file mode 100644 (file)
index 0000000..4e2beb3
--- /dev/null
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Purgatory code running between two kernels.
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/kexec.h>
+#include <linux/sha256.h>
+#include <linux/string.h>
+#include <asm/purgatory.h>
+
+struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX];
+u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE];
+
+u64 kernel_entry;
+u64 kernel_type;
+
+u64 crash_start;
+u64 crash_size;
+
+int verify_sha256_digest(void)
+{
+       struct kexec_sha_region *ptr, *end;
+       u8 digest[SHA256_DIGEST_SIZE];
+       struct sha256_state sctx;
+
+       sha256_init(&sctx);
+       end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions);
+
+       for (ptr = purgatory_sha_regions; ptr < end; ptr++)
+               sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len);
+
+       sha256_final(&sctx, digest);
+
+       if (memcmp(digest, purgatory_sha256_digest, sizeof(digest)))
+               return 1;
+
+       return 0;
+}
index 722951908b0a45c7dafd8a5861833b221ebe28d2..4f6676fe4bcc8981384928eec5a715f4d99e5225 100644 (file)
@@ -3,7 +3,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
index 1a0fa10cb6b721747b479651119b095d05893de0..32bae68e34c1b617c2e1547cbea9f609dc285d8f 100644 (file)
@@ -403,7 +403,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        if (err) {
                printk(KERN_ERR "VIO: Could not register device %s, err=%d\n",
                       dev_name(&vdev->dev), err);
-               kfree(vdev);
+               put_device(&vdev->dev);
                return NULL;
        }
        if (vdev->dp)
index 00fcf81f2c569b813a4b48f0800fc3ac72684d33..c07f492b871a8bf0f47cfb7be03a004dd740c2c1 100644 (file)
@@ -52,6 +52,7 @@ config X86
        select ARCH_HAS_DEVMEM_IS_ALLOWED
        select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAS_FAST_MULTIPLIER
+       select ARCH_HAS_FILTER_PGPROT
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_GCOV_PROFILE_ALL
        select ARCH_HAS_KCOV                    if X86_64
@@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX
 config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
 
+config ARCH_HAS_FILTER_PGPROT
+       def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
        def_bool y
 
index 9af927e59d49745757dd1bf07ad148df0db5a006..9de7f1e1dede7f6e6ebdc66e5f63756a173cdc0a 100644 (file)
@@ -84,13 +84,13 @@ ENTRY(entry_SYSENTER_compat)
        pushq   %rdx                    /* pt_regs->dx */
        pushq   %rcx                    /* pt_regs->cx */
        pushq   $-ENOSYS                /* pt_regs->ax */
-       pushq   $0                      /* pt_regs->r8  = 0 */
+       pushq   %r8                     /* pt_regs->r8 */
        xorl    %r8d, %r8d              /* nospec   r8 */
-       pushq   $0                      /* pt_regs->r9  = 0 */
+       pushq   %r9                     /* pt_regs->r9 */
        xorl    %r9d, %r9d              /* nospec   r9 */
-       pushq   $0                      /* pt_regs->r10 = 0 */
+       pushq   %r10                    /* pt_regs->r10 */
        xorl    %r10d, %r10d            /* nospec   r10 */
-       pushq   $0                      /* pt_regs->r11 = 0 */
+       pushq   %r11                    /* pt_regs->r11 */
        xorl    %r11d, %r11d            /* nospec   r11 */
        pushq   %rbx                    /* pt_regs->rbx */
        xorl    %ebx, %ebx              /* nospec   rbx */
index 607bf565a90c97c3d0d72bf979fdf88cf10c8e28..707b2a96e516b5579c9321cbf0822a627bc8a8d8 100644 (file)
@@ -3339,7 +3339,8 @@ static void intel_pmu_cpu_starting(int cpu)
 
        cpuc->lbr_sel = NULL;
 
-       flip_smm_bit(&x86_pmu.attr_freeze_on_smi);
+       if (x86_pmu.version > 1)
+               flip_smm_bit(&x86_pmu.attr_freeze_on_smi);
 
        if (!cpuc->shared_regs)
                return;
@@ -3502,6 +3503,8 @@ static __initconst const struct x86_pmu core_pmu = {
        .cpu_dying              = intel_pmu_cpu_dying,
 };
 
+static struct attribute *intel_pmu_attrs[];
+
 static __initconst const struct x86_pmu intel_pmu = {
        .name                   = "Intel",
        .handle_irq             = intel_pmu_handle_irq,
@@ -3533,6 +3536,8 @@ static __initconst const struct x86_pmu intel_pmu = {
        .format_attrs           = intel_arch3_formats_attr,
        .events_sysfs_show      = intel_event_sysfs_show,
 
+       .attrs                  = intel_pmu_attrs,
+
        .cpu_prepare            = intel_pmu_cpu_prepare,
        .cpu_starting           = intel_pmu_cpu_starting,
        .cpu_dying              = intel_pmu_cpu_dying,
@@ -3911,8 +3916,6 @@ __init int intel_pmu_init(void)
 
        x86_pmu.max_pebs_events         = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
 
-
-       x86_pmu.attrs                   = intel_pmu_attrs;
        /*
         * Quirk: v2 perfmon does not report fixed-purpose events, so
         * assume at least 3 events, when not running in a hypervisor:
index c98b943e58b4fca0a5144a20342229b013fe1ee1..77076a102e34a46252a9758d16f6e8f4fefc4012 100644 (file)
@@ -3028,10 +3028,27 @@ static struct intel_uncore_type bdx_uncore_cbox = {
        .format_group           = &hswep_uncore_cbox_format_group,
 };
 
+static struct intel_uncore_type bdx_uncore_sbox = {
+       .name                   = "sbox",
+       .num_counters           = 4,
+       .num_boxes              = 4,
+       .perf_ctr_bits          = 48,
+       .event_ctl              = HSWEP_S0_MSR_PMON_CTL0,
+       .perf_ctr               = HSWEP_S0_MSR_PMON_CTR0,
+       .event_mask             = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
+       .box_ctl                = HSWEP_S0_MSR_PMON_BOX_CTL,
+       .msr_offset             = HSWEP_SBOX_MSR_OFFSET,
+       .ops                    = &hswep_uncore_sbox_msr_ops,
+       .format_group           = &hswep_uncore_sbox_format_group,
+};
+
+#define BDX_MSR_UNCORE_SBOX    3
+
 static struct intel_uncore_type *bdx_msr_uncores[] = {
        &bdx_uncore_ubox,
        &bdx_uncore_cbox,
        &hswep_uncore_pcu,
+       &bdx_uncore_sbox,
        NULL,
 };
 
@@ -3043,10 +3060,25 @@ static struct event_constraint bdx_uncore_pcu_constraints[] = {
 
 void bdx_uncore_cpu_init(void)
 {
+       int pkg = topology_phys_to_logical_pkg(0);
+
        if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
                bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
        uncore_msr_uncores = bdx_msr_uncores;
 
+       /* BDX-DE doesn't have SBOX */
+       if (boot_cpu_data.x86_model == 86) {
+               uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
+       /* Detect systems with no SBOXes */
+       } else if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) {
+               struct pci_dev *pdev;
+               u32 capid4;
+
+               pdev = uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3];
+               pci_read_config_dword(pdev, 0x94, &capid4);
+               if (((capid4 >> 6) & 0x3) == 0)
+                       bdx_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
+       }
        hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints;
 }
 
@@ -3264,6 +3296,11 @@ static const struct pci_device_id bdx_uncore_pci_ids[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46),
                .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 2),
        },
+       { /* PCU.3 (for Capability registers) */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fc0),
+               .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+                                                  HSWEP_PCI_PCU_3),
+       },
        { /* end: all zeroes */ }
 };
 
index 386a6900e206f6578e3b38ee7f085d36ac50a928..219faaec51dfa192f69d8893c8844219c0c89029 100644 (file)
 #endif
 
 #ifndef __ASSEMBLY__
-#ifndef __BPF__
 /*
  * This output constraint should be used for any inline asm which has a "call"
  * instruction.  Otherwise the asm may be inserted before the frame pointer
 register unsigned long current_stack_pointer asm(_ASM_SP);
 #define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
 #endif
-#endif
 
 #endif /* _ASM_X86_ASM_H */
index d554c11e01ff46742d53148df0ffb9c3476e8d6e..578793e97431da25b0d5f3cbc20ae4c0655db075 100644 (file)
 #define X86_FEATURE_AVX512_VPOPCNTDQ   (16*32+14) /* POPCNT for vectors of DW/QW */
 #define X86_FEATURE_LA57               (16*32+16) /* 5-level page tables */
 #define X86_FEATURE_RDPID              (16*32+22) /* RDPID instruction */
+#define X86_FEATURE_CLDEMOTE           (16*32+25) /* CLDEMOTE instruction */
 
 /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */
 #define X86_FEATURE_OVERFLOW_RECOV     (17*32+ 0) /* MCA overflow recovery support */
index 404c5fdff859ded0e55325ac601ced0332910aac..548d90bbf919e8d75f9983a2cb97235637708bd8 100644 (file)
  * (0x80 is the syscall vector, 0x30-0x3f are for ISA)
  */
 #define FIRST_EXTERNAL_VECTOR          0x20
-/*
- * We start allocating at 0x21 to spread out vectors evenly between
- * priority levels. (0x80 is the syscall vector)
- */
-#define VECTOR_OFFSET_START            1
 
 /*
  * Reserve the lowest usable vector (and hence lowest priority)  0x20 for
 #define FIRST_SYSTEM_VECTOR            NR_VECTORS
 #endif
 
-#define FPU_IRQ                                  13
-
 /*
  * Size the maximum number of interrupts.
  *
index b885a961a150f079e38d4e5dbb8670ef9fde0b57..a34897aef2c295a8100716263d06153f1a1811e7 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL2.0 */
+/* SPDX-License-Identifier: GPL-2.0 */
 
 /*
  * Jailhouse paravirt detection
index 949c977bc4c941b5b1ba9db039b948ce22a0ae13..c25775fad4ed19d73452f530f4fecfb8d2373176 100644 (file)
@@ -1013,6 +1013,7 @@ struct kvm_x86_ops {
 
        bool (*has_wbinvd_exit)(void);
 
+       u64 (*read_l1_tsc_offset)(struct kvm_vcpu *vcpu);
        void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
        void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
index 5f49b4ff0c248493f77cc12cadee0c2b6261c25d..f1633de5a675925b7b250e5b2e9e16b2ae6dd5e5 100644 (file)
@@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
 
 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
 
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+       return canon_pgprot(prot);
+}
+
 static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
                                         enum page_cache_mode pcm,
                                         enum page_cache_mode new_pcm)
index d5c21a38247570cf025b33ef2c6c203a9d3a4aef..adb47552e6bb700158788b4d42094f2d83931c86 100644 (file)
@@ -105,14 +105,14 @@ extern unsigned int ptrs_per_p4d;
 #define LDT_PGD_ENTRY          (pgtable_l5_enabled ? LDT_PGD_ENTRY_L5 : LDT_PGD_ENTRY_L4)
 #define LDT_BASE_ADDR          (LDT_PGD_ENTRY << PGDIR_SHIFT)
 
-#define __VMALLOC_BASE_L4      0xffffc90000000000
-#define __VMALLOC_BASE_L5      0xffa0000000000000
+#define __VMALLOC_BASE_L4      0xffffc90000000000UL
+#define __VMALLOC_BASE_L5      0xffa0000000000000UL
 
 #define VMALLOC_SIZE_TB_L4     32UL
 #define VMALLOC_SIZE_TB_L5     12800UL
 
-#define __VMEMMAP_BASE_L4      0xffffea0000000000
-#define __VMEMMAP_BASE_L5      0xffd4000000000000
+#define __VMEMMAP_BASE_L4      0xffffea0000000000UL
+#define __VMEMMAP_BASE_L5      0xffd4000000000000UL
 
 #ifdef CONFIG_DYNAMIC_MEMORY_LAYOUT
 # define VMALLOC_START         vmalloc_base
index 4fa4206029e3e126abc671ff0af71d6660c737fc..21a114914ba435e9f56b1c6df941bca1d72b9588 100644 (file)
@@ -749,13 +749,11 @@ enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
 extern void enable_sep_cpu(void);
 extern int sysenter_setup(void);
 
-extern void early_trap_init(void);
 void early_trap_pf_init(void);
 
 /* Defined in head.S */
 extern struct desc_ptr         early_gdt_descr;
 
-extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
 extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
index 809134c644a677032e9eb2ae5d5a844806bc347e..90ab9a795b49329b5d06cdb45e15cb800a04ff63 100644 (file)
@@ -1 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_X64_MSGBUF_H
+#define __ASM_X64_MSGBUF_H
+
+#if !defined(__x86_64__) || !defined(__ILP32__)
 #include <asm-generic/msgbuf.h>
+#else
+/*
+ * The msqid64_ds structure for x86 architecture with x32 ABI.
+ *
+ * On x86-32 and x86-64 we can just use the generic definition, but
+ * x32 uses the same binary layout as x86_64, which is differnet
+ * from other 32-bit architectures.
+ */
+
+struct msqid64_ds {
+       struct ipc64_perm msg_perm;
+       __kernel_time_t msg_stime;      /* last msgsnd time */
+       __kernel_time_t msg_rtime;      /* last msgrcv time */
+       __kernel_time_t msg_ctime;      /* last change time */
+       __kernel_ulong_t msg_cbytes;    /* current number of bytes on queue */
+       __kernel_ulong_t msg_qnum;      /* number of messages in queue */
+       __kernel_ulong_t msg_qbytes;    /* max number of bytes on queue */
+       __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
+       __kernel_pid_t msg_lrpid;       /* last receive pid */
+       __kernel_ulong_t __unused4;
+       __kernel_ulong_t __unused5;
+};
+
+#endif
+
+#endif /* __ASM_GENERIC_MSGBUF_H */
index 83c05fc2de385c3260286bf12fed846617c8c095..644421f3823beefb16ddc83979fbdf01c15c6a7a 100644 (file)
@@ -1 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_X86_SHMBUF_H
+#define __ASM_X86_SHMBUF_H
+
+#if !defined(__x86_64__) || !defined(__ILP32__)
 #include <asm-generic/shmbuf.h>
+#else
+/*
+ * The shmid64_ds structure for x86 architecture with x32 ABI.
+ *
+ * On x86-32 and x86-64 we can just use the generic definition, but
+ * x32 uses the same binary layout as x86_64, which is differnet
+ * from other 32-bit architectures.
+ */
+
+struct shmid64_ds {
+       struct ipc64_perm       shm_perm;       /* operation perms */
+       size_t                  shm_segsz;      /* size of segment (bytes) */
+       __kernel_time_t         shm_atime;      /* last attach time */
+       __kernel_time_t         shm_dtime;      /* last detach time */
+       __kernel_time_t         shm_ctime;      /* last change time */
+       __kernel_pid_t          shm_cpid;       /* pid of creator */
+       __kernel_pid_t          shm_lpid;       /* pid of last operator */
+       __kernel_ulong_t        shm_nattch;     /* no. of current attaches */
+       __kernel_ulong_t        __unused4;
+       __kernel_ulong_t        __unused5;
+};
+
+struct shminfo64 {
+       __kernel_ulong_t        shmmax;
+       __kernel_ulong_t        shmmin;
+       __kernel_ulong_t        shmmni;
+       __kernel_ulong_t        shmseg;
+       __kernel_ulong_t        shmall;
+       __kernel_ulong_t        __unused1;
+       __kernel_ulong_t        __unused2;
+       __kernel_ulong_t        __unused3;
+       __kernel_ulong_t        __unused4;
+};
+
+#endif
+
+#endif /* __ASM_X86_SHMBUF_H */
index dde444f932c135d11f93b22188689e3e97e8e046..3b20607d581b5340fcf5e0345b7e70f9e83d95ad 100644 (file)
@@ -215,6 +215,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
        apic_id = processor->local_apic_id;
        enabled = processor->lapic_flags & ACPI_MADT_ENABLED;
 
+       /* Ignore invalid ID */
+       if (apic_id == 0xffffffff)
+               return 0;
+
        /*
         * We need to register disabled CPU as well to permit
         * counting disabled CPUs. This allows us to size
index b9693b80fc219c74b29800d226777de3e6f3130e..60d1897041da89c19b97f03ca2c577102ec3186c 100644 (file)
@@ -835,6 +835,9 @@ static const struct _tlb_table intel_tlb_table[] = {
        { 0x5d, TLB_DATA_4K_4M,         256,    " TLB_DATA 4 KByte and 4 MByte pages" },
        { 0x61, TLB_INST_4K,            48,     " TLB_INST 4 KByte pages, full associative" },
        { 0x63, TLB_DATA_1G,            4,      " TLB_DATA 1 GByte pages, 4-way set associative" },
+       { 0x6b, TLB_DATA_4K,            256,    " TLB_DATA 4 KByte pages, 8-way associative" },
+       { 0x6c, TLB_DATA_2M_4M,         128,    " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" },
+       { 0x6d, TLB_DATA_1G,            16,     " TLB_DATA 1 GByte pages, fully associative" },
        { 0x76, TLB_INST_2M_4M,         8,      " TLB_INST 2-MByte or 4-MByte pages, fully associative" },
        { 0xb0, TLB_INST_4K,            128,    " TLB_INST 4 KByte pages, 4-way set associative" },
        { 0xb1, TLB_INST_2M_4M,         4,      " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" },
index 10c4fc2c91f8ed1dd6879c8b0b8aa24d7275cd3b..77e201301528817e32537194cf5e075b29aa9686 100644 (file)
@@ -564,14 +564,12 @@ static int __reload_late(void *info)
        apply_microcode_local(&err);
        spin_unlock(&update_lock);
 
+       /* siblings return UCODE_OK because their engine got updated already */
        if (err > UCODE_NFOUND) {
                pr_warn("Error reloading microcode on CPU %d\n", cpu);
-               return -1;
-       /* siblings return UCODE_OK because their engine got updated already */
+               ret = -1;
        } else if (err == UCODE_UPDATED || err == UCODE_OK) {
                ret = 1;
-       } else {
-               return ret;
        }
 
        /*
index 32b8e5724f966abbc67153065dd17b5ddcfd6d70..1c2cfa0644aa979c97cc01a42925a44c25f9f852 100644 (file)
@@ -485,7 +485,6 @@ static void show_saved_mc(void)
  */
 static void save_mc_for_early(u8 *mc, unsigned int size)
 {
-#ifdef CONFIG_HOTPLUG_CPU
        /* Synchronization during CPU hotplug. */
        static DEFINE_MUTEX(x86_cpu_microcode_mutex);
 
@@ -495,7 +494,6 @@ static void save_mc_for_early(u8 *mc, unsigned int size)
        show_saved_mc();
 
        mutex_unlock(&x86_cpu_microcode_mutex);
-#endif
 }
 
 static bool load_builtin_intel_microcode(struct cpio_data *cp)
index fa183a131edc7b493dd86f47cf637ba42f15d274..a15fe0e92cf994be8a0d84284e6ee458c0f91e5a 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL2.0
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Jailhouse paravirt_ops implementation
  *
index 3182908b7e6c70c621f8e5f8446cb0cfbc850de9..7326078eaa7a6518d30cb98d6443d507299c70c0 100644 (file)
@@ -398,11 +398,10 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
         * little bit simple
         */
        efi_map_sz = efi_get_runtime_map_size();
-       efi_map_sz = ALIGN(efi_map_sz, 16);
        params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
                                MAX_ELFCOREHDR_STR_LEN;
        params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
-       kbuf.bufsz = params_cmdline_sz + efi_map_sz +
+       kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
                                sizeof(struct setup_data) +
                                sizeof(struct efi_setup_data);
 
@@ -410,7 +409,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
        if (!params)
                return ERR_PTR(-ENOMEM);
        efi_map_offset = params_cmdline_sz;
-       efi_setup_data_offset = efi_map_offset + efi_map_sz;
+       efi_setup_data_offset = efi_map_offset + ALIGN(efi_map_sz, 16);
 
        /* Copy setup header onto bootparams. Documentation/x86/boot.txt */
        setup_header_size = 0x0202 + kernel[0x0201] - setup_hdr_offset;
index d41d896481b841e271c9521fd0a894512dbb7def..c9b14020f4ddf433c5d96f6f4930a65340f214a2 100644 (file)
@@ -166,7 +166,7 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
                 */
                pte_prot = __pgprot(__PAGE_KERNEL_RO & ~_PAGE_GLOBAL);
                /* Filter out unsuppored __PAGE_KERNEL* bits: */
-               pgprot_val(pte_prot) |= __supported_pte_mask;
+               pgprot_val(pte_prot) &= __supported_pte_mask;
                pte = pfn_pte(pfn, pte_prot);
                set_pte_at(mm, va, ptep, pte);
                pte_unmap_unlock(ptep, ptl);
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
deleted file mode 100644 (file)
index ac7ea3a..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Fallback functions when the main IOMMU code is not compiled in. This
-   code is roughly equivalent to i386. */
-#include <linux/dma-direct.h>
-#include <linux/scatterlist.h>
-#include <linux/string.h>
-#include <linux/gfp.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
-
-#include <asm/processor.h>
-#include <asm/iommu.h>
-#include <asm/dma.h>
-
-#define NOMMU_MAPPING_ERROR            0
-
-static int
-check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
-{
-       if (hwdev && !dma_capable(hwdev, bus, size)) {
-               if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
-                       printk(KERN_ERR
-                           "nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
-                               name, (long long)bus, size,
-                               (long long)*hwdev->dma_mask);
-               return 0;
-       }
-       return 1;
-}
-
-static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction dir,
-                                unsigned long attrs)
-{
-       dma_addr_t bus = phys_to_dma(dev, page_to_phys(page)) + offset;
-       WARN_ON(size == 0);
-       if (!check_addr("map_single", dev, bus, size))
-               return NOMMU_MAPPING_ERROR;
-       return bus;
-}
-
-/* Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scatter-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
-                       int nents, enum dma_data_direction dir,
-                       unsigned long attrs)
-{
-       struct scatterlist *s;
-       int i;
-
-       WARN_ON(nents == 0 || sg[0].length == 0);
-
-       for_each_sg(sg, s, nents, i) {
-               BUG_ON(!sg_page(s));
-               s->dma_address = sg_phys(s);
-               if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
-                       return 0;
-               s->dma_length = s->length;
-       }
-       return nents;
-}
-
-static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return dma_addr == NOMMU_MAPPING_ERROR;
-}
-
-const struct dma_map_ops nommu_dma_ops = {
-       .alloc                  = dma_generic_alloc_coherent,
-       .free                   = dma_generic_free_coherent,
-       .map_sg                 = nommu_map_sg,
-       .map_page               = nommu_map_page,
-       .is_phys                = 1,
-       .mapping_error          = nommu_mapping_error,
-       .dma_supported          = x86_dma_supported,
-};
index 6285697b6e565c61611787f0a07274c2f3308630..5c623dfe39d159822f12602e2f1f7ae4d9024f6d 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/init_ohci1394_dma.h>
 #include <linux/kvm_para.h>
 #include <linux/dma-contiguous.h>
+#include <xen/xen.h>
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -534,6 +535,11 @@ static void __init reserve_crashkernel(void)
                high = true;
        }
 
+       if (xen_pv_domain()) {
+               pr_info("Ignoring crashkernel for a Xen PV domain\n");
+               return;
+       }
+
        /* 0 means: find the address automatically */
        if (crash_base <= 0) {
                /*
index ff99e2b6fc541a0faf8afaa17328679533b7838a..0f1cbb042f49b82e7a01b7ace0bce08061a8e6f1 100644 (file)
@@ -77,6 +77,8 @@
 #include <asm/i8259.h>
 #include <asm/misc.h>
 #include <asm/qspinlock.h>
+#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
@@ -390,15 +392,47 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
        return false;
 }
 
+/*
+ * Define snc_cpu[] for SNC (Sub-NUMA Cluster) CPUs.
+ *
+ * These are Intel CPUs that enumerate an LLC that is shared by
+ * multiple NUMA nodes. The LLC on these systems is shared for
+ * off-package data access but private to the NUMA node (half
+ * of the package) for on-package access.
+ *
+ * CPUID (the source of the information about the LLC) can only
+ * enumerate the cache as being shared *or* unshared, but not
+ * this particular configuration. The CPU in this case enumerates
+ * the cache to be shared across the entire package (spanning both
+ * NUMA nodes).
+ */
+
+static const struct x86_cpu_id snc_cpu[] = {
+       { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X },
+       {}
+};
+
 static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 {
        int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
 
-       if (per_cpu(cpu_llc_id, cpu1) != BAD_APICID &&
-           per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2))
-               return topology_sane(c, o, "llc");
+       /* Do not match if we do not have a valid APICID for cpu: */
+       if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID)
+               return false;
 
-       return false;
+       /* Do not match if LLC id does not match: */
+       if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2))
+               return false;
+
+       /*
+        * Allow the SNC topology without warning. Return of false
+        * means 'c' does not share the LLC of 'o'. This will be
+        * reflected to userspace.
+        */
+       if (!topology_same_node(c, o) && x86_match_cpu(snc_cpu))
+               return false;
+
+       return topology_sane(c, o, "llc");
 }
 
 /*
@@ -456,7 +490,8 @@ static struct sched_domain_topology_level x86_topology[] = {
 
 /*
  * Set if a package/die has multiple NUMA nodes inside.
- * AMD Magny-Cours and Intel Cluster-on-Die have this.
+ * AMD Magny-Cours, Intel Cluster-on-Die, and Intel
+ * Sub-NUMA Clustering have this.
  */
 static bool x86_has_numa_in_package;
 
@@ -1536,6 +1571,8 @@ static inline void mwait_play_dead(void)
        void *mwait_ptr;
        int i;
 
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+               return;
        if (!this_cpu_has(X86_FEATURE_MWAIT))
                return;
        if (!this_cpu_has(X86_FEATURE_CLFLUSH))
index ef32297ff17e5bdc6a852bb38f88546f90e0af22..91e6da48cbb673a8fc373750d59f776e57c20ae4 100644 (file)
@@ -317,7 +317,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2)
        hpet2 -= hpet1;
        tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
        do_div(tmp, 1000000);
-       do_div(deltatsc, tmp);
+       deltatsc = div64_u64(deltatsc, tmp);
 
        return (unsigned long) deltatsc;
 }
index b58787daf9f8c0ab24c88164e295d521e00c873b..1fc05e428aba824e252bc3c2dcb9e1b6f4fb2e69 100644 (file)
@@ -1423,12 +1423,23 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
        seg->base = 0;
 }
 
+static u64 svm_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
+{
+       struct vcpu_svm *svm = to_svm(vcpu);
+
+       if (is_guest_mode(vcpu))
+               return svm->nested.hsave->control.tsc_offset;
+
+       return vcpu->arch.tsc_offset;
+}
+
 static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
        u64 g_tsc_offset = 0;
 
        if (is_guest_mode(vcpu)) {
+               /* Write L1's TSC offset.  */
                g_tsc_offset = svm->vmcb->control.tsc_offset -
                               svm->nested.hsave->control.tsc_offset;
                svm->nested.hsave->control.tsc_offset = offset;
@@ -3322,6 +3333,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
        /* Restore the original control entries */
        copy_vmcb_control_area(vmcb, hsave);
 
+       svm->vcpu.arch.tsc_offset = svm->vmcb->control.tsc_offset;
        kvm_clear_exception_queue(&svm->vcpu);
        kvm_clear_interrupt_queue(&svm->vcpu);
 
@@ -3482,10 +3494,12 @@ static void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa,
        /* We don't want to see VMMCALLs from a nested guest */
        clr_intercept(svm, INTERCEPT_VMMCALL);
 
+       svm->vcpu.arch.tsc_offset += nested_vmcb->control.tsc_offset;
+       svm->vmcb->control.tsc_offset = svm->vcpu.arch.tsc_offset;
+
        svm->vmcb->control.virt_ext = nested_vmcb->control.virt_ext;
        svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
        svm->vmcb->control.int_state = nested_vmcb->control.int_state;
-       svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset;
        svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
        svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
 
@@ -4035,12 +4049,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        struct vcpu_svm *svm = to_svm(vcpu);
 
        switch (msr_info->index) {
-       case MSR_IA32_TSC: {
-               msr_info->data = svm->vmcb->control.tsc_offset +
-                       kvm_scale_tsc(vcpu, rdtsc());
-
-               break;
-       }
        case MSR_STAR:
                msr_info->data = svm->vmcb->save.star;
                break;
@@ -4193,9 +4201,6 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
                svm->vmcb->save.g_pat = data;
                mark_dirty(svm->vmcb, VMCB_NPT);
                break;
-       case MSR_IA32_TSC:
-               kvm_write_tsc(vcpu, msr);
-               break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr->host_initiated &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_IBRS))
@@ -5265,9 +5270,8 @@ static int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
                }
 
                if (!ret && svm) {
-                       trace_kvm_pi_irte_update(svm->vcpu.vcpu_id,
-                                                host_irq, e->gsi,
-                                                vcpu_info.vector,
+                       trace_kvm_pi_irte_update(host_irq, svm->vcpu.vcpu_id,
+                                                e->gsi, vcpu_info.vector,
                                                 vcpu_info.pi_desc_addr, set);
                }
 
@@ -7102,6 +7106,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
 
        .has_wbinvd_exit = svm_has_wbinvd_exit,
 
+       .read_l1_tsc_offset = svm_read_l1_tsc_offset,
        .write_tsc_offset = svm_write_tsc_offset,
 
        .set_tdp_cr3 = set_tdp_cr3,
index aafcc9881e888dcb7e24416b368cb17398e6ed54..c7668806163fd5ac493f59b6d9f08823828c7758 100644 (file)
@@ -2880,18 +2880,15 @@ static void setup_msrs(struct vcpu_vmx *vmx)
                vmx_update_msr_bitmap(&vmx->vcpu);
 }
 
-/*
- * reads and returns guest's timestamp counter "register"
- * guest_tsc = (host_tsc * tsc multiplier) >> 48 + tsc_offset
- * -- Intel TSC Scaling for Virtualization White Paper, sec 1.3
- */
-static u64 guest_read_tsc(struct kvm_vcpu *vcpu)
+static u64 vmx_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
 {
-       u64 host_tsc, tsc_offset;
+       struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
 
-       host_tsc = rdtsc();
-       tsc_offset = vmcs_read64(TSC_OFFSET);
-       return kvm_scale_tsc(vcpu, host_tsc) + tsc_offset;
+       if (is_guest_mode(vcpu) &&
+           (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING))
+               return vcpu->arch.tsc_offset - vmcs12->tsc_offset;
+
+       return vcpu->arch.tsc_offset;
 }
 
 /*
@@ -3524,9 +3521,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 #endif
        case MSR_EFER:
                return kvm_get_msr_common(vcpu, msr_info);
-       case MSR_IA32_TSC:
-               msr_info->data = guest_read_tsc(vcpu);
-               break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) &&
@@ -3646,9 +3640,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        return 1;
                vmcs_write64(GUEST_BNDCFGS, data);
                break;
-       case MSR_IA32_TSC:
-               kvm_write_tsc(vcpu, msr_info);
-               break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) &&
@@ -4553,12 +4544,6 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
        __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid, invalidate_gpa);
 }
 
-static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu)
-{
-       if (enable_ept)
-               vmx_flush_tlb(vcpu, true);
-}
-
 static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
 {
        ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
@@ -9287,7 +9272,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
        } else {
                sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
                sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
        vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control);
 
@@ -9315,7 +9300,7 @@ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa)
            !nested_cpu_has2(get_vmcs12(&vmx->vcpu),
                             SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
                vmcs_write64(APIC_ACCESS_ADDR, hpa);
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
 }
 
@@ -10608,6 +10593,16 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
        return true;
 }
 
+static int nested_vmx_check_apic_access_controls(struct kvm_vcpu *vcpu,
+                                         struct vmcs12 *vmcs12)
+{
+       if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) &&
+           !page_address_valid(vcpu, vmcs12->apic_access_addr))
+               return -EINVAL;
+       else
+               return 0;
+}
+
 static int nested_vmx_check_apicv_controls(struct kvm_vcpu *vcpu,
                                           struct vmcs12 *vmcs12)
 {
@@ -11176,11 +11171,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat);
        }
 
-       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
-               vmcs_write64(TSC_OFFSET,
-                       vcpu->arch.tsc_offset + vmcs12->tsc_offset);
-       else
-               vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
+       vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
+
        if (kvm_has_tsc_control)
                decache_tsc_multiplier(vmx);
 
@@ -11222,7 +11214,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                }
        } else if (nested_cpu_has2(vmcs12,
                                   SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
 
        /*
@@ -11299,6 +11291,9 @@ static int check_vmentry_prereqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
        if (nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12))
                return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
 
+       if (nested_vmx_check_apic_access_controls(vcpu, vmcs12))
+               return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
+
        if (nested_vmx_check_tpr_shadow_controls(vcpu, vmcs12))
                return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
 
@@ -11420,6 +11415,7 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry)
        struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
        u32 msr_entry_idx;
        u32 exit_qual;
+       int r;
 
        enter_guest_mode(vcpu);
 
@@ -11429,26 +11425,21 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry)
        vmx_switch_vmcs(vcpu, &vmx->nested.vmcs02);
        vmx_segment_cache_clear(vmx);
 
-       if (prepare_vmcs02(vcpu, vmcs12, from_vmentry, &exit_qual)) {
-               leave_guest_mode(vcpu);
-               vmx_switch_vmcs(vcpu, &vmx->vmcs01);
-               nested_vmx_entry_failure(vcpu, vmcs12,
-                                        EXIT_REASON_INVALID_STATE, exit_qual);
-               return 1;
-       }
+       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
+               vcpu->arch.tsc_offset += vmcs12->tsc_offset;
+
+       r = EXIT_REASON_INVALID_STATE;
+       if (prepare_vmcs02(vcpu, vmcs12, from_vmentry, &exit_qual))
+               goto fail;
 
        nested_get_vmcs12_pages(vcpu, vmcs12);
 
+       r = EXIT_REASON_MSR_LOAD_FAIL;
        msr_entry_idx = nested_vmx_load_msr(vcpu,
                                            vmcs12->vm_entry_msr_load_addr,
                                            vmcs12->vm_entry_msr_load_count);
-       if (msr_entry_idx) {
-               leave_guest_mode(vcpu);
-               vmx_switch_vmcs(vcpu, &vmx->vmcs01);
-               nested_vmx_entry_failure(vcpu, vmcs12,
-                               EXIT_REASON_MSR_LOAD_FAIL, msr_entry_idx);
-               return 1;
-       }
+       if (msr_entry_idx)
+               goto fail;
 
        /*
         * Note no nested_vmx_succeed or nested_vmx_fail here. At this point
@@ -11457,6 +11448,14 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry)
         * the success flag) when L2 exits (see nested_vmx_vmexit()).
         */
        return 0;
+
+fail:
+       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
+               vcpu->arch.tsc_offset -= vmcs12->tsc_offset;
+       leave_guest_mode(vcpu);
+       vmx_switch_vmcs(vcpu, &vmx->vmcs01);
+       nested_vmx_entry_failure(vcpu, vmcs12, r, exit_qual);
+       return 1;
 }
 
 /*
@@ -12028,6 +12027,9 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
 
        leave_guest_mode(vcpu);
 
+       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
+               vcpu->arch.tsc_offset -= vmcs12->tsc_offset;
+
        if (likely(!vmx->fail)) {
                if (exit_reason == -1)
                        sync_vmcs12(vcpu, vmcs12);
@@ -12065,7 +12067,7 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
        } else if (!nested_cpu_has_ept(vmcs12) &&
                   nested_cpu_has2(vmcs12,
                                   SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
 
        /* This is needed for same reason as it was needed in prepare_vmcs02 */
@@ -12224,10 +12226,16 @@ static inline int u64_shl_div_u64(u64 a, unsigned int shift,
 
 static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc)
 {
-       struct vcpu_vmx *vmx = to_vmx(vcpu);
-       u64 tscl = rdtsc();
-       u64 guest_tscl = kvm_read_l1_tsc(vcpu, tscl);
-       u64 delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl;
+       struct vcpu_vmx *vmx;
+       u64 tscl, guest_tscl, delta_tsc;
+
+       if (kvm_mwait_in_guest(vcpu->kvm))
+               return -EOPNOTSUPP;
+
+       vmx = to_vmx(vcpu);
+       tscl = rdtsc();
+       guest_tscl = kvm_read_l1_tsc(vcpu, tscl);
+       delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl;
 
        /* Convert to host delta tsc if tsc scaling is enabled */
        if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio &&
@@ -12533,7 +12541,7 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
                vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu));
                vcpu_info.vector = irq.vector;
 
-               trace_kvm_pi_irte_update(vcpu->vcpu_id, host_irq, e->gsi,
+               trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi,
                                vcpu_info.vector, vcpu_info.pi_desc_addr, set);
 
                if (set)
@@ -12712,6 +12720,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
 
        .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
 
+       .read_l1_tsc_offset = vmx_read_l1_tsc_offset,
        .write_tsc_offset = vmx_write_tsc_offset,
 
        .set_tdp_cr3 = vmx_set_cr3,
index b2ff74b12ec45f9b8a126c0606ab17219df47363..51ecd381793b4f281563779b97a04e5063572fdf 100644 (file)
@@ -1490,7 +1490,7 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
 
 static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
 {
-       u64 curr_offset = vcpu->arch.tsc_offset;
+       u64 curr_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu);
        vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset;
 }
 
@@ -1532,7 +1532,9 @@ static u64 kvm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
 
 u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
 {
-       return vcpu->arch.tsc_offset + kvm_scale_tsc(vcpu, host_tsc);
+       u64 tsc_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu);
+
+       return tsc_offset + kvm_scale_tsc(vcpu, host_tsc);
 }
 EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
 
@@ -2362,6 +2364,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        return 1;
                vcpu->arch.smbase = data;
                break;
+       case MSR_IA32_TSC:
+               kvm_write_tsc(vcpu, msr_info);
+               break;
        case MSR_SMI_COUNT:
                if (!msr_info->host_initiated)
                        return 1;
@@ -2605,6 +2610,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_IA32_UCODE_REV:
                msr_info->data = vcpu->arch.microcode_version;
                break;
+       case MSR_IA32_TSC:
+               msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset;
+               break;
        case MSR_MTRRcap:
        case 0x200 ... 0x2ff:
                return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data);
@@ -2819,7 +2827,8 @@ out:
 static inline bool kvm_can_mwait_in_guest(void)
 {
        return boot_cpu_has(X86_FEATURE_MWAIT) &&
-               !boot_cpu_has_bug(X86_BUG_MONITOR);
+               !boot_cpu_has_bug(X86_BUG_MONITOR) &&
+               boot_cpu_has(X86_FEATURE_ARAT);
 }
 
 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
index 7d35ce672989ddcbc719db96081d37607c79734f..c9492f7649020e2990b420e545e91470ec744e73 100644 (file)
@@ -302,13 +302,6 @@ static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
            __rem;                                              \
         })
 
-#define KVM_X86_DISABLE_EXITS_MWAIT          (1 << 0)
-#define KVM_X86_DISABLE_EXITS_HTL            (1 << 1)
-#define KVM_X86_DISABLE_EXITS_PAUSE          (1 << 2)
-#define KVM_X86_DISABLE_VALID_EXITS          (KVM_X86_DISABLE_EXITS_MWAIT | \
-                                              KVM_X86_DISABLE_EXITS_HTL | \
-                                              KVM_X86_DISABLE_EXITS_PAUSE)
-
 static inline bool kvm_mwait_in_guest(struct kvm *kvm)
 {
        return kvm->arch.mwait_in_guest;
index 62a7e9f65decfcc5c447c01a9b5f986079f1de6f..cc7ff59571943fbcd09295e4d0c83c5be551cb80 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
+#include <linux/highmem.h>
 
 #include <asm/pgtable.h>
 
@@ -334,16 +335,16 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
                           pgprotval_t eff_in, unsigned long P)
 {
        int i;
-       pte_t *start;
+       pte_t *pte;
        pgprotval_t prot, eff;
 
-       start = (pte_t *)pmd_page_vaddr(addr);
        for (i = 0; i < PTRS_PER_PTE; i++) {
-               prot = pte_flags(*start);
-               eff = effective_prot(eff_in, prot);
                st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT);
+               pte = pte_offset_map(&addr, st->current_address);
+               prot = pte_flags(*pte);
+               eff = effective_prot(eff_in, prot);
                note_page(m, st, __pgprot(prot), eff, 5);
-               start++;
+               pte_unmap(pte);
        }
 }
 #ifdef CONFIG_KASAN
index 0f3d50f4c48c5bc7e96f43b007870262245666e4..3bded76e8d5c5676bd972b0217e96fb84753ff7f 100644 (file)
@@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m)
 static inline void split_page_count(int level) { }
 #endif
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+       return addr >= start && addr < end;
+}
+
+static inline int
+within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+{
+       return addr >= start && addr <= end;
+}
+
 #ifdef CONFIG_X86_64
 
 static inline unsigned long highmap_start_pfn(void)
@@ -106,20 +118,25 @@ static inline unsigned long highmap_end_pfn(void)
        return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
 }
 
-#endif
-
-static inline int
-within(unsigned long addr, unsigned long start, unsigned long end)
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-       return addr >= start && addr < end;
+       /*
+        * Kernel text has an alias mapping at a high address, known
+        * here as "highmap".
+        */
+       return within_inclusive(pfn, highmap_start_pfn(), highmap_end_pfn());
 }
 
-static inline int
-within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+#else
+
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-       return addr >= start && addr <= end;
+       /* There is no highmap on 32-bit */
+       return false;
 }
 
+#endif
+
 /*
  * Flushing functions
  */
@@ -172,7 +189,7 @@ static void __cpa_flush_all(void *arg)
 
 static void cpa_flush_all(unsigned long cache)
 {
-       BUG_ON(irqs_disabled());
+       BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
        on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
@@ -236,7 +253,7 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache,
        unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 #endif
 
-       BUG_ON(irqs_disabled());
+       BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
        on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 
@@ -1183,6 +1200,10 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
                cpa->numpages = 1;
                cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
                return 0;
+
+       } else if (__cpa_pfn_in_highmap(cpa->pfn)) {
+               /* Faults in the highmap are OK, so do not warn: */
+               return -EFAULT;
        } else {
                WARN(1, KERN_WARNING "CPA: called for zero pte. "
                        "vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1356,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
         * to touch the high mapped kernel as well:
         */
        if (!within(vaddr, (unsigned long)_text, _brk_end) &&
-           within_inclusive(cpa->pfn, highmap_start_pfn(),
-                            highmap_end_pfn())) {
+           __cpa_pfn_in_highmap(cpa->pfn)) {
                unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
                                               __START_KERNEL_map - phys_base;
                alias_cpa = *cpa;
index f1fd52f449e00ce717f360fb833a26cd02769681..4d418e70587802b05aff3ae49e80db7faf47a64c 100644 (file)
@@ -421,6 +421,16 @@ static inline bool pti_kernel_image_global_ok(void)
        if (boot_cpu_has(X86_FEATURE_K8))
                return false;
 
+       /*
+        * RANDSTRUCT derives its hardening benefits from the
+        * attacker's lack of knowledge about the layout of kernel
+        * data structures.  Keep the kernel image non-global in
+        * cases where RANDSTRUCT is in use to help keep the layout a
+        * secret.
+        */
+       if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT))
+               return false;
+
        return true;
 }
 
@@ -430,12 +440,24 @@ static inline bool pti_kernel_image_global_ok(void)
  */
 void pti_clone_kernel_text(void)
 {
+       /*
+        * rodata is part of the kernel image and is normally
+        * readable on the filesystem or on the web.  But, do not
+        * clone the areas past rodata, they might contain secrets.
+        */
        unsigned long start = PFN_ALIGN(_text);
-       unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE);
+       unsigned long end = (unsigned long)__end_rodata_hpage_align;
 
        if (!pti_kernel_image_global_ok())
                return;
 
+       pr_debug("mapping partial kernel image into user address space\n");
+
+       /*
+        * Note that this will undo _some_ of the work that
+        * pti_set_kernel_image_nonglobal() did to clear the
+        * global bit.
+        */
        pti_clone_pmds(start, end, _PAGE_RW);
 }
 
@@ -458,8 +480,6 @@ void pti_set_kernel_image_nonglobal(void)
        if (pti_kernel_image_global_ok())
                return;
 
-       pr_debug("set kernel image non-global\n");
-
        set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT);
 }
 
index 48b14b534897e21a29e5cc4b6829e00389b90091..ccf4a49bb065e1cc3f78f57f9780c1e8ee8d67d9 100644 (file)
@@ -98,7 +98,7 @@ static int set_up_temporary_text_mapping(pgd_t *pgd)
                set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
        } else {
                /* No p4d for 4-level paging: point the pgd to the pud page table */
-               pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot));
+               pgd_t new_pgd = __pgd(__pa(pud) | pgprot_val(pgtable_prot));
                set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
        }
 
index f0ecd98509d849fd1011b619d6917d9a3da6dd4d..771ae9730ac6869430f8f8d196eb804d9f356053 100644 (file)
@@ -4934,8 +4934,16 @@ static void bfq_prepare_request(struct request *rq, struct bio *bio)
        bool new_queue = false;
        bool bfqq_already_existing = false, split = false;
 
-       if (!rq->elv.icq)
+       /*
+        * Even if we don't have an icq attached, we should still clear
+        * the scheduler pointers, as they might point to previously
+        * allocated bic/bfqq structs.
+        */
+       if (!rq->elv.icq) {
+               rq->elv.priv[0] = rq->elv.priv[1] = NULL;
                return;
+       }
+
        bic = icq_to_bic(rq->elv.icq);
 
        spin_lock_irq(&bfqd->lock);
index 1c16694ae14523c144f7be2af43c3c697cc13f7a..eb85cb87c40f46f54b96cd06ae078600e8e8cac4 100644 (file)
@@ -1177,26 +1177,20 @@ int blkcg_init_queue(struct request_queue *q)
 
        preloaded = !radix_tree_preload(GFP_KERNEL);
 
-       /*
-        * Make sure the root blkg exists and count the existing blkgs.  As
-        * @q is bypassing at this point, blkg_lookup_create() can't be
-        * used.  Open code insertion.
-        */
+       /* Make sure the root blkg exists. */
        rcu_read_lock();
        spin_lock_irq(q->queue_lock);
        blkg = blkg_create(&blkcg_root, q, new_blkg);
+       if (IS_ERR(blkg))
+               goto err_unlock;
+       q->root_blkg = blkg;
+       q->root_rl.blkg = blkg;
        spin_unlock_irq(q->queue_lock);
        rcu_read_unlock();
 
        if (preloaded)
                radix_tree_preload_end();
 
-       if (IS_ERR(blkg))
-               return PTR_ERR(blkg);
-
-       q->root_blkg = blkg;
-       q->root_rl.blkg = blkg;
-
        ret = blk_throtl_init(q);
        if (ret) {
                spin_lock_irq(q->queue_lock);
@@ -1204,6 +1198,13 @@ int blkcg_init_queue(struct request_queue *q)
                spin_unlock_irq(q->queue_lock);
        }
        return ret;
+
+err_unlock:
+       spin_unlock_irq(q->queue_lock);
+       rcu_read_unlock();
+       if (preloaded)
+               radix_tree_preload_end();
+       return PTR_ERR(blkg);
 }
 
 /**
@@ -1410,9 +1411,6 @@ void blkcg_deactivate_policy(struct request_queue *q,
        __clear_bit(pol->plid, q->blkcg_pols);
 
        list_for_each_entry(blkg, &q->blkg_list, q_node) {
-               /* grab blkcg lock too while removing @pd from @blkg */
-               spin_lock(&blkg->blkcg->lock);
-
                if (blkg->pd[pol->plid]) {
                        if (!blkg->pd[pol->plid]->offline &&
                            pol->pd_offline_fn) {
@@ -1422,8 +1420,6 @@ void blkcg_deactivate_policy(struct request_queue *q,
                        pol->pd_free_fn(blkg->pd[pol->plid]);
                        blkg->pd[pol->plid] = NULL;
                }
-
-               spin_unlock(&blkg->blkcg->lock);
        }
 
        spin_unlock_irq(q->queue_lock);
index 806ce2442819c751f8a36ed83efc659c416d510f..85909b431eb0d52d5f29633fcb2ccfff0b14d9e0 100644 (file)
@@ -201,6 +201,10 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
        rq->part = NULL;
        seqcount_init(&rq->gstate_seq);
        u64_stats_init(&rq->aborted_gstate_sync);
+       /*
+        * See comment of blk_mq_init_request
+        */
+       WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC);
 }
 EXPORT_SYMBOL(blk_rq_init);
 
@@ -915,7 +919,6 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
 
        while (true) {
                bool success = false;
-               int ret;
 
                rcu_read_lock();
                if (percpu_ref_tryget_live(&q->q_usage_counter)) {
@@ -947,14 +950,12 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
                 */
                smp_rmb();
 
-               ret = wait_event_interruptible(q->mq_freeze_wq,
-                               (atomic_read(&q->mq_freeze_depth) == 0 &&
-                                (preempt || !blk_queue_preempt_only(q))) ||
-                               blk_queue_dying(q));
+               wait_event(q->mq_freeze_wq,
+                          (atomic_read(&q->mq_freeze_depth) == 0 &&
+                           (preempt || !blk_queue_preempt_only(q))) ||
+                          blk_queue_dying(q));
                if (blk_queue_dying(q))
                        return -ENODEV;
-               if (ret)
-                       return ret;
        }
 }
 
index 0dc9e341c2a72c65f6de9dbb5b019903ce95d723..c3621453ad87991ce712e5eadabe3ee3b98fc25b 100644 (file)
@@ -2042,6 +2042,13 @@ static int blk_mq_init_request(struct blk_mq_tag_set *set, struct request *rq,
 
        seqcount_init(&rq->gstate_seq);
        u64_stats_init(&rq->aborted_gstate_sync);
+       /*
+        * start gstate with gen 1 instead of 0, otherwise it will be equal
+        * to aborted_gstate, and be identified timed out by
+        * blk_mq_terminate_expired.
+        */
+       WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC);
+
        return 0;
 }
 
@@ -2329,7 +2336,7 @@ static void blk_mq_free_map_and_requests(struct blk_mq_tag_set *set,
 
 static void blk_mq_map_swqueue(struct request_queue *q)
 {
-       unsigned int i;
+       unsigned int i, hctx_idx;
        struct blk_mq_hw_ctx *hctx;
        struct blk_mq_ctx *ctx;
        struct blk_mq_tag_set *set = q->tag_set;
@@ -2346,8 +2353,23 @@ static void blk_mq_map_swqueue(struct request_queue *q)
 
        /*
         * Map software to hardware queues.
+        *
+        * If the cpu isn't present, the cpu is mapped to first hctx.
         */
        for_each_possible_cpu(i) {
+               hctx_idx = q->mq_map[i];
+               /* unmapped hw queue can be remapped after CPU topo changed */
+               if (!set->tags[hctx_idx] &&
+                   !__blk_mq_alloc_rq_map(set, hctx_idx)) {
+                       /*
+                        * If tags initialization fail for some hctx,
+                        * that hctx won't be brought online.  In this
+                        * case, remap the current ctx to hctx[0] which
+                        * is guaranteed to always have tags allocated
+                        */
+                       q->mq_map[i] = 0;
+               }
+
                ctx = per_cpu_ptr(q->queue_ctx, i);
                hctx = blk_mq_map_queue(q, i);
 
@@ -2359,8 +2381,21 @@ static void blk_mq_map_swqueue(struct request_queue *q)
        mutex_unlock(&q->sysfs_lock);
 
        queue_for_each_hw_ctx(q, hctx, i) {
-               /* every hctx should get mapped by at least one CPU */
-               WARN_ON(!hctx->nr_ctx);
+               /*
+                * If no software queues are mapped to this hardware queue,
+                * disable it and free the request entries.
+                */
+               if (!hctx->nr_ctx) {
+                       /* Never unmap queue 0.  We need it as a
+                        * fallback in case of a new remap fails
+                        * allocation
+                        */
+                       if (i && set->tags[i])
+                               blk_mq_free_map_and_requests(set, i);
+
+                       hctx->tags = NULL;
+                       continue;
+               }
 
                hctx->tags = set->tags[i];
                WARN_ON(!hctx->tags);
index 88c558f718190f88e123bba0444b0c50b296e572..89b5cd3a6c7088f3fac5d0dd14ef1fee76a49fc8 100644 (file)
@@ -7,6 +7,9 @@
 
 struct blk_mq_tag_set;
 
+/**
+ * struct blk_mq_ctx - State for a software queue facing the submitting CPUs
+ */
 struct blk_mq_ctx {
        struct {
                spinlock_t              lock;
index 1d5290c67108316f6495f33674094b5a476e2e14..0ee632bba06461021d7e4eb43127e7781a5114ee 100644 (file)
@@ -204,9 +204,14 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
 
        down_read(&crypto_alg_sem);
        alg = __crypto_alg_lookup(name, type | test, mask | test);
-       if (!alg && test)
-               alg = __crypto_alg_lookup(name, type, mask) ?
-                     ERR_PTR(-ELIBBAD) : NULL;
+       if (!alg && test) {
+               alg = __crypto_alg_lookup(name, type, mask);
+               if (alg && !crypto_is_larval(alg)) {
+                       /* Test failed */
+                       crypto_mod_put(alg);
+                       alg = ERR_PTR(-ELIBBAD);
+               }
+       }
        up_read(&crypto_alg_sem);
 
        return alg;
index 4faa2781c964e290f8b28e752993b9a408d927b4..466a112a4446820ff655c3b72076c86d3c7e4f2d 100644 (file)
@@ -1134,8 +1134,10 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
        if (!drbg)
                return;
        kzfree(drbg->Vbuf);
+       drbg->Vbuf = NULL;
        drbg->V = NULL;
        kzfree(drbg->Cbuf);
+       drbg->Cbuf = NULL;
        drbg->C = NULL;
        kzfree(drbg->scratchpadbuf);
        drbg->scratchpadbuf = NULL;
index 76fb96966f7b111a8b084cbb9ef7c6084e750695..2f2e737be0f84a966020102ba21ce906c21b9584 100644 (file)
@@ -2123,6 +2123,25 @@ static int __init intel_opregion_present(void)
        return opregion;
 }
 
+static bool dmi_is_desktop(void)
+{
+       const char *chassis_type;
+
+       chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
+       if (!chassis_type)
+               return false;
+
+       if (!strcmp(chassis_type, "3") || /*  3: Desktop */
+           !strcmp(chassis_type, "4") || /*  4: Low Profile Desktop */
+           !strcmp(chassis_type, "5") || /*  5: Pizza Box */
+           !strcmp(chassis_type, "6") || /*  6: Mini Tower */
+           !strcmp(chassis_type, "7") || /*  7: Tower */
+           !strcmp(chassis_type, "11"))  /* 11: Main Server Chassis */
+               return true;
+
+       return false;
+}
+
 int acpi_video_register(void)
 {
        int ret = 0;
@@ -2143,8 +2162,12 @@ int acpi_video_register(void)
         * win8 ready (where we also prefer the native backlight driver, so
         * normally the acpi_video code should not register there anyways).
         */
-       if (only_lcd == -1)
-               only_lcd = acpi_osi_is_win8();
+       if (only_lcd == -1) {
+               if (dmi_is_desktop() && acpi_osi_is_win8())
+                       only_lcd = true;
+               else
+                       only_lcd = false;
+       }
 
        dmi_check_system(video_dmi_table);
 
index ebb626ffb5fa2d38c853ddcbbe7227aa09c7f7dd..4bde16fb97d8818f59e893adf9bb642fed5f9d5c 100644 (file)
 #define pr_fmt(fmt) "ACPI: watchdog: " fmt
 
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 
 #include "internal.h"
 
+static const struct dmi_system_id acpi_watchdog_skip[] = {
+       {
+               /*
+                * On Lenovo Z50-70 there are two issues with the WDAT
+                * table. First some of the instructions use RTC SRAM
+                * to store persistent information. This does not work well
+                * with Linux RTC driver. Second, more important thing is
+                * that the instructions do not actually reset the system.
+                *
+                * On this particular system iTCO_wdt seems to work just
+                * fine so we prefer that over WDAT for now.
+                *
+                * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
+                */
+               .ident = "Lenovo Z50-70",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "20354"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"),
+               },
+       },
+       {}
+};
+
+static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
+{
+       const struct acpi_table_wdat *wdat = NULL;
+       acpi_status status;
+
+       if (acpi_disabled)
+               return NULL;
+
+       if (dmi_check_system(acpi_watchdog_skip))
+               return NULL;
+
+       status = acpi_get_table(ACPI_SIG_WDAT, 0,
+                               (struct acpi_table_header **)&wdat);
+       if (ACPI_FAILURE(status)) {
+               /* It is fine if there is no WDAT */
+               return NULL;
+       }
+
+       return wdat;
+}
+
 /**
  * Returns true if this system should prefer ACPI based watchdog instead of
  * the native one (which are typically the same hardware).
  */
 bool acpi_has_watchdog(void)
 {
-       struct acpi_table_header hdr;
-
-       if (acpi_disabled)
-               return false;
-
-       return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr));
+       return !!acpi_watchdog_get_wdat();
 }
 EXPORT_SYMBOL_GPL(acpi_has_watchdog);
 
@@ -41,12 +82,10 @@ void __init acpi_watchdog_init(void)
        struct platform_device *pdev;
        struct resource *resources;
        size_t nresources = 0;
-       acpi_status status;
        int i;
 
-       status = acpi_get_table(ACPI_SIG_WDAT, 0,
-                               (struct acpi_table_header **)&wdat);
-       if (ACPI_FAILURE(status)) {
+       wdat = acpi_watchdog_get_wdat();
+       if (!wdat) {
                /* It is fine if there is no WDAT */
                return;
        }
index e1eee7a60fadda50f666ab93d2969cb66576e0be..f1cc4f9d31cd92a39ec603f1ac7db5031f156ef4 100644 (file)
@@ -635,4 +635,26 @@ module_param_call(lid_init_state,
                  NULL, 0644);
 MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
 
-module_acpi_driver(acpi_button_driver);
+static int acpi_button_register_driver(struct acpi_driver *driver)
+{
+       /*
+        * Modules such as nouveau.ko and i915.ko have a link time dependency
+        * on acpi_lid_open(), and would therefore not be loadable on ACPI
+        * capable kernels booted in non-ACPI mode if the return value of
+        * acpi_bus_register_driver() is returned from here with ACPI disabled
+        * when this driver is built as a module.
+        */
+       if (acpi_disabled)
+               return 0;
+
+       return acpi_bus_register_driver(driver);
+}
+
+static void acpi_button_unregister_driver(struct acpi_driver *driver)
+{
+       if (!acpi_disabled)
+               acpi_bus_unregister_driver(driver);
+}
+
+module_driver(acpi_button_driver, acpi_button_register_driver,
+              acpi_button_unregister_driver);
index cc234e6a6297586a5c64b8252fb827474ae1e348..970dd87d347c786fbc25922464e6bc20c1dbb4ee 100644 (file)
@@ -2166,10 +2166,10 @@ int __init acpi_scan_init(void)
        acpi_cmos_rtc_init();
        acpi_container_init();
        acpi_memory_hotplug_init();
+       acpi_watchdog_init();
        acpi_pnp_init();
        acpi_int340x_thermal_init();
        acpi_amba_init();
-       acpi_watchdog_init();
        acpi_init_lpit();
 
        acpi_scan_add_handler(&generic_device_handler);
index 99a1a650326d016e171fee4e56c6dc43f192d8a6..974e58457697fce086248a4af23aed15fc608c4e 100644 (file)
@@ -364,6 +364,19 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
                DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"),
                },
        },
+       /*
+        * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using
+        * the Low Power S0 Idle firmware interface (see
+        * https://bugzilla.kernel.org/show_bug.cgi?id=199057).
+        */
+       {
+       .callback = init_no_lps0,
+       .ident = "ThinkPad X1 Tablet(2016)",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"),
+               },
+       },
        {},
 };
 
index 594c228d2f02112345ebc2ad345cd02a7e563a52..4a3ac31c07d0ee49615a00af001e49ff8e30f005 100644 (file)
@@ -69,11 +69,12 @@ static ssize_t driver_override_show(struct device *_dev,
                                    struct device_attribute *attr, char *buf)
 {
        struct amba_device *dev = to_amba_device(_dev);
+       ssize_t len;
 
-       if (!dev->driver_override)
-               return 0;
-
-       return sprintf(buf, "%s\n", dev->driver_override);
+       device_lock(_dev);
+       len = sprintf(buf, "%s\n", dev->driver_override);
+       device_unlock(_dev);
+       return len;
 }
 
 static ssize_t driver_override_store(struct device *_dev,
@@ -81,9 +82,10 @@ static ssize_t driver_override_store(struct device *_dev,
                                     const char *buf, size_t count)
 {
        struct amba_device *dev = to_amba_device(_dev);
-       char *driver_override, *old = dev->driver_override, *cp;
+       char *driver_override, *old, *cp;
 
-       if (count > PATH_MAX)
+       /* We need to keep extra room for a newline */
+       if (count >= (PAGE_SIZE - 1))
                return -EINVAL;
 
        driver_override = kstrndup(buf, count, GFP_KERNEL);
@@ -94,12 +96,15 @@ static ssize_t driver_override_store(struct device *_dev,
        if (cp)
                *cp = '\0';
 
+       device_lock(_dev);
+       old = dev->driver_override;
        if (strlen(driver_override)) {
                dev->driver_override = driver_override;
        } else {
               kfree(driver_override);
               dev->driver_override = NULL;
        }
+       device_unlock(_dev);
 
        kfree(old);
 
index 764b63a5aadefe5c73ef849ee5b377b134e3841e..e578eee315895d8c2783b933f5c252f5ec53824b 100644 (file)
@@ -2839,6 +2839,14 @@ static void binder_transaction(struct binder_proc *proc,
                        else
                                return_error = BR_DEAD_REPLY;
                        mutex_unlock(&context->context_mgr_node_lock);
+                       if (target_node && target_proc == proc) {
+                               binder_user_error("%d:%d got transaction to context manager from process owning it\n",
+                                                 proc->pid, thread->pid);
+                               return_error = BR_FAILED_REPLY;
+                               return_error_param = -EINVAL;
+                               return_error_line = __LINE__;
+                               goto err_invalid_target_handle;
+                       }
                }
                if (!target_node) {
                        /*
index 44abb8a0a5e522b7a8f73111aad6fd8fc5297402..be076606d30e09cb3b56fe779059cd892ef796b8 100644 (file)
@@ -671,7 +671,7 @@ static void ia_tx_poll (IADEV *iadev) {
           if ((vcc->pop) && (skb1->len != 0))
           {
              vcc->pop(vcc, skb1);
-             IF_EVENT(printk("Tansmit Done - skb 0x%lx return\n",
+             IF_EVENT(printk("Transmit Done - skb 0x%lx return\n",
                                                           (long)skb1);)
           }
           else 
@@ -1665,7 +1665,7 @@ static void tx_intr(struct atm_dev *dev)
        status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG);  
         if (status & TRANSMIT_DONE){
 
-           IF_EVENT(printk("Tansmit Done Intr logic run\n");)
+           IF_EVENT(printk("Transmit Done Intr logic run\n");)
            spin_lock_irqsave(&iadev->tx_lock, flags);
            ia_tx_poll(iadev);
            spin_unlock_irqrestore(&iadev->tx_lock, flags);
index 1e6396bb807b1255ab61e0a168e1b7eac40f892c..597d40893862696ed76457c7071c8d5fd074f612 100644 (file)
@@ -312,8 +312,9 @@ static int __dma_mmap_from_coherent(struct dma_coherent_mem *mem,
  * This checks whether the memory was allocated from the per-device
  * coherent memory pool and if so, maps that memory to the provided vma.
  *
- * Returns 1 if we correctly mapped the memory, or 0 if the caller should
- * proceed with mapping memory from generic pools.
+ * Returns 1 if @vaddr belongs to the device coherent pool and the caller
+ * should return @ret, or 0 if they should proceed with mapping memory from
+ * generic areas.
  */
 int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma,
                           void *vaddr, size_t size, int *ret)
index 3b118353ea176af270d72a95ca1f79772a3f5602..d82566d6e2378f4f4ba074260223b398fa7860c1 100644 (file)
@@ -226,7 +226,6 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
 #ifndef CONFIG_ARCH_NO_COHERENT_DMA_MMAP
        unsigned long user_count = vma_pages(vma);
        unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-       unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
        unsigned long off = vma->vm_pgoff;
 
        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
@@ -234,12 +233,11 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
        if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
                return ret;
 
-       if (off < count && user_count <= (count - off)) {
+       if (off < count && user_count <= (count - off))
                ret = remap_pfn_range(vma, vma->vm_start,
-                                     pfn + off,
+                                     page_to_pfn(virt_to_page(cpu_addr)) + off,
                                      user_count << PAGE_SHIFT,
                                      vma->vm_page_prot);
-       }
 #endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
 
        return ret;
index 31b5015b59fecb456167e57ce697a4228bc77680..358354148decc4b4e49ff6df805426a2d72a63d4 100644 (file)
@@ -537,8 +537,8 @@ exit:
 }
 
 /**
- * fw_load_sysfs_fallback - load a firmware via the syfs fallback mechanism
- * @fw_sysfs: firmware syfs information for the firmware to load
+ * fw_load_sysfs_fallback - load a firmware via the sysfs fallback mechanism
+ * @fw_sysfs: firmware sysfs information for the firmware to load
  * @opt_flags: flags of options, FW_OPT_*
  * @timeout: timeout to wait for the load
  *
index dfebc644ed35a1a410db821455ef54dcb8e025b6..f8255670a66352023225377e41d30b22bb35d1ea 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/device.h>
 
 /**
- * struct firmware_fallback_config - firmware fallback configuratioon settings
+ * struct firmware_fallback_config - firmware fallback configuration settings
  *
  * Helps describe and fine tune the fallback mechanism.
  *
index c9d04497a415c436b8486630d9b3c5a0812d19d2..5d4e31655d9629732c42b02a602ebdc20bec2cda 100644 (file)
@@ -451,25 +451,47 @@ static int lo_req_flush(struct loop_device *lo, struct request *rq)
 static void lo_complete_rq(struct request *rq)
 {
        struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
+       blk_status_t ret = BLK_STS_OK;
 
-       if (unlikely(req_op(cmd->rq) == REQ_OP_READ && cmd->use_aio &&
-                    cmd->ret >= 0 && cmd->ret < blk_rq_bytes(cmd->rq))) {
-               struct bio *bio = cmd->rq->bio;
-
-               bio_advance(bio, cmd->ret);
-               zero_fill_bio(bio);
+       if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||
+           req_op(rq) != REQ_OP_READ) {
+               if (cmd->ret < 0)
+                       ret = BLK_STS_IOERR;
+               goto end_io;
        }
 
-       blk_mq_end_request(rq, cmd->ret < 0 ? BLK_STS_IOERR : BLK_STS_OK);
+       /*
+        * Short READ - if we got some data, advance our request and
+        * retry it. If we got no data, end the rest with EIO.
+        */
+       if (cmd->ret) {
+               blk_update_request(rq, BLK_STS_OK, cmd->ret);
+               cmd->ret = 0;
+               blk_mq_requeue_request(rq, true);
+       } else {
+               if (cmd->use_aio) {
+                       struct bio *bio = rq->bio;
+
+                       while (bio) {
+                               zero_fill_bio(bio);
+                               bio = bio->bi_next;
+                       }
+               }
+               ret = BLK_STS_IOERR;
+end_io:
+               blk_mq_end_request(rq, ret);
+       }
 }
 
 static void lo_rw_aio_do_completion(struct loop_cmd *cmd)
 {
+       struct request *rq = blk_mq_rq_from_pdu(cmd);
+
        if (!atomic_dec_and_test(&cmd->ref))
                return;
        kfree(cmd->bvec);
        cmd->bvec = NULL;
-       blk_mq_complete_request(cmd->rq);
+       blk_mq_complete_request(rq);
 }
 
 static void lo_rw_aio_complete(struct kiocb *iocb, long ret, long ret2)
@@ -487,7 +509,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
 {
        struct iov_iter iter;
        struct bio_vec *bvec;
-       struct request *rq = cmd->rq;
+       struct request *rq = blk_mq_rq_from_pdu(cmd);
        struct bio *bio = rq->bio;
        struct file *file = lo->lo_backing_file;
        unsigned int offset;
@@ -1702,15 +1724,16 @@ EXPORT_SYMBOL(loop_unregister_transfer);
 static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
                const struct blk_mq_queue_data *bd)
 {
-       struct loop_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
-       struct loop_device *lo = cmd->rq->q->queuedata;
+       struct request *rq = bd->rq;
+       struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
+       struct loop_device *lo = rq->q->queuedata;
 
-       blk_mq_start_request(bd->rq);
+       blk_mq_start_request(rq);
 
        if (lo->lo_state != Lo_bound)
                return BLK_STS_IOERR;
 
-       switch (req_op(cmd->rq)) {
+       switch (req_op(rq)) {
        case REQ_OP_FLUSH:
        case REQ_OP_DISCARD:
        case REQ_OP_WRITE_ZEROES:
@@ -1723,8 +1746,8 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
 
        /* always use the first bio's css */
 #ifdef CONFIG_BLK_CGROUP
-       if (cmd->use_aio && cmd->rq->bio && cmd->rq->bio->bi_css) {
-               cmd->css = cmd->rq->bio->bi_css;
+       if (cmd->use_aio && rq->bio && rq->bio->bi_css) {
+               cmd->css = rq->bio->bi_css;
                css_get(cmd->css);
        } else
 #endif
@@ -1736,8 +1759,9 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
 
 static void loop_handle_cmd(struct loop_cmd *cmd)
 {
-       const bool write = op_is_write(req_op(cmd->rq));
-       struct loop_device *lo = cmd->rq->q->queuedata;
+       struct request *rq = blk_mq_rq_from_pdu(cmd);
+       const bool write = op_is_write(req_op(rq));
+       struct loop_device *lo = rq->q->queuedata;
        int ret = 0;
 
        if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) {
@@ -1745,12 +1769,12 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
                goto failed;
        }
 
-       ret = do_req_filebacked(lo, cmd->rq);
+       ret = do_req_filebacked(lo, rq);
  failed:
        /* complete non-aio request */
        if (!cmd->use_aio || ret) {
                cmd->ret = ret ? -EIO : 0;
-               blk_mq_complete_request(cmd->rq);
+               blk_mq_complete_request(rq);
        }
 }
 
@@ -1767,9 +1791,7 @@ static int loop_init_request(struct blk_mq_tag_set *set, struct request *rq,
 {
        struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);
 
-       cmd->rq = rq;
        kthread_init_work(&cmd->work, loop_queue_work);
-
        return 0;
 }
 
index 0f45416e4fcfe4cbe0ea9d1baa179f89cbfadeb7..b78de9879f4f2f95409425d14d2197bc38d0c6c1 100644 (file)
@@ -66,7 +66,6 @@ struct loop_device {
 
 struct loop_cmd {
        struct kthread_work work;
-       struct request *rq;
        bool use_aio; /* use AIO interface to handle I/O */
        atomic_t ref; /* only for aio */
        long ret;
index 07dc5419bd63bec43af2de5da0a485ec99bab7cd..8e8b04cc569a44222c1e3f4ee4a3a188455ddf04 100644 (file)
@@ -732,6 +732,7 @@ static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts)
  */
 enum {
        Opt_queue_depth,
+       Opt_lock_timeout,
        Opt_last_int,
        /* int args above */
        Opt_last_string,
@@ -740,11 +741,13 @@ enum {
        Opt_read_write,
        Opt_lock_on_read,
        Opt_exclusive,
+       Opt_notrim,
        Opt_err
 };
 
 static match_table_t rbd_opts_tokens = {
        {Opt_queue_depth, "queue_depth=%d"},
+       {Opt_lock_timeout, "lock_timeout=%d"},
        /* int args above */
        /* string args above */
        {Opt_read_only, "read_only"},
@@ -753,20 +756,25 @@ static match_table_t rbd_opts_tokens = {
        {Opt_read_write, "rw"},         /* Alternate spelling */
        {Opt_lock_on_read, "lock_on_read"},
        {Opt_exclusive, "exclusive"},
+       {Opt_notrim, "notrim"},
        {Opt_err, NULL}
 };
 
 struct rbd_options {
        int     queue_depth;
+       unsigned long   lock_timeout;
        bool    read_only;
        bool    lock_on_read;
        bool    exclusive;
+       bool    trim;
 };
 
 #define RBD_QUEUE_DEPTH_DEFAULT        BLKDEV_MAX_RQ
+#define RBD_LOCK_TIMEOUT_DEFAULT 0  /* no timeout */
 #define RBD_READ_ONLY_DEFAULT  false
 #define RBD_LOCK_ON_READ_DEFAULT false
 #define RBD_EXCLUSIVE_DEFAULT  false
+#define RBD_TRIM_DEFAULT       true
 
 static int parse_rbd_opts_token(char *c, void *private)
 {
@@ -796,6 +804,14 @@ static int parse_rbd_opts_token(char *c, void *private)
                }
                rbd_opts->queue_depth = intval;
                break;
+       case Opt_lock_timeout:
+               /* 0 is "wait forever" (i.e. infinite timeout) */
+               if (intval < 0 || intval > INT_MAX / 1000) {
+                       pr_err("lock_timeout out of range\n");
+                       return -EINVAL;
+               }
+               rbd_opts->lock_timeout = msecs_to_jiffies(intval * 1000);
+               break;
        case Opt_read_only:
                rbd_opts->read_only = true;
                break;
@@ -808,6 +824,9 @@ static int parse_rbd_opts_token(char *c, void *private)
        case Opt_exclusive:
                rbd_opts->exclusive = true;
                break;
+       case Opt_notrim:
+               rbd_opts->trim = false;
+               break;
        default:
                /* libceph prints "bad option" msg */
                return -EINVAL;
@@ -1392,7 +1411,7 @@ static bool rbd_img_is_write(struct rbd_img_request *img_req)
        case OBJ_OP_DISCARD:
                return true;
        default:
-               rbd_assert(0);
+               BUG();
        }
 }
 
@@ -2466,7 +2485,7 @@ again:
                }
                return false;
        default:
-               rbd_assert(0);
+               BUG();
        }
 }
 
@@ -2494,7 +2513,7 @@ static bool __rbd_obj_handle_request(struct rbd_obj_request *obj_req)
                }
                return false;
        default:
-               rbd_assert(0);
+               BUG();
        }
 }
 
@@ -3533,9 +3552,22 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
 /*
  * lock_rwsem must be held for read
  */
-static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
+static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire)
 {
        DEFINE_WAIT(wait);
+       unsigned long timeout;
+       int ret = 0;
+
+       if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags))
+               return -EBLACKLISTED;
+
+       if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED)
+               return 0;
+
+       if (!may_acquire) {
+               rbd_warn(rbd_dev, "exclusive lock required");
+               return -EROFS;
+       }
 
        do {
                /*
@@ -3547,12 +3579,22 @@ static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
                prepare_to_wait_exclusive(&rbd_dev->lock_waitq, &wait,
                                          TASK_UNINTERRUPTIBLE);
                up_read(&rbd_dev->lock_rwsem);
-               schedule();
+               timeout = schedule_timeout(ceph_timeout_jiffies(
+                                               rbd_dev->opts->lock_timeout));
                down_read(&rbd_dev->lock_rwsem);
-       } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED &&
-                !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags));
+               if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
+                       ret = -EBLACKLISTED;
+                       break;
+               }
+               if (!timeout) {
+                       rbd_warn(rbd_dev, "timed out waiting for lock");
+                       ret = -ETIMEDOUT;
+                       break;
+               }
+       } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED);
 
        finish_wait(&rbd_dev->lock_waitq, &wait);
+       return ret;
 }
 
 static void rbd_queue_workfn(struct work_struct *work)
@@ -3638,19 +3680,10 @@ static void rbd_queue_workfn(struct work_struct *work)
            (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read);
        if (must_be_locked) {
                down_read(&rbd_dev->lock_rwsem);
-               if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED &&
-                   !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
-                       if (rbd_dev->opts->exclusive) {
-                               rbd_warn(rbd_dev, "exclusive lock required");
-                               result = -EROFS;
-                               goto err_unlock;
-                       }
-                       rbd_wait_state_locked(rbd_dev);
-               }
-               if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
-                       result = -EBLACKLISTED;
+               result = rbd_wait_state_locked(rbd_dev,
+                                              !rbd_dev->opts->exclusive);
+               if (result)
                        goto err_unlock;
-               }
        }
 
        img_request = rbd_img_request_create(rbd_dev, op_type, snapc);
@@ -3902,7 +3935,8 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
 {
        struct gendisk *disk;
        struct request_queue *q;
-       u64 segment_size;
+       unsigned int objset_bytes =
+           rbd_dev->layout.object_size * rbd_dev->layout.stripe_count;
        int err;
 
        /* create gendisk info */
@@ -3942,20 +3976,19 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
        /* QUEUE_FLAG_ADD_RANDOM is off by default for blk-mq */
 
-       /* set io sizes to object size */
-       segment_size = rbd_obj_bytes(&rbd_dev->header);
-       blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE);
+       blk_queue_max_hw_sectors(q, objset_bytes >> SECTOR_SHIFT);
        q->limits.max_sectors = queue_max_hw_sectors(q);
        blk_queue_max_segments(q, USHRT_MAX);
        blk_queue_max_segment_size(q, UINT_MAX);
-       blk_queue_io_min(q, segment_size);
-       blk_queue_io_opt(q, segment_size);
+       blk_queue_io_min(q, objset_bytes);
+       blk_queue_io_opt(q, objset_bytes);
 
-       /* enable the discard support */
-       blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
-       q->limits.discard_granularity = segment_size;
-       blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE);
-       blk_queue_max_write_zeroes_sectors(q, segment_size / SECTOR_SIZE);
+       if (rbd_dev->opts->trim) {
+               blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
+               q->limits.discard_granularity = objset_bytes;
+               blk_queue_max_discard_sectors(q, objset_bytes >> SECTOR_SHIFT);
+               blk_queue_max_write_zeroes_sectors(q, objset_bytes >> SECTOR_SHIFT);
+       }
 
        if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC))
                q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES;
@@ -5179,8 +5212,10 @@ static int rbd_add_parse_args(const char *buf,
 
        rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
        rbd_opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
+       rbd_opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
        rbd_opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
        rbd_opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
+       rbd_opts->trim = RBD_TRIM_DEFAULT;
 
        copts = ceph_parse_options(options, mon_addrs,
                                        mon_addrs + mon_addrs_size - 1,
@@ -5216,6 +5251,8 @@ static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
 
 static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
 {
+       int ret;
+
        if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) {
                rbd_warn(rbd_dev, "exclusive-lock feature is not enabled");
                return -EINVAL;
@@ -5223,9 +5260,9 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
 
        /* FIXME: "rbd map --exclusive" should be in interruptible */
        down_read(&rbd_dev->lock_rwsem);
-       rbd_wait_state_locked(rbd_dev);
+       ret = rbd_wait_state_locked(rbd_dev, true);
        up_read(&rbd_dev->lock_rwsem);
-       if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
+       if (ret) {
                rbd_warn(rbd_dev, "failed to acquire exclusive lock");
                return -EROFS;
        }
index 64e066eba72e03abec38d49036d0f3677aafb2a3..0e31884a9519614398c1f1f6b048934a09ac5906 100644 (file)
@@ -110,7 +110,7 @@ struct iwm {
 /* Select values for swim_select and swim_readbit */
 
 #define READ_DATA_0    0x074
-#define TWOMEG_DRIVE   0x075
+#define ONEMEG_DRIVE   0x075
 #define SINGLE_SIDED   0x076
 #define DRIVE_PRESENT  0x077
 #define DISK_IN                0x170
@@ -118,9 +118,9 @@ struct iwm {
 #define TRACK_ZERO     0x172
 #define TACHO          0x173
 #define READ_DATA_1    0x174
-#define MFM_MODE       0x175
+#define GCR_MODE       0x175
 #define SEEK_COMPLETE  0x176
-#define ONEMEG_MEDIA   0x177
+#define TWOMEG_MEDIA   0x177
 
 /* Bits in handshake register */
 
@@ -612,7 +612,6 @@ static void setup_medium(struct floppy_state *fs)
                struct floppy_struct *g;
                fs->disk_in = 1;
                fs->write_protected = swim_readbit(base, WRITE_PROT);
-               fs->type = swim_readbit(base, ONEMEG_MEDIA);
 
                if (swim_track00(base))
                        printk(KERN_ERR
@@ -620,6 +619,9 @@ static void setup_medium(struct floppy_state *fs)
 
                swim_track00(base);
 
+               fs->type = swim_readbit(base, TWOMEG_MEDIA) ?
+                       HD_MEDIA : DD_MEDIA;
+               fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2;
                get_floppy_geometry(fs, 0, &g);
                fs->total_secs = g->size;
                fs->secpercyl = g->head * g->sect;
@@ -646,7 +648,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
 
        swim_write(base, setup, S_IBM_DRIVE  | S_FCLK_DIV2);
        udelay(10);
-       swim_drive(base, INTERNAL_DRIVE);
+       swim_drive(base, fs->location);
        swim_motor(base, ON);
        swim_action(base, SETMFM);
        if (fs->ejected)
@@ -656,6 +658,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
                goto out;
        }
 
+       set_capacity(fs->disk, fs->total_secs);
+
        if (mode & FMODE_NDELAY)
                return 0;
 
@@ -727,14 +731,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
                if (copy_to_user((void __user *) param, (void *) &floppy_type,
                                 sizeof(struct floppy_struct)))
                        return -EFAULT;
-               break;
-
-       default:
-               printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n",
-                      cmd);
-               return -ENOSYS;
+               return 0;
        }
-       return 0;
+       return -ENOTTY;
 }
 
 static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
@@ -795,7 +794,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        struct swim_priv *swd = data;
        int drive = (*part & 3);
 
-       if (drive > swd->floppy_count)
+       if (drive >= swd->floppy_count)
                return NULL;
 
        *part = 0;
@@ -813,10 +812,9 @@ static int swim_add_floppy(struct swim_priv *swd, enum drive_location location)
 
        swim_motor(base, OFF);
 
-       if (swim_readbit(base, SINGLE_SIDED))
-               fs->head_number = 1;
-       else
-               fs->head_number = 2;
+       fs->type = HD_MEDIA;
+       fs->head_number = 2;
+
        fs->ref_count = 0;
        fs->ejected = 1;
 
@@ -834,10 +832,12 @@ static int swim_floppy_init(struct swim_priv *swd)
        /* scan floppy drives */
 
        swim_drive(base, INTERNAL_DRIVE);
-       if (swim_readbit(base, DRIVE_PRESENT))
+       if (swim_readbit(base, DRIVE_PRESENT) &&
+           !swim_readbit(base, ONEMEG_DRIVE))
                swim_add_floppy(swd, INTERNAL_DRIVE);
        swim_drive(base, EXTERNAL_DRIVE);
-       if (swim_readbit(base, DRIVE_PRESENT))
+       if (swim_readbit(base, DRIVE_PRESENT) &&
+           !swim_readbit(base, ONEMEG_DRIVE))
                swim_add_floppy(swd, EXTERNAL_DRIVE);
 
        /* register floppy drives */
@@ -861,7 +861,6 @@ static int swim_floppy_init(struct swim_priv *swd)
                                                              &swd->lock);
                if (!swd->unit[drive].disk->queue) {
                        err = -ENOMEM;
-                       put_disk(swd->unit[drive].disk);
                        goto exit_put_disks;
                }
                blk_queue_bounce_limit(swd->unit[drive].disk->queue,
@@ -911,7 +910,7 @@ static int swim_probe(struct platform_device *dev)
                goto out;
        }
 
-       swim_base = ioremap(res->start, resource_size(res));
+       swim_base = (struct swim __iomem *)res->start;
        if (!swim_base) {
                ret = -ENOMEM;
                goto out_release_io;
@@ -923,7 +922,7 @@ static int swim_probe(struct platform_device *dev)
        if (!get_swim_mode(swim_base)) {
                printk(KERN_INFO "SWIM device not found !\n");
                ret = -ENODEV;
-               goto out_iounmap;
+               goto out_release_io;
        }
 
        /* set platform driver data */
@@ -931,7 +930,7 @@ static int swim_probe(struct platform_device *dev)
        swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL);
        if (!swd) {
                ret = -ENOMEM;
-               goto out_iounmap;
+               goto out_release_io;
        }
        platform_set_drvdata(dev, swd);
 
@@ -945,8 +944,6 @@ static int swim_probe(struct platform_device *dev)
 
 out_kfree:
        kfree(swd);
-out_iounmap:
-       iounmap(swim_base);
 out_release_io:
        release_mem_region(res->start, resource_size(res));
 out:
@@ -974,8 +971,6 @@ static int swim_remove(struct platform_device *dev)
        for (drive = 0; drive < swd->floppy_count; drive++)
                floppy_eject(&swd->unit[drive]);
 
-       iounmap(swd->base);
-
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (res)
                release_mem_region(res->start, resource_size(res));
index af51015d056eff1a6b1a2dfac264e30259c669d9..469541c1e51eed13b589f47b295f0e916ade4170 100644 (file)
@@ -148,7 +148,7 @@ struct swim3 {
 #define MOTOR_ON       2
 #define RELAX          3       /* also eject in progress */
 #define READ_DATA_0    4
-#define TWOMEG_DRIVE   5
+#define ONEMEG_DRIVE   5
 #define SINGLE_SIDED   6       /* drive or diskette is 4MB type? */
 #define DRIVE_PRESENT  7
 #define DISK_IN                8
@@ -156,9 +156,9 @@ struct swim3 {
 #define TRACK_ZERO     10
 #define TACHO          11
 #define READ_DATA_1    12
-#define MFM_MODE       13
+#define GCR_MODE       13
 #define SEEK_COMPLETE  14
-#define ONEMEG_MEDIA   15
+#define TWOMEG_MEDIA   15
 
 /* Definitions of values used in writing and formatting */
 #define DATA_ESCAPE    0x99
index d1c0b60e9326f5f5a0b0db56ac7d328283f27506..6dc177bf4c42f6fce5b9787072aba2b7aa94e98c 100644 (file)
@@ -33,6 +33,7 @@ config HISILICON_LPC
        bool "Support for ISA I/O space on HiSilicon Hip06/7"
        depends on ARM64 && (ARCH_HISI || COMPILE_TEST)
        select INDIRECT_PIO
+       select MFD_CORE if ACPI
        help
          Driver to enable I/O access to devices attached to the Low Pin
          Count bus on the HiSilicon Hip06/7 SoC.
index 8327478effd0b1c7da0b892a3b857cd6423e5a88..bfc566d3f31a40cf5b89d9284b2538644af68dee 100644 (file)
@@ -2371,7 +2371,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi,
        if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
                return media_changed(cdi, 1);
 
-       if ((unsigned int)arg >= cdi->capacity)
+       if (arg >= cdi->capacity)
                return -EINVAL;
 
        info = kmalloc(sizeof(*info), GFP_KERNEL);
index e027e7fa1472b6612a50b597a9c3b13bf94939a8..cd888d4ee605e0b9cf5f4970d34989d4b72f3b72 100644 (file)
 #include <linux/ptrace.h>
 #include <linux/workqueue.h>
 #include <linux/irq.h>
+#include <linux/ratelimit.h>
 #include <linux/syscalls.h>
 #include <linux/completion.h>
 #include <linux/uuid.h>
@@ -427,8 +428,9 @@ struct crng_state primary_crng = {
  * its value (from 0->1->2).
  */
 static int crng_init = 0;
-#define crng_ready() (likely(crng_init > 0))
+#define crng_ready() (likely(crng_init > 1))
 static int crng_init_cnt = 0;
+static unsigned long crng_global_init_time = 0;
 #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
 static void _extract_crng(struct crng_state *crng,
                          __u32 out[CHACHA20_BLOCK_WORDS]);
@@ -437,6 +439,16 @@ static void _crng_backtrack_protect(struct crng_state *crng,
 static void process_random_ready_list(void);
 static void _get_random_bytes(void *buf, int nbytes);
 
+static struct ratelimit_state unseeded_warning =
+       RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3);
+static struct ratelimit_state urandom_warning =
+       RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
+
+static int ratelimit_disable __read_mostly;
+
+module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
+MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
+
 /**********************************************************************
  *
  * OS independent entropy store.   Here are the functions which handle
@@ -787,6 +799,43 @@ static void crng_initialize(struct crng_state *crng)
        crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
 }
 
+#ifdef CONFIG_NUMA
+static void do_numa_crng_init(struct work_struct *work)
+{
+       int i;
+       struct crng_state *crng;
+       struct crng_state **pool;
+
+       pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
+       for_each_online_node(i) {
+               crng = kmalloc_node(sizeof(struct crng_state),
+                                   GFP_KERNEL | __GFP_NOFAIL, i);
+               spin_lock_init(&crng->lock);
+               crng_initialize(crng);
+               pool[i] = crng;
+       }
+       mb();
+       if (cmpxchg(&crng_node_pool, NULL, pool)) {
+               for_each_node(i)
+                       kfree(pool[i]);
+               kfree(pool);
+       }
+}
+
+static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init);
+
+static void numa_crng_init(void)
+{
+       schedule_work(&numa_crng_init_work);
+}
+#else
+static void numa_crng_init(void) {}
+#endif
+
+/*
+ * crng_fast_load() can be called by code in the interrupt service
+ * path.  So we can't afford to dilly-dally.
+ */
 static int crng_fast_load(const char *cp, size_t len)
 {
        unsigned long flags;
@@ -794,7 +843,7 @@ static int crng_fast_load(const char *cp, size_t len)
 
        if (!spin_trylock_irqsave(&primary_crng.lock, flags))
                return 0;
-       if (crng_ready()) {
+       if (crng_init != 0) {
                spin_unlock_irqrestore(&primary_crng.lock, flags);
                return 0;
        }
@@ -813,6 +862,51 @@ static int crng_fast_load(const char *cp, size_t len)
        return 1;
 }
 
+/*
+ * crng_slow_load() is called by add_device_randomness, which has two
+ * attributes.  (1) We can't trust the buffer passed to it is
+ * guaranteed to be unpredictable (so it might not have any entropy at
+ * all), and (2) it doesn't have the performance constraints of
+ * crng_fast_load().
+ *
+ * So we do something more comprehensive which is guaranteed to touch
+ * all of the primary_crng's state, and which uses a LFSR with a
+ * period of 255 as part of the mixing algorithm.  Finally, we do
+ * *not* advance crng_init_cnt since buffer we may get may be something
+ * like a fixed DMI table (for example), which might very well be
+ * unique to the machine, but is otherwise unvarying.
+ */
+static int crng_slow_load(const char *cp, size_t len)
+{
+       unsigned long           flags;
+       static unsigned char    lfsr = 1;
+       unsigned char           tmp;
+       unsigned                i, max = CHACHA20_KEY_SIZE;
+       const char *            src_buf = cp;
+       char *                  dest_buf = (char *) &primary_crng.state[4];
+
+       if (!spin_trylock_irqsave(&primary_crng.lock, flags))
+               return 0;
+       if (crng_init != 0) {
+               spin_unlock_irqrestore(&primary_crng.lock, flags);
+               return 0;
+       }
+       if (len > max)
+               max = len;
+
+       for (i = 0; i < max ; i++) {
+               tmp = lfsr;
+               lfsr >>= 1;
+               if (tmp & 1)
+                       lfsr ^= 0xE1;
+               tmp = dest_buf[i % CHACHA20_KEY_SIZE];
+               dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr;
+               lfsr += (tmp << 3) | (tmp >> 5);
+       }
+       spin_unlock_irqrestore(&primary_crng.lock, flags);
+       return 1;
+}
+
 static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
 {
        unsigned long   flags;
@@ -831,7 +925,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
                _crng_backtrack_protect(&primary_crng, buf.block,
                                        CHACHA20_KEY_SIZE);
        }
-       spin_lock_irqsave(&primary_crng.lock, flags);
+       spin_lock_irqsave(&crng->lock, flags);
        for (i = 0; i < 8; i++) {
                unsigned long   rv;
                if (!arch_get_random_seed_long(&rv) &&
@@ -841,13 +935,26 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
        }
        memzero_explicit(&buf, sizeof(buf));
        crng->init_time = jiffies;
-       spin_unlock_irqrestore(&primary_crng.lock, flags);
+       spin_unlock_irqrestore(&crng->lock, flags);
        if (crng == &primary_crng && crng_init < 2) {
                invalidate_batched_entropy();
+               numa_crng_init();
                crng_init = 2;
                process_random_ready_list();
                wake_up_interruptible(&crng_init_wait);
                pr_notice("random: crng init done\n");
+               if (unseeded_warning.missed) {
+                       pr_notice("random: %d get_random_xx warning(s) missed "
+                                 "due to ratelimiting\n",
+                                 unseeded_warning.missed);
+                       unseeded_warning.missed = 0;
+               }
+               if (urandom_warning.missed) {
+                       pr_notice("random: %d urandom warning(s) missed "
+                                 "due to ratelimiting\n",
+                                 urandom_warning.missed);
+                       urandom_warning.missed = 0;
+               }
        }
 }
 
@@ -856,8 +963,9 @@ static void _extract_crng(struct crng_state *crng,
 {
        unsigned long v, flags;
 
-       if (crng_init > 1 &&
-           time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))
+       if (crng_ready() &&
+           (time_after(crng_global_init_time, crng->init_time) ||
+            time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)))
                crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
        spin_lock_irqsave(&crng->lock, flags);
        if (arch_get_random_long(&v))
@@ -981,10 +1089,8 @@ void add_device_randomness(const void *buf, unsigned int size)
        unsigned long time = random_get_entropy() ^ jiffies;
        unsigned long flags;
 
-       if (!crng_ready()) {
-               crng_fast_load(buf, size);
-               return;
-       }
+       if (!crng_ready() && size)
+               crng_slow_load(buf, size);
 
        trace_add_device_randomness(size, _RET_IP_);
        spin_lock_irqsave(&input_pool.lock, flags);
@@ -1139,7 +1245,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
        fast_mix(fast_pool);
        add_interrupt_bench(cycles);
 
-       if (!crng_ready()) {
+       if (unlikely(crng_init == 0)) {
                if ((fast_pool->count >= 64) &&
                    crng_fast_load((char *) fast_pool->pool,
                                   sizeof(fast_pool->pool))) {
@@ -1489,8 +1595,9 @@ static void _warn_unseeded_randomness(const char *func_name, void *caller,
 #ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM
        print_once = true;
 #endif
-       pr_notice("random: %s called from %pS with crng_init=%d\n",
-                 func_name, caller, crng_init);
+       if (__ratelimit(&unseeded_warning))
+               pr_notice("random: %s called from %pS with crng_init=%d\n",
+                         func_name, caller, crng_init);
 }
 
 /*
@@ -1680,28 +1787,14 @@ static void init_std_data(struct entropy_store *r)
  */
 static int rand_initialize(void)
 {
-#ifdef CONFIG_NUMA
-       int i;
-       struct crng_state *crng;
-       struct crng_state **pool;
-#endif
-
        init_std_data(&input_pool);
        init_std_data(&blocking_pool);
        crng_initialize(&primary_crng);
-
-#ifdef CONFIG_NUMA
-       pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
-       for_each_online_node(i) {
-               crng = kmalloc_node(sizeof(struct crng_state),
-                                   GFP_KERNEL | __GFP_NOFAIL, i);
-               spin_lock_init(&crng->lock);
-               crng_initialize(crng);
-               pool[i] = crng;
+       crng_global_init_time = jiffies;
+       if (ratelimit_disable) {
+               urandom_warning.interval = 0;
+               unseeded_warning.interval = 0;
        }
-       mb();
-       crng_node_pool = pool;
-#endif
        return 0;
 }
 early_initcall(rand_initialize);
@@ -1769,9 +1862,10 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 
        if (!crng_ready() && maxwarn > 0) {
                maxwarn--;
-               printk(KERN_NOTICE "random: %s: uninitialized urandom read "
-                      "(%zd bytes read)\n",
-                      current->comm, nbytes);
+               if (__ratelimit(&urandom_warning))
+                       printk(KERN_NOTICE "random: %s: uninitialized "
+                              "urandom read (%zd bytes read)\n",
+                              current->comm, nbytes);
                spin_lock_irqsave(&primary_crng.lock, flags);
                crng_init_cnt = 0;
                spin_unlock_irqrestore(&primary_crng.lock, flags);
@@ -1875,6 +1969,14 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
                input_pool.entropy_count = 0;
                blocking_pool.entropy_count = 0;
                return 0;
+       case RNDRESEEDCRNG:
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               if (crng_init < 2)
+                       return -ENODATA;
+               crng_reseed(&primary_crng, NULL);
+               crng_global_init_time = jiffies - 1;
+               return 0;
        default:
                return -EINVAL;
        }
@@ -2212,7 +2314,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
 {
        struct entropy_store *poolp = &input_pool;
 
-       if (!crng_ready()) {
+       if (unlikely(crng_init == 0)) {
                crng_fast_load(buffer, count);
                return;
        }
index 468f0613401268205762709e2382b5444a06ed91..21085515814f23f09e6fbea4cb49d4d3d99d86c7 100644 (file)
@@ -422,7 +422,7 @@ static void reclaim_dma_bufs(void)
        }
 }
 
-static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
+static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size,
                                     int pages)
 {
        struct port_buffer *buf;
@@ -445,16 +445,16 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
                return buf;
        }
 
-       if (is_rproc_serial(vq->vdev)) {
+       if (is_rproc_serial(vdev)) {
                /*
                 * Allocate DMA memory from ancestor. When a virtio
                 * device is created by remoteproc, the DMA memory is
                 * associated with the grandparent device:
                 * vdev => rproc => platform-dev.
                 */
-               if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
+               if (!vdev->dev.parent || !vdev->dev.parent->parent)
                        goto free_buf;
-               buf->dev = vq->vdev->dev.parent->parent;
+               buf->dev = vdev->dev.parent->parent;
 
                /* Increase device refcnt to avoid freeing it */
                get_device(buf->dev);
@@ -838,7 +838,7 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
 
        count = min((size_t)(32 * 1024), count);
 
-       buf = alloc_buf(port->out_vq, count, 0);
+       buf = alloc_buf(port->portdev->vdev, count, 0);
        if (!buf)
                return -ENOMEM;
 
@@ -957,7 +957,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
        if (ret < 0)
                goto error_out;
 
-       buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
+       buf = alloc_buf(port->portdev->vdev, 0, pipe->nrbufs);
        if (!buf) {
                ret = -ENOMEM;
                goto error_out;
@@ -1374,7 +1374,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
 
        nr_added_bufs = 0;
        do {
-               buf = alloc_buf(vq, PAGE_SIZE, 0);
+               buf = alloc_buf(vq->vdev, PAGE_SIZE, 0);
                if (!buf)
                        break;
 
@@ -1402,7 +1402,6 @@ static int add_port(struct ports_device *portdev, u32 id)
 {
        char debugfs_name[16];
        struct port *port;
-       struct port_buffer *buf;
        dev_t devt;
        unsigned int nr_added_bufs;
        int err;
@@ -1513,8 +1512,6 @@ static int add_port(struct ports_device *portdev, u32 id)
        return 0;
 
 free_inbufs:
-       while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
-               free_buf(buf, true);
 free_device:
        device_destroy(pdrvdata.class, port->dev->devt);
 free_cdev:
@@ -1539,34 +1536,14 @@ static void remove_port(struct kref *kref)
 
 static void remove_port_data(struct port *port)
 {
-       struct port_buffer *buf;
-
        spin_lock_irq(&port->inbuf_lock);
        /* Remove unused data this port might have received. */
        discard_port_data(port);
        spin_unlock_irq(&port->inbuf_lock);
 
-       /* Remove buffers we queued up for the Host to send us data in. */
-       do {
-               spin_lock_irq(&port->inbuf_lock);
-               buf = virtqueue_detach_unused_buf(port->in_vq);
-               spin_unlock_irq(&port->inbuf_lock);
-               if (buf)
-                       free_buf(buf, true);
-       } while (buf);
-
        spin_lock_irq(&port->outvq_lock);
        reclaim_consumed_buffers(port);
        spin_unlock_irq(&port->outvq_lock);
-
-       /* Free pending buffers from the out-queue. */
-       do {
-               spin_lock_irq(&port->outvq_lock);
-               buf = virtqueue_detach_unused_buf(port->out_vq);
-               spin_unlock_irq(&port->outvq_lock);
-               if (buf)
-                       free_buf(buf, true);
-       } while (buf);
 }
 
 /*
@@ -1791,13 +1768,24 @@ static void control_work_handler(struct work_struct *work)
        spin_unlock(&portdev->c_ivq_lock);
 }
 
+static void flush_bufs(struct virtqueue *vq, bool can_sleep)
+{
+       struct port_buffer *buf;
+       unsigned int len;
+
+       while ((buf = virtqueue_get_buf(vq, &len)))
+               free_buf(buf, can_sleep);
+}
+
 static void out_intr(struct virtqueue *vq)
 {
        struct port *port;
 
        port = find_port_by_vq(vq->vdev->priv, vq);
-       if (!port)
+       if (!port) {
+               flush_bufs(vq, false);
                return;
+       }
 
        wake_up_interruptible(&port->waitqueue);
 }
@@ -1808,8 +1796,10 @@ static void in_intr(struct virtqueue *vq)
        unsigned long flags;
 
        port = find_port_by_vq(vq->vdev->priv, vq);
-       if (!port)
+       if (!port) {
+               flush_bufs(vq, false);
                return;
+       }
 
        spin_lock_irqsave(&port->inbuf_lock, flags);
        port->inbuf = get_inbuf(port);
@@ -1984,24 +1974,54 @@ static const struct file_operations portdev_fops = {
 
 static void remove_vqs(struct ports_device *portdev)
 {
+       struct virtqueue *vq;
+
+       virtio_device_for_each_vq(portdev->vdev, vq) {
+               struct port_buffer *buf;
+
+               flush_bufs(vq, true);
+               while ((buf = virtqueue_detach_unused_buf(vq)))
+                       free_buf(buf, true);
+       }
        portdev->vdev->config->del_vqs(portdev->vdev);
        kfree(portdev->in_vqs);
        kfree(portdev->out_vqs);
 }
 
-static void remove_controlq_data(struct ports_device *portdev)
+static void virtcons_remove(struct virtio_device *vdev)
 {
-       struct port_buffer *buf;
-       unsigned int len;
+       struct ports_device *portdev;
+       struct port *port, *port2;
 
-       if (!use_multiport(portdev))
-               return;
+       portdev = vdev->priv;
 
-       while ((buf = virtqueue_get_buf(portdev->c_ivq, &len)))
-               free_buf(buf, true);
+       spin_lock_irq(&pdrvdata_lock);
+       list_del(&portdev->list);
+       spin_unlock_irq(&pdrvdata_lock);
 
-       while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq)))
-               free_buf(buf, true);
+       /* Disable interrupts for vqs */
+       vdev->config->reset(vdev);
+       /* Finish up work that's lined up */
+       if (use_multiport(portdev))
+               cancel_work_sync(&portdev->control_work);
+       else
+               cancel_work_sync(&portdev->config_work);
+
+       list_for_each_entry_safe(port, port2, &portdev->ports, list)
+               unplug_port(port);
+
+       unregister_chrdev(portdev->chr_major, "virtio-portsdev");
+
+       /*
+        * When yanking out a device, we immediately lose the
+        * (device-side) queues.  So there's no point in keeping the
+        * guest side around till we drop our final reference.  This
+        * also means that any ports which are in an open state will
+        * have to just stop using the port, as the vqs are going
+        * away.
+        */
+       remove_vqs(portdev);
+       kfree(portdev);
 }
 
 /*
@@ -2070,6 +2090,7 @@ static int virtcons_probe(struct virtio_device *vdev)
 
        spin_lock_init(&portdev->ports_lock);
        INIT_LIST_HEAD(&portdev->ports);
+       INIT_LIST_HEAD(&portdev->list);
 
        virtio_device_ready(portdev->vdev);
 
@@ -2087,8 +2108,15 @@ static int virtcons_probe(struct virtio_device *vdev)
                if (!nr_added_bufs) {
                        dev_err(&vdev->dev,
                                "Error allocating buffers for control queue\n");
-                       err = -ENOMEM;
-                       goto free_vqs;
+                       /*
+                        * The host might want to notify mgmt sw about device
+                        * add failure.
+                        */
+                       __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
+                                          VIRTIO_CONSOLE_DEVICE_READY, 0);
+                       /* Device was functional: we need full cleanup. */
+                       virtcons_remove(vdev);
+                       return -ENOMEM;
                }
        } else {
                /*
@@ -2119,11 +2147,6 @@ static int virtcons_probe(struct virtio_device *vdev)
 
        return 0;
 
-free_vqs:
-       /* The host might want to notify mgmt sw about device add failure */
-       __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
-                          VIRTIO_CONSOLE_DEVICE_READY, 0);
-       remove_vqs(portdev);
 free_chrdev:
        unregister_chrdev(portdev->chr_major, "virtio-portsdev");
 free:
@@ -2132,43 +2155,6 @@ fail:
        return err;
 }
 
-static void virtcons_remove(struct virtio_device *vdev)
-{
-       struct ports_device *portdev;
-       struct port *port, *port2;
-
-       portdev = vdev->priv;
-
-       spin_lock_irq(&pdrvdata_lock);
-       list_del(&portdev->list);
-       spin_unlock_irq(&pdrvdata_lock);
-
-       /* Disable interrupts for vqs */
-       vdev->config->reset(vdev);
-       /* Finish up work that's lined up */
-       if (use_multiport(portdev))
-               cancel_work_sync(&portdev->control_work);
-       else
-               cancel_work_sync(&portdev->config_work);
-
-       list_for_each_entry_safe(port, port2, &portdev->ports, list)
-               unplug_port(port);
-
-       unregister_chrdev(portdev->chr_major, "virtio-portsdev");
-
-       /*
-        * When yanking out a device, we immediately lose the
-        * (device-side) queues.  So there's no point in keeping the
-        * guest side around till we drop our final reference.  This
-        * also means that any ports which are in an open state will
-        * have to just stop using the port, as the vqs are going
-        * away.
-        */
-       remove_controlq_data(portdev);
-       remove_vqs(portdev);
-       kfree(portdev);
-}
-
 static struct virtio_device_id id_table[] = {
        { VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
        { 0 },
@@ -2209,7 +2195,6 @@ static int virtcons_freeze(struct virtio_device *vdev)
         */
        if (use_multiport(portdev))
                virtqueue_disable_cb(portdev->c_ivq);
-       remove_controlq_data(portdev);
 
        list_for_each_entry(port, &portdev->ports, list) {
                virtqueue_disable_cb(port->in_vq);
index 9ee2888275c1954d433a08636d27bb25d83c1eb1..8e8a09755d10431e27f42479a08c8a6fb842ab0c 100644 (file)
@@ -133,6 +133,14 @@ config VT8500_TIMER
        help
          Enables support for the VT8500 driver.
 
+config NPCM7XX_TIMER
+       bool "NPCM7xx timer driver" if COMPILE_TEST
+       depends on HAS_IOMEM
+       select CLKSRC_MMIO
+       help
+         Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx architecture,
+         While TIMER0 serves as clockevent and TIMER1 serves as clocksource.
+
 config CADENCE_TTC_TIMER
        bool "Cadence TTC timer driver" if COMPILE_TEST
        depends on COMMON_CLK
index e8e76dfef00bbc500d5e8a9b06cb0947b6518e82..00caf37e52f9c6cad3913c2c0b18bd32aa20756a 100644 (file)
@@ -56,6 +56,7 @@ obj-$(CONFIG_CLKSRC_NPS)      += timer-nps.o
 obj-$(CONFIG_OXNAS_RPS_TIMER)  += timer-oxnas-rps.o
 obj-$(CONFIG_OWL_TIMER)                += owl-timer.o
 obj-$(CONFIG_SPRD_TIMER)       += timer-sprd.o
+obj-$(CONFIG_NPCM7XX_TIMER)    += timer-npcm7xx.o
 
 obj-$(CONFIG_ARC_TIMERS)               += arc_timer.o
 obj-$(CONFIG_ARM_ARCH_TIMER)           += arm_arch_timer.o
index 21bffdcb2f202640391fd54e1c5ec1c2c53835e4..6c8318470b48774efefd09437dac7cb365c92d33 100644 (file)
 #include <linux/of_irq.h>
 #include <linux/sched_clock.h>
 
+#define TPM_PARAM                      0x4
+#define TPM_PARAM_WIDTH_SHIFT          16
+#define TPM_PARAM_WIDTH_MASK           (0xff << 16)
 #define TPM_SC                         0x10
 #define TPM_SC_CMOD_INC_PER_CNT                (0x1 << 3)
 #define TPM_SC_CMOD_DIV_DEFAULT                0x3
+#define TPM_SC_CMOD_DIV_MAX            0x7
+#define TPM_SC_TOF_MASK                        (0x1 << 7)
 #define TPM_CNT                                0x14
 #define TPM_MOD                                0x18
 #define TPM_STATUS                     0x1c
 #define TPM_C0SC_MODE_SHIFT            2
 #define TPM_C0SC_MODE_MASK             0x3c
 #define TPM_C0SC_MODE_SW_COMPARE       0x4
+#define TPM_C0SC_CHF_MASK              (0x1 << 7)
 #define TPM_C0V                                0x24
 
+static int counter_width;
+static int rating;
 static void __iomem *timer_base;
 static struct clock_event_device clockevent_tpm;
 
@@ -83,10 +91,11 @@ static int __init tpm_clocksource_init(unsigned long rate)
        tpm_delay_timer.freq = rate;
        register_current_timer_delay(&tpm_delay_timer);
 
-       sched_clock_register(tpm_read_sched_clock, 32, rate);
+       sched_clock_register(tpm_read_sched_clock, counter_width, rate);
 
        return clocksource_mmio_init(timer_base + TPM_CNT, "imx-tpm",
-                                    rate, 200, 32, clocksource_mmio_readl_up);
+                                    rate, rating, counter_width,
+                                    clocksource_mmio_readl_up);
 }
 
 static int tpm_set_next_event(unsigned long delta,
@@ -105,7 +114,7 @@ static int tpm_set_next_event(unsigned long delta,
         * of writing CNT registers which may cause the min_delta event got
         * missed, so we need add a ETIME check here in case it happened.
         */
-       return (int)((next - now) <= 0) ? -ETIME : 0;
+       return (int)(next - now) <= 0 ? -ETIME : 0;
 }
 
 static int tpm_set_state_oneshot(struct clock_event_device *evt)
@@ -139,7 +148,6 @@ static struct clock_event_device clockevent_tpm = {
        .set_state_oneshot      = tpm_set_state_oneshot,
        .set_next_event         = tpm_set_next_event,
        .set_state_shutdown     = tpm_set_state_shutdown,
-       .rating                 = 200,
 };
 
 static int __init tpm_clockevent_init(unsigned long rate, int irq)
@@ -149,10 +157,11 @@ static int __init tpm_clockevent_init(unsigned long rate, int irq)
        ret = request_irq(irq, tpm_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
                          "i.MX7ULP TPM Timer", &clockevent_tpm);
 
+       clockevent_tpm.rating = rating;
        clockevent_tpm.cpumask = cpumask_of(0);
        clockevent_tpm.irq = irq;
-       clockevents_config_and_register(&clockevent_tpm,
-                                       rate, 300, 0xfffffffe);
+       clockevents_config_and_register(&clockevent_tpm, rate, 300,
+                                       GENMASK(counter_width - 1, 1));
 
        return ret;
 }
@@ -179,7 +188,7 @@ static int __init tpm_timer_init(struct device_node *np)
        ipg = of_clk_get_by_name(np, "ipg");
        per = of_clk_get_by_name(np, "per");
        if (IS_ERR(ipg) || IS_ERR(per)) {
-               pr_err("tpm: failed to get igp or per clk\n");
+               pr_err("tpm: failed to get ipg or per clk\n");
                ret = -ENODEV;
                goto err_clk_get;
        }
@@ -197,6 +206,11 @@ static int __init tpm_timer_init(struct device_node *np)
                goto err_per_clk_enable;
        }
 
+       counter_width = (readl(timer_base + TPM_PARAM) & TPM_PARAM_WIDTH_MASK)
+               >> TPM_PARAM_WIDTH_SHIFT;
+       /* use rating 200 for 32-bit counter and 150 for 16-bit counter */
+       rating = counter_width == 0x20 ? 200 : 150;
+
        /*
         * Initialize tpm module to a known state
         * 1) Counter disabled
@@ -205,16 +219,25 @@ static int __init tpm_timer_init(struct device_node *np)
         * 4) Channel0 disabled
         * 5) DMA transfers disabled
         */
+       /* make sure counter is disabled */
        writel(0, timer_base + TPM_SC);
+       /* TOF is W1C */
+       writel(TPM_SC_TOF_MASK, timer_base + TPM_SC);
        writel(0, timer_base + TPM_CNT);
-       writel(0, timer_base + TPM_C0SC);
+       /* CHF is W1C */
+       writel(TPM_C0SC_CHF_MASK, timer_base + TPM_C0SC);
 
-       /* increase per cnt, div 8 by default */
-       writel(TPM_SC_CMOD_INC_PER_CNT | TPM_SC_CMOD_DIV_DEFAULT,
+       /*
+        * increase per cnt,
+        * div 8 for 32-bit counter and div 128 for 16-bit counter
+        */
+       writel(TPM_SC_CMOD_INC_PER_CNT |
+               (counter_width == 0x20 ?
+               TPM_SC_CMOD_DIV_DEFAULT : TPM_SC_CMOD_DIV_MAX),
                     timer_base + TPM_SC);
 
        /* set MOD register to maximum for free running mode */
-       writel(0xffffffff, timer_base + TPM_MOD);
+       writel(GENMASK(counter_width - 1, 0), timer_base + TPM_MOD);
 
        rate = clk_get_rate(per) >> 3;
        ret = tpm_clocksource_init(rate);
diff --git a/drivers/clocksource/timer-npcm7xx.c b/drivers/clocksource/timer-npcm7xx.c
new file mode 100644 (file)
index 0000000..7a9bb55
--- /dev/null
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2014-2018 Nuvoton Technologies tomer.maimon@nuvoton.com
+ * All rights reserved.
+ *
+ * Copyright 2017 Google, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include "timer-of.h"
+
+/* Timers registers */
+#define NPCM7XX_REG_TCSR0      0x0 /* Timer 0 Control and Status Register */
+#define NPCM7XX_REG_TICR0      0x8 /* Timer 0 Initial Count Register */
+#define NPCM7XX_REG_TCSR1      0x4 /* Timer 1 Control and Status Register */
+#define NPCM7XX_REG_TICR1      0xc /* Timer 1 Initial Count Register */
+#define NPCM7XX_REG_TDR1       0x14 /* Timer 1 Data Register */
+#define NPCM7XX_REG_TISR       0x18 /* Timer Interrupt Status Register */
+
+/* Timers control */
+#define NPCM7XX_Tx_RESETINT            0x1f
+#define NPCM7XX_Tx_PERIOD              BIT(27)
+#define NPCM7XX_Tx_INTEN               BIT(29)
+#define NPCM7XX_Tx_COUNTEN             BIT(30)
+#define NPCM7XX_Tx_ONESHOT             0x0
+#define NPCM7XX_Tx_OPER                        GENMASK(3, 27)
+#define NPCM7XX_Tx_MIN_PRESCALE                0x1
+#define NPCM7XX_Tx_TDR_MASK_BITS       24
+#define NPCM7XX_Tx_MAX_CNT             0xFFFFFF
+#define NPCM7XX_T0_CLR_INT             0x1
+#define NPCM7XX_Tx_CLR_CSR             0x0
+
+/* Timers operating mode */
+#define NPCM7XX_START_PERIODIC_Tx (NPCM7XX_Tx_PERIOD | NPCM7XX_Tx_COUNTEN | \
+                                       NPCM7XX_Tx_INTEN | \
+                                       NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_START_ONESHOT_Tx (NPCM7XX_Tx_ONESHOT | NPCM7XX_Tx_COUNTEN | \
+                                       NPCM7XX_Tx_INTEN | \
+                                       NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_START_Tx (NPCM7XX_Tx_COUNTEN | NPCM7XX_Tx_PERIOD | \
+                               NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_DEFAULT_CSR (NPCM7XX_Tx_CLR_CSR | NPCM7XX_Tx_MIN_PRESCALE)
+
+static int npcm7xx_timer_resume(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val |= NPCM7XX_Tx_COUNTEN;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_timer_shutdown(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val &= ~NPCM7XX_Tx_COUNTEN;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_timer_oneshot(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val &= ~NPCM7XX_Tx_OPER;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val |= NPCM7XX_START_ONESHOT_Tx;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_timer_periodic(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val &= ~NPCM7XX_Tx_OPER;
+
+       writel(timer_of_period(to), timer_of_base(to) + NPCM7XX_REG_TICR0);
+       val |= NPCM7XX_START_PERIODIC_Tx;
+
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_clockevent_set_next_event(unsigned long evt,
+               struct clock_event_device *clk)
+{
+       struct timer_of *to = to_timer_of(clk);
+       u32 val;
+
+       writel(evt, timer_of_base(to) + NPCM7XX_REG_TICR0);
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val |= NPCM7XX_START_Tx;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static irqreturn_t npcm7xx_timer0_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+       struct timer_of *to = to_timer_of(evt);
+
+       writel(NPCM7XX_T0_CLR_INT, timer_of_base(to) + NPCM7XX_REG_TISR);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct timer_of npcm7xx_to = {
+       .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+
+       .clkevt = {
+               .name               = "npcm7xx-timer0",
+               .features           = CLOCK_EVT_FEAT_PERIODIC |
+                                     CLOCK_EVT_FEAT_ONESHOT,
+               .set_next_event     = npcm7xx_clockevent_set_next_event,
+               .set_state_shutdown = npcm7xx_timer_shutdown,
+               .set_state_periodic = npcm7xx_timer_periodic,
+               .set_state_oneshot  = npcm7xx_timer_oneshot,
+               .tick_resume        = npcm7xx_timer_resume,
+               .rating             = 300,
+       },
+
+       .of_irq = {
+               .handler = npcm7xx_timer0_interrupt,
+               .flags = IRQF_TIMER | IRQF_IRQPOLL,
+       },
+};
+
+static void __init npcm7xx_clockevents_init(void)
+{
+       writel(NPCM7XX_DEFAULT_CSR,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR0);
+
+       writel(NPCM7XX_Tx_RESETINT,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TISR);
+
+       npcm7xx_to.clkevt.cpumask = cpumask_of(0);
+       clockevents_config_and_register(&npcm7xx_to.clkevt,
+                                       timer_of_rate(&npcm7xx_to),
+                                       0x1, NPCM7XX_Tx_MAX_CNT);
+}
+
+static void __init npcm7xx_clocksource_init(void)
+{
+       u32 val;
+
+       writel(NPCM7XX_DEFAULT_CSR,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
+       writel(NPCM7XX_Tx_MAX_CNT,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TICR1);
+
+       val = readl(timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
+       val |= NPCM7XX_START_Tx;
+       writel(val, timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
+
+       clocksource_mmio_init(timer_of_base(&npcm7xx_to) +
+                               NPCM7XX_REG_TDR1,
+                               "npcm7xx-timer1", timer_of_rate(&npcm7xx_to),
+                               200, (unsigned int)NPCM7XX_Tx_TDR_MASK_BITS,
+                               clocksource_mmio_readl_down);
+}
+
+static int __init npcm7xx_timer_init(struct device_node *np)
+{
+       int ret;
+
+       ret = timer_of_init(np, &npcm7xx_to);
+       if (ret)
+               return ret;
+
+       /* Clock input is divided by PRESCALE + 1 before it is fed */
+       /* to the counter */
+       npcm7xx_to.of_clk.rate = npcm7xx_to.of_clk.rate /
+               (NPCM7XX_Tx_MIN_PRESCALE + 1);
+
+       npcm7xx_clocksource_init();
+       npcm7xx_clockevents_init();
+
+       pr_info("Enabling NPCM7xx clocksource timer base: %px, IRQ: %d ",
+               timer_of_base(&npcm7xx_to), timer_of_irq(&npcm7xx_to));
+
+       return 0;
+}
+
+TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);
+
index 7f56fe5183f27817c0e818cf216890b520562243..de55c7d57438c8e094a49d2d1d0b9240c20971ab 100644 (file)
@@ -71,16 +71,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ
 
          Say Y, if you have a Broadcom SoC with AVS support for DFS or DVFS.
 
-config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
-       bool "Broadcom STB AVS CPUfreq driver sysfs debug capability"
-       depends on ARM_BRCMSTB_AVS_CPUFREQ
-       help
-         Enabling this option turns on debug support via sysfs under
-         /sys/kernel/debug/brcmstb-avs-cpufreq. It is possible to read all and
-         write some AVS mailbox registers through sysfs entries.
-
-         If in doubt, say N.
-
 config ARM_EXYNOS5440_CPUFREQ
        tristate "SAMSUNG EXYNOS5440"
        depends on SOC_EXYNOS5440
index 6cdac1aaf23c5de81869f15d5591bb23f2beacd2..b07559b9ed99a6e256ba5afce20b5e156304ade7 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/semaphore.h>
 
-#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
-#include <linux/ctype.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#endif
-
 /* Max number of arguments AVS calls take */
 #define AVS_MAX_CMD_ARGS       4
 /*
@@ -182,88 +175,11 @@ struct private_data {
        void __iomem *base;
        void __iomem *avs_intr_base;
        struct device *dev;
-#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
-       struct dentry *debugfs;
-#endif
        struct completion done;
        struct semaphore sem;
        struct pmap pmap;
 };
 
-#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
-
-enum debugfs_format {
-       DEBUGFS_NORMAL,
-       DEBUGFS_FLOAT,
-       DEBUGFS_REV,
-};
-
-struct debugfs_data {
-       struct debugfs_entry *entry;
-       struct private_data *priv;
-};
-
-struct debugfs_entry {
-       char *name;
-       u32 offset;
-       fmode_t mode;
-       enum debugfs_format format;
-};
-
-#define DEBUGFS_ENTRY(name, mode, format)      { \
-       #name, AVS_MBOX_##name, mode, format \
-}
-
-/*
- * These are used for debugfs only. Otherwise we use AVS_MBOX_PARAM() directly.
- */
-#define AVS_MBOX_PARAM1                AVS_MBOX_PARAM(0)
-#define AVS_MBOX_PARAM2                AVS_MBOX_PARAM(1)
-#define AVS_MBOX_PARAM3                AVS_MBOX_PARAM(2)
-#define AVS_MBOX_PARAM4                AVS_MBOX_PARAM(3)
-
-/*
- * This table stores the name, access permissions and offset for each hardware
- * register and is used to generate debugfs entries.
- */
-static struct debugfs_entry debugfs_entries[] = {
-       DEBUGFS_ENTRY(COMMAND, S_IWUSR, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(STATUS, S_IWUSR, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(VOLTAGE0, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(TEMP0, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(PV0, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(MV0, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(PARAM1, S_IWUSR, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(PARAM2, S_IWUSR, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(PARAM3, S_IWUSR, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(PARAM4, S_IWUSR, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(REVISION, 0, DEBUGFS_REV),
-       DEBUGFS_ENTRY(PSTATE, 0, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(HEARTBEAT, 0, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(MAGIC, S_IWUSR, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(SIGMA_HVT, 0, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(SIGMA_SVT, 0, DEBUGFS_NORMAL),
-       DEBUGFS_ENTRY(VOLTAGE1, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(TEMP1, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(PV1, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(MV1, 0, DEBUGFS_FLOAT),
-       DEBUGFS_ENTRY(FREQUENCY, 0, DEBUGFS_NORMAL),
-};
-
-static int brcm_avs_target_index(struct cpufreq_policy *, unsigned int);
-
-static char *__strtolower(char *s)
-{
-       char *p;
-
-       for (p = s; *p; p++)
-               *p = tolower(*p);
-
-       return s;
-}
-
-#endif /* CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG */
-
 static void __iomem *__map_region(const char *name)
 {
        struct device_node *np;
@@ -516,238 +432,6 @@ brcm_avs_get_freq_table(struct device *dev, struct private_data *priv)
        return table;
 }
 
-#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG
-
-#define MANT(x)        (unsigned int)(abs((x)) / 1000)
-#define FRAC(x)        (unsigned int)(abs((x)) - abs((x)) / 1000 * 1000)
-
-static int brcm_avs_debug_show(struct seq_file *s, void *data)
-{
-       struct debugfs_data *dbgfs = s->private;
-       void __iomem *base;
-       u32 val, offset;
-
-       if (!dbgfs) {
-               seq_puts(s, "No device pointer\n");
-               return 0;
-       }
-
-       base = dbgfs->priv->base;
-       offset = dbgfs->entry->offset;
-       val = readl(base + offset);
-       switch (dbgfs->entry->format) {
-       case DEBUGFS_NORMAL:
-               seq_printf(s, "%u\n", val);
-               break;
-       case DEBUGFS_FLOAT:
-               seq_printf(s, "%d.%03d\n", MANT(val), FRAC(val));
-               break;
-       case DEBUGFS_REV:
-               seq_printf(s, "%c.%c.%c.%c\n", (val >> 24 & 0xff),
-                          (val >> 16 & 0xff), (val >> 8 & 0xff),
-                          val & 0xff);
-               break;
-       }
-       seq_printf(s, "0x%08x\n", val);
-
-       return 0;
-}
-
-#undef MANT
-#undef FRAC
-
-static ssize_t brcm_avs_seq_write(struct file *file, const char __user *buf,
-                                 size_t size, loff_t *ppos)
-{
-       struct seq_file *s = file->private_data;
-       struct debugfs_data *dbgfs = s->private;
-       struct private_data *priv = dbgfs->priv;
-       void __iomem *base, *avs_intr_base;
-       bool use_issue_command = false;
-       unsigned long val, offset;
-       char str[128];
-       int ret;
-       char *str_ptr = str;
-
-       if (size >= sizeof(str))
-               return -E2BIG;
-
-       memset(str, 0, sizeof(str));
-       ret = copy_from_user(str, buf, size);
-       if (ret)
-               return ret;
-
-       base = priv->base;
-       avs_intr_base = priv->avs_intr_base;
-       offset = dbgfs->entry->offset;
-       /*
-        * Special case writing to "command" entry only: if the string starts
-        * with a 'c', we use the driver's __issue_avs_command() function.
-        * Otherwise, we perform a raw write. This should allow testing of raw
-        * access as well as using the higher level function. (Raw access
-        * doesn't clear the firmware return status after issuing the command.)
-        */
-       if (str_ptr[0] == 'c' && offset == AVS_MBOX_COMMAND) {
-               use_issue_command = true;
-               str_ptr++;
-       }
-       if (kstrtoul(str_ptr, 0, &val) != 0)
-               return -EINVAL;
-
-       /*
-        * Setting the P-state is a special case. We need to update the CPU
-        * frequency we report.
-        */
-       if (val == AVS_CMD_SET_PSTATE) {
-               struct cpufreq_policy *policy;
-               unsigned int pstate;
-
-               policy = cpufreq_cpu_get(smp_processor_id());
-               /* Read back the P-state we are about to set */
-               pstate = readl(base + AVS_MBOX_PARAM(0));
-               if (use_issue_command) {
-                       ret = brcm_avs_target_index(policy, pstate);
-                       return ret ? ret : size;
-               }
-               policy->cur = policy->freq_table[pstate].frequency;
-       }
-
-       if (use_issue_command) {
-               ret = __issue_avs_command(priv, val, false, NULL);
-       } else {
-               /* Locking here is not perfect, but is only for debug. */
-               ret = down_interruptible(&priv->sem);
-               if (ret)
-                       return ret;
-
-               writel(val, base + offset);
-               /* We have to wake up the firmware to process a command. */
-               if (offset == AVS_MBOX_COMMAND)
-                       writel(AVS_CPU_L2_INT_MASK,
-                              avs_intr_base + AVS_CPU_L2_SET0);
-               up(&priv->sem);
-       }
-
-       return ret ? ret : size;
-}
-
-static struct debugfs_entry *__find_debugfs_entry(const char *name)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(debugfs_entries); i++)
-               if (strcasecmp(debugfs_entries[i].name, name) == 0)
-                       return &debugfs_entries[i];
-
-       return NULL;
-}
-
-static int brcm_avs_debug_open(struct inode *inode, struct file *file)
-{
-       struct debugfs_data *data;
-       fmode_t fmode;
-       int ret;
-
-       /*
-        * seq_open(), which is called by single_open(), clears "write" access.
-        * We need write access to some files, so we preserve our access mode
-        * and restore it.
-        */
-       fmode = file->f_mode;
-       /*
-        * Check access permissions even for root. We don't want to be writing
-        * to read-only registers. Access for regular users has already been
-        * checked by the VFS layer.
-        */
-       if ((fmode & FMODE_WRITER) && !(inode->i_mode & S_IWUSR))
-               return -EACCES;
-
-       data = kmalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-       /*
-        * We use the same file system operations for all our debug files. To
-        * produce specific output, we look up the file name upon opening a
-        * debugfs entry and map it to a memory offset. This offset is then used
-        * in the generic "show" function to read a specific register.
-        */
-       data->entry = __find_debugfs_entry(file->f_path.dentry->d_iname);
-       data->priv = inode->i_private;
-
-       ret = single_open(file, brcm_avs_debug_show, data);
-       if (ret)
-               kfree(data);
-       file->f_mode = fmode;
-
-       return ret;
-}
-
-static int brcm_avs_debug_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq_priv = file->private_data;
-       struct debugfs_data *data = seq_priv->private;
-
-       kfree(data);
-       return single_release(inode, file);
-}
-
-static const struct file_operations brcm_avs_debug_ops = {
-       .open           = brcm_avs_debug_open,
-       .read           = seq_read,
-       .write          = brcm_avs_seq_write,
-       .llseek         = seq_lseek,
-       .release        = brcm_avs_debug_release,
-};
-
-static void brcm_avs_cpufreq_debug_init(struct platform_device *pdev)
-{
-       struct private_data *priv = platform_get_drvdata(pdev);
-       struct dentry *dir;
-       int i;
-
-       if (!priv)
-               return;
-
-       dir = debugfs_create_dir(BRCM_AVS_CPUFREQ_NAME, NULL);
-       if (IS_ERR_OR_NULL(dir))
-               return;
-       priv->debugfs = dir;
-
-       for (i = 0; i < ARRAY_SIZE(debugfs_entries); i++) {
-               /*
-                * The DEBUGFS_ENTRY macro generates uppercase strings. We
-                * convert them to lowercase before creating the debugfs
-                * entries.
-                */
-               char *entry = __strtolower(debugfs_entries[i].name);
-               fmode_t mode = debugfs_entries[i].mode;
-
-               if (!debugfs_create_file(entry, S_IFREG | S_IRUGO | mode,
-                                        dir, priv, &brcm_avs_debug_ops)) {
-                       priv->debugfs = NULL;
-                       debugfs_remove_recursive(dir);
-                       break;
-               }
-       }
-}
-
-static void brcm_avs_cpufreq_debug_exit(struct platform_device *pdev)
-{
-       struct private_data *priv = platform_get_drvdata(pdev);
-
-       if (priv && priv->debugfs) {
-               debugfs_remove_recursive(priv->debugfs);
-               priv->debugfs = NULL;
-       }
-}
-
-#else
-
-static void brcm_avs_cpufreq_debug_init(struct platform_device *pdev) {}
-static void brcm_avs_cpufreq_debug_exit(struct platform_device *pdev) {}
-
-#endif /* CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG */
-
 /*
  * To ensure the right firmware is running we need to
  *    - check the MAGIC matches what we expect
@@ -1016,11 +700,8 @@ static int brcm_avs_cpufreq_probe(struct platform_device *pdev)
                return ret;
 
        brcm_avs_driver.driver_data = pdev;
-       ret = cpufreq_register_driver(&brcm_avs_driver);
-       if (!ret)
-               brcm_avs_cpufreq_debug_init(pdev);
 
-       return ret;
+       return cpufreq_register_driver(&brcm_avs_driver);
 }
 
 static int brcm_avs_cpufreq_remove(struct platform_device *pdev)
@@ -1032,8 +713,6 @@ static int brcm_avs_cpufreq_remove(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       brcm_avs_cpufreq_debug_exit(pdev);
-
        priv = platform_get_drvdata(pdev);
        iounmap(priv->base);
        iounmap(priv->avs_intr_base);
index 0591874856d3c8ba037537bc863c4bbbfe21e0a5..54edaec1e60837dfcc515430012979482652271a 100644 (file)
@@ -679,6 +679,16 @@ void gpstate_timer_handler(struct timer_list *t)
 
        if (!spin_trylock(&gpstates->gpstate_lock))
                return;
+       /*
+        * If the timer has migrated to the different cpu then bring
+        * it back to one of the policy->cpus
+        */
+       if (!cpumask_test_cpu(raw_smp_processor_id(), policy->cpus)) {
+               gpstates->timer.expires = jiffies + msecs_to_jiffies(1);
+               add_timer_on(&gpstates->timer, cpumask_first(policy->cpus));
+               spin_unlock(&gpstates->gpstate_lock);
+               return;
+       }
 
        /*
         * If PMCR was last updated was using fast_swtich then
@@ -718,10 +728,8 @@ void gpstate_timer_handler(struct timer_list *t)
        if (gpstate_idx != gpstates->last_lpstate_idx)
                queue_gpstate_timer(gpstates);
 
+       set_pstate(&freq_data);
        spin_unlock(&gpstates->gpstate_lock);
-
-       /* Timer may get migrated to a different cpu on cpu hot unplug */
-       smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1);
 }
 
 /*
index be8606457f27f02dc046ad1e8f02841742f8e4b4..aff2c1594220a9973e63894255d6873c2a9a53e7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/dax.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/mman.h>
 #include "dax-private.h"
 #include "dax.h"
 
@@ -540,6 +541,7 @@ static const struct file_operations dax_fops = {
        .release = dax_release,
        .get_unmapped_area = dax_get_unmapped_area,
        .mmap = dax_mmap,
+       .mmap_supported_flags = MAP_SYNC,
 };
 
 static void dev_dax_release(struct device *dev)
index e6f17825db7942594e657ce9126b2e8612d45c86..2b90606452a2faf1a845b82bfd5bd9ce83b8bd00 100644 (file)
@@ -284,7 +284,7 @@ scmi_clock_info_get(const struct scmi_handle *handle, u32 clk_id)
        struct clock_info *ci = handle->clk_priv;
        struct scmi_clock_info *clk = ci->clk + clk_id;
 
-       if (!clk->name || !clk->name[0])
+       if (!clk->name[0])
                return NULL;
 
        return clk;
index 14f14efdf0d53ca23c24d7c514cdd4c4ad4b8174..06d212a3d49dd6ebdba471aa1814759ff828d1aa 100644 (file)
@@ -249,7 +249,7 @@ static int altera_ps_probe(struct spi_device *spi)
 
        conf->data = of_id->data;
        conf->spi = spi;
-       conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_HIGH);
+       conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_LOW);
        if (IS_ERR(conf->config)) {
                dev_err(&spi->dev, "Failed to get config gpio: %ld\n",
                        PTR_ERR(conf->config));
index b0e591eaa71a21754e1e2246bf41df3cdd1936cf..e14263fca1c91472ead16fd5bfdceed0b11be81e 100644 (file)
@@ -1459,10 +1459,11 @@ static const u32 sgpr_init_compute_shader[] =
 static const u32 vgpr_init_regs[] =
 {
        mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff,
-       mmCOMPUTE_RESOURCE_LIMITS, 0,
+       mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */
        mmCOMPUTE_NUM_THREAD_X, 256*4,
        mmCOMPUTE_NUM_THREAD_Y, 1,
        mmCOMPUTE_NUM_THREAD_Z, 1,
+       mmCOMPUTE_PGM_RSRC1, 0x100004f, /* VGPRS=15 (64 logical VGPRs), SGPRS=1 (16 SGPRs), BULKY=1 */
        mmCOMPUTE_PGM_RSRC2, 20,
        mmCOMPUTE_USER_DATA_0, 0xedcedc00,
        mmCOMPUTE_USER_DATA_1, 0xedcedc01,
@@ -1479,10 +1480,11 @@ static const u32 vgpr_init_regs[] =
 static const u32 sgpr1_init_regs[] =
 {
        mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f,
-       mmCOMPUTE_RESOURCE_LIMITS, 0x1000000,
+       mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */
        mmCOMPUTE_NUM_THREAD_X, 256*5,
        mmCOMPUTE_NUM_THREAD_Y, 1,
        mmCOMPUTE_NUM_THREAD_Z, 1,
+       mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */
        mmCOMPUTE_PGM_RSRC2, 20,
        mmCOMPUTE_USER_DATA_0, 0xedcedc00,
        mmCOMPUTE_USER_DATA_1, 0xedcedc01,
@@ -1503,6 +1505,7 @@ static const u32 sgpr2_init_regs[] =
        mmCOMPUTE_NUM_THREAD_X, 256*5,
        mmCOMPUTE_NUM_THREAD_Y, 1,
        mmCOMPUTE_NUM_THREAD_Z, 1,
+       mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */
        mmCOMPUTE_PGM_RSRC2, 20,
        mmCOMPUTE_USER_DATA_0, 0xedcedc00,
        mmCOMPUTE_USER_DATA_1, 0xedcedc01,
index ed2f06c9f3462173d0d2f8cf2ce6a09e0a532e94..3858820a0055d31fb30621f55efa9067d8eebfd8 100644 (file)
@@ -6,5 +6,6 @@ config HSA_AMD
        tristate "HSA kernel driver for AMD GPU devices"
        depends on DRM_AMDGPU && X86_64
        imply AMD_IOMMU_V2
+       select MMU_NOTIFIER
        help
          Enable this if you want to use HSA features on AMD GPU devices.
index cd679cf1fd308fa5e436c6691399351e0f2f0c71..59808a39ecf4afb98587369384111948b4997adc 100644 (file)
@@ -749,12 +749,13 @@ static int kfd_ioctl_get_clock_counters(struct file *filep,
        struct timespec64 time;
 
        dev = kfd_device_by_id(args->gpu_id);
-       if (dev == NULL)
-               return -EINVAL;
-
-       /* Reading GPU clock counter from KGD */
-       args->gpu_clock_counter =
-               dev->kfd2kgd->get_gpu_clock_counter(dev->kgd);
+       if (dev)
+               /* Reading GPU clock counter from KGD */
+               args->gpu_clock_counter =
+                       dev->kfd2kgd->get_gpu_clock_counter(dev->kgd);
+       else
+               /* Node without GPU resource */
+               args->gpu_clock_counter = 0;
 
        /* No access to rdtsc. Using raw monotonic time */
        getrawmonotonic64(&time);
@@ -1147,7 +1148,7 @@ err_unlock:
        return ret;
 }
 
-bool kfd_dev_is_large_bar(struct kfd_dev *dev)
+static bool kfd_dev_is_large_bar(struct kfd_dev *dev)
 {
        struct kfd_local_mem_info mem_info;
 
@@ -1421,7 +1422,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
 
        pdd = kfd_get_process_device_data(dev, p);
        if (!pdd) {
-               err = PTR_ERR(pdd);
+               err = -EINVAL;
                goto bind_process_to_device_failed;
        }
 
index 4e2f379ce2172c4a8b7925aec15873105f4b2c40..1dd1142246c25f0ef3a2b7cbae42bc534f86491e 100644 (file)
@@ -4557,6 +4557,7 @@ static int dm_update_crtcs_state(struct dc *dc,
                struct amdgpu_dm_connector *aconnector = NULL;
                struct drm_connector_state *new_con_state = NULL;
                struct dm_connector_state *dm_conn_state = NULL;
+               struct drm_plane_state *new_plane_state = NULL;
 
                new_stream = NULL;
 
@@ -4564,6 +4565,13 @@ static int dm_update_crtcs_state(struct dc *dc,
                dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
                acrtc = to_amdgpu_crtc(crtc);
 
+               new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary);
+
+               if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) {
+                       ret = -EINVAL;
+                       goto fail;
+               }
+
                aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
 
                /* TODO This hack should go away */
@@ -4760,7 +4768,7 @@ static int dm_update_planes_state(struct dc *dc,
                        if (!dm_old_crtc_state->stream)
                                continue;
 
-                       DRM_DEBUG_DRIVER("Disabling DRM plane: %d on DRM crtc %d\n",
+                       DRM_DEBUG_ATOMIC("Disabling DRM plane: %d on DRM crtc %d\n",
                                        plane->base.id, old_plane_crtc->base.id);
 
                        if (!dc_remove_plane_from_context(
index f6cb502c303f3e76fac70c1f797525e78e940a48..25f064c010384664c9c157382ddb518cd7d6af4a 100644 (file)
@@ -138,13 +138,6 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc)
        lut = (struct drm_color_lut *)blob->data;
        lut_size = blob->length / sizeof(struct drm_color_lut);
 
-       if (__is_lut_linear(lut, lut_size)) {
-               /* Set to bypass if lut is set to linear */
-               stream->out_transfer_func->type = TF_TYPE_BYPASS;
-               stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-               return 0;
-       }
-
        gamma = dc_create_gamma();
        if (!gamma)
                return -ENOMEM;
index 490017df371de3bd1ae902f1794ea46d2c6a7a96..4be21bf5474981a8b954f4b1fb6b5c6a283cc82b 100644 (file)
@@ -329,14 +329,15 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
 {
        int src;
        struct irq_list_head *lh;
+       unsigned long irq_table_flags;
        DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n");
-
        for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
-
+               DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
                /* The handler was removed from the table,
                 * it means it is safe to flush all the 'work'
                 * (because no code can schedule a new one). */
                lh = &adev->dm.irq_handler_list_low_tab[src];
+               DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
                flush_work(&lh->work);
        }
 }
index 8291d74f26bcfd8934f424232297b7b60822268d..ace9ad578ca08f85aeccf49ac4d744b071444274 100644 (file)
@@ -161,6 +161,11 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
        struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
        struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder;
 
+       if (amdgpu_dm_connector->edid) {
+               kfree(amdgpu_dm_connector->edid);
+               amdgpu_dm_connector->edid = NULL;
+       }
+
        drm_encoder_cleanup(&amdgpu_encoder->base);
        kfree(amdgpu_encoder);
        drm_connector_cleanup(connector);
@@ -181,28 +186,22 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
 void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
 {
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
-       struct edid *edid;
        struct dc_sink *dc_sink;
        struct dc_sink_init_data init_params = {
                        .link = aconnector->dc_link,
                        .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
 
+       /* FIXME none of this is safe. we shouldn't touch aconnector here in
+        * atomic_check
+        */
+
        /*
         * TODO: Need to further figure out why ddc.algo is NULL while MST port exists
         */
        if (!aconnector->port || !aconnector->port->aux.ddc.algo)
                return;
 
-       edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
-
-       if (!edid) {
-               drm_mode_connector_update_edid_property(
-                       &aconnector->base,
-                       NULL);
-               return;
-       }
-
-       aconnector->edid = edid;
+       ASSERT(aconnector->edid);
 
        dc_sink = dc_link_add_remote_sink(
                aconnector->dc_link,
@@ -215,9 +214,6 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
 
        amdgpu_dm_add_sink_to_freesync_module(
                        connector, aconnector->edid);
-
-       drm_mode_connector_update_edid_property(
-                                       &aconnector->base, aconnector->edid);
 }
 
 static int dm_dp_mst_get_modes(struct drm_connector *connector)
@@ -230,10 +226,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
 
        if (!aconnector->edid) {
                struct edid *edid;
-               struct dc_sink *dc_sink;
-               struct dc_sink_init_data init_params = {
-                               .link = aconnector->dc_link,
-                               .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
                edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
 
                if (!edid) {
@@ -244,11 +236,17 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
                }
 
                aconnector->edid = edid;
+       }
 
+       if (!aconnector->dc_sink) {
+               struct dc_sink *dc_sink;
+               struct dc_sink_init_data init_params = {
+                               .link = aconnector->dc_link,
+                               .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
                dc_sink = dc_link_add_remote_sink(
                        aconnector->dc_link,
-                       (uint8_t *)edid,
-                       (edid->extensions + 1) * EDID_LENGTH,
+                       (uint8_t *)aconnector->edid,
+                       (aconnector->edid->extensions + 1) * EDID_LENGTH,
                        &init_params);
 
                dc_sink->priv = aconnector;
@@ -256,12 +254,12 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
 
                if (aconnector->dc_sink)
                        amdgpu_dm_add_sink_to_freesync_module(
-                                       connector, edid);
-
-               drm_mode_connector_update_edid_property(
-                                               &aconnector->base, edid);
+                                       connector, aconnector->edid);
        }
 
+       drm_mode_connector_update_edid_property(
+                                       &aconnector->base, aconnector->edid);
+
        ret = drm_add_edid_modes(connector, aconnector->edid);
 
        return ret;
@@ -424,14 +422,6 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
                dc_sink_release(aconnector->dc_sink);
                aconnector->dc_sink = NULL;
        }
-       if (aconnector->edid) {
-               kfree(aconnector->edid);
-               aconnector->edid = NULL;
-       }
-
-       drm_mode_connector_update_edid_property(
-                       &aconnector->base,
-                       NULL);
 
        aconnector->mst_connected = false;
 }
index add90675fd2afcfd72d66b8f30f4f6c4ab6a2540..26fbeafc3c9654dbf4ed205c684c8097e0429c27 100644 (file)
@@ -4743,23 +4743,27 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
 
        for (i=0; i < dep_table->count; i++) {
                if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
-                       break;
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;
+                       return;
                }
        }
-       if (i == dep_table->count)
+       if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
                data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
+               data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
+       }
 
        dep_table = table_info->vdd_dep_on_sclk;
        odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);
        for (i=0; i < dep_table->count; i++) {
                if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
-                       break;
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;
+                       return;
                }
        }
-       if (i == dep_table->count)
+       if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
                data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
+               data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
+       }
 }
 
 static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
index fb696e3d06cfc46f680d1668ebb985adcb988ea3..2f8a3b983cce0c9444cac949ed7ce79a420b06ba 100644 (file)
@@ -412,8 +412,10 @@ typedef struct {
   QuadraticInt_t    ReservedEquation2;
   QuadraticInt_t    ReservedEquation3;
 
+       uint16_t     MinVoltageUlvGfx;
+       uint16_t     MinVoltageUlvSoc;
 
-  uint32_t     Reserved[15];
+       uint32_t     Reserved[14];
 
 
 
index 02a50929af6759ab7769bba100134b2e6f4b0713..e7f4fe2848a542c3e45b55a8c92b258273cd71c8 100644 (file)
@@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
 {
        uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
        ssize_t ret;
+       int retry;
 
        if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
                return 0;
 
-       ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
-                                    &tmds_oen, sizeof(tmds_oen));
-       if (ret) {
-               DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
-                             enable ? "enable" : "disable");
-               return ret;
+       /*
+        * LSPCON adapters in low-power state may ignore the first write, so
+        * read back and verify the written value a few times.
+        */
+       for (retry = 0; retry < 3; retry++) {
+               uint8_t tmp;
+
+               ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+                                            &tmds_oen, sizeof(tmds_oen));
+               if (ret) {
+                       DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
+                                     enable ? "enable" : "disable",
+                                     retry + 1);
+                       return ret;
+               }
+
+               ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+                                           &tmp, sizeof(tmp));
+               if (ret) {
+                       DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
+                                     enable ? "enabling" : "disabling",
+                                     retry + 1);
+                       return ret;
+               }
+
+               if (tmp == tmds_oen)
+                       return 0;
        }
 
-       return 0;
+       DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
+                     enable ? "enabling" : "disabling");
+
+       return -EIO;
 }
 EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
 
index 134069f364829030c8bbd7d7bf1e45b3c7340666..39f1db4acda4eaf1059be7071c1d48e384416193 100644 (file)
@@ -4451,6 +4451,7 @@ drm_reset_display_info(struct drm_connector *connector)
        info->max_tmds_clock = 0;
        info->dvi_dual = false;
        info->has_hdmi_infoframe = false;
+       memset(&info->hdmi, 0, sizeof(info->hdmi));
 
        info->non_desktop = 0;
 }
@@ -4462,17 +4463,11 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
 
        u32 quirks = edid_get_quirks(edid);
 
+       drm_reset_display_info(connector);
+
        info->width_mm = edid->width_cm * 10;
        info->height_mm = edid->height_cm * 10;
 
-       /* driver figures it out in this case */
-       info->bpc = 0;
-       info->color_formats = 0;
-       info->cea_rev = 0;
-       info->max_tmds_clock = 0;
-       info->dvi_dual = false;
-       info->has_hdmi_infoframe = false;
-
        info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
 
        DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
index 0faaf829f5bf52a9d730d47f5de035a16a77a165..f0e79178bde61dea434f15d5cc47f30786812994 100644 (file)
@@ -18,6 +18,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <uapi/drm/exynos_drm.h>
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_iommu.h"
 #include "exynos_drm_crtc.h"
 
-#define to_exynos_fb(x)        container_of(x, struct exynos_drm_fb, fb)
-
-/*
- * exynos specific framebuffer structure.
- *
- * @fb: drm framebuffer obejct.
- * @exynos_gem: array of exynos specific gem object containing a gem object.
- */
-struct exynos_drm_fb {
-       struct drm_framebuffer  fb;
-       struct exynos_drm_gem   *exynos_gem[MAX_FB_BUFFER];
-       dma_addr_t                      dma_addr[MAX_FB_BUFFER];
-};
-
 static int check_fb_gem_memory_type(struct drm_device *drm_dev,
                                    struct exynos_drm_gem *exynos_gem)
 {
@@ -66,40 +53,9 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev,
        return 0;
 }
 
-static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
-{
-       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
-       unsigned int i;
-
-       drm_framebuffer_cleanup(fb);
-
-       for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) {
-               struct drm_gem_object *obj;
-
-               if (exynos_fb->exynos_gem[i] == NULL)
-                       continue;
-
-               obj = &exynos_fb->exynos_gem[i]->base;
-               drm_gem_object_unreference_unlocked(obj);
-       }
-
-       kfree(exynos_fb);
-       exynos_fb = NULL;
-}
-
-static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
-                                       struct drm_file *file_priv,
-                                       unsigned int *handle)
-{
-       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
-
-       return drm_gem_handle_create(file_priv,
-                                    &exynos_fb->exynos_gem[0]->base, handle);
-}
-
 static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
-       .destroy        = exynos_drm_fb_destroy,
-       .create_handle  = exynos_drm_fb_create_handle,
+       .destroy        = drm_gem_fb_destroy,
+       .create_handle  = drm_gem_fb_create_handle,
 };
 
 struct drm_framebuffer *
@@ -108,12 +64,12 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
                            struct exynos_drm_gem **exynos_gem,
                            int count)
 {
-       struct exynos_drm_fb *exynos_fb;
+       struct drm_framebuffer *fb;
        int i;
        int ret;
 
-       exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
-       if (!exynos_fb)
+       fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+       if (!fb)
                return ERR_PTR(-ENOMEM);
 
        for (i = 0; i < count; i++) {
@@ -121,23 +77,21 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
                if (ret < 0)
                        goto err;
 
-               exynos_fb->exynos_gem[i] = exynos_gem[i];
-               exynos_fb->dma_addr[i] = exynos_gem[i]->dma_addr
-                                               + mode_cmd->offsets[i];
+               fb->obj[i] = &exynos_gem[i]->base;
        }
 
-       drm_helper_mode_fill_fb_struct(dev, &exynos_fb->fb, mode_cmd);
+       drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
 
-       ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs);
+       ret = drm_framebuffer_init(dev, fb, &exynos_drm_fb_funcs);
        if (ret < 0) {
                DRM_ERROR("failed to initialize framebuffer\n");
                goto err;
        }
 
-       return &exynos_fb->fb;
+       return fb;
 
 err:
-       kfree(exynos_fb);
+       kfree(fb);
        return ERR_PTR(ret);
 }
 
@@ -191,12 +145,13 @@ err:
 
 dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
 {
-       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
+       struct exynos_drm_gem *exynos_gem;
 
        if (WARN_ON_ONCE(index >= MAX_FB_BUFFER))
                return 0;
 
-       return exynos_fb->dma_addr[index];
+       exynos_gem = to_exynos_gem(fb->obj[index]);
+       return exynos_gem->dma_addr + fb->offsets[index];
 }
 
 static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
index db6b94dda5dfaede1ebb97cc21b17ea301fdd275..d85939bd7b4719c077d65b97d94ecbe8d229288c 100644 (file)
@@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
 {
        set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt,
                        s->workload->pending_events);
+       patch_value(s, cmd_ptr(s, 0), MI_NOOP);
        return 0;
 }
 
index dd96ffc878acda99ef0a87206391f1f24f269248..6d8180e8d1e21a71916e8b6cad404dab8d8c3257 100644 (file)
@@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
 static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
 {
        struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+       int pipe;
+
        vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
                        SDE_PORTC_HOTPLUG_CPT |
                        SDE_PORTD_HOTPLUG_CPT);
@@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
        if (IS_BROADWELL(dev_priv))
                vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
 
+       /* Disable Primary/Sprite/Cursor plane */
+       for_each_pipe(dev_priv, pipe) {
+               vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
+               vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
+               vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~CURSOR_MODE;
+               vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= CURSOR_MODE_DISABLE;
+       }
+
        vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
 }
 
index b555eb26f9ceb94a0eb2e3f408849c98c00ad1e9..6f4f8e941fc200aa66972be703a811c17fff93d8 100644 (file)
@@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
                      struct intel_vgpu_fb_info *fb_info)
 {
        gvt_dmabuf->drm_format = fb_info->drm_format;
+       gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod;
        gvt_dmabuf->width = fb_info->width;
        gvt_dmabuf->height = fb_info->height;
        gvt_dmabuf->stride = fb_info->stride;
index 6b50fe78dc1b8bf3bbede208d801ca5b58a68007..1c120683e9588c5a1d379c370e2760234f2d3ab1 100644 (file)
@@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
        plane->hw_format = fmt;
 
        plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
-       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                            (unsigned long)plane->base);
+       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
                return  -EINVAL;
-       }
 
        plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
        if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                               (unsigned long)plane->base);
+               gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
+                               plane->base);
                return  -EINVAL;
        }
 
@@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
                        alpha_plane, alpha_force);
 
        plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
-       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                            (unsigned long)plane->base);
+       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
                return  -EINVAL;
-       }
 
        plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
        if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                               (unsigned long)plane->base);
+               gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
+                               plane->base);
                return  -EINVAL;
        }
 
@@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
        plane->drm_format = drm_format;
 
        plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
-       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                            (unsigned long)plane->base);
+       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
                return  -EINVAL;
-       }
 
        plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
        if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                               (unsigned long)plane->base);
+               gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
+                               plane->base);
                return  -EINVAL;
        }
 
index d292812315077469848dc536a36fb7fa086d003d..78e55aafc8bca047d42e5f853ed7025af005e96c 100644 (file)
@@ -530,6 +530,16 @@ static void ggtt_set_guest_entry(struct intel_vgpu_mm *mm,
                           false, 0, mm->vgpu);
 }
 
+static void ggtt_get_host_entry(struct intel_vgpu_mm *mm,
+               struct intel_gvt_gtt_entry *entry, unsigned long index)
+{
+       struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;
+
+       GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT);
+
+       pte_ops->get_entry(NULL, entry, index, false, 0, mm->vgpu);
+}
+
 static void ggtt_set_host_entry(struct intel_vgpu_mm *mm,
                struct intel_gvt_gtt_entry *entry, unsigned long index)
 {
@@ -1818,6 +1828,18 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, unsigned int off,
        return ret;
 }
 
+static void ggtt_invalidate_pte(struct intel_vgpu *vgpu,
+               struct intel_gvt_gtt_entry *entry)
+{
+       struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
+       unsigned long pfn;
+
+       pfn = pte_ops->get_pfn(entry);
+       if (pfn != vgpu->gvt->gtt.scratch_mfn)
+               intel_gvt_hypervisor_dma_unmap_guest_page(vgpu,
+                                               pfn << PAGE_SHIFT);
+}
+
 static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
        void *p_data, unsigned int bytes)
 {
@@ -1844,10 +1866,10 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
 
        memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
                        bytes);
-       m = e;
 
        if (ops->test_present(&e)) {
                gfn = ops->get_pfn(&e);
+               m = e;
 
                /* one PTE update may be issued in multiple writes and the
                 * first write may not construct a valid gfn
@@ -1868,8 +1890,12 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
                        ops->set_pfn(&m, gvt->gtt.scratch_mfn);
                } else
                        ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
-       } else
+       } else {
+               ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
+               ggtt_invalidate_pte(vgpu, &m);
                ops->set_pfn(&m, gvt->gtt.scratch_mfn);
+               ops->clear_present(&m);
+       }
 
 out:
        ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
@@ -2030,7 +2056,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
                return PTR_ERR(gtt->ggtt_mm);
        }
 
-       intel_vgpu_reset_ggtt(vgpu);
+       intel_vgpu_reset_ggtt(vgpu, false);
 
        return create_scratch_page_tree(vgpu);
 }
@@ -2315,17 +2341,19 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu)
 /**
  * intel_vgpu_reset_ggtt - reset the GGTT entry
  * @vgpu: a vGPU
+ * @invalidate_old: invalidate old entries
  *
  * This function is called at the vGPU create stage
  * to reset all the GGTT entries.
  *
  */
-void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
+void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old)
 {
        struct intel_gvt *gvt = vgpu->gvt;
        struct drm_i915_private *dev_priv = gvt->dev_priv;
        struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
        struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE};
+       struct intel_gvt_gtt_entry old_entry;
        u32 index;
        u32 num_entries;
 
@@ -2334,13 +2362,23 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
 
        index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
        num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
-       while (num_entries--)
+       while (num_entries--) {
+               if (invalidate_old) {
+                       ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
+                       ggtt_invalidate_pte(vgpu, &old_entry);
+               }
                ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
+       }
 
        index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
        num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
-       while (num_entries--)
+       while (num_entries--) {
+               if (invalidate_old) {
+                       ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
+                       ggtt_invalidate_pte(vgpu, &old_entry);
+               }
                ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
+       }
 
        ggtt_invalidate(dev_priv);
 }
@@ -2360,5 +2398,5 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
         * removing the shadow pages.
         */
        intel_vgpu_destroy_all_ppgtt_mm(vgpu);
-       intel_vgpu_reset_ggtt(vgpu);
+       intel_vgpu_reset_ggtt(vgpu, true);
 }
index a8b369cd352b89d567fb9f8926e58debf76cfc40..3792f2b7f4ff0686832458efcf533248c4aa356d 100644 (file)
@@ -193,7 +193,7 @@ struct intel_vgpu_gtt {
 
 extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
 extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
-void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu);
+void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old);
 void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);
 
 extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
index 8c5d5d005854217057e9bc347db5ce074cc46adb..a33c1c3e4a21e2ff96486b79440ef4553149b324 100644 (file)
@@ -1150,6 +1150,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification)
        switch (notification) {
        case VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE:
                root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY;
+               /* fall through */
        case VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE:
                mm = intel_vgpu_get_ppgtt_mm(vgpu, root_entry_type, pdps);
                return PTR_ERR_OR_ZERO(mm);
index c16a492449d7d158a6f2d9d13c42fafa523df962..1466d8769ec9facfc73c9ae4db922d0e09944840 100644 (file)
@@ -1301,7 +1301,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
 
        }
 
-       return 0;
+       return -ENOTTY;
 }
 
 static ssize_t
index 84ca369f15a5c04f478a716eb7dfb13c96993f43..3b4daafebdcb3fc465696d9a8d88c25f14a2e8ff 100644 (file)
@@ -1105,30 +1105,32 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 
        ret = i915_ggtt_probe_hw(dev_priv);
        if (ret)
-               return ret;
+               goto err_perf;
 
-       /* WARNING: Apparently we must kick fbdev drivers before vgacon,
-        * otherwise the vga fbdev driver falls over. */
+       /*
+        * WARNING: Apparently we must kick fbdev drivers before vgacon,
+        * otherwise the vga fbdev driver falls over.
+        */
        ret = i915_kick_out_firmware_fb(dev_priv);
        if (ret) {
                DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
-               goto out_ggtt;
+               goto err_ggtt;
        }
 
        ret = i915_kick_out_vgacon(dev_priv);
        if (ret) {
                DRM_ERROR("failed to remove conflicting VGA console\n");
-               goto out_ggtt;
+               goto err_ggtt;
        }
 
        ret = i915_ggtt_init_hw(dev_priv);
        if (ret)
-               return ret;
+               goto err_ggtt;
 
        ret = i915_ggtt_enable_hw(dev_priv);
        if (ret) {
                DRM_ERROR("failed to enable GGTT\n");
-               goto out_ggtt;
+               goto err_ggtt;
        }
 
        pci_set_master(pdev);
@@ -1139,7 +1141,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
                if (ret) {
                        DRM_ERROR("failed to set DMA mask\n");
 
-                       goto out_ggtt;
+                       goto err_ggtt;
                }
        }
 
@@ -1157,7 +1159,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
                if (ret) {
                        DRM_ERROR("failed to set DMA mask\n");
 
-                       goto out_ggtt;
+                       goto err_ggtt;
                }
        }
 
@@ -1190,13 +1192,14 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 
        ret = intel_gvt_init(dev_priv);
        if (ret)
-               goto out_ggtt;
+               goto err_ggtt;
 
        return 0;
 
-out_ggtt:
+err_ggtt:
        i915_ggtt_cleanup_hw(dev_priv);
-
+err_perf:
+       i915_perf_fini(dev_priv);
        return ret;
 }
 
index 8c170db8495d0317379ba76381042b7828a51551..0414228cd2b5f3c66489eafe7cf1152c7583db25 100644 (file)
@@ -728,7 +728,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 
                err = radix_tree_insert(handles_vma, handle, vma);
                if (unlikely(err)) {
-                       kfree(lut);
+                       kmem_cache_free(eb->i915->luts, lut);
                        goto err_obj;
                }
 
index d8feb9053e0cc8e1bc5552189b9ff020c6e7495c..f0519e31543a6506d4eaf3d3213311c81be2ea1c 100644 (file)
@@ -473,20 +473,37 @@ static u64 get_rc6(struct drm_i915_private *i915)
                spin_lock_irqsave(&i915->pmu.lock, flags);
                spin_lock(&kdev->power.lock);
 
-               if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
-                       i915->pmu.suspended_jiffies_last =
-                                               kdev->power.suspended_jiffies;
+               /*
+                * After the above branch intel_runtime_pm_get_if_in_use failed
+                * to get the runtime PM reference we cannot assume we are in
+                * runtime suspend since we can either: a) race with coming out
+                * of it before we took the power.lock, or b) there are other
+                * states than suspended which can bring us here.
+                *
+                * We need to double-check that we are indeed currently runtime
+                * suspended and if not we cannot do better than report the last
+                * known RC6 value.
+                */
+               if (kdev->power.runtime_status == RPM_SUSPENDED) {
+                       if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
+                               i915->pmu.suspended_jiffies_last =
+                                                 kdev->power.suspended_jiffies;
 
-               val = kdev->power.suspended_jiffies -
-                     i915->pmu.suspended_jiffies_last;
-               val += jiffies - kdev->power.accounting_timestamp;
+                       val = kdev->power.suspended_jiffies -
+                             i915->pmu.suspended_jiffies_last;
+                       val += jiffies - kdev->power.accounting_timestamp;
 
-               spin_unlock(&kdev->power.lock);
+                       val = jiffies_to_nsecs(val);
+                       val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
 
-               val = jiffies_to_nsecs(val);
-               val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
-               i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
+                       i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
+               } else if (i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
+                       val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
+               } else {
+                       val = i915->pmu.sample[__I915_SAMPLE_RC6].cur;
+               }
 
+               spin_unlock(&kdev->power.lock);
                spin_unlock_irqrestore(&i915->pmu.lock, flags);
        }
 
index 709d6ca680747d8d4458c72945093a8052d6f8c4..3ea566f99450e37f10317712b651b8104bda2a28 100644 (file)
@@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev,
        struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
        u32 tmp;
 
-       if (!IS_GEN9_BC(dev_priv))
+       if (!IS_GEN9(dev_priv))
                return;
 
        i915_audio_component_get_power(kdev);
index c5c7530ba1570618d06a04f789029944296366de..447b721c3be9c2da800d0c39fb4208d1ab93e913 100644 (file)
@@ -1256,7 +1256,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
                return;
 
        aux_channel = child->aux_channel;
-       ddc_pin = child->ddc_pin;
 
        is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
        is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
@@ -1303,9 +1302,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
                DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
 
        if (is_dvi) {
-               info->alternate_ddc_pin = map_ddc_pin(dev_priv, ddc_pin);
-
-               sanitize_ddc_pin(dev_priv, port);
+               ddc_pin = map_ddc_pin(dev_priv, child->ddc_pin);
+               if (intel_gmbus_is_valid_pin(dev_priv, ddc_pin)) {
+                       info->alternate_ddc_pin = ddc_pin;
+                       sanitize_ddc_pin(dev_priv, port);
+               } else {
+                       DRM_DEBUG_KMS("Port %c has invalid DDC pin %d, "
+                                     "sticking to defaults\n",
+                                     port_name(port), ddc_pin);
+               }
        }
 
        if (is_dp) {
index fc8b2c6e35088410a61f81eb317bfaa09848d6cf..32d24c69da3c699a0dd3a0b88a99429a1db929f8 100644 (file)
@@ -2140,10 +2140,22 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
                }
        }
 
-       /* According to BSpec, "The CD clock frequency must be at least twice
+       /*
+        * According to BSpec, "The CD clock frequency must be at least twice
         * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
+        *
+        * FIXME: Check the actual, not default, BCLK being used.
+        *
+        * FIXME: This does not depend on ->has_audio because the higher CDCLK
+        * is required for audio probe, also when there are no audio capable
+        * displays connected at probe time. This leads to unnecessarily high
+        * CDCLK when audio is not required.
+        *
+        * FIXME: This limit is only applied when there are displays connected
+        * at probe time. If we probe without displays, we'll still end up using
+        * the platform minimum CDCLK, failing audio probe.
         */
-       if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                min_cdclk = max(2 * 96000, min_cdclk);
 
        /*
index d4368589b3553657e14adbcc9c54a56ed5f30865..a80fbad9be0fe4defd46c597d2e76f9b479228b4 100644 (file)
  * check the condition before the timeout.
  */
 #define __wait_for(OP, COND, US, Wmin, Wmax) ({ \
-       unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1;   \
+       const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \
        long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \
        int ret__;                                                      \
        might_sleep();                                                  \
        for (;;) {                                                      \
-               bool expired__ = time_after(jiffies, timeout__);        \
+               const bool expired__ = ktime_after(ktime_get_raw(), end__); \
                OP;                                                     \
                if (COND) {                                             \
                        ret__ = 0;                                      \
index 6f12adc063650c1ad4f696922dee1215a98398c0..6467a5cc2ca30e1ac33cca2c2dc08177e886ae1a 100644 (file)
@@ -806,7 +806,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
                return;
 
        intel_fbdev_sync(ifbdev);
-       if (ifbdev->vma)
+       if (ifbdev->vma || ifbdev->helper.deferred_setup)
                drm_fb_helper_hotplug_event(&ifbdev->helper);
 }
 
index 697af5add78bac2668987809fdbd94bc08aa0dc7..e3a5f673ff673d2784bfc2bff7ca14c0a959578e 100644 (file)
@@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                 * know the next preemption status we see corresponds
                 * to this ELSP update.
                 */
+               GEM_BUG_ON(!execlists_is_active(execlists,
+                                               EXECLISTS_ACTIVE_USER));
                GEM_BUG_ON(!port_count(&port[0]));
                if (port_count(&port[0]) > 1)
                        goto unlock;
@@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
                memset(port, 0, sizeof(*port));
                port++;
        }
+
+       execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
 }
 
 static void execlists_cancel_requests(struct intel_engine_cs *engine)
@@ -1001,6 +1005,11 @@ static void execlists_submission_tasklet(unsigned long data)
 
        if (fw)
                intel_uncore_forcewake_put(dev_priv, execlists->fw_domains);
+
+       /* If the engine is now idle, so should be the flag; and vice versa. */
+       GEM_BUG_ON(execlists_is_active(&engine->execlists,
+                                      EXECLISTS_ACTIVE_USER) ==
+                  !port_isset(engine->execlists.port));
 }
 
 static void queue_request(struct intel_engine_cs *engine,
index 53ea564f971ef6acd0ecf01d79254f2993450a78..66de4b2dc8b75c7f4faebd3c8d2f8af54c6a6871 100644 (file)
@@ -641,19 +641,18 @@ void skl_enable_dc6(struct drm_i915_private *dev_priv)
 
        DRM_DEBUG_KMS("Enabling DC6\n");
 
-       gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
+       /* Wa Display #1183: skl,kbl,cfl */
+       if (IS_GEN9_BC(dev_priv))
+               I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
+                          SKL_SELECT_ALTERNATE_DC_EXIT);
 
+       gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
 }
 
 void skl_disable_dc6(struct drm_i915_private *dev_priv)
 {
        DRM_DEBUG_KMS("Disabling DC6\n");
 
-       /* Wa Display #1183: skl,kbl,cfl */
-       if (IS_GEN9_BC(dev_priv))
-               I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
-                          SKL_SELECT_ALTERNATE_DC_EXIT);
-
        gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 }
 
index 6e5e1aa54ce19774340bd752785f25b8dcd20389..b001699297c486ab075a76bedd3c27d0c95572ee 100644 (file)
@@ -351,6 +351,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc,
 
        spin_lock_irqsave(&dev->event_lock, flags);
        mdp4_crtc->event = crtc->state->event;
+       crtc->state->event = NULL;
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
        blend_setup(crtc);
index 9893e43ba6c5e530af187b1114f853f87c1fcd88..76b96081916f0b9567a8b021d890cd572cad0534 100644 (file)
@@ -708,6 +708,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
 
        spin_lock_irqsave(&dev->event_lock, flags);
        mdp5_crtc->event = crtc->state->event;
+       crtc->state->event = NULL;
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
        /*
index b4a8aa4490eed8ced3aaf167d4172331abcd5d4f..005760bee708ea5d0c59c1935df0b4224c334ee5 100644 (file)
@@ -171,7 +171,8 @@ uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats,
        return i;
 }
 
-const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format)
+const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format,
+               uint64_t modifier)
 {
        int i;
        for (i = 0; i < ARRAY_SIZE(formats); i++) {
index 1185487e7e5e36c6f208a9e6254a17aec1931700..4fa8dbe4e165cdd834ffc76d08949b073b3c61cf 100644 (file)
@@ -98,7 +98,7 @@ struct mdp_format {
 #define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv)
 
 uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
-const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format);
+const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier);
 
 /* MDP capabilities */
 #define MDP_CAP_SMP            BIT(0)  /* Shared Memory Pool                 */
index 7a03a94897088a474aa966ea86f778e5dde238e9..8baba30d6c659cfde69c52cd69b2adc3203c54a9 100644 (file)
@@ -173,6 +173,7 @@ struct msm_dsi_host {
 
        bool registered;
        bool power_on;
+       bool enabled;
        int irq;
 };
 
@@ -775,7 +776,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
        switch (mipi_fmt) {
        case MIPI_DSI_FMT_RGB888:       return CMD_DST_FORMAT_RGB888;
        case MIPI_DSI_FMT_RGB666_PACKED:
-       case MIPI_DSI_FMT_RGB666:       return VID_DST_FORMAT_RGB666;
+       case MIPI_DSI_FMT_RGB666:       return CMD_DST_FORMAT_RGB666;
        case MIPI_DSI_FMT_RGB565:       return CMD_DST_FORMAT_RGB565;
        default:                        return CMD_DST_FORMAT_RGB888;
        }
@@ -986,13 +987,19 @@ static void dsi_set_tx_power_mode(int mode, struct msm_dsi_host *msm_host)
 
 static void dsi_wait4video_done(struct msm_dsi_host *msm_host)
 {
+       u32 ret = 0;
+       struct device *dev = &msm_host->pdev->dev;
+
        dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 1);
 
        reinit_completion(&msm_host->video_comp);
 
-       wait_for_completion_timeout(&msm_host->video_comp,
+       ret = wait_for_completion_timeout(&msm_host->video_comp,
                        msecs_to_jiffies(70));
 
+       if (ret <= 0)
+               dev_err(dev, "wait for video done timed out\n");
+
        dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0);
 }
 
@@ -1001,7 +1008,7 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
        if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
                return;
 
-       if (msm_host->power_on) {
+       if (msm_host->power_on && msm_host->enabled) {
                dsi_wait4video_done(msm_host);
                /* delay 4 ms to skip BLLP */
                usleep_range(2000, 4000);
@@ -2203,7 +2210,7 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
         *      pm_runtime_put_autosuspend(&msm_host->pdev->dev);
         * }
         */
-
+       msm_host->enabled = true;
        return 0;
 }
 
@@ -2211,6 +2218,7 @@ int msm_dsi_host_disable(struct mipi_dsi_host *host)
 {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
 
+       msm_host->enabled = false;
        dsi_op_mode_config(msm_host,
                !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), false);
 
index 8e9d5c255820272ebe0a759ed51e4aa0ee6047b9..9a9fa0c75a131083f32c57f5cd89a0e02c7b87d1 100644 (file)
@@ -265,6 +265,115 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
        return 0;
 }
 
+int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
+       struct msm_dsi_phy_clk_request *clk_req)
+{
+       const unsigned long bit_rate = clk_req->bitclk_rate;
+       const unsigned long esc_rate = clk_req->escclk_rate;
+       s32 ui, ui_x8, lpx;
+       s32 tmax, tmin;
+       s32 pcnt0 = 50;
+       s32 pcnt1 = 50;
+       s32 pcnt2 = 10;
+       s32 pcnt3 = 30;
+       s32 pcnt4 = 10;
+       s32 pcnt5 = 2;
+       s32 coeff = 1000; /* Precision, should avoid overflow */
+       s32 hb_en, hb_en_ckln;
+       s32 temp;
+
+       if (!bit_rate || !esc_rate)
+               return -EINVAL;
+
+       timing->hs_halfbyte_en = 0;
+       hb_en = 0;
+       timing->hs_halfbyte_en_ckln = 0;
+       hb_en_ckln = 0;
+
+       ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
+       ui_x8 = ui << 3;
+       lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
+
+       temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
+       tmin = max_t(s32, temp, 0);
+       temp = (95 * coeff) / ui_x8;
+       tmax = max_t(s32, temp, 0);
+       timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
+
+       temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
+       tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = (tmin > 255) ? 511 : 255;
+       timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
+
+       tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
+       temp = 105 * coeff + 12 * ui - 20 * coeff;
+       tmax = (temp + 3 * ui) / ui_x8;
+       timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+       temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
+       tmin = max_t(s32, temp, 0);
+       temp = (85 * coeff + 6 * ui) / ui_x8;
+       tmax = max_t(s32, temp, 0);
+       timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
+
+       temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
+       tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = 255;
+       timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
+
+       tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
+       temp = 105 * coeff + 12 * ui - 20 * coeff;
+       tmax = (temp / ui_x8) - 1;
+       timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+       temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
+       timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
+
+       tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
+       tmax = 255;
+       timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
+
+       temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
+       timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
+
+       temp = 60 * coeff + 52 * ui - 43 * ui;
+       tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = 63;
+       timing->shared_timings.clk_post =
+               linear_inter(tmax, tmin, pcnt2, 0, false);
+
+       temp = 8 * ui + (timing->clk_prepare << 3) * ui;
+       temp += (((timing->clk_zero + 3) << 3) + 11) * ui;
+       temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
+               (((timing->hs_rqst_ckln << 3) + 8) * ui);
+       tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = 63;
+       if (tmin > tmax) {
+               temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
+               timing->shared_timings.clk_pre = temp >> 1;
+               timing->shared_timings.clk_pre_inc_by_2 = 1;
+       } else {
+               timing->shared_timings.clk_pre =
+                       linear_inter(tmax, tmin, pcnt2, 0, false);
+                       timing->shared_timings.clk_pre_inc_by_2 = 0;
+       }
+
+       timing->ta_go = 3;
+       timing->ta_sure = 0;
+       timing->ta_get = 4;
+
+       DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+               timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+               timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
+               timing->clk_trail, timing->clk_prepare, timing->hs_exit,
+               timing->hs_zero, timing->hs_prepare, timing->hs_trail,
+               timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
+               timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
+               timing->hs_prep_dly_ckln);
+
+       return 0;
+}
+
 void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
                                u32 bit_mask)
 {
index c56268cbdb3d81925410be764515d0f6be8a9864..a24ab80994a3c08710723f6a0325512785196a84 100644 (file)
@@ -101,6 +101,8 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
                             struct msm_dsi_phy_clk_request *clk_req);
 int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
                                struct msm_dsi_phy_clk_request *clk_req);
+int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
+                               struct msm_dsi_phy_clk_request *clk_req);
 void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
                                u32 bit_mask);
 int msm_dsi_phy_init_common(struct msm_dsi_phy *phy);
index 0af951aaeea1e2d563d4bd2238241e87791a65f7..b3fffc8dbb2ab572aa688aabe8ef4546728e3fb8 100644 (file)
@@ -79,34 +79,6 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
        dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04);
 }
 
-static int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
-                                      struct msm_dsi_phy_clk_request *clk_req)
-{
-       /*
-        * TODO: These params need to be computed, they're currently hardcoded
-        * for a 1440x2560@60Hz panel with a byteclk of 100.618 Mhz, and a
-        * default escape clock of 19.2 Mhz.
-        */
-
-       timing->hs_halfbyte_en = 0;
-       timing->clk_zero = 0x1c;
-       timing->clk_prepare = 0x07;
-       timing->clk_trail = 0x07;
-       timing->hs_exit = 0x23;
-       timing->hs_zero = 0x21;
-       timing->hs_prepare = 0x07;
-       timing->hs_trail = 0x07;
-       timing->hs_rqst = 0x05;
-       timing->ta_sure = 0x00;
-       timing->ta_go = 0x03;
-       timing->ta_get = 0x04;
-
-       timing->shared_timings.clk_pre = 0x2d;
-       timing->shared_timings.clk_post = 0x0d;
-
-       return 0;
-}
-
 static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
                               struct msm_dsi_phy_clk_request *clk_req)
 {
index 0e0c87252ab07c9777cd5f623e71d92c86ea0175..7a16242bf8bf28bb5d7493fb47ded89c754f7092 100644 (file)
@@ -183,7 +183,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
        hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
        vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
 
-       format = kms->funcs->get_format(kms, mode_cmd->pixel_format);
+       format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
+                       mode_cmd->modifier[0]);
        if (!format) {
                dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
                                (char *)&mode_cmd->pixel_format);
index c178563fcd4dc56a2d1fbdaf4197c847b5c11904..456622b4633558b7d0d98a1d57729aac9d33c57f 100644 (file)
@@ -92,8 +92,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
 
        if (IS_ERR(fb)) {
                dev_err(dev->dev, "failed to allocate fb\n");
-               ret = PTR_ERR(fb);
-               goto fail;
+               return PTR_ERR(fb);
        }
 
        bo = msm_framebuffer_bo(fb, 0);
@@ -151,13 +150,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
 
 fail_unlock:
        mutex_unlock(&dev->struct_mutex);
-fail:
-
-       if (ret) {
-               if (fb)
-                       drm_framebuffer_remove(fb);
-       }
-
+       drm_framebuffer_remove(fb);
        return ret;
 }
 
index 95196479f651b18697229765432a0493f6b7d4ce..f583bb4222f9ad13dc17d74ec13d65ad16734506 100644 (file)
@@ -132,17 +132,19 @@ static void put_pages(struct drm_gem_object *obj)
        struct msm_gem_object *msm_obj = to_msm_bo(obj);
 
        if (msm_obj->pages) {
-               /* For non-cached buffers, ensure the new pages are clean
-                * because display controller, GPU, etc. are not coherent:
-                */
-               if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-                       dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
-                                       msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+               if (msm_obj->sgt) {
+                       /* For non-cached buffers, ensure the new
+                        * pages are clean because display controller,
+                        * GPU, etc. are not coherent:
+                        */
+                       if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
+                               dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
+                                            msm_obj->sgt->nents,
+                                            DMA_BIDIRECTIONAL);
 
-               if (msm_obj->sgt)
                        sg_free_table(msm_obj->sgt);
-
-               kfree(msm_obj->sgt);
+                       kfree(msm_obj->sgt);
+               }
 
                if (use_pages(obj))
                        drm_gem_put_pages(obj, msm_obj->pages, true, false);
index 17d5824417ad32a0fbddaf94069a0bb453c8403c..aaa329dc020ece445a5334329ae8ab34f68c8035 100644 (file)
@@ -48,8 +48,11 @@ struct msm_kms_funcs {
        /* functions to wait for atomic commit completed on each CRTC */
        void (*wait_for_crtc_commit_done)(struct msm_kms *kms,
                                        struct drm_crtc *crtc);
+       /* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
+       const struct msm_format *(*get_format)(struct msm_kms *kms,
+                                       const uint32_t format,
+                                       const uint64_t modifiers);
        /* misc: */
-       const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format);
        long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
                        struct drm_encoder *encoder);
        int (*set_split_display)(struct msm_kms *kms,
index c0fb52c6d4caaae43753a387f2fa5898019524db..01665b98c57e18cd2bf5c59323e1df9e95702aff 100644 (file)
@@ -179,10 +179,9 @@ qxl_push_command_ring_release(struct qxl_device *qdev, struct qxl_release *relea
                              uint32_t type, bool interruptible)
 {
        struct qxl_command cmd;
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
 
        cmd.type = type;
-       cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset);
+       cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset);
 
        return qxl_ring_push(qdev->command_ring, &cmd, interruptible);
 }
@@ -192,10 +191,9 @@ qxl_push_cursor_ring_release(struct qxl_device *qdev, struct qxl_release *releas
                             uint32_t type, bool interruptible)
 {
        struct qxl_command cmd;
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
 
        cmd.type = type;
-       cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset);
+       cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset);
 
        return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible);
 }
index 00a1a66b052a5c31fe925bebb4800155013e3897..864b456080c4bf9262121e2e0bbee51a47272a07 100644 (file)
@@ -167,6 +167,7 @@ struct qxl_release {
 
        int id;
        int type;
+       struct qxl_bo *release_bo;
        uint32_t release_offset;
        uint32_t surface_release_id;
        struct ww_acquire_ctx ticket;
index e238a1a2eca1cf47c88248ff3b7419579055a5bc..6cc9f3367fa05581a90280b7cc111259cc2692fa 100644 (file)
@@ -182,9 +182,9 @@ static int qxl_process_single_command(struct qxl_device *qdev,
                goto out_free_reloc;
 
        /* TODO copy slow path code from i915 */
-       fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE));
+       fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK));
        unwritten = __copy_from_user_inatomic_nocache
-               (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE),
+               (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_MASK),
                 u64_to_user_ptr(cmd->command), cmd->command_size);
 
        {
index 5d84a66fed3638144917124a02c68dfd420a2baa..7cb214577275ba76ab0b6045e5863394f1ebb5f9 100644 (file)
@@ -173,6 +173,7 @@ qxl_release_free_list(struct qxl_release *release)
                list_del(&entry->tv.head);
                kfree(entry);
        }
+       release->release_bo = NULL;
 }
 
 void
@@ -296,7 +297,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
 {
        if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) {
                int idr_ret;
-               struct qxl_bo_list *entry = list_first_entry(&create_rel->bos, struct qxl_bo_list, tv.head);
                struct qxl_bo *bo;
                union qxl_release_info *info;
 
@@ -304,8 +304,9 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
                idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
                if (idr_ret < 0)
                        return idr_ret;
-               bo = to_qxl_bo(entry->tv.bo);
+               bo = create_rel->release_bo;
 
+               (*release)->release_bo = bo;
                (*release)->release_offset = create_rel->release_offset + 64;
 
                qxl_release_list_add(*release, bo);
@@ -365,6 +366,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
 
        bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]);
 
+       (*release)->release_bo = bo;
        (*release)->release_offset = qdev->current_release_bo_offset[cur_idx] * release_size_per_bo[cur_idx];
        qdev->current_release_bo_offset[cur_idx]++;
 
@@ -408,13 +410,12 @@ union qxl_release_info *qxl_release_map(struct qxl_device *qdev,
 {
        void *ptr;
        union qxl_release_info *info;
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
-       struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
+       struct qxl_bo *bo = release->release_bo;
 
-       ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_SIZE);
+       ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_MASK);
        if (!ptr)
                return NULL;
-       info = ptr + (release->release_offset & ~PAGE_SIZE);
+       info = ptr + (release->release_offset & ~PAGE_MASK);
        return info;
 }
 
@@ -422,11 +423,10 @@ void qxl_release_unmap(struct qxl_device *qdev,
                       struct qxl_release *release,
                       union qxl_release_info *info)
 {
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
-       struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
+       struct qxl_bo *bo = release->release_bo;
        void *ptr;
 
-       ptr = ((void *)info) - (release->release_offset & ~PAGE_SIZE);
+       ptr = ((void *)info) - (release->release_offset & ~PAGE_MASK);
        qxl_bo_kunmap_atomic_page(qdev, bo, ptr);
 }
 
index bffff4c9fbf56f92dc8a3b566c33e266c729fb95..be3f14d7746deee1b0183c113dc653e4c7e3629d 100644 (file)
@@ -94,64 +94,9 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
        }
 }
 
-static enum drm_mode_status sun4i_lvds_encoder_mode_valid(struct drm_encoder *crtc,
-                                                         const struct drm_display_mode *mode)
-{
-       struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(crtc);
-       struct sun4i_tcon *tcon = lvds->tcon;
-       u32 hsync = mode->hsync_end - mode->hsync_start;
-       u32 vsync = mode->vsync_end - mode->vsync_start;
-       unsigned long rate = mode->clock * 1000;
-       long rounded_rate;
-
-       DRM_DEBUG_DRIVER("Validating modes...\n");
-
-       if (hsync < 1)
-               return MODE_HSYNC_NARROW;
-
-       if (hsync > 0x3ff)
-               return MODE_HSYNC_WIDE;
-
-       if ((mode->hdisplay < 1) || (mode->htotal < 1))
-               return MODE_H_ILLEGAL;
-
-       if ((mode->hdisplay > 0x7ff) || (mode->htotal > 0xfff))
-               return MODE_BAD_HVALUE;
-
-       DRM_DEBUG_DRIVER("Horizontal parameters OK\n");
-
-       if (vsync < 1)
-               return MODE_VSYNC_NARROW;
-
-       if (vsync > 0x3ff)
-               return MODE_VSYNC_WIDE;
-
-       if ((mode->vdisplay < 1) || (mode->vtotal < 1))
-               return MODE_V_ILLEGAL;
-
-       if ((mode->vdisplay > 0x7ff) || (mode->vtotal > 0xfff))
-               return MODE_BAD_VVALUE;
-
-       DRM_DEBUG_DRIVER("Vertical parameters OK\n");
-
-       tcon->dclk_min_div = 7;
-       tcon->dclk_max_div = 7;
-       rounded_rate = clk_round_rate(tcon->dclk, rate);
-       if (rounded_rate < rate)
-               return MODE_CLOCK_LOW;
-
-       if (rounded_rate > rate)
-               return MODE_CLOCK_HIGH;
-
-       DRM_DEBUG_DRIVER("Clock rate OK\n");
-
-       return MODE_OK;
-}
-
 static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
        .disable        = sun4i_lvds_encoder_disable,
        .enable         = sun4i_lvds_encoder_enable,
-       .mode_valid     = sun4i_lvds_encoder_mode_valid,
 };
 
 static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
index 2decc8e2c79f58aad6ea7626a32a0f26665d23eb..add9cc97a3b63baa1194ec82a497180b11d204b5 100644 (file)
@@ -195,6 +195,7 @@ static void vc4_bo_destroy(struct vc4_bo *bo)
        vc4_bo_set_label(obj, -1);
 
        if (bo->validated_shader) {
+               kfree(bo->validated_shader->uniform_addr_offsets);
                kfree(bo->validated_shader->texture_samples);
                kfree(bo->validated_shader);
                bo->validated_shader = NULL;
@@ -591,6 +592,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
        }
 
        if (bo->validated_shader) {
+               kfree(bo->validated_shader->uniform_addr_offsets);
                kfree(bo->validated_shader->texture_samples);
                kfree(bo->validated_shader);
                bo->validated_shader = NULL;
index d3f15bf609008f869f11bb132a1a9f0b2f457739..7cf82b071de2904d2169e67d9cde40df00ce5900 100644 (file)
@@ -942,6 +942,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
 fail:
        kfree(validation_state.branch_targets);
        if (validated_shader) {
+               kfree(validated_shader->uniform_addr_offsets);
                kfree(validated_shader->texture_samples);
                kfree(validated_shader);
        }
index 48e4f1df6e5d933bb5e4204a8866139a70de7f70..020070d483d350a58695c7fa9f21f7c2be4db463 100644 (file)
@@ -293,7 +293,7 @@ retry:
        ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC);
        if (ret == -ENOSPC) {
                spin_unlock(&vgdev->ctrlq.qlock);
-               wait_event(vgdev->ctrlq.ack_queue, vq->num_free);
+               wait_event(vgdev->ctrlq.ack_queue, vq->num_free >= outcnt + incnt);
                spin_lock(&vgdev->ctrlq.qlock);
                goto retry;
        } else {
@@ -368,7 +368,7 @@ retry:
        ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC);
        if (ret == -ENOSPC) {
                spin_unlock(&vgdev->cursorq.qlock);
-               wait_event(vgdev->cursorq.ack_queue, vq->num_free);
+               wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt);
                spin_lock(&vgdev->cursorq.qlock);
                goto retry;
        } else {
index 5a3a7ead301214dceb5cbe99308a08160515ae89..0b5cc910f62e560758f50bb03585ac27942ef199 100644 (file)
 #define I2C_VENDOR_ID_HANTICK          0x0911
 #define I2C_PRODUCT_ID_HANTICK_5288    0x5288
 
+#define I2C_VENDOR_ID_RAYD             0x2386
+#define I2C_PRODUCT_ID_RAYD_3118       0x3118
+
 #define USB_VENDOR_ID_HANWANG          0x0b57
 #define USB_DEVICE_ID_HANWANG_TABLET_FIRST     0x5000
 #define USB_DEVICE_ID_HANWANG_TABLET_LAST      0x8fff
index 6836a856c243ab5c05ff7b1ff2f4af354fd34efb..930652c25120ee14e57859af3bbce8d5072dab26 100644 (file)
@@ -387,7 +387,8 @@ static int hidinput_get_battery_property(struct power_supply *psy,
                break;
 
        case POWER_SUPPLY_PROP_CAPACITY:
-               if (dev->battery_report_type == HID_FEATURE_REPORT) {
+               if (dev->battery_status != HID_BATTERY_REPORTED &&
+                   !dev->battery_avoid_query) {
                        value = hidinput_query_battery_capacity(dev);
                        if (value < 0)
                                return value;
@@ -403,17 +404,17 @@ static int hidinput_get_battery_property(struct power_supply *psy,
                break;
 
        case POWER_SUPPLY_PROP_STATUS:
-               if (!dev->battery_reported &&
-                   dev->battery_report_type == HID_FEATURE_REPORT) {
+               if (dev->battery_status != HID_BATTERY_REPORTED &&
+                   !dev->battery_avoid_query) {
                        value = hidinput_query_battery_capacity(dev);
                        if (value < 0)
                                return value;
 
                        dev->battery_capacity = value;
-                       dev->battery_reported = true;
+                       dev->battery_status = HID_BATTERY_QUERIED;
                }
 
-               if (!dev->battery_reported)
+               if (dev->battery_status == HID_BATTERY_UNKNOWN)
                        val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
                else if (dev->battery_capacity == 100)
                        val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -486,6 +487,14 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
        dev->battery_report_type = report_type;
        dev->battery_report_id = field->report->id;
 
+       /*
+        * Stylus is normally not connected to the device and thus we
+        * can't query the device and get meaningful battery strength.
+        * We have to wait for the device to report it on its own.
+        */
+       dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
+                                  field->physical == HID_DG_STYLUS;
+
        dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
        if (IS_ERR(dev->battery)) {
                error = PTR_ERR(dev->battery);
@@ -530,9 +539,10 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
 
        capacity = hidinput_scale_battery_capacity(dev, value);
 
-       if (!dev->battery_reported || capacity != dev->battery_capacity) {
+       if (dev->battery_status != HID_BATTERY_REPORTED ||
+           capacity != dev->battery_capacity) {
                dev->battery_capacity = capacity;
-               dev->battery_reported = true;
+               dev->battery_status = HID_BATTERY_REPORTED;
                power_supply_changed(dev->battery);
        }
 }
index fbfcc80094329e561c7dfaa0fd3e411144503a49..b39844adea47a333f52079abbefa2ee0186bb13b 100644 (file)
@@ -192,6 +192,11 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t
        int ret = 0, len;
        unsigned char report_number;
 
+       if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+               ret = -ENODEV;
+               goto out;
+       }
+
        dev = hidraw_table[minor]->hid;
 
        if (!dev->ll_driver->raw_request) {
index 97689e98e53fbe9ba1ca80e2d8a9c34a42224026..963328674e93af929fde1e20a3dc3deff3d75569 100644 (file)
@@ -47,6 +47,7 @@
 /* quirks to control the device */
 #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV       BIT(0)
 #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET       BIT(1)
+#define I2C_HID_QUIRK_RESEND_REPORT_DESCR      BIT(2)
 
 /* flags */
 #define I2C_HID_STARTED                0
@@ -171,6 +172,8 @@ static const struct i2c_hid_quirks {
                I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
        { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
                I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
+       { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118,
+               I2C_HID_QUIRK_RESEND_REPORT_DESCR },
        { 0, 0 }
 };
 
@@ -1220,6 +1223,16 @@ static int i2c_hid_resume(struct device *dev)
        if (ret)
                return ret;
 
+       /* RAYDIUM device (2386:3118) need to re-send report descr cmd
+        * after resume, after this it will be back normal.
+        * otherwise it issues too many incomplete reports.
+        */
+       if (ihid->quirks & I2C_HID_QUIRK_RESEND_REPORT_DESCR) {
+               ret = i2c_hid_command(client, &hid_report_descr_cmd, NULL, 0);
+               if (ret)
+                       return ret;
+       }
+
        if (hid->driver && hid->driver->reset_resume) {
                ret = hid->driver->reset_resume(hid);
                return ret;
index 6da16a879c9f27e6c1281684c5200a27f21448d5..5f947ec20dcb35de628c321086c4178e96527f2c 100644 (file)
@@ -689,6 +689,45 @@ static int wacom_intuos_get_tool_type(int tool_id)
        return tool_type;
 }
 
+static void wacom_exit_report(struct wacom_wac *wacom)
+{
+       struct input_dev *input = wacom->pen_input;
+       struct wacom_features *features = &wacom->features;
+       unsigned char *data = wacom->data;
+       int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;
+
+       /*
+        * Reset all states otherwise we lose the initial states
+        * when in-prox next time
+        */
+       input_report_abs(input, ABS_X, 0);
+       input_report_abs(input, ABS_Y, 0);
+       input_report_abs(input, ABS_DISTANCE, 0);
+       input_report_abs(input, ABS_TILT_X, 0);
+       input_report_abs(input, ABS_TILT_Y, 0);
+       if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
+               input_report_key(input, BTN_LEFT, 0);
+               input_report_key(input, BTN_MIDDLE, 0);
+               input_report_key(input, BTN_RIGHT, 0);
+               input_report_key(input, BTN_SIDE, 0);
+               input_report_key(input, BTN_EXTRA, 0);
+               input_report_abs(input, ABS_THROTTLE, 0);
+               input_report_abs(input, ABS_RZ, 0);
+       } else {
+               input_report_abs(input, ABS_PRESSURE, 0);
+               input_report_key(input, BTN_STYLUS, 0);
+               input_report_key(input, BTN_STYLUS2, 0);
+               input_report_key(input, BTN_TOUCH, 0);
+               input_report_abs(input, ABS_WHEEL, 0);
+               if (features->type >= INTUOS3S)
+                       input_report_abs(input, ABS_Z, 0);
+       }
+       input_report_key(input, wacom->tool[idx], 0);
+       input_report_abs(input, ABS_MISC, 0); /* reset tool id */
+       input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+       wacom->id[idx] = 0;
+}
+
 static int wacom_intuos_inout(struct wacom_wac *wacom)
 {
        struct wacom_features *features = &wacom->features;
@@ -741,36 +780,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                if (!wacom->id[idx])
                        return 1;
 
-               /*
-                * Reset all states otherwise we lose the initial states
-                * when in-prox next time
-                */
-               input_report_abs(input, ABS_X, 0);
-               input_report_abs(input, ABS_Y, 0);
-               input_report_abs(input, ABS_DISTANCE, 0);
-               input_report_abs(input, ABS_TILT_X, 0);
-               input_report_abs(input, ABS_TILT_Y, 0);
-               if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
-                       input_report_key(input, BTN_LEFT, 0);
-                       input_report_key(input, BTN_MIDDLE, 0);
-                       input_report_key(input, BTN_RIGHT, 0);
-                       input_report_key(input, BTN_SIDE, 0);
-                       input_report_key(input, BTN_EXTRA, 0);
-                       input_report_abs(input, ABS_THROTTLE, 0);
-                       input_report_abs(input, ABS_RZ, 0);
-               } else {
-                       input_report_abs(input, ABS_PRESSURE, 0);
-                       input_report_key(input, BTN_STYLUS, 0);
-                       input_report_key(input, BTN_STYLUS2, 0);
-                       input_report_key(input, BTN_TOUCH, 0);
-                       input_report_abs(input, ABS_WHEEL, 0);
-                       if (features->type >= INTUOS3S)
-                               input_report_abs(input, ABS_Z, 0);
-               }
-               input_report_key(input, wacom->tool[idx], 0);
-               input_report_abs(input, ABS_MISC, 0); /* reset tool id */
-               input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-               wacom->id[idx] = 0;
+               wacom_exit_report(wacom);
                return 2;
        }
 
@@ -1235,6 +1245,12 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
                if (!valid)
                        continue;
 
+               if (!prox) {
+                       wacom->shared->stylus_in_proximity = false;
+                       wacom_exit_report(wacom);
+                       input_sync(pen_input);
+                       return;
+               }
                if (range) {
                        input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));
                        input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));
index 051a72eecb2455794d51becf66ea66348e6f17c9..d2cc55e213747963de9cf5e061896032f1609fd5 100644 (file)
@@ -40,6 +40,10 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
 #define PCI_DEVICE_ID_AMD_17H_DF_F3    0x1463
 #endif
 
+#ifndef PCI_DEVICE_ID_AMD_17H_RR_NB
+#define PCI_DEVICE_ID_AMD_17H_RR_NB    0x15d0
+#endif
+
 /* CPUID function 0x80000001, ebx */
 #define CPUID_PKGTYPE_MASK     0xf0000000
 #define CPUID_PKGTYPE_F                0x00000000
@@ -72,6 +76,7 @@ struct k10temp_data {
        struct pci_dev *pdev;
        void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
        int temp_offset;
+       u32 temp_adjust_mask;
 };
 
 struct tctl_offset {
@@ -84,6 +89,7 @@ static const struct tctl_offset tctl_offset_table[] = {
        { 0x17, "AMD Ryzen 5 1600X", 20000 },
        { 0x17, "AMD Ryzen 7 1700X", 20000 },
        { 0x17, "AMD Ryzen 7 1800X", 20000 },
+       { 0x17, "AMD Ryzen 7 2700X", 10000 },
        { 0x17, "AMD Ryzen Threadripper 1950X", 27000 },
        { 0x17, "AMD Ryzen Threadripper 1920X", 27000 },
        { 0x17, "AMD Ryzen Threadripper 1900X", 27000 },
@@ -129,6 +135,8 @@ static ssize_t temp1_input_show(struct device *dev,
 
        data->read_tempreg(data->pdev, &regval);
        temp = (regval >> 21) * 125;
+       if (regval & data->temp_adjust_mask)
+               temp -= 49000;
        if (temp > data->temp_offset)
                temp -= data->temp_offset;
        else
@@ -259,12 +267,14 @@ static int k10temp_probe(struct pci_dev *pdev,
        data->pdev = pdev;
 
        if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
-                                         boot_cpu_data.x86_model == 0x70))
+                                         boot_cpu_data.x86_model == 0x70)) {
                data->read_tempreg = read_tempreg_nb_f15;
-       else if (boot_cpu_data.x86 == 0x17)
+       } else if (boot_cpu_data.x86 == 0x17) {
+               data->temp_adjust_mask = 0x80000;
                data->read_tempreg = read_tempreg_nb_f17;
-       else
+       } else {
                data->read_tempreg = read_tempreg_pci;
+       }
 
        for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
                const struct tctl_offset *entry = &tctl_offset_table[i];
@@ -292,6 +302,7 @@ static const struct pci_device_id k10temp_id_table[] = {
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_RR_NB) },
        {}
 };
 MODULE_DEVICE_TABLE(pci, k10temp_id_table);
index 8b0bc4fc06e8ccccdd94029bcb541b436d473469..b0bc77bf2cd9b3a92f6c186add19aa34b5a6cc7d 100644 (file)
@@ -1380,8 +1380,8 @@ static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data)
        /* Activate logical device if needed */
        val = superio_inb(sioaddr, SIO_REG_ENABLE);
        if (!(val & 0x01)) {
-               pr_err("EC is disabled\n");
-               goto fail;
+               pr_warn("Forcibly enabling EC access. Data may be unusable.\n");
+               superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
        }
 
        superio_exit(sioaddr);
index 363bf56eb0f29c89965d48317282653c6598f417..91976b6ca30002b985ef6594f82fcf10aabf91db 100644 (file)
@@ -170,7 +170,10 @@ static int scmi_hwmon_probe(struct scmi_device *sdev)
        scmi_chip_info.info = ptr_scmi_ci;
        chip_info = &scmi_chip_info;
 
-       for (type = 0; type < hwmon_max && nr_count[type]; type++) {
+       for (type = 0; type < hwmon_max; type++) {
+               if (!nr_count[type])
+                       continue;
+
                scmi_hwmon_add_chan_info(scmi_hwmon_chan, dev, nr_count[type],
                                         type, hwmon_attributes[type]);
                *ptr_scmi_ci++ = scmi_hwmon_chan++;
index c4865b08d7fb9e3b194dba2830b837fe6ab17819..8d21b9825d71764dc950a47dec4a3bc3dc102e25 100644 (file)
@@ -707,7 +707,6 @@ config I2C_MPC
 config I2C_MT65XX
        tristate "MediaTek I2C adapter"
        depends on ARCH_MEDIATEK || COMPILE_TEST
-       depends on HAS_DMA
        help
          This selects the MediaTek(R) Integrated Inter Circuit bus driver
          for MT65xx and MT81xx.
@@ -885,7 +884,6 @@ config I2C_SH7760
 
 config I2C_SH_MOBILE
        tristate "SuperH Mobile I2C Controller"
-       depends on HAS_DMA
        depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST
        help
          If you say yes to this option, support will be included for the
@@ -1098,7 +1096,6 @@ config I2C_XLP9XX
 
 config I2C_RCAR
        tristate "Renesas R-Car I2C Controller"
-       depends on HAS_DMA
        depends on ARCH_RENESAS || COMPILE_TEST
        select I2C_SLAVE
        help
index 25fcc3c1e32bf3d9a41fa345982039fb234dbcbd..4053259bccb8d704d9d386287086841690174844 100644 (file)
@@ -86,6 +86,7 @@ struct sprd_i2c {
        u32 count;
        int irq;
        int err;
+       bool is_suspended;
 };
 
 static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count)
@@ -283,6 +284,9 @@ static int sprd_i2c_master_xfer(struct i2c_adapter *i2c_adap,
        struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
        int im, ret;
 
+       if (i2c_dev->is_suspended)
+               return -EBUSY;
+
        ret = pm_runtime_get_sync(i2c_dev->dev);
        if (ret < 0)
                return ret;
@@ -364,13 +368,12 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
        struct sprd_i2c *i2c_dev = dev_id;
        struct i2c_msg *msg = i2c_dev->msg;
        bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
-       u32 i2c_count = readl(i2c_dev->base + I2C_COUNT);
        u32 i2c_tran;
 
        if (msg->flags & I2C_M_RD)
                i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
        else
-               i2c_tran = i2c_count;
+               i2c_tran = i2c_dev->count;
 
        /*
         * If we got one ACK from slave when writing data, and we did not
@@ -408,14 +411,13 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
 {
        struct sprd_i2c *i2c_dev = dev_id;
        struct i2c_msg *msg = i2c_dev->msg;
-       u32 i2c_count = readl(i2c_dev->base + I2C_COUNT);
        bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
        u32 i2c_tran;
 
        if (msg->flags & I2C_M_RD)
                i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
        else
-               i2c_tran = i2c_count;
+               i2c_tran = i2c_dev->count;
 
        /*
         * If we did not get one ACK from slave when writing data, then we
@@ -586,11 +588,23 @@ static int sprd_i2c_remove(struct platform_device *pdev)
 
 static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev)
 {
+       struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
+
+       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_dev->is_suspended = true;
+       i2c_unlock_adapter(&i2c_dev->adap);
+
        return pm_runtime_force_suspend(pdev);
 }
 
 static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev)
 {
+       struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
+
+       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_dev->is_suspended = false;
+       i2c_unlock_adapter(&i2c_dev->adap);
+
        return pm_runtime_force_resume(pdev);
 }
 
index 036a03f0d0a6866001d0badd11cb9b30516ca5de..1667b6e7674f4a0439befcd544d74753e41d43f3 100644 (file)
@@ -280,7 +280,7 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
                 */
                if (msgs[i].flags & I2C_M_RECV_LEN) {
                        if (!(msgs[i].flags & I2C_M_RD) ||
-                           msgs[i].buf[0] < 1 ||
+                           msgs[i].len < 1 || msgs[i].buf[0] < 1 ||
                            msgs[i].len < msgs[i].buf[0] +
                                             I2C_SMBUS_BLOCK_MAX) {
                                res = -EINVAL;
index 46115a39209821830c1a3789d1cb93d67ff35746..c81c79d01d93078fb2a4357e6f0c51aea6a2b12b 100644 (file)
@@ -31,6 +31,7 @@
 enum evdev_clock_type {
        EV_CLK_REAL = 0,
        EV_CLK_MONO,
+       EV_CLK_BOOT,
        EV_CLK_MAX
 };
 
@@ -197,10 +198,12 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
        case CLOCK_REALTIME:
                clk_type = EV_CLK_REAL;
                break;
-       case CLOCK_BOOTTIME:
        case CLOCK_MONOTONIC:
                clk_type = EV_CLK_MONO;
                break;
+       case CLOCK_BOOTTIME:
+               clk_type = EV_CLK_BOOT;
+               break;
        default:
                return -EINVAL;
        }
@@ -311,6 +314,8 @@ static void evdev_events(struct input_handle *handle,
 
        ev_time[EV_CLK_MONO] = ktime_get();
        ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
+       ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
+                                                TK_OFFS_BOOT);
 
        rcu_read_lock();
 
index 766bf26601163c37aebf265160b4d3d0ce09617f..5f04b2d946350d2ef29d579d6e002da061d93ce0 100644 (file)
@@ -88,6 +88,7 @@ static int input_leds_connect(struct input_handler *handler,
                              const struct input_device_id *id)
 {
        struct input_leds *leds;
+       struct input_led *led;
        unsigned int num_leds;
        unsigned int led_code;
        int led_no;
@@ -119,14 +120,13 @@ static int input_leds_connect(struct input_handler *handler,
 
        led_no = 0;
        for_each_set_bit(led_code, dev->ledbit, LED_CNT) {
-               struct input_led *led = &leds->leds[led_no];
+               if (!input_led_info[led_code].name)
+                       continue;
 
+               led = &leds->leds[led_no];
                led->handle = &leds->handle;
                led->code = led_code;
 
-               if (!input_led_info[led_code].name)
-                       continue;
-
                led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s",
                                           dev_name(&dev->dev),
                                           input_led_info[led_code].name);
index 0a67f235ba88a7b6e25877a43b35488a31d8fdf5..38f9501acdf04c6127a45667e831c807e52be09b 100644 (file)
@@ -583,7 +583,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
 
        x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
        y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
-       z = packet[4] & 0x7c;
+       z = packet[4] & 0x7f;
 
        /*
         * The x and y values tend to be quite large, and when used
index 76edbf2c1bced8ac02fd58bd1ea2dc719d4f83b7..082defc329a8e2cb8e4f6744d6fb7cba4c51fe5e 100644 (file)
@@ -147,8 +147,11 @@ static int rmi_spi_xfer(struct rmi_spi_xport *rmi_spi,
        if (len > RMI_SPI_XFER_SIZE_LIMIT)
                return -EINVAL;
 
-       if (rmi_spi->xfer_buf_size < len)
-               rmi_spi_manage_pools(rmi_spi, len);
+       if (rmi_spi->xfer_buf_size < len) {
+               ret = rmi_spi_manage_pools(rmi_spi, len);
+               if (ret < 0)
+                       return ret;
+       }
 
        if (addr == 0)
                /*
index 4f15496fec8b56ebaa75dd22051b0ce63d9a6827..3e613afa10b4ba967a7def75f631997c0e0c6ae4 100644 (file)
@@ -362,7 +362,7 @@ config TOUCHSCREEN_HIDEEP
 
          If unsure, say N.
 
-         To compile this driver as a moudle, choose M here : the
+         To compile this driver as a module, choose M here : the
          module will be called hideep_ts.
 
 config TOUCHSCREEN_ILI210X
index 5d9699fe1b55aa007171d0f99efbbb5b0bbbd35b..09194721aed2dcc23b65a1fae48fbc17766f8671 100644 (file)
@@ -280,7 +280,8 @@ struct mxt_data {
        struct input_dev *input_dev;
        char phys[64];          /* device physical location */
        struct mxt_object *object_table;
-       struct mxt_info info;
+       struct mxt_info *info;
+       void *raw_info_block;
        unsigned int irq;
        unsigned int max_x;
        unsigned int max_y;
@@ -460,12 +461,13 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry)
 {
        u8 appmode = data->client->addr;
        u8 bootloader;
+       u8 family_id = data->info ? data->info->family_id : 0;
 
        switch (appmode) {
        case 0x4a:
        case 0x4b:
                /* Chips after 1664S use different scheme */
-               if (retry || data->info.family_id >= 0xa2) {
+               if (retry || family_id >= 0xa2) {
                        bootloader = appmode - 0x24;
                        break;
                }
@@ -692,7 +694,7 @@ mxt_get_object(struct mxt_data *data, u8 type)
        struct mxt_object *object;
        int i;
 
-       for (i = 0; i < data->info.object_num; i++) {
+       for (i = 0; i < data->info->object_num; i++) {
                object = data->object_table + i;
                if (object->type == type)
                        return object;
@@ -1462,12 +1464,12 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
                data_pos += offset;
        }
 
-       if (cfg_info.family_id != data->info.family_id) {
+       if (cfg_info.family_id != data->info->family_id) {
                dev_err(dev, "Family ID mismatch!\n");
                return -EINVAL;
        }
 
-       if (cfg_info.variant_id != data->info.variant_id) {
+       if (cfg_info.variant_id != data->info->variant_id) {
                dev_err(dev, "Variant ID mismatch!\n");
                return -EINVAL;
        }
@@ -1512,7 +1514,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
 
        /* Malloc memory to store configuration */
        cfg_start_ofs = MXT_OBJECT_START +
-                       data->info.object_num * sizeof(struct mxt_object) +
+                       data->info->object_num * sizeof(struct mxt_object) +
                        MXT_INFO_CHECKSUM_SIZE;
        config_mem_size = data->mem_size - cfg_start_ofs;
        config_mem = kzalloc(config_mem_size, GFP_KERNEL);
@@ -1563,20 +1565,6 @@ release_mem:
        return ret;
 }
 
-static int mxt_get_info(struct mxt_data *data)
-{
-       struct i2c_client *client = data->client;
-       struct mxt_info *info = &data->info;
-       int error;
-
-       /* Read 7-byte info block starting at address 0 */
-       error = __mxt_read_reg(client, 0, sizeof(*info), info);
-       if (error)
-               return error;
-
-       return 0;
-}
-
 static void mxt_free_input_device(struct mxt_data *data)
 {
        if (data->input_dev) {
@@ -1591,9 +1579,10 @@ static void mxt_free_object_table(struct mxt_data *data)
        video_unregister_device(&data->dbg.vdev);
        v4l2_device_unregister(&data->dbg.v4l2);
 #endif
-
-       kfree(data->object_table);
        data->object_table = NULL;
+       data->info = NULL;
+       kfree(data->raw_info_block);
+       data->raw_info_block = NULL;
        kfree(data->msg_buf);
        data->msg_buf = NULL;
        data->T5_address = 0;
@@ -1609,34 +1598,18 @@ static void mxt_free_object_table(struct mxt_data *data)
        data->max_reportid = 0;
 }
 
-static int mxt_get_object_table(struct mxt_data *data)
+static int mxt_parse_object_table(struct mxt_data *data,
+                                 struct mxt_object *object_table)
 {
        struct i2c_client *client = data->client;
-       size_t table_size;
-       struct mxt_object *object_table;
-       int error;
        int i;
        u8 reportid;
        u16 end_address;
 
-       table_size = data->info.object_num * sizeof(struct mxt_object);
-       object_table = kzalloc(table_size, GFP_KERNEL);
-       if (!object_table) {
-               dev_err(&data->client->dev, "Failed to allocate memory\n");
-               return -ENOMEM;
-       }
-
-       error = __mxt_read_reg(client, MXT_OBJECT_START, table_size,
-                       object_table);
-       if (error) {
-               kfree(object_table);
-               return error;
-       }
-
        /* Valid Report IDs start counting from 1 */
        reportid = 1;
        data->mem_size = 0;
-       for (i = 0; i < data->info.object_num; i++) {
+       for (i = 0; i < data->info->object_num; i++) {
                struct mxt_object *object = object_table + i;
                u8 min_id, max_id;
 
@@ -1660,8 +1633,8 @@ static int mxt_get_object_table(struct mxt_data *data)
 
                switch (object->type) {
                case MXT_GEN_MESSAGE_T5:
-                       if (data->info.family_id == 0x80 &&
-                           data->info.version < 0x20) {
+                       if (data->info->family_id == 0x80 &&
+                           data->info->version < 0x20) {
                                /*
                                 * On mXT224 firmware versions prior to V2.0
                                 * read and discard unused CRC byte otherwise
@@ -1716,24 +1689,102 @@ static int mxt_get_object_table(struct mxt_data *data)
        /* If T44 exists, T5 position has to be directly after */
        if (data->T44_address && (data->T5_address != data->T44_address + 1)) {
                dev_err(&client->dev, "Invalid T44 position\n");
-               error = -EINVAL;
-               goto free_object_table;
+               return -EINVAL;
        }
 
        data->msg_buf = kcalloc(data->max_reportid,
                                data->T5_msg_size, GFP_KERNEL);
-       if (!data->msg_buf) {
-               dev_err(&client->dev, "Failed to allocate message buffer\n");
+       if (!data->msg_buf)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static int mxt_read_info_block(struct mxt_data *data)
+{
+       struct i2c_client *client = data->client;
+       int error;
+       size_t size;
+       void *id_buf, *buf;
+       uint8_t num_objects;
+       u32 calculated_crc;
+       u8 *crc_ptr;
+
+       /* If info block already allocated, free it */
+       if (data->raw_info_block)
+               mxt_free_object_table(data);
+
+       /* Read 7-byte ID information block starting at address 0 */
+       size = sizeof(struct mxt_info);
+       id_buf = kzalloc(size, GFP_KERNEL);
+       if (!id_buf)
+               return -ENOMEM;
+
+       error = __mxt_read_reg(client, 0, size, id_buf);
+       if (error)
+               goto err_free_mem;
+
+       /* Resize buffer to give space for rest of info block */
+       num_objects = ((struct mxt_info *)id_buf)->object_num;
+       size += (num_objects * sizeof(struct mxt_object))
+               + MXT_INFO_CHECKSUM_SIZE;
+
+       buf = krealloc(id_buf, size, GFP_KERNEL);
+       if (!buf) {
                error = -ENOMEM;
-               goto free_object_table;
+               goto err_free_mem;
+       }
+       id_buf = buf;
+
+       /* Read rest of info block */
+       error = __mxt_read_reg(client, MXT_OBJECT_START,
+                              size - MXT_OBJECT_START,
+                              id_buf + MXT_OBJECT_START);
+       if (error)
+               goto err_free_mem;
+
+       /* Extract & calculate checksum */
+       crc_ptr = id_buf + size - MXT_INFO_CHECKSUM_SIZE;
+       data->info_crc = crc_ptr[0] | (crc_ptr[1] << 8) | (crc_ptr[2] << 16);
+
+       calculated_crc = mxt_calculate_crc(id_buf, 0,
+                                          size - MXT_INFO_CHECKSUM_SIZE);
+
+       /*
+        * CRC mismatch can be caused by data corruption due to I2C comms
+        * issue or else device is not using Object Based Protocol (eg i2c-hid)
+        */
+       if ((data->info_crc == 0) || (data->info_crc != calculated_crc)) {
+               dev_err(&client->dev,
+                       "Info Block CRC error calculated=0x%06X read=0x%06X\n",
+                       calculated_crc, data->info_crc);
+               error = -EIO;
+               goto err_free_mem;
+       }
+
+       data->raw_info_block = id_buf;
+       data->info = (struct mxt_info *)id_buf;
+
+       dev_info(&client->dev,
+                "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
+                data->info->family_id, data->info->variant_id,
+                data->info->version >> 4, data->info->version & 0xf,
+                data->info->build, data->info->object_num);
+
+       /* Parse object table information */
+       error = mxt_parse_object_table(data, id_buf + MXT_OBJECT_START);
+       if (error) {
+               dev_err(&client->dev, "Error %d parsing object table\n", error);
+               mxt_free_object_table(data);
+               goto err_free_mem;
        }
 
-       data->object_table = object_table;
+       data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START);
 
        return 0;
 
-free_object_table:
-       mxt_free_object_table(data);
+err_free_mem:
+       kfree(id_buf);
        return error;
 }
 
@@ -2046,7 +2097,7 @@ static int mxt_initialize(struct mxt_data *data)
        int error;
 
        while (1) {
-               error = mxt_get_info(data);
+               error = mxt_read_info_block(data);
                if (!error)
                        break;
 
@@ -2077,16 +2128,9 @@ static int mxt_initialize(struct mxt_data *data)
                msleep(MXT_FW_RESET_TIME);
        }
 
-       /* Get object table information */
-       error = mxt_get_object_table(data);
-       if (error) {
-               dev_err(&client->dev, "Error %d reading object table\n", error);
-               return error;
-       }
-
        error = mxt_acquire_irq(data);
        if (error)
-               goto err_free_object_table;
+               return error;
 
        error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
                                        &client->dev, GFP_KERNEL, data,
@@ -2094,14 +2138,10 @@ static int mxt_initialize(struct mxt_data *data)
        if (error) {
                dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
                        error);
-               goto err_free_object_table;
+               return error;
        }
 
        return 0;
-
-err_free_object_table:
-       mxt_free_object_table(data);
-       return error;
 }
 
 static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep)
@@ -2162,7 +2202,7 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
                               unsigned int y)
 {
-       struct mxt_info *info = &data->info;
+       struct mxt_info *info = data->info;
        struct mxt_dbg *dbg = &data->dbg;
        unsigned int ofs, page;
        unsigned int col = 0;
@@ -2490,7 +2530,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
-       struct mxt_info *info = &data->info;
+       struct mxt_info *info = data->info;
        struct mxt_dbg *dbg = &data->dbg;
        struct mxt_object *object;
        int error;
@@ -2576,7 +2616,6 @@ static int mxt_configure_objects(struct mxt_data *data,
                                 const struct firmware *cfg)
 {
        struct device *dev = &data->client->dev;
-       struct mxt_info *info = &data->info;
        int error;
 
        error = mxt_init_t7_power_cfg(data);
@@ -2601,11 +2640,6 @@ static int mxt_configure_objects(struct mxt_data *data,
 
        mxt_debug_init(data);
 
-       dev_info(dev,
-                "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
-                info->family_id, info->variant_id, info->version >> 4,
-                info->version & 0xf, info->build, info->object_num);
-
        return 0;
 }
 
@@ -2614,7 +2648,7 @@ static ssize_t mxt_fw_version_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
        struct mxt_data *data = dev_get_drvdata(dev);
-       struct mxt_info *info = &data->info;
+       struct mxt_info *info = data->info;
        return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n",
                         info->version >> 4, info->version & 0xf, info->build);
 }
@@ -2624,7 +2658,7 @@ static ssize_t mxt_hw_version_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
        struct mxt_data *data = dev_get_drvdata(dev);
-       struct mxt_info *info = &data->info;
+       struct mxt_info *info = data->info;
        return scnprintf(buf, PAGE_SIZE, "%u.%u\n",
                         info->family_id, info->variant_id);
 }
@@ -2663,7 +2697,7 @@ static ssize_t mxt_object_show(struct device *dev,
                return -ENOMEM;
 
        error = 0;
-       for (i = 0; i < data->info.object_num; i++) {
+       for (i = 0; i < data->info->object_num; i++) {
                object = data->object_table + i;
 
                if (!mxt_object_readable(object->type))
@@ -3034,6 +3068,15 @@ static const struct dmi_system_id mxt_dmi_table[] = {
                },
                .driver_data = samus_platform_data,
        },
+       {
+               /* Samsung Chromebook Pro */
+               .ident = "Samsung Chromebook Pro",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"),
+               },
+               .driver_data = samus_platform_data,
+       },
        {
                /* Other Google Chromebooks */
                .ident = "Chromebook",
@@ -3254,6 +3297,11 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
 
 static const struct of_device_id mxt_of_match[] = {
        { .compatible = "atmel,maxtouch", },
+       /* Compatibles listed below are deprecated */
+       { .compatible = "atmel,qt602240_ts", },
+       { .compatible = "atmel,atmel_mxt_ts", },
+       { .compatible = "atmel,atmel_mxt_tp", },
+       { .compatible = "atmel,mXT224", },
        {},
 };
 MODULE_DEVICE_TABLE(of, mxt_of_match);
index a6e87076acc23419efcc66f57fe0731b9d975572..5336bbdbfdc500ccfd18cf2b38c6f9c34effc112 100644 (file)
@@ -68,12 +68,12 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
                goto _do;
 
        {
-               char _dup[len + 1];
                char *dup, *tok, *name, *val;
                int tmp;
 
-               strcpy(_dup, arg);
-               dup = _dup;
+               dup = kstrdup(arg, GFP_ATOMIC);
+               if (!dup)
+                       return;
 
                while ((tok = strsep(&dup, ","))) {
                        if (!strlen(tok))
@@ -89,6 +89,8 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
                                        deftaps = tmp;
                        }
                }
+
+               kfree(dup);
        }
 
 _do:
index 21d50e4cc5e1db760f4cdaf726cc3c106551a839..b05022f94f18c22ff2c72fa71cf11984077152b7 100644 (file)
@@ -279,7 +279,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
                  u16 timebase, u8 *buf, int len)
 {
        u8 *p;
-       u8 frame[len + 32];
+       u8 frame[MAX_DFRAME_LEN_L1 + 32];
        struct socket *socket = NULL;
 
        if (debug & DEBUG_L1OIP_MSG)
@@ -902,7 +902,11 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                p = skb->data;
                l = skb->len;
                while (l) {
-                       ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
+                       /*
+                        * This is technically bounded by L1OIP_MAX_PERFRAME but
+                        * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
+                        */
+                       ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
                        l1oip_socket_send(hc, 0, dch->slot, 0,
                                          hc->chan[dch->slot].tx_counter++, p, ll);
                        p += ll;
@@ -1140,7 +1144,11 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                p = skb->data;
                l = skb->len;
                while (l) {
-                       ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
+                       /*
+                        * This is technically bounded by L1OIP_MAX_PERFRAME but
+                        * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
+                        */
+                       ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
                        l1oip_socket_send(hc, hc->codec, bch->slot, 0,
                                          hc->chan[bch->slot].tx_counter, p, ll);
                        hc->chan[bch->slot].tx_counter += ll;
index 3bea45e8ccff1779682afa98abe8ab3bcca4b0c5..c208c01f63a5a297334f5a21ca1f83816e665fa5 100644 (file)
@@ -9256,8 +9256,10 @@ void md_reload_sb(struct mddev *mddev, int nr)
        check_sb_changes(mddev, rdev);
 
        /* Read all rdev's to update recovery_offset */
-       rdev_for_each_rcu(rdev, mddev)
-               read_rdev(mddev, rdev);
+       rdev_for_each_rcu(rdev, mddev) {
+               if (!test_bit(Faulty, &rdev->flags))
+                       read_rdev(mddev, rdev);
+       }
 }
 EXPORT_SYMBOL(md_reload_sb);
 
index e2943fb74056a3a672395f09dfac9c44c59ca43f..e9e3308cb0a75948e54c135d9b5da2621c073bc6 100644 (file)
@@ -854,7 +854,7 @@ static void flush_pending_writes(struct r1conf *conf)
  *    there is no normal IO happeing.  It must arrange to call
  *    lower_barrier when the particular background IO completes.
  */
-static void raise_barrier(struct r1conf *conf, sector_t sector_nr)
+static sector_t raise_barrier(struct r1conf *conf, sector_t sector_nr)
 {
        int idx = sector_to_idx(sector_nr);
 
@@ -885,13 +885,23 @@ static void raise_barrier(struct r1conf *conf, sector_t sector_nr)
         *    max resync count which allowed on current I/O barrier bucket.
         */
        wait_event_lock_irq(conf->wait_barrier,
-                           !conf->array_frozen &&
+                           (!conf->array_frozen &&
                             !atomic_read(&conf->nr_pending[idx]) &&
-                            atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH,
+                            atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH) ||
+                               test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery),
                            conf->resync_lock);
 
+       if (test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
+               atomic_dec(&conf->barrier[idx]);
+               spin_unlock_irq(&conf->resync_lock);
+               wake_up(&conf->wait_barrier);
+               return -EINTR;
+       }
+
        atomic_inc(&conf->nr_sync_pending);
        spin_unlock_irq(&conf->resync_lock);
+
+       return 0;
 }
 
 static void lower_barrier(struct r1conf *conf, sector_t sector_nr)
@@ -1092,6 +1102,8 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio,
                goto skip_copy;
        }
 
+       behind_bio->bi_write_hint = bio->bi_write_hint;
+
        while (i < vcnt && size) {
                struct page *page;
                int len = min_t(int, PAGE_SIZE, size);
@@ -2662,9 +2674,12 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
 
        bitmap_cond_end_sync(mddev->bitmap, sector_nr,
                mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
-       r1_bio = raid1_alloc_init_r1buf(conf);
 
-       raise_barrier(conf, sector_nr);
+
+       if (raise_barrier(conf, sector_nr))
+               return 0;
+
+       r1_bio = raid1_alloc_init_r1buf(conf);
 
        rcu_read_lock();
        /*
index 71a89d5d3efd773f03bbf2359b91b1fa292619f2..db8043019ec62f9a1cb589bf1e523e43050db419 100644 (file)
 
 int main(void)
 {
-       DEFINE(EMIF_SDCFG_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_sdcfg_val));
-       DEFINE(EMIF_TIMING1_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_timing1_val));
-       DEFINE(EMIF_TIMING2_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_timing2_val));
-       DEFINE(EMIF_TIMING3_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_timing3_val));
-       DEFINE(EMIF_REF_CTRL_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ref_ctrl_val));
-       DEFINE(EMIF_ZQCFG_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_zqcfg_val));
-       DEFINE(EMIF_PMCR_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_pmcr_val));
-       DEFINE(EMIF_PMCR_SHDW_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_pmcr_shdw_val));
-       DEFINE(EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_rd_wr_level_ramp_ctrl));
-       DEFINE(EMIF_RD_WR_EXEC_THRESH_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_rd_wr_exec_thresh));
-       DEFINE(EMIF_COS_CONFIG_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_cos_config));
-       DEFINE(EMIF_PRIORITY_TO_COS_MAPPING_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_priority_to_cos_mapping));
-       DEFINE(EMIF_CONNECT_ID_SERV_1_MAP_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_connect_id_serv_1_map));
-       DEFINE(EMIF_CONNECT_ID_SERV_2_MAP_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_connect_id_serv_2_map));
-       DEFINE(EMIF_OCP_CONFIG_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ocp_config_val));
-       DEFINE(EMIF_LPDDR2_NVM_TIM_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim));
-       DEFINE(EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim_shdw));
-       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val));
-       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val_shdw));
-       DEFINE(EMIF_DDR_PHY_CTLR_1_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ddr_phy_ctlr_1));
-       DEFINE(EMIF_EXT_PHY_CTRL_VALS_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ext_phy_ctrl_vals));
-       DEFINE(EMIF_REGS_AMX3_SIZE, sizeof(struct emif_regs_amx3));
-
-       BLANK();
-
-       DEFINE(EMIF_PM_BASE_ADDR_VIRT_OFFSET,
-              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_virt));
-       DEFINE(EMIF_PM_BASE_ADDR_PHYS_OFFSET,
-              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_phys));
-       DEFINE(EMIF_PM_CONFIG_OFFSET,
-              offsetof(struct ti_emif_pm_data, ti_emif_sram_config));
-       DEFINE(EMIF_PM_REGS_VIRT_OFFSET,
-              offsetof(struct ti_emif_pm_data, regs_virt));
-       DEFINE(EMIF_PM_REGS_PHYS_OFFSET,
-              offsetof(struct ti_emif_pm_data, regs_phys));
-       DEFINE(EMIF_PM_DATA_SIZE, sizeof(struct ti_emif_pm_data));
-
-       BLANK();
-
-       DEFINE(EMIF_PM_SAVE_CONTEXT_OFFSET,
-              offsetof(struct ti_emif_pm_functions, save_context));
-       DEFINE(EMIF_PM_RESTORE_CONTEXT_OFFSET,
-              offsetof(struct ti_emif_pm_functions, restore_context));
-       DEFINE(EMIF_PM_ENTER_SR_OFFSET,
-              offsetof(struct ti_emif_pm_functions, enter_sr));
-       DEFINE(EMIF_PM_EXIT_SR_OFFSET,
-              offsetof(struct ti_emif_pm_functions, exit_sr));
-       DEFINE(EMIF_PM_ABORT_SR_OFFSET,
-              offsetof(struct ti_emif_pm_functions, abort_sr));
-       DEFINE(EMIF_PM_FUNCTIONS_SIZE, sizeof(struct ti_emif_pm_functions));
+       ti_emif_asm_offsets();
 
        return 0;
 }
index 231f3a1e27bff66b64e06751c429a21c31aa12f1..86503f60468fa6a7f10a4e339f01df1934ca7d55 100644 (file)
@@ -1994,6 +1994,7 @@ static struct scsi_host_template mptsas_driver_template = {
        .cmd_per_lun                    = 7,
        .use_clustering                 = ENABLE_CLUSTERING,
        .shost_attrs                    = mptscsih_host_attrs,
+       .no_write_same                  = 1,
 };
 
 static int mptsas_get_linkerrors(struct sas_phy *phy)
index 8e0acd197c43c03756f3263a7710d7f1326d0c89..6af946d16d241f685814fa8933f32fd672c40c22 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
  *   need a custom accessor.
  */
 
+static unsigned long global_flags;
+/*
+ * Workaround for avoiding to use RX DMAC by multiple channels.
+ * On R-Car H3 ES1.* and M3-W ES1.0, when multiple SDHI channels use
+ * RX DMAC simultaneously, sometimes hundreds of bytes data are not
+ * stored into the system memory even if the DMAC interrupt happened.
+ * So, this driver then uses one RX DMAC channel only.
+ */
+#define SDHI_INTERNAL_DMAC_ONE_RX_ONLY 0
+#define SDHI_INTERNAL_DMAC_RX_IN_USE   1
+
 /* Definitions for sampling clocks */
 static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
        {
@@ -126,6 +138,9 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) {
        renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST,
                                            RST_RESERVED_BITS | val);
 
+       if (host->data && host->data->flags & MMC_DATA_READ)
+               clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
+
        renesas_sdhi_internal_dmac_enable_dma(host, true);
 }
 
@@ -155,6 +170,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
        if (data->flags & MMC_DATA_READ) {
                dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
                dir = DMA_FROM_DEVICE;
+               if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) &&
+                   test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags))
+                       goto force_pio;
        } else {
                dtran_mode |= DTRAN_MODE_CH_NUM_CH0;
                dir = DMA_TO_DEVICE;
@@ -208,6 +226,9 @@ static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg)
        renesas_sdhi_internal_dmac_enable_dma(host, false);
        dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->sg_len, dir);
 
+       if (dir == DMA_FROM_DEVICE)
+               clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
+
        tmio_mmc_do_data_irq(host);
 out:
        spin_unlock_irq(&host->lock);
@@ -251,18 +272,24 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = {
  * implementation as others may use a different implementation.
  */
 static const struct soc_device_attribute gen3_soc_whitelist[] = {
-        { .soc_id = "r8a7795", .revision = "ES1.*" },
-        { .soc_id = "r8a7795", .revision = "ES2.0" },
-        { .soc_id = "r8a7796", .revision = "ES1.0" },
-        { .soc_id = "r8a77995", .revision = "ES1.0" },
-        { /* sentinel */ }
+       { .soc_id = "r8a7795", .revision = "ES1.*",
+         .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) },
+       { .soc_id = "r8a7795", .revision = "ES2.0" },
+       { .soc_id = "r8a7796", .revision = "ES1.0",
+         .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) },
+       { .soc_id = "r8a77995", .revision = "ES1.0" },
+       { /* sentinel */ }
 };
 
 static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
 {
-       if (!soc_device_match(gen3_soc_whitelist))
+       const struct soc_device_attribute *soc = soc_device_match(gen3_soc_whitelist);
+
+       if (!soc)
                return -ENODEV;
 
+       global_flags |= (unsigned long)soc->data;
+
        return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops);
 }
 
index 787434e5589dbc15525eee7f2ca851ce224744e4..78c25ad35fd27f019b24f2f4045f214b0e8b5ed5 100644 (file)
@@ -1312,7 +1312,7 @@ static void amd_enable_manual_tuning(struct pci_dev *pdev)
        pci_write_config_dword(pdev, AMD_SD_MISC_CONTROL, val);
 }
 
-static int amd_execute_tuning(struct sdhci_host *host, u32 opcode)
+static int amd_execute_tuning_hs200(struct sdhci_host *host, u32 opcode)
 {
        struct sdhci_pci_slot *slot = sdhci_priv(host);
        struct pci_dev *pdev = slot->chip->pdev;
@@ -1351,6 +1351,27 @@ static int amd_execute_tuning(struct sdhci_host *host, u32 opcode)
        return 0;
 }
 
+static int amd_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       /* AMD requires custom HS200 tuning */
+       if (host->timing == MMC_TIMING_MMC_HS200)
+               return amd_execute_tuning_hs200(host, opcode);
+
+       /* Otherwise perform standard SDHCI tuning */
+       return sdhci_execute_tuning(mmc, opcode);
+}
+
+static int amd_probe_slot(struct sdhci_pci_slot *slot)
+{
+       struct mmc_host_ops *ops = &slot->host->mmc_host_ops;
+
+       ops->execute_tuning = amd_execute_tuning;
+
+       return 0;
+}
+
 static int amd_probe(struct sdhci_pci_chip *chip)
 {
        struct pci_dev  *smbus_dev;
@@ -1385,12 +1406,12 @@ static const struct sdhci_ops amd_sdhci_pci_ops = {
        .set_bus_width                  = sdhci_set_bus_width,
        .reset                          = sdhci_reset,
        .set_uhs_signaling              = sdhci_set_uhs_signaling,
-       .platform_execute_tuning        = amd_execute_tuning,
 };
 
 static const struct sdhci_pci_fixes sdhci_amd = {
        .probe          = amd_probe,
        .ops            = &amd_sdhci_pci_ops,
+       .probe_slot     = amd_probe_slot,
 };
 
 static const struct pci_device_id pci_ids[] = {
index d4c07b85f18e598ef8c0f85e8ce6fd70c9709396..f5695be14499855a2a54071004e8107c3289f680 100644 (file)
@@ -45,6 +45,7 @@
 #define I82802AB       0x00ad
 #define I82802AC       0x00ac
 #define PF38F4476      0x881c
+#define M28F00AP30     0x8963
 /* STMicroelectronics chips */
 #define M50LPW080       0x002F
 #define M50FLW080A     0x0080
@@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,
                extp->MinorVersion = '1';
 }
 
+static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
+{
+       /*
+        * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
+        * Erase Supend for their small Erase Blocks(0x8000)
+        */
+       if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
+               return 1;
+       return 0;
+}
+
 static inline struct cfi_pri_intelext *
 read_pri_intelext(struct map_info *map, __u16 adr)
 {
@@ -831,21 +843,30 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
                     (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
                        goto sleep;
 
+               /* Do not allow suspend iff read/write to EB address */
+               if ((adr & chip->in_progress_block_mask) ==
+                   chip->in_progress_block_addr)
+                       goto sleep;
+
+               /* do not suspend small EBs, buggy Micron Chips */
+               if (cfi_is_micron_28F00AP30(cfi, chip) &&
+                   (chip->in_progress_block_mask == ~(0x8000-1)))
+                       goto sleep;
 
                /* Erase suspend */
-               map_write(map, CMD(0xB0), adr);
+               map_write(map, CMD(0xB0), chip->in_progress_block_addr);
 
                /* If the flash has finished erasing, then 'erase suspend'
                 * appears to make some (28F320) flash devices switch to
                 * 'read' mode.  Make sure that we switch to 'read status'
                 * mode so we get the right data. --rmk
                 */
-               map_write(map, CMD(0x70), adr);
+               map_write(map, CMD(0x70), chip->in_progress_block_addr);
                chip->oldstate = FL_ERASING;
                chip->state = FL_ERASE_SUSPENDING;
                chip->erase_suspended = 1;
                for (;;) {
-                       status = map_read(map, adr);
+                       status = map_read(map, chip->in_progress_block_addr);
                        if (map_word_andequal(map, status, status_OK, status_OK))
                                break;
 
@@ -1041,8 +1062,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
                   sending the 0x70 (Read Status) command to an erasing
                   chip and expecting it to be ignored, that's what we
                   do. */
-               map_write(map, CMD(0xd0), adr);
-               map_write(map, CMD(0x70), adr);
+               map_write(map, CMD(0xd0), chip->in_progress_block_addr);
+               map_write(map, CMD(0x70), chip->in_progress_block_addr);
                chip->oldstate = FL_READY;
                chip->state = FL_ERASING;
                break;
@@ -1933,6 +1954,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        map_write(map, CMD(0xD0), adr);
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
+       chip->in_progress_block_addr = adr;
+       chip->in_progress_block_mask = ~(len - 1);
 
        ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
                                   adr, len,
index 668e2cbc155bbe008858ba9a11a5467fb5fc39ba..692902df259892a78e69964cf1069867d7336acc 100644 (file)
@@ -816,9 +816,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                    (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
                        goto sleep;
 
-               /* We could check to see if we're trying to access the sector
-                * that is currently being erased. However, no user will try
-                * anything like that so we just wait for the timeout. */
+               /* Do not allow suspend iff read/write to EB address */
+               if ((adr & chip->in_progress_block_mask) ==
+                   chip->in_progress_block_addr)
+                       goto sleep;
 
                /* Erase suspend */
                /* It's harmless to issue the Erase-Suspend and Erase-Resume
@@ -2267,6 +2268,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
        chip->in_progress_block_addr = adr;
+       chip->in_progress_block_mask = ~(map->size - 1);
 
        INVALIDATE_CACHE_UDELAY(map, chip,
                                adr, map->size,
@@ -2356,6 +2358,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
        chip->in_progress_block_addr = adr;
+       chip->in_progress_block_mask = ~(len - 1);
 
        INVALIDATE_CACHE_UDELAY(map, chip,
                                adr, len,
index d0cd6f8635d722ab3c1bcfcc32184f47c8dab24c..9c9f8936b63bc37bbcbd7c6d22d6ca85d69f388f 100644 (file)
@@ -162,7 +162,6 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
                ret = nanddev_erase(nand, &pos);
                if (ret) {
                        einfo->fail_addr = nanddev_pos_to_offs(nand, &pos);
-                       einfo->state = MTD_ERASE_FAILED;
 
                        return ret;
                }
@@ -170,8 +169,6 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
                nanddev_pos_next_eraseblock(nand, &pos);
        }
 
-       einfo->state = MTD_ERASE_DONE;
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(nanddev_mtd_erase);
index 10e953218948836e0151f022ef8745d8b523e574..1d779a35ac8ee03152f8d9b1a4f99df753995785 100644 (file)
@@ -2299,29 +2299,20 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
        /*
         * The legacy "num-cs" property indicates the number of CS on the only
         * chip connected to the controller (legacy bindings does not support
-        * more than one chip). CS are only incremented one by one while the RB
-        * pin is always the #0.
+        * more than one chip). The CS and RB pins are always the #0.
         *
         * When not using legacy bindings, a couple of "reg" and "nand-rb"
         * properties must be filled. For each chip, expressed as a subnode,
         * "reg" points to the CS lines and "nand-rb" to the RB line.
         */
-       if (pdata) {
+       if (pdata || nfc->caps->legacy_of_bindings) {
                nsels = 1;
-       } else if (nfc->caps->legacy_of_bindings &&
-                  !of_get_property(np, "num-cs", &nsels)) {
-               dev_err(dev, "missing num-cs property\n");
-               return -EINVAL;
-       } else if (!of_get_property(np, "reg", &nsels)) {
-               dev_err(dev, "missing reg property\n");
-               return -EINVAL;
-       }
-
-       if (!pdata)
-               nsels /= sizeof(u32);
-       if (!nsels) {
-               dev_err(dev, "invalid reg property size\n");
-               return -EINVAL;
+       } else {
+               nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32));
+               if (nsels <= 0) {
+                       dev_err(dev, "missing/invalid reg property\n");
+                       return -EINVAL;
+               }
        }
 
        /* Alloc the nand chip structure */
index f54518ffb36af43221bc01905a731d3c9e73d968..f2052fae21c7453ae6f5fa3698fd2d38fa1884ad 100644 (file)
@@ -645,7 +645,7 @@ static int tango_nand_probe(struct platform_device *pdev)
 
        writel_relaxed(MODE_RAW, nfc->pbus_base + PBUS_PAD_MODE);
 
-       clk = clk_get(&pdev->dev, NULL);
+       clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
index 4b8e9183489aa444edfa193d20fd004581470544..5872f31eaa60f91dae62bc1690e78aa97ca5c2a8 100644 (file)
@@ -501,7 +501,9 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
        void __iomem *reg_base = cqspi->iobase;
        void __iomem *ahb_base = cqspi->ahb_base;
        unsigned int remaining = n_rx;
+       unsigned int mod_bytes = n_rx % 4;
        unsigned int bytes_to_read = 0;
+       u8 *rxbuf_end = rxbuf + n_rx;
        int ret = 0;
 
        writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
@@ -530,11 +532,24 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
                }
 
                while (bytes_to_read != 0) {
+                       unsigned int word_remain = round_down(remaining, 4);
+
                        bytes_to_read *= cqspi->fifo_width;
                        bytes_to_read = bytes_to_read > remaining ?
                                        remaining : bytes_to_read;
-                       ioread32_rep(ahb_base, rxbuf,
-                                    DIV_ROUND_UP(bytes_to_read, 4));
+                       bytes_to_read = round_down(bytes_to_read, 4);
+                       /* Read 4 byte word chunks then single bytes */
+                       if (bytes_to_read) {
+                               ioread32_rep(ahb_base, rxbuf,
+                                            (bytes_to_read / 4));
+                       } else if (!word_remain && mod_bytes) {
+                               unsigned int temp = ioread32(ahb_base);
+
+                               bytes_to_read = mod_bytes;
+                               memcpy(rxbuf, &temp, min((unsigned int)
+                                                        (rxbuf_end - rxbuf),
+                                                        bytes_to_read));
+                       }
                        rxbuf += bytes_to_read;
                        remaining -= bytes_to_read;
                        bytes_to_read = cqspi_get_rd_sram_level(cqspi);
index b7b11301885334315700dc8e3386253dd8178afb..718e4914e3a0b64b0c963e15478ca3c795542a60 100644 (file)
@@ -1660,8 +1660,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
        } /* switch(bond_mode) */
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       slave_dev->npinfo = bond->dev->npinfo;
-       if (slave_dev->npinfo) {
+       if (bond->dev->npinfo) {
                if (slave_enable_netpoll(new_slave)) {
                        netdev_info(bond_dev, "master_dev is using netpoll, but new slave device does not support netpoll\n");
                        res = -EBUSY;
index ac7694c71266e10323c498dc659fbe75e810b359..a036c490b7ce0662f0c29f8fe0e6609344639455 100644 (file)
@@ -285,10 +285,18 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
                               struct sk_buff_head *rxq)
 {
        u16 buf[4] = { 0 }, status, seq_id;
-       u64 ns, timelo, timehi;
        struct skb_shared_hwtstamps *shwt;
+       struct sk_buff_head received;
+       u64 ns, timelo, timehi;
+       unsigned long flags;
        int err;
 
+       /* The latched timestamp belongs to one of the received frames. */
+       __skb_queue_head_init(&received);
+       spin_lock_irqsave(&rxq->lock, flags);
+       skb_queue_splice_tail_init(rxq, &received);
+       spin_unlock_irqrestore(&rxq->lock, flags);
+
        mutex_lock(&chip->reg_lock);
        err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
                                      reg, buf, ARRAY_SIZE(buf));
@@ -311,7 +319,7 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
        /* Since the device can only handle one time stamp at a time,
         * we purge any extra frames from the queue.
         */
-       for ( ; skb; skb = skb_dequeue(rxq)) {
+       for ( ; skb; skb = __skb_dequeue(&received)) {
                if (mv88e6xxx_ts_valid(status) && seq_match(skb, seq_id)) {
                        ns = timehi << 16 | timelo;
 
index 7ea72ef11a55d5a4425959da1d12c69b108676b2..d272dc6984ac6ef3f61743a16912c13552c35b2f 100644 (file)
 #define MDIO_VEND2_AN_STAT             0x8002
 #endif
 
+#ifndef MDIO_VEND2_PMA_CDR_CONTROL
+#define MDIO_VEND2_PMA_CDR_CONTROL     0x8056
+#endif
+
 #ifndef MDIO_CTRL1_SPEED1G
 #define MDIO_CTRL1_SPEED1G             (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
 #endif
 #define XGBE_AN_CL37_TX_CONFIG_MASK    0x08
 #define XGBE_AN_CL37_MII_CTRL_8BIT     0x0100
 
+#define XGBE_PMA_CDR_TRACK_EN_MASK     0x01
+#define XGBE_PMA_CDR_TRACK_EN_OFF      0x00
+#define XGBE_PMA_CDR_TRACK_EN_ON       0x01
+
 /* Bit setting and getting macros
  *  The get macro will extract the current bit field value from within
  *  the variable
index 7d128be613103a1088655c4b1dcc2e10e234a82f..b91143947ed271a6d29c83040aae6f4304e1549d 100644 (file)
@@ -519,6 +519,22 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
                                   "debugfs_create_file failed\n");
        }
 
+       if (pdata->vdata->an_cdr_workaround) {
+               pfile = debugfs_create_bool("an_cdr_workaround", 0600,
+                                           pdata->xgbe_debugfs,
+                                           &pdata->debugfs_an_cdr_workaround);
+               if (!pfile)
+                       netdev_err(pdata->netdev,
+                                  "debugfs_create_bool failed\n");
+
+               pfile = debugfs_create_bool("an_cdr_track_early", 0600,
+                                           pdata->xgbe_debugfs,
+                                           &pdata->debugfs_an_cdr_track_early);
+               if (!pfile)
+                       netdev_err(pdata->netdev,
+                                  "debugfs_create_bool failed\n");
+       }
+
        kfree(buf);
 }
 
index 795e556d4a3f89d70b088189b28dcaae686e6e3f..441d0973957ba0670c847fa1d37c6ef607e66643 100644 (file)
@@ -349,6 +349,7 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
        XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
 
        /* Call MDIO/PHY initialization routine */
+       pdata->debugfs_an_cdr_workaround = pdata->vdata->an_cdr_workaround;
        ret = pdata->phy_if.phy_init(pdata);
        if (ret)
                return ret;
index 072b9f6645978d0c53ce40271b9dbfe44a6baa0a..1b45cd73a258f05211bfc2ca6e69124c5347bda8 100644 (file)
@@ -432,11 +432,16 @@ static void xgbe_an73_disable(struct xgbe_prv_data *pdata)
        xgbe_an73_set(pdata, false, false);
        xgbe_an73_disable_interrupts(pdata);
 
+       pdata->an_start = 0;
+
        netif_dbg(pdata, link, pdata->netdev, "CL73 AN disabled\n");
 }
 
 static void xgbe_an_restart(struct xgbe_prv_data *pdata)
 {
+       if (pdata->phy_if.phy_impl.an_pre)
+               pdata->phy_if.phy_impl.an_pre(pdata);
+
        switch (pdata->an_mode) {
        case XGBE_AN_MODE_CL73:
        case XGBE_AN_MODE_CL73_REDRV:
@@ -453,6 +458,9 @@ static void xgbe_an_restart(struct xgbe_prv_data *pdata)
 
 static void xgbe_an_disable(struct xgbe_prv_data *pdata)
 {
+       if (pdata->phy_if.phy_impl.an_post)
+               pdata->phy_if.phy_impl.an_post(pdata);
+
        switch (pdata->an_mode) {
        case XGBE_AN_MODE_CL73:
        case XGBE_AN_MODE_CL73_REDRV:
@@ -505,11 +513,11 @@ static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata,
                XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL,
                            reg);
 
-               if (pdata->phy_if.phy_impl.kr_training_post)
-                       pdata->phy_if.phy_impl.kr_training_post(pdata);
-
                netif_dbg(pdata, link, pdata->netdev,
                          "KR training initiated\n");
+
+               if (pdata->phy_if.phy_impl.kr_training_post)
+                       pdata->phy_if.phy_impl.kr_training_post(pdata);
        }
 
        return XGBE_AN_PAGE_RECEIVED;
@@ -637,11 +645,11 @@ static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
                        return XGBE_AN_NO_LINK;
        }
 
-       xgbe_an73_disable(pdata);
+       xgbe_an_disable(pdata);
 
        xgbe_switch_mode(pdata);
 
-       xgbe_an73_restart(pdata);
+       xgbe_an_restart(pdata);
 
        return XGBE_AN_INCOMPAT_LINK;
 }
@@ -820,6 +828,9 @@ static void xgbe_an37_state_machine(struct xgbe_prv_data *pdata)
                pdata->an_result = pdata->an_state;
                pdata->an_state = XGBE_AN_READY;
 
+               if (pdata->phy_if.phy_impl.an_post)
+                       pdata->phy_if.phy_impl.an_post(pdata);
+
                netif_dbg(pdata, link, pdata->netdev, "CL37 AN result: %s\n",
                          xgbe_state_as_string(pdata->an_result));
        }
@@ -903,6 +914,9 @@ again:
                pdata->kx_state = XGBE_RX_BPA;
                pdata->an_start = 0;
 
+               if (pdata->phy_if.phy_impl.an_post)
+                       pdata->phy_if.phy_impl.an_post(pdata);
+
                netif_dbg(pdata, link, pdata->netdev, "CL73 AN result: %s\n",
                          xgbe_state_as_string(pdata->an_result));
        }
index eb23f9ba1a9a10091f8d42bb71e35291e224c4f1..82d1f416ee2ac96c9aa2d7e5d70c22650e0407fe 100644 (file)
@@ -456,6 +456,7 @@ static const struct xgbe_version_data xgbe_v2a = {
        .irq_reissue_support            = 1,
        .tx_desc_prefetch               = 5,
        .rx_desc_prefetch               = 5,
+       .an_cdr_workaround              = 1,
 };
 
 static const struct xgbe_version_data xgbe_v2b = {
@@ -470,6 +471,7 @@ static const struct xgbe_version_data xgbe_v2b = {
        .irq_reissue_support            = 1,
        .tx_desc_prefetch               = 5,
        .rx_desc_prefetch               = 5,
+       .an_cdr_workaround              = 1,
 };
 
 static const struct pci_device_id xgbe_pci_table[] = {
index 3304a291aa964c034f1ebcace56d8aaec32c8407..aac884314000c9114decb1a29e743a593a5bce89 100644 (file)
 /* Rate-change complete wait/retry count */
 #define XGBE_RATECHANGE_COUNT          500
 
+/* CDR delay values for KR support (in usec) */
+#define XGBE_CDR_DELAY_INIT            10000
+#define XGBE_CDR_DELAY_INC             10000
+#define XGBE_CDR_DELAY_MAX             100000
+
+/* RRC frequency during link status check */
+#define XGBE_RRC_FREQUENCY             10
+
 enum xgbe_port_mode {
        XGBE_PORT_MODE_RSVD = 0,
        XGBE_PORT_MODE_BACKPLANE,
@@ -245,6 +253,10 @@ enum xgbe_sfp_speed {
 #define XGBE_SFP_BASE_VENDOR_SN                        4
 #define XGBE_SFP_BASE_VENDOR_SN_LEN            16
 
+#define XGBE_SFP_EXTD_OPT1                     1
+#define XGBE_SFP_EXTD_OPT1_RX_LOS              BIT(1)
+#define XGBE_SFP_EXTD_OPT1_TX_FAULT            BIT(3)
+
 #define XGBE_SFP_EXTD_DIAG                     28
 #define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE         BIT(2)
 
@@ -324,6 +336,7 @@ struct xgbe_phy_data {
 
        unsigned int sfp_gpio_address;
        unsigned int sfp_gpio_mask;
+       unsigned int sfp_gpio_inputs;
        unsigned int sfp_gpio_rx_los;
        unsigned int sfp_gpio_tx_fault;
        unsigned int sfp_gpio_mod_absent;
@@ -355,6 +368,10 @@ struct xgbe_phy_data {
        unsigned int redrv_addr;
        unsigned int redrv_lane;
        unsigned int redrv_model;
+
+       /* KR AN support */
+       unsigned int phy_cdr_notrack;
+       unsigned int phy_cdr_delay;
 };
 
 /* I2C, MDIO and GPIO lines are muxed, so only one device at a time */
@@ -974,6 +991,49 @@ static void xgbe_phy_sfp_external_phy(struct xgbe_prv_data *pdata)
        phy_data->sfp_phy_avail = 1;
 }
 
+static bool xgbe_phy_check_sfp_rx_los(struct xgbe_phy_data *phy_data)
+{
+       u8 *sfp_extd = phy_data->sfp_eeprom.extd;
+
+       if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_RX_LOS))
+               return false;
+
+       if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS)
+               return false;
+
+       if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_rx_los))
+               return true;
+
+       return false;
+}
+
+static bool xgbe_phy_check_sfp_tx_fault(struct xgbe_phy_data *phy_data)
+{
+       u8 *sfp_extd = phy_data->sfp_eeprom.extd;
+
+       if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_TX_FAULT))
+               return false;
+
+       if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT)
+               return false;
+
+       if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_tx_fault))
+               return true;
+
+       return false;
+}
+
+static bool xgbe_phy_check_sfp_mod_absent(struct xgbe_phy_data *phy_data)
+{
+       if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT)
+               return false;
+
+       if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_mod_absent))
+               return true;
+
+       return false;
+}
+
 static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -1019,6 +1079,10 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
        if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP)
                return;
 
+       /* Update transceiver signals (eeprom extd/options) */
+       phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data);
+       phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data);
+
        if (xgbe_phy_sfp_parse_quirks(pdata))
                return;
 
@@ -1184,7 +1248,6 @@ put:
 static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
-       unsigned int gpio_input;
        u8 gpio_reg, gpio_ports[2];
        int ret;
 
@@ -1199,23 +1262,9 @@ static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
                return;
        }
 
-       gpio_input = (gpio_ports[1] << 8) | gpio_ports[0];
-
-       if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT) {
-               /* No GPIO, just assume the module is present for now */
-               phy_data->sfp_mod_absent = 0;
-       } else {
-               if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent)))
-                       phy_data->sfp_mod_absent = 0;
-       }
-
-       if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS) &&
-           (gpio_input & (1 << phy_data->sfp_gpio_rx_los)))
-               phy_data->sfp_rx_los = 1;
+       phy_data->sfp_gpio_inputs = (gpio_ports[1] << 8) | gpio_ports[0];
 
-       if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) &&
-           (gpio_input & (1 << phy_data->sfp_gpio_tx_fault)))
-               phy_data->sfp_tx_fault = 1;
+       phy_data->sfp_mod_absent = xgbe_phy_check_sfp_mod_absent(phy_data);
 }
 
 static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata)
@@ -2361,7 +2410,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
                return 1;
 
        /* No link, attempt a receiver reset cycle */
-       if (phy_data->rrc_count++) {
+       if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
                phy_data->rrc_count = 0;
                xgbe_phy_rrc(pdata);
        }
@@ -2669,6 +2718,103 @@ static bool xgbe_phy_port_enabled(struct xgbe_prv_data *pdata)
        return true;
 }
 
+static void xgbe_phy_cdr_track(struct xgbe_prv_data *pdata)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+
+       if (!pdata->debugfs_an_cdr_workaround)
+               return;
+
+       if (!phy_data->phy_cdr_notrack)
+               return;
+
+       usleep_range(phy_data->phy_cdr_delay,
+                    phy_data->phy_cdr_delay + 500);
+
+       XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
+                        XGBE_PMA_CDR_TRACK_EN_MASK,
+                        XGBE_PMA_CDR_TRACK_EN_ON);
+
+       phy_data->phy_cdr_notrack = 0;
+}
+
+static void xgbe_phy_cdr_notrack(struct xgbe_prv_data *pdata)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+
+       if (!pdata->debugfs_an_cdr_workaround)
+               return;
+
+       if (phy_data->phy_cdr_notrack)
+               return;
+
+       XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
+                        XGBE_PMA_CDR_TRACK_EN_MASK,
+                        XGBE_PMA_CDR_TRACK_EN_OFF);
+
+       xgbe_phy_rrc(pdata);
+
+       phy_data->phy_cdr_notrack = 1;
+}
+
+static void xgbe_phy_kr_training_post(struct xgbe_prv_data *pdata)
+{
+       if (!pdata->debugfs_an_cdr_track_early)
+               xgbe_phy_cdr_track(pdata);
+}
+
+static void xgbe_phy_kr_training_pre(struct xgbe_prv_data *pdata)
+{
+       if (pdata->debugfs_an_cdr_track_early)
+               xgbe_phy_cdr_track(pdata);
+}
+
+static void xgbe_phy_an_post(struct xgbe_prv_data *pdata)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+
+       switch (pdata->an_mode) {
+       case XGBE_AN_MODE_CL73:
+       case XGBE_AN_MODE_CL73_REDRV:
+               if (phy_data->cur_mode != XGBE_MODE_KR)
+                       break;
+
+               xgbe_phy_cdr_track(pdata);
+
+               switch (pdata->an_result) {
+               case XGBE_AN_READY:
+               case XGBE_AN_COMPLETE:
+                       break;
+               default:
+                       if (phy_data->phy_cdr_delay < XGBE_CDR_DELAY_MAX)
+                               phy_data->phy_cdr_delay += XGBE_CDR_DELAY_INC;
+                       else
+                               phy_data->phy_cdr_delay = XGBE_CDR_DELAY_INIT;
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+static void xgbe_phy_an_pre(struct xgbe_prv_data *pdata)
+{
+       struct xgbe_phy_data *phy_data = pdata->phy_data;
+
+       switch (pdata->an_mode) {
+       case XGBE_AN_MODE_CL73:
+       case XGBE_AN_MODE_CL73_REDRV:
+               if (phy_data->cur_mode != XGBE_MODE_KR)
+                       break;
+
+               xgbe_phy_cdr_notrack(pdata);
+               break;
+       default:
+               break;
+       }
+}
+
 static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
 {
        struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -2680,6 +2826,9 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
        xgbe_phy_sfp_reset(phy_data);
        xgbe_phy_sfp_mod_absent(pdata);
 
+       /* Reset CDR support */
+       xgbe_phy_cdr_track(pdata);
+
        /* Power off the PHY */
        xgbe_phy_power_off(pdata);
 
@@ -2712,6 +2861,9 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
        /* Start in highest supported mode */
        xgbe_phy_set_mode(pdata, phy_data->start_mode);
 
+       /* Reset CDR support */
+       xgbe_phy_cdr_track(pdata);
+
        /* After starting the I2C controller, we can check for an SFP */
        switch (phy_data->port_mode) {
        case XGBE_PORT_MODE_SFP:
@@ -3019,6 +3171,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
                }
        }
 
+       phy_data->phy_cdr_delay = XGBE_CDR_DELAY_INIT;
+
        /* Register for driving external PHYs */
        mii = devm_mdiobus_alloc(pdata->dev);
        if (!mii) {
@@ -3071,4 +3225,10 @@ void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if *phy_if)
        phy_impl->an_advertising        = xgbe_phy_an_advertising;
 
        phy_impl->an_outcome            = xgbe_phy_an_outcome;
+
+       phy_impl->an_pre                = xgbe_phy_an_pre;
+       phy_impl->an_post               = xgbe_phy_an_post;
+
+       phy_impl->kr_training_pre       = xgbe_phy_kr_training_pre;
+       phy_impl->kr_training_post      = xgbe_phy_kr_training_post;
 }
index ad102c8bac7bf44d8fa92d0bc175333b12f415fc..95d4b56448c68058102cc4fb3da9e1aefc9fea59 100644 (file)
@@ -833,6 +833,7 @@ struct xgbe_hw_if {
 /* This structure represents implementation specific routines for an
  * implementation of a PHY. All routines are required unless noted below.
  *   Optional routines:
+ *     an_pre, an_post
  *     kr_training_pre, kr_training_post
  */
 struct xgbe_phy_impl_if {
@@ -875,6 +876,10 @@ struct xgbe_phy_impl_if {
        /* Process results of auto-negotiation */
        enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *);
 
+       /* Pre/Post auto-negotiation support */
+       void (*an_pre)(struct xgbe_prv_data *);
+       void (*an_post)(struct xgbe_prv_data *);
+
        /* Pre/Post KR training enablement support */
        void (*kr_training_pre)(struct xgbe_prv_data *);
        void (*kr_training_post)(struct xgbe_prv_data *);
@@ -989,6 +994,7 @@ struct xgbe_version_data {
        unsigned int irq_reissue_support;
        unsigned int tx_desc_prefetch;
        unsigned int rx_desc_prefetch;
+       unsigned int an_cdr_workaround;
 };
 
 struct xgbe_vxlan_data {
@@ -1257,6 +1263,9 @@ struct xgbe_prv_data {
        unsigned int debugfs_xprop_reg;
 
        unsigned int debugfs_xi2c_reg;
+
+       bool debugfs_an_cdr_workaround;
+       bool debugfs_an_cdr_track_early;
 };
 
 /* Function prototypes*/
index 1f622ca2a64f4d2e82557df6efdf87e9c4778df4..8ba14ae00e8ffcbc0849ad2080c4efca6893ff53 100644 (file)
@@ -1927,22 +1927,39 @@ static char *bnxt_parse_pkglog(int desired_field, u8 *data, size_t datalen)
        return retval;
 }
 
-static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen)
+static void bnxt_get_pkgver(struct net_device *dev)
 {
+       struct bnxt *bp = netdev_priv(dev);
        u16 index = 0;
-       u32 datalen;
+       char *pkgver;
+       u32 pkglen;
+       u8 *pkgbuf;
+       int len;
 
        if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG,
                                 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
-                                &index, NULL, &datalen) != 0)
-               return NULL;
+                                &index, NULL, &pkglen) != 0)
+               return;
 
-       memset(buf, 0, buflen);
-       if (bnxt_get_nvram_item(dev, index, 0, datalen, buf) != 0)
-               return NULL;
+       pkgbuf = kzalloc(pkglen, GFP_KERNEL);
+       if (!pkgbuf) {
+               dev_err(&bp->pdev->dev, "Unable to allocate memory for pkg version, length = %u\n",
+                       pkglen);
+               return;
+       }
+
+       if (bnxt_get_nvram_item(dev, index, 0, pkglen, pkgbuf))
+               goto err;
 
-       return bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, buf,
-               datalen);
+       pkgver = bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, pkgbuf,
+                                  pkglen);
+       if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
+               len = strlen(bp->fw_ver_str);
+               snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
+                        "/pkg %s", pkgver);
+       }
+err:
+       kfree(pkgbuf);
 }
 
 static int bnxt_get_eeprom(struct net_device *dev,
@@ -2615,22 +2632,10 @@ void bnxt_ethtool_init(struct bnxt *bp)
        struct hwrm_selftest_qlist_input req = {0};
        struct bnxt_test_info *test_info;
        struct net_device *dev = bp->dev;
-       char *pkglog;
        int i, rc;
 
-       pkglog = kzalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL);
-       if (pkglog) {
-               char *pkgver;
-               int len;
+       bnxt_get_pkgver(dev);
 
-               pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH);
-               if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
-                       len = strlen(bp->fw_ver_str);
-                       snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
-                                "/pkg %s", pkgver);
-               }
-               kfree(pkglog);
-       }
        if (bp->hwrm_spec_code < 0x10704 || !BNXT_SINGLE_PF(bp))
                return;
 
index 73f2249555b57c2b0ef4470e076f4bdd442dd463..83444811d3c6bbe28b518fe91ce540d88daf55af 100644 (file)
@@ -59,8 +59,6 @@ enum bnxt_nvm_directory_type {
 #define BNX_DIR_ATTR_NO_CHKSUM                 (1 << 0)
 #define BNX_DIR_ATTR_PROP_STREAM               (1 << 1)
 
-#define BNX_PKG_LOG_MAX_LENGTH                 4096
-
 enum bnxnvm_pkglog_field_index {
        BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP       = 0,
        BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION           = 1,
index 3e62692af0119e0e4f3dfe85d74457500951f19b..fa5b30f547f6620a6e761860be6afa341dc185c8 100644 (file)
@@ -87,7 +87,7 @@ do { \
 
 #define HNAE_AE_REGISTER 0x1
 
-#define RCB_RING_NAME_LEN 16
+#define RCB_RING_NAME_LEN (IFNAMSIZ + 4)
 
 #define HNAE_LOWEST_LATENCY_COAL_PARAM 30
 #define HNAE_LOW_LATENCY_COAL_PARAM    80
index aad5658d79d5f74424a784bbe55ef3df9bc567b7..6e8d6a6f6aaf2c809a92349f64c83f406bd35e9a 100644 (file)
@@ -794,46 +794,61 @@ static int ibmvnic_login(struct net_device *netdev)
 {
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
        unsigned long timeout = msecs_to_jiffies(30000);
-       struct device *dev = &adapter->vdev->dev;
+       int retry_count = 0;
        int rc;
 
        do {
-               if (adapter->renegotiate) {
-                       adapter->renegotiate = false;
+               if (retry_count > IBMVNIC_MAX_QUEUES) {
+                       netdev_warn(netdev, "Login attempts exceeded\n");
+                       return -1;
+               }
+
+               adapter->init_done_rc = 0;
+               reinit_completion(&adapter->init_done);
+               rc = send_login(adapter);
+               if (rc) {
+                       netdev_warn(netdev, "Unable to login\n");
+                       return rc;
+               }
+
+               if (!wait_for_completion_timeout(&adapter->init_done,
+                                                timeout)) {
+                       netdev_warn(netdev, "Login timed out\n");
+                       return -1;
+               }
+
+               if (adapter->init_done_rc == PARTIALSUCCESS) {
+                       retry_count++;
                        release_sub_crqs(adapter, 1);
 
+                       adapter->init_done_rc = 0;
                        reinit_completion(&adapter->init_done);
                        send_cap_queries(adapter);
                        if (!wait_for_completion_timeout(&adapter->init_done,
                                                         timeout)) {
-                               dev_err(dev, "Capabilities query timeout\n");
+                               netdev_warn(netdev,
+                                           "Capabilities query timed out\n");
                                return -1;
                        }
+
                        rc = init_sub_crqs(adapter);
                        if (rc) {
-                               dev_err(dev,
-                                       "Initialization of SCRQ's failed\n");
+                               netdev_warn(netdev,
+                                           "SCRQ initialization failed\n");
                                return -1;
                        }
+
                        rc = init_sub_crq_irqs(adapter);
                        if (rc) {
-                               dev_err(dev,
-                                       "Initialization of SCRQ's irqs failed\n");
+                               netdev_warn(netdev,
+                                           "SCRQ irq initialization failed\n");
                                return -1;
                        }
-               }
-
-               reinit_completion(&adapter->init_done);
-               rc = send_login(adapter);
-               if (rc) {
-                       dev_err(dev, "Unable to attempt device login\n");
-                       return rc;
-               } else if (!wait_for_completion_timeout(&adapter->init_done,
-                                                timeout)) {
-                       dev_err(dev, "Login timeout\n");
+               } else if (adapter->init_done_rc) {
+                       netdev_warn(netdev, "Adapter login failed\n");
                        return -1;
                }
-       } while (adapter->renegotiate);
+       } while (adapter->init_done_rc == PARTIALSUCCESS);
 
        /* handle pending MAC address changes after successful login */
        if (adapter->mac_change_pending) {
@@ -1034,16 +1049,14 @@ static int __ibmvnic_open(struct net_device *netdev)
                netdev_dbg(netdev, "Enabling rx_scrq[%d] irq\n", i);
                if (prev_state == VNIC_CLOSED)
                        enable_irq(adapter->rx_scrq[i]->irq);
-               else
-                       enable_scrq_irq(adapter, adapter->rx_scrq[i]);
+               enable_scrq_irq(adapter, adapter->rx_scrq[i]);
        }
 
        for (i = 0; i < adapter->req_tx_queues; i++) {
                netdev_dbg(netdev, "Enabling tx_scrq[%d] irq\n", i);
                if (prev_state == VNIC_CLOSED)
                        enable_irq(adapter->tx_scrq[i]->irq);
-               else
-                       enable_scrq_irq(adapter, adapter->tx_scrq[i]);
+               enable_scrq_irq(adapter, adapter->tx_scrq[i]);
        }
 
        rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
@@ -1115,7 +1128,7 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter)
        if (!adapter->rx_pool)
                return;
 
-       rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+       rx_scrqs = adapter->num_active_rx_pools;
        rx_entries = adapter->req_rx_add_entries_per_subcrq;
 
        /* Free any remaining skbs in the rx buffer pools */
@@ -1164,7 +1177,7 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter)
        if (!adapter->tx_pool || !adapter->tso_pool)
                return;
 
-       tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
+       tx_scrqs = adapter->num_active_tx_pools;
 
        /* Free any remaining skbs in the tx buffer pools */
        for (i = 0; i < tx_scrqs; i++) {
@@ -1184,6 +1197,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter)
                        if (adapter->tx_scrq[i]->irq) {
                                netdev_dbg(netdev,
                                           "Disabling tx_scrq[%d] irq\n", i);
+                               disable_scrq_irq(adapter, adapter->tx_scrq[i]);
                                disable_irq(adapter->tx_scrq[i]->irq);
                        }
        }
@@ -1193,6 +1207,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter)
                        if (adapter->rx_scrq[i]->irq) {
                                netdev_dbg(netdev,
                                           "Disabling rx_scrq[%d] irq\n", i);
+                               disable_scrq_irq(adapter, adapter->rx_scrq[i]);
                                disable_irq(adapter->rx_scrq[i]->irq);
                        }
                }
@@ -1828,7 +1843,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
        for (i = 0; i < adapter->req_rx_queues; i++)
                napi_schedule(&adapter->napi[i]);
 
-       if (adapter->reset_reason != VNIC_RESET_FAILOVER)
+       if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
+           adapter->reset_reason != VNIC_RESET_CHANGE_PARAM)
                netdev_notify_peers(netdev);
 
        netif_carrier_on(netdev);
@@ -2601,12 +2617,19 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter,
 {
        struct device *dev = &adapter->vdev->dev;
        unsigned long rc;
+       u64 val;
 
        if (scrq->hw_irq > 0x100000000ULL) {
                dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq);
                return 1;
        }
 
+       val = (0xff000000) | scrq->hw_irq;
+       rc = plpar_hcall_norets(H_EOI, val);
+       if (rc)
+               dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
+                       val, rc);
+
        rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
                                H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0);
        if (rc)
@@ -3170,7 +3193,7 @@ static int send_version_xchg(struct ibmvnic_adapter *adapter)
 struct vnic_login_client_data {
        u8      type;
        __be16  len;
-       char    name;
+       char    name[];
 } __packed;
 
 static int vnic_client_data_len(struct ibmvnic_adapter *adapter)
@@ -3199,21 +3222,21 @@ static void vnic_add_client_data(struct ibmvnic_adapter *adapter,
        vlcd->type = 1;
        len = strlen(os_name) + 1;
        vlcd->len = cpu_to_be16(len);
-       strncpy(&vlcd->name, os_name, len);
-       vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len);
+       strncpy(vlcd->name, os_name, len);
+       vlcd = (struct vnic_login_client_data *)(vlcd->name + len);
 
        /* Type 2 - LPAR name */
        vlcd->type = 2;
        len = strlen(utsname()->nodename) + 1;
        vlcd->len = cpu_to_be16(len);
-       strncpy(&vlcd->name, utsname()->nodename, len);
-       vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len);
+       strncpy(vlcd->name, utsname()->nodename, len);
+       vlcd = (struct vnic_login_client_data *)(vlcd->name + len);
 
        /* Type 3 - device name */
        vlcd->type = 3;
        len = strlen(adapter->netdev->name) + 1;
        vlcd->len = cpu_to_be16(len);
-       strncpy(&vlcd->name, adapter->netdev->name, len);
+       strncpy(vlcd->name, adapter->netdev->name, len);
 }
 
 static int send_login(struct ibmvnic_adapter *adapter)
@@ -3942,7 +3965,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
         * to resend the login buffer with fewer queues requested.
         */
        if (login_rsp_crq->generic.rc.code) {
-               adapter->renegotiate = true;
+               adapter->init_done_rc = login_rsp_crq->generic.rc.code;
                complete(&adapter->init_done);
                return 0;
        }
index 99c0b58c2c39258564ba55a6527786c6f7c0be5d..22391e8805f6ffe6abcba00666bdf0231dfbf54f 100644 (file)
@@ -1035,7 +1035,6 @@ struct ibmvnic_adapter {
 
        struct ibmvnic_sub_crq_queue **tx_scrq;
        struct ibmvnic_sub_crq_queue **rx_scrq;
-       bool renegotiate;
 
        /* rx structs */
        struct napi_struct *napi;
index 5b13ca1bd85f6ecc10df136f3aaf2cba78ce979a..7dc5f045e969aaa164bc20c05e63fb22e848ced2 100644 (file)
@@ -586,7 +586,7 @@ struct ice_sw_rule_lg_act {
 #define ICE_LG_ACT_MIRROR_VSI_ID_S     3
 #define ICE_LG_ACT_MIRROR_VSI_ID_M     (0x3FF << ICE_LG_ACT_MIRROR_VSI_ID_S)
 
-       /* Action type = 5 - Large Action */
+       /* Action type = 5 - Generic Value */
 #define ICE_LG_ACT_GENERIC             0x5
 #define ICE_LG_ACT_GENERIC_VALUE_S     3
 #define ICE_LG_ACT_GENERIC_VALUE_M     (0xFFFF << ICE_LG_ACT_GENERIC_VALUE_S)
index 21977ec984c4a1f193d7b68f3dce278edae02986..71d032cc5fa7d7ee8d6af579ca3d0e7813de05b5 100644 (file)
@@ -78,6 +78,7 @@ ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
        struct ice_aq_desc desc;
        enum ice_status status;
        u16 flags;
+       u8 i;
 
        cmd = &desc.params.mac_read;
 
@@ -98,8 +99,16 @@ ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
                return ICE_ERR_CFG;
        }
 
-       ether_addr_copy(hw->port_info->mac.lan_addr, resp->mac_addr);
-       ether_addr_copy(hw->port_info->mac.perm_addr, resp->mac_addr);
+       /* A single port can report up to two (LAN and WoL) addresses */
+       for (i = 0; i < cmd->num_addr; i++)
+               if (resp[i].addr_type == ICE_AQC_MAN_MAC_ADDR_TYPE_LAN) {
+                       ether_addr_copy(hw->port_info->mac.lan_addr,
+                                       resp[i].mac_addr);
+                       ether_addr_copy(hw->port_info->mac.perm_addr,
+                                       resp[i].mac_addr);
+                       break;
+               }
+
        return 0;
 }
 
@@ -464,9 +473,12 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
        if (status)
                goto err_unroll_sched;
 
-       /* Get port MAC information */
-       mac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp);
-       mac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL);
+       /* Get MAC information */
+       /* A single port can report up to two (LAN and WoL) addresses */
+       mac_buf = devm_kcalloc(ice_hw_to_dev(hw), 2,
+                              sizeof(struct ice_aqc_manage_mac_read_resp),
+                              GFP_KERNEL);
+       mac_buf_len = 2 * sizeof(struct ice_aqc_manage_mac_read_resp);
 
        if (!mac_buf) {
                status = ICE_ERR_NO_MEMORY;
index 1b9e2ef48a9dc6ed1a915fc9905b33c53bc22bfd..499904874b3ff863554c315add28a03f3a260eeb 100644 (file)
 #define PFINT_FW_CTL_CAUSE_ENA_S       30
 #define PFINT_FW_CTL_CAUSE_ENA_M       BIT(PFINT_FW_CTL_CAUSE_ENA_S)
 #define PFINT_OICR                     0x0016CA00
-#define PFINT_OICR_INTEVENT_S          0
-#define PFINT_OICR_INTEVENT_M          BIT(PFINT_OICR_INTEVENT_S)
 #define PFINT_OICR_HLP_RDY_S           14
 #define PFINT_OICR_HLP_RDY_M           BIT(PFINT_OICR_HLP_RDY_S)
 #define PFINT_OICR_CPM_RDY_S           15
index 210b7910f1cd1947f000feec0a313273bdaae52c..5299caf55a7f2b44772988d9f4eeb70b27c51cc4 100644 (file)
@@ -1722,9 +1722,6 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
        oicr = rd32(hw, PFINT_OICR);
        ena_mask = rd32(hw, PFINT_OICR_ENA);
 
-       if (!(oicr & PFINT_OICR_INTEVENT_M))
-               goto ena_intr;
-
        if (oicr & PFINT_OICR_GRST_M) {
                u32 reset;
                /* we have a reset warning */
@@ -1782,7 +1779,6 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
        }
        ret = IRQ_HANDLED;
 
-ena_intr:
        /* re-enable interrupt causes that are not handled during this pass */
        wr32(hw, PFINT_OICR_ENA, ena_mask);
        if (!test_bit(__ICE_DOWN, pf->state)) {
index f16ff3e4a84043e0b8a9a12d465cc4214e4484d5..2e6c1d92cc8884b2bb9755483f82c421b5d9e6f1 100644 (file)
@@ -751,14 +751,14 @@ ice_sched_add_nodes_to_layer(struct ice_port_info *pi,
        u16 num_added = 0;
        u32 temp;
 
+       *num_nodes_added = 0;
+
        if (!num_nodes)
                return status;
 
        if (!parent || layer < hw->sw_entry_point_layer)
                return ICE_ERR_PARAM;
 
-       *num_nodes_added = 0;
-
        /* max children per node per layer */
        max_child_nodes =
            le16_to_cpu(hw->layer_info[parent->tx_sched_layer].max_children);
index c1c0bc30a16d8196f8319a21dcb1f8d13ef4ac52..cce7ada8925510b81d7f3e996a1b9e63d32bcd86 100644 (file)
@@ -1700,7 +1700,22 @@ static void igb_configure_cbs(struct igb_adapter *adapter, int queue,
        WARN_ON(hw->mac.type != e1000_i210);
        WARN_ON(queue < 0 || queue > 1);
 
-       if (enable) {
+       if (enable || queue == 0) {
+               /* i210 does not allow the queue 0 to be in the Strict
+                * Priority mode while the Qav mode is enabled, so,
+                * instead of disabling strict priority mode, we give
+                * queue 0 the maximum of credits possible.
+                *
+                * See section 8.12.19 of the i210 datasheet, "Note:
+                * Queue0 QueueMode must be set to 1b when
+                * TransmitMode is set to Qav."
+                */
+               if (queue == 0 && !enable) {
+                       /* max "linkspeed" idleslope in kbps */
+                       idleslope = 1000000;
+                       hicredit = ETH_FRAME_LEN;
+               }
+
                set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_HIGH);
                set_queue_mode(hw, queue, QUEUE_MODE_STREAM_RESERVATION);
 
index 3d9033f26effa743fc4142a6b99a64d7a5effcfd..e3d04f226d57f10a22aff7424a0cb90a28b58602 100644 (file)
@@ -3420,7 +3420,7 @@ static int ixgbevf_setup_all_tx_resources(struct ixgbevf_adapter *adapter)
                if (!err)
                        continue;
                hw_dbg(&adapter->hw, "Allocation for XDP Queue %u failed\n", j);
-               break;
+               goto err_setup_tx;
        }
 
        return 0;
index 54a038943c0649f74f72c8bdb5120d9c285ce8d2..4202f9b5b966345f1aae651ff20377b9b2977b1a 100644 (file)
@@ -663,7 +663,7 @@ enum mvpp2_tag_type {
 #define MVPP2_PE_VID_FILT_RANGE_END     (MVPP2_PRS_TCAM_SRAM_SIZE - 31)
 #define MVPP2_PE_VID_FILT_RANGE_START   (MVPP2_PE_VID_FILT_RANGE_END - \
                                         MVPP2_PRS_VLAN_FILT_RANGE_SIZE + 1)
-#define MVPP2_PE_LAST_FREE_TID          (MVPP2_PE_VID_FILT_RANGE_START - 1)
+#define MVPP2_PE_LAST_FREE_TID          (MVPP2_PE_MAC_RANGE_START - 1)
 #define MVPP2_PE_IP6_EXT_PROTO_UN      (MVPP2_PRS_TCAM_SRAM_SIZE - 30)
 #define MVPP2_PE_IP6_ADDR_UN           (MVPP2_PRS_TCAM_SRAM_SIZE - 29)
 #define MVPP2_PE_IP4_ADDR_UN           (MVPP2_PRS_TCAM_SRAM_SIZE - 28)
@@ -916,6 +916,8 @@ static struct {
 
 #define MVPP2_MIB_COUNTERS_STATS_DELAY         (1 * HZ)
 
+#define MVPP2_DESC_DMA_MASK    DMA_BIT_MASK(40)
+
 /* Definitions */
 
 /* Shared Packet Processor resources */
@@ -1429,7 +1431,7 @@ static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port,
        if (port->priv->hw_version == MVPP21)
                return tx_desc->pp21.buf_dma_addr;
        else
-               return tx_desc->pp22.buf_dma_addr_ptp & GENMASK_ULL(40, 0);
+               return tx_desc->pp22.buf_dma_addr_ptp & MVPP2_DESC_DMA_MASK;
 }
 
 static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
@@ -1447,7 +1449,7 @@ static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
        } else {
                u64 val = (u64)addr;
 
-               tx_desc->pp22.buf_dma_addr_ptp &= ~GENMASK_ULL(40, 0);
+               tx_desc->pp22.buf_dma_addr_ptp &= ~MVPP2_DESC_DMA_MASK;
                tx_desc->pp22.buf_dma_addr_ptp |= val;
                tx_desc->pp22.packet_offset = offset;
        }
@@ -1507,7 +1509,7 @@ static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port,
        if (port->priv->hw_version == MVPP21)
                return rx_desc->pp21.buf_dma_addr;
        else
-               return rx_desc->pp22.buf_dma_addr_key_hash & GENMASK_ULL(40, 0);
+               return rx_desc->pp22.buf_dma_addr_key_hash & MVPP2_DESC_DMA_MASK;
 }
 
 static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
@@ -1516,7 +1518,7 @@ static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
        if (port->priv->hw_version == MVPP21)
                return rx_desc->pp21.buf_cookie;
        else
-               return rx_desc->pp22.buf_cookie_misc & GENMASK_ULL(40, 0);
+               return rx_desc->pp22.buf_cookie_misc & MVPP2_DESC_DMA_MASK;
 }
 
 static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
@@ -8789,7 +8791,7 @@ static int mvpp2_probe(struct platform_device *pdev)
        }
 
        if (priv->hw_version == MVPP22) {
-               err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40));
+               err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK);
                if (err)
                        goto err_mg_clk;
                /* Sadly, the BM pools all share the same register to
index 3735c09d211279a35772d6cbf82f961ebe81c679..577659f332e41e9b36befa3188d1644193466578 100644 (file)
@@ -258,9 +258,6 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
        case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
                nfp_tunnel_keep_alive(app, skb);
                break;
-       case NFP_FLOWER_CMSG_TYPE_TUN_NEIGH:
-               /* Acks from the NFP that the route is added - ignore. */
-               break;
        default:
                nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n",
                                     type);
@@ -275,18 +272,49 @@ out:
 
 void nfp_flower_cmsg_process_rx(struct work_struct *work)
 {
+       struct sk_buff_head cmsg_joined;
        struct nfp_flower_priv *priv;
        struct sk_buff *skb;
 
        priv = container_of(work, struct nfp_flower_priv, cmsg_work);
+       skb_queue_head_init(&cmsg_joined);
+
+       spin_lock_bh(&priv->cmsg_skbs_high.lock);
+       skb_queue_splice_tail_init(&priv->cmsg_skbs_high, &cmsg_joined);
+       spin_unlock_bh(&priv->cmsg_skbs_high.lock);
 
-       while ((skb = skb_dequeue(&priv->cmsg_skbs)))
+       spin_lock_bh(&priv->cmsg_skbs_low.lock);
+       skb_queue_splice_tail_init(&priv->cmsg_skbs_low, &cmsg_joined);
+       spin_unlock_bh(&priv->cmsg_skbs_low.lock);
+
+       while ((skb = __skb_dequeue(&cmsg_joined)))
                nfp_flower_cmsg_process_one_rx(priv->app, skb);
 }
 
-void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
+static void
+nfp_flower_queue_ctl_msg(struct nfp_app *app, struct sk_buff *skb, int type)
 {
        struct nfp_flower_priv *priv = app->priv;
+       struct sk_buff_head *skb_head;
+
+       if (type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY ||
+           type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
+               skb_head = &priv->cmsg_skbs_high;
+       else
+               skb_head = &priv->cmsg_skbs_low;
+
+       if (skb_queue_len(skb_head) >= NFP_FLOWER_WORKQ_MAX_SKBS) {
+               nfp_flower_cmsg_warn(app, "Dropping queued control messages\n");
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
+       skb_queue_tail(skb_head, skb);
+       schedule_work(&priv->cmsg_work);
+}
+
+void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
+{
        struct nfp_flower_cmsg_hdr *cmsg_hdr;
 
        cmsg_hdr = nfp_flower_cmsg_get_hdr(skb);
@@ -306,8 +334,10 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
                   nfp_flower_process_mtu_ack(app, skb)) {
                /* Handle MTU acks outside wq to prevent RTNL conflict. */
                dev_consume_skb_any(skb);
+       } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH) {
+               /* Acks from the NFP that the route is added - ignore. */
+               dev_consume_skb_any(skb);
        } else {
-               skb_queue_tail(&priv->cmsg_skbs, skb);
-               schedule_work(&priv->cmsg_work);
+               nfp_flower_queue_ctl_msg(app, skb, cmsg_hdr->type);
        }
 }
index 96bc0e33980c1066650e7aa3c6c2fcead3db8ba6..b6c0fd053a503d8f087ccca90e0d9655cecd0661 100644 (file)
 #define NFP_FL_IPV4_TUNNEL_TYPE                GENMASK(7, 4)
 #define NFP_FL_IPV4_PRE_TUN_INDEX      GENMASK(2, 0)
 
+#define NFP_FLOWER_WORKQ_MAX_SKBS      30000
+
 #define nfp_flower_cmsg_warn(app, fmt, args...)                         \
        do {                                                            \
                if (net_ratelimit())                                    \
index 6357e0720f43af301451ce15df3a69b8024f3718..ad02592a82b748de1d83bfd26224e3e8b452411d 100644 (file)
@@ -519,7 +519,8 @@ static int nfp_flower_init(struct nfp_app *app)
 
        app->priv = app_priv;
        app_priv->app = app;
-       skb_queue_head_init(&app_priv->cmsg_skbs);
+       skb_queue_head_init(&app_priv->cmsg_skbs_high);
+       skb_queue_head_init(&app_priv->cmsg_skbs_low);
        INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
        init_waitqueue_head(&app_priv->reify_wait_queue);
 
@@ -549,7 +550,8 @@ static void nfp_flower_clean(struct nfp_app *app)
 {
        struct nfp_flower_priv *app_priv = app->priv;
 
-       skb_queue_purge(&app_priv->cmsg_skbs);
+       skb_queue_purge(&app_priv->cmsg_skbs_high);
+       skb_queue_purge(&app_priv->cmsg_skbs_low);
        flush_work(&app_priv->cmsg_work);
 
        nfp_flower_metadata_cleanup(app);
index e030b3ce45106cbe21a1dce850ae37c6deff7ed4..c67e1b54c6141e494d9f30735755ce7b6f8e2b20 100644 (file)
@@ -107,7 +107,10 @@ struct nfp_mtu_conf {
  * @mask_table:                Hash table used to store masks
  * @flow_table:                Hash table used to store flower rules
  * @cmsg_work:         Workqueue for control messages processing
- * @cmsg_skbs:         List of skbs for control message processing
+ * @cmsg_skbs_high:    List of higher priority skbs for control message
+ *                     processing
+ * @cmsg_skbs_low:     List of lower priority skbs for control message
+ *                     processing
  * @nfp_mac_off_list:  List of MAC addresses to offload
  * @nfp_mac_index_list:        List of unique 8-bit indexes for non NFP netdevs
  * @nfp_ipv4_off_list: List of IPv4 addresses to offload
@@ -136,7 +139,8 @@ struct nfp_flower_priv {
        DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS);
        DECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS);
        struct work_struct cmsg_work;
-       struct sk_buff_head cmsg_skbs;
+       struct sk_buff_head cmsg_skbs_high;
+       struct sk_buff_head cmsg_skbs_low;
        struct list_head nfp_mac_off_list;
        struct list_head nfp_mac_index_list;
        struct list_head nfp_ipv4_off_list;
index f7b95818112636941f110673c5a1c32d5cbe1618..cb28ac03e4cacf093207c84de9c490e6ee91f513 100644 (file)
@@ -211,8 +211,11 @@ int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex)
                        break;
 
                err = msleep_interruptible(timeout_ms);
-               if (err != 0)
+               if (err != 0) {
+                       nfp_info(mutex->cpp,
+                                "interrupted waiting for NFP mutex\n");
                        return -ERESTARTSYS;
+               }
 
                if (time_is_before_eq_jiffies(warn_at)) {
                        warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
index 99bb679a980196e769e625d13934ab9f1ef4dcfb..2abee0fe3a7c51633acf63f0f23a07b52cb2bc3e 100644 (file)
@@ -281,8 +281,7 @@ nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg, u32 nsp_cpp, u64 addr,
                if ((*reg & mask) == val)
                        return 0;
 
-               if (msleep_interruptible(25))
-                       return -ERESTARTSYS;
+               msleep(25);
 
                if (time_after(start_time, wait_until))
                        return -ETIMEDOUT;
index d33988570217ba1665d2a7677ac0034e11c074a6..5f4e447c5dce2d2cd4e4f8f981bde86d0335e10a 100644 (file)
@@ -350,15 +350,16 @@ static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev)
 
        real_dev = priv->real_dev;
 
-       if (!rmnet_is_real_dev_registered(real_dev))
-               return -ENODEV;
-
        if (nla_put_u16(skb, IFLA_RMNET_MUX_ID, priv->mux_id))
                goto nla_put_failure;
 
-       port = rmnet_get_port_rtnl(real_dev);
+       if (rmnet_is_real_dev_registered(real_dev)) {
+               port = rmnet_get_port_rtnl(real_dev);
+               f.flags = port->data_format;
+       } else {
+               f.flags = 0;
+       }
 
-       f.flags = port->data_format;
        f.mask  = ~0;
 
        if (nla_put(skb, IFLA_RMNET_FLAGS, sizeof(f), &f))
index 50daad0a14823f44b118881af1e92c00c04ab618..63036d9bf3e63efaaf41d267af35b4970bcbc142 100644 (file)
@@ -3999,29 +3999,6 @@ static void efx_ef10_prepare_flr(struct efx_nic *efx)
        atomic_set(&efx->active_queues, 0);
 }
 
-static bool efx_ef10_filter_equal(const struct efx_filter_spec *left,
-                                 const struct efx_filter_spec *right)
-{
-       if ((left->match_flags ^ right->match_flags) |
-           ((left->flags ^ right->flags) &
-            (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)))
-               return false;
-
-       return memcmp(&left->outer_vid, &right->outer_vid,
-                     sizeof(struct efx_filter_spec) -
-                     offsetof(struct efx_filter_spec, outer_vid)) == 0;
-}
-
-static unsigned int efx_ef10_filter_hash(const struct efx_filter_spec *spec)
-{
-       BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3);
-       return jhash2((const u32 *)&spec->outer_vid,
-                     (sizeof(struct efx_filter_spec) -
-                      offsetof(struct efx_filter_spec, outer_vid)) / 4,
-                     0);
-       /* XXX should we randomise the initval? */
-}
-
 /* Decide whether a filter should be exclusive or else should allow
  * delivery to additional recipients.  Currently we decide that
  * filters for specific local unicast MAC and IP addresses are
@@ -4346,7 +4323,7 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx,
                goto out_unlock;
        match_pri = rc;
 
-       hash = efx_ef10_filter_hash(spec);
+       hash = efx_filter_spec_hash(spec);
        is_mc_recip = efx_filter_is_mc_recipient(spec);
        if (is_mc_recip)
                bitmap_zero(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT);
@@ -4378,7 +4355,7 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx,
                if (!saved_spec) {
                        if (ins_index < 0)
                                ins_index = i;
-               } else if (efx_ef10_filter_equal(spec, saved_spec)) {
+               } else if (efx_filter_spec_equal(spec, saved_spec)) {
                        if (spec->priority < saved_spec->priority &&
                            spec->priority != EFX_FILTER_PRI_AUTO) {
                                rc = -EPERM;
@@ -4762,28 +4739,62 @@ static s32 efx_ef10_filter_get_rx_ids(struct efx_nic *efx,
 static bool efx_ef10_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
                                           unsigned int filter_idx)
 {
+       struct efx_filter_spec *spec, saved_spec;
        struct efx_ef10_filter_table *table;
-       struct efx_filter_spec *spec;
-       bool ret;
+       struct efx_arfs_rule *rule = NULL;
+       bool ret = true, force = false;
+       u16 arfs_id;
 
        down_read(&efx->filter_sem);
        table = efx->filter_state;
        down_write(&table->lock);
        spec = efx_ef10_filter_entry_spec(table, filter_idx);
 
-       if (!spec || spec->priority != EFX_FILTER_PRI_HINT) {
-               ret = true;
+       if (!spec || spec->priority != EFX_FILTER_PRI_HINT)
                goto out_unlock;
-       }
 
-       if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id,
-                                flow_id, filter_idx)) {
-               ret = false;
-               goto out_unlock;
+       spin_lock_bh(&efx->rps_hash_lock);
+       if (!efx->rps_hash_table) {
+               /* In the absence of the table, we always return 0 to ARFS. */
+               arfs_id = 0;
+       } else {
+               rule = efx_rps_hash_find(efx, spec);
+               if (!rule)
+                       /* ARFS table doesn't know of this filter, so remove it */
+                       goto expire;
+               arfs_id = rule->arfs_id;
+               ret = efx_rps_check_rule(rule, filter_idx, &force);
+               if (force)
+                       goto expire;
+               if (!ret) {
+                       spin_unlock_bh(&efx->rps_hash_lock);
+                       goto out_unlock;
+               }
        }
-
+       if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id, flow_id, arfs_id))
+               ret = false;
+       else if (rule)
+               rule->filter_id = EFX_ARFS_FILTER_ID_REMOVING;
+expire:
+       saved_spec = *spec; /* remove operation will kfree spec */
+       spin_unlock_bh(&efx->rps_hash_lock);
+       /* At this point (since we dropped the lock), another thread might queue
+        * up a fresh insertion request (but the actual insertion will be held
+        * up by our possession of the filter table lock).  In that case, it
+        * will set rule->filter_id to EFX_ARFS_FILTER_ID_PENDING, meaning that
+        * the rule is not removed by efx_rps_hash_del() below.
+        */
        ret = efx_ef10_filter_remove_internal(efx, 1U << spec->priority,
                                              filter_idx, true) == 0;
+       /* While we can't safely dereference rule (we dropped the lock), we can
+        * still test it for NULL.
+        */
+       if (ret && rule) {
+               /* Expiring, so remove entry from ARFS table */
+               spin_lock_bh(&efx->rps_hash_lock);
+               efx_rps_hash_del(efx, &saved_spec);
+               spin_unlock_bh(&efx->rps_hash_lock);
+       }
 out_unlock:
        up_write(&table->lock);
        up_read(&efx->filter_sem);
@@ -5265,7 +5276,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
                ids = vlan->uc;
        }
 
-       filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
+       filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;
 
        /* Insert/renew filters */
        for (i = 0; i < addr_count; i++) {
@@ -5334,7 +5345,7 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx,
        int rc;
        u16 *id;
 
-       filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
+       filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;
 
        efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
 
index 692dd729ee2ac05a1c2b74c429fe69dfb9e24498..a4ebd87154946ec11c3067139afee2c4e7395e6b 100644 (file)
@@ -3027,6 +3027,10 @@ static int efx_init_struct(struct efx_nic *efx,
        mutex_init(&efx->mac_lock);
 #ifdef CONFIG_RFS_ACCEL
        mutex_init(&efx->rps_mutex);
+       spin_lock_init(&efx->rps_hash_lock);
+       /* Failure to allocate is not fatal, but may degrade ARFS performance */
+       efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE,
+                                     sizeof(*efx->rps_hash_table), GFP_KERNEL);
 #endif
        efx->phy_op = &efx_dummy_phy_operations;
        efx->mdio.dev = net_dev;
@@ -3070,6 +3074,10 @@ static void efx_fini_struct(struct efx_nic *efx)
 {
        int i;
 
+#ifdef CONFIG_RFS_ACCEL
+       kfree(efx->rps_hash_table);
+#endif
+
        for (i = 0; i < EFX_MAX_CHANNELS; i++)
                kfree(efx->channel[i]);
 
@@ -3092,6 +3100,141 @@ void efx_update_sw_stats(struct efx_nic *efx, u64 *stats)
        stats[GENERIC_STAT_rx_noskb_drops] = atomic_read(&efx->n_rx_noskb_drops);
 }
 
+bool efx_filter_spec_equal(const struct efx_filter_spec *left,
+                          const struct efx_filter_spec *right)
+{
+       if ((left->match_flags ^ right->match_flags) |
+           ((left->flags ^ right->flags) &
+            (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)))
+               return false;
+
+       return memcmp(&left->outer_vid, &right->outer_vid,
+                     sizeof(struct efx_filter_spec) -
+                     offsetof(struct efx_filter_spec, outer_vid)) == 0;
+}
+
+u32 efx_filter_spec_hash(const struct efx_filter_spec *spec)
+{
+       BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3);
+       return jhash2((const u32 *)&spec->outer_vid,
+                     (sizeof(struct efx_filter_spec) -
+                      offsetof(struct efx_filter_spec, outer_vid)) / 4,
+                     0);
+}
+
+#ifdef CONFIG_RFS_ACCEL
+bool efx_rps_check_rule(struct efx_arfs_rule *rule, unsigned int filter_idx,
+                       bool *force)
+{
+       if (rule->filter_id == EFX_ARFS_FILTER_ID_PENDING) {
+               /* ARFS is currently updating this entry, leave it */
+               return false;
+       }
+       if (rule->filter_id == EFX_ARFS_FILTER_ID_ERROR) {
+               /* ARFS tried and failed to update this, so it's probably out
+                * of date.  Remove the filter and the ARFS rule entry.
+                */
+               rule->filter_id = EFX_ARFS_FILTER_ID_REMOVING;
+               *force = true;
+               return true;
+       } else if (WARN_ON(rule->filter_id != filter_idx)) { /* can't happen */
+               /* ARFS has moved on, so old filter is not needed.  Since we did
+                * not mark the rule with EFX_ARFS_FILTER_ID_REMOVING, it will
+                * not be removed by efx_rps_hash_del() subsequently.
+                */
+               *force = true;
+               return true;
+       }
+       /* Remove it iff ARFS wants to. */
+       return true;
+}
+
+struct hlist_head *efx_rps_hash_bucket(struct efx_nic *efx,
+                                      const struct efx_filter_spec *spec)
+{
+       u32 hash = efx_filter_spec_hash(spec);
+
+       WARN_ON(!spin_is_locked(&efx->rps_hash_lock));
+       if (!efx->rps_hash_table)
+               return NULL;
+       return &efx->rps_hash_table[hash % EFX_ARFS_HASH_TABLE_SIZE];
+}
+
+struct efx_arfs_rule *efx_rps_hash_find(struct efx_nic *efx,
+                                       const struct efx_filter_spec *spec)
+{
+       struct efx_arfs_rule *rule;
+       struct hlist_head *head;
+       struct hlist_node *node;
+
+       head = efx_rps_hash_bucket(efx, spec);
+       if (!head)
+               return NULL;
+       hlist_for_each(node, head) {
+               rule = container_of(node, struct efx_arfs_rule, node);
+               if (efx_filter_spec_equal(spec, &rule->spec))
+                       return rule;
+       }
+       return NULL;
+}
+
+struct efx_arfs_rule *efx_rps_hash_add(struct efx_nic *efx,
+                                      const struct efx_filter_spec *spec,
+                                      bool *new)
+{
+       struct efx_arfs_rule *rule;
+       struct hlist_head *head;
+       struct hlist_node *node;
+
+       head = efx_rps_hash_bucket(efx, spec);
+       if (!head)
+               return NULL;
+       hlist_for_each(node, head) {
+               rule = container_of(node, struct efx_arfs_rule, node);
+               if (efx_filter_spec_equal(spec, &rule->spec)) {
+                       *new = false;
+                       return rule;
+               }
+       }
+       rule = kmalloc(sizeof(*rule), GFP_ATOMIC);
+       *new = true;
+       if (rule) {
+               memcpy(&rule->spec, spec, sizeof(rule->spec));
+               hlist_add_head(&rule->node, head);
+       }
+       return rule;
+}
+
+void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec)
+{
+       struct efx_arfs_rule *rule;
+       struct hlist_head *head;
+       struct hlist_node *node;
+
+       head = efx_rps_hash_bucket(efx, spec);
+       if (WARN_ON(!head))
+               return;
+       hlist_for_each(node, head) {
+               rule = container_of(node, struct efx_arfs_rule, node);
+               if (efx_filter_spec_equal(spec, &rule->spec)) {
+                       /* Someone already reused the entry.  We know that if
+                        * this check doesn't fire (i.e. filter_id == REMOVING)
+                        * then the REMOVING mark was put there by our caller,
+                        * because caller is holding a lock on filter table and
+                        * only holders of that lock set REMOVING.
+                        */
+                       if (rule->filter_id != EFX_ARFS_FILTER_ID_REMOVING)
+                               return;
+                       hlist_del(node);
+                       kfree(rule);
+                       return;
+               }
+       }
+       /* We didn't find it. */
+       WARN_ON(1);
+}
+#endif
+
 /* RSS contexts.  We're using linked lists and crappy O(n) algorithms, because
  * (a) this is an infrequent control-plane operation and (b) n is small (max 64)
  */
index a3140e16fcef31f553eeab15e60e8696781ad324..3f759ebdcf1012ce9e913dcd6e96f5fd9307e1a6 100644 (file)
@@ -186,6 +186,27 @@ static inline void efx_filter_rfs_expire(struct work_struct *data) {}
 #endif
 bool efx_filter_is_mc_recipient(const struct efx_filter_spec *spec);
 
+bool efx_filter_spec_equal(const struct efx_filter_spec *left,
+                          const struct efx_filter_spec *right);
+u32 efx_filter_spec_hash(const struct efx_filter_spec *spec);
+
+#ifdef CONFIG_RFS_ACCEL
+bool efx_rps_check_rule(struct efx_arfs_rule *rule, unsigned int filter_idx,
+                       bool *force);
+
+struct efx_arfs_rule *efx_rps_hash_find(struct efx_nic *efx,
+                                       const struct efx_filter_spec *spec);
+
+/* @new is written to indicate if entry was newly added (true) or if an old
+ * entry was found and returned (false).
+ */
+struct efx_arfs_rule *efx_rps_hash_add(struct efx_nic *efx,
+                                      const struct efx_filter_spec *spec,
+                                      bool *new);
+
+void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec);
+#endif
+
 /* RSS contexts */
 struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx);
 struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id);
index 4a19c7efdf8d6c3cb20c4f5a27f9434f1fdd6211..c72adf8b52eac62fd31cf16f3dbae15ee1404381 100644 (file)
@@ -2905,18 +2905,45 @@ bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
 {
        struct efx_farch_filter_state *state = efx->filter_state;
        struct efx_farch_filter_table *table;
-       bool ret = false;
+       bool ret = false, force = false;
+       u16 arfs_id;
 
        down_write(&state->lock);
+       spin_lock_bh(&efx->rps_hash_lock);
        table = &state->table[EFX_FARCH_FILTER_TABLE_RX_IP];
        if (test_bit(index, table->used_bitmap) &&
-           table->spec[index].priority == EFX_FILTER_PRI_HINT &&
-           rps_may_expire_flow(efx->net_dev, table->spec[index].dmaq_id,
-                               flow_id, index)) {
-               efx_farch_filter_table_clear_entry(efx, table, index);
-               ret = true;
+           table->spec[index].priority == EFX_FILTER_PRI_HINT) {
+               struct efx_arfs_rule *rule = NULL;
+               struct efx_filter_spec spec;
+
+               efx_farch_filter_to_gen_spec(&spec, &table->spec[index]);
+               if (!efx->rps_hash_table) {
+                       /* In the absence of the table, we always returned 0 to
+                        * ARFS, so use the same to query it.
+                        */
+                       arfs_id = 0;
+               } else {
+                       rule = efx_rps_hash_find(efx, &spec);
+                       if (!rule) {
+                               /* ARFS table doesn't know of this filter, remove it */
+                               force = true;
+                       } else {
+                               arfs_id = rule->arfs_id;
+                               if (!efx_rps_check_rule(rule, index, &force))
+                                       goto out_unlock;
+                       }
+               }
+               if (force || rps_may_expire_flow(efx->net_dev, spec.dmaq_id,
+                                                flow_id, arfs_id)) {
+                       if (rule)
+                               rule->filter_id = EFX_ARFS_FILTER_ID_REMOVING;
+                       efx_rps_hash_del(efx, &spec);
+                       efx_farch_filter_table_clear_entry(efx, table, index);
+                       ret = true;
+               }
        }
-
+out_unlock:
+       spin_unlock_bh(&efx->rps_hash_lock);
        up_write(&state->lock);
        return ret;
 }
index 5e379a83c729dde0eeebb0bd9535c77b98dd8cc6..65568925c3efe6398d1e26ca1520b53919f60291 100644 (file)
@@ -733,6 +733,56 @@ struct efx_rss_context {
        u32 rx_indir_table[128];
 };
 
+#ifdef CONFIG_RFS_ACCEL
+/* Order of these is important, since filter_id >= %EFX_ARFS_FILTER_ID_PENDING
+ * is used to test if filter does or will exist.
+ */
+#define EFX_ARFS_FILTER_ID_PENDING     -1
+#define EFX_ARFS_FILTER_ID_ERROR       -2
+#define EFX_ARFS_FILTER_ID_REMOVING    -3
+/**
+ * struct efx_arfs_rule - record of an ARFS filter and its IDs
+ * @node: linkage into hash table
+ * @spec: details of the filter (used as key for hash table).  Use efx->type to
+ *     determine which member to use.
+ * @rxq_index: channel to which the filter will steer traffic.
+ * @arfs_id: filter ID which was returned to ARFS
+ * @filter_id: index in software filter table.  May be
+ *     %EFX_ARFS_FILTER_ID_PENDING if filter was not inserted yet,
+ *     %EFX_ARFS_FILTER_ID_ERROR if filter insertion failed, or
+ *     %EFX_ARFS_FILTER_ID_REMOVING if expiry is currently removing the filter.
+ */
+struct efx_arfs_rule {
+       struct hlist_node node;
+       struct efx_filter_spec spec;
+       u16 rxq_index;
+       u16 arfs_id;
+       s32 filter_id;
+};
+
+/* Size chosen so that the table is one page (4kB) */
+#define EFX_ARFS_HASH_TABLE_SIZE       512
+
+/**
+ * struct efx_async_filter_insertion - Request to asynchronously insert a filter
+ * @net_dev: Reference to the netdevice
+ * @spec: The filter to insert
+ * @work: Workitem for this request
+ * @rxq_index: Identifies the channel for which this request was made
+ * @flow_id: Identifies the kernel-side flow for which this request was made
+ */
+struct efx_async_filter_insertion {
+       struct net_device *net_dev;
+       struct efx_filter_spec spec;
+       struct work_struct work;
+       u16 rxq_index;
+       u32 flow_id;
+};
+
+/* Maximum number of ARFS workitems that may be in flight on an efx_nic */
+#define EFX_RPS_MAX_IN_FLIGHT  8
+#endif /* CONFIG_RFS_ACCEL */
+
 /**
  * struct efx_nic - an Efx NIC
  * @name: Device name (net device name or bus id before net device registered)
@@ -850,6 +900,12 @@ struct efx_rss_context {
  * @rps_expire_channel: Next channel to check for expiry
  * @rps_expire_index: Next index to check for expiry in
  *     @rps_expire_channel's @rps_flow_id
+ * @rps_slot_map: bitmap of in-flight entries in @rps_slot
+ * @rps_slot: array of ARFS insertion requests for efx_filter_rfs_work()
+ * @rps_hash_lock: Protects ARFS filter mapping state (@rps_hash_table and
+ *     @rps_next_id).
+ * @rps_hash_table: Mapping between ARFS filters and their various IDs
+ * @rps_next_id: next arfs_id for an ARFS filter
  * @active_queues: Count of RX and TX queues that haven't been flushed and drained.
  * @rxq_flush_pending: Count of number of receive queues that need to be flushed.
  *     Decremented when the efx_flush_rx_queue() is called.
@@ -1004,6 +1060,11 @@ struct efx_nic {
        struct mutex rps_mutex;
        unsigned int rps_expire_channel;
        unsigned int rps_expire_index;
+       unsigned long rps_slot_map;
+       struct efx_async_filter_insertion rps_slot[EFX_RPS_MAX_IN_FLIGHT];
+       spinlock_t rps_hash_lock;
+       struct hlist_head *rps_hash_table;
+       u32 rps_next_id;
 #endif
 
        atomic_t active_queues;
index 95682831484e8457a99eb56a2f8e5c80074cbff9..64a94f2420270e6f64d3524f1a4e755cf35bd0eb 100644 (file)
@@ -827,31 +827,36 @@ MODULE_PARM_DESC(rx_refill_threshold,
 
 #ifdef CONFIG_RFS_ACCEL
 
-/**
- * struct efx_async_filter_insertion - Request to asynchronously insert a filter
- * @net_dev: Reference to the netdevice
- * @spec: The filter to insert
- * @work: Workitem for this request
- * @rxq_index: Identifies the channel for which this request was made
- * @flow_id: Identifies the kernel-side flow for which this request was made
- */
-struct efx_async_filter_insertion {
-       struct net_device *net_dev;
-       struct efx_filter_spec spec;
-       struct work_struct work;
-       u16 rxq_index;
-       u32 flow_id;
-};
-
 static void efx_filter_rfs_work(struct work_struct *data)
 {
        struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion,
                                                              work);
        struct efx_nic *efx = netdev_priv(req->net_dev);
        struct efx_channel *channel = efx_get_channel(efx, req->rxq_index);
+       int slot_idx = req - efx->rps_slot;
+       struct efx_arfs_rule *rule;
+       u16 arfs_id = 0;
        int rc;
 
-       rc = efx->type->filter_insert(efx, &req->spec, false);
+       rc = efx->type->filter_insert(efx, &req->spec, true);
+       if (efx->rps_hash_table) {
+               spin_lock_bh(&efx->rps_hash_lock);
+               rule = efx_rps_hash_find(efx, &req->spec);
+               /* The rule might have already gone, if someone else's request
+                * for the same spec was already worked and then expired before
+                * we got around to our work.  In that case we have nothing
+                * tying us to an arfs_id, meaning that as soon as the filter
+                * is considered for expiry it will be removed.
+                */
+               if (rule) {
+                       if (rc < 0)
+                               rule->filter_id = EFX_ARFS_FILTER_ID_ERROR;
+                       else
+                               rule->filter_id = rc;
+                       arfs_id = rule->arfs_id;
+               }
+               spin_unlock_bh(&efx->rps_hash_lock);
+       }
        if (rc >= 0) {
                /* Remember this so we can check whether to expire the filter
                 * later.
@@ -863,23 +868,23 @@ static void efx_filter_rfs_work(struct work_struct *data)
 
                if (req->spec.ether_type == htons(ETH_P_IP))
                        netif_info(efx, rx_status, efx->net_dev,
-                                  "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n",
+                                  "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d id %u]\n",
                                   (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
                                   req->spec.rem_host, ntohs(req->spec.rem_port),
                                   req->spec.loc_host, ntohs(req->spec.loc_port),
-                                  req->rxq_index, req->flow_id, rc);
+                                  req->rxq_index, req->flow_id, rc, arfs_id);
                else
                        netif_info(efx, rx_status, efx->net_dev,
-                                  "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n",
+                                  "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d id %u]\n",
                                   (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
                                   req->spec.rem_host, ntohs(req->spec.rem_port),
                                   req->spec.loc_host, ntohs(req->spec.loc_port),
-                                  req->rxq_index, req->flow_id, rc);
+                                  req->rxq_index, req->flow_id, rc, arfs_id);
        }
 
        /* Release references */
+       clear_bit(slot_idx, &efx->rps_slot_map);
        dev_put(req->net_dev);
-       kfree(req);
 }
 
 int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
@@ -887,23 +892,39 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
 {
        struct efx_nic *efx = netdev_priv(net_dev);
        struct efx_async_filter_insertion *req;
+       struct efx_arfs_rule *rule;
        struct flow_keys fk;
+       int slot_idx;
+       bool new;
+       int rc;
 
-       if (flow_id == RPS_FLOW_ID_INVALID)
-               return -EINVAL;
+       /* find a free slot */
+       for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++)
+               if (!test_and_set_bit(slot_idx, &efx->rps_slot_map))
+                       break;
+       if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT)
+               return -EBUSY;
 
-       if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
-               return -EPROTONOSUPPORT;
+       if (flow_id == RPS_FLOW_ID_INVALID) {
+               rc = -EINVAL;
+               goto out_clear;
+       }
 
-       if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6))
-               return -EPROTONOSUPPORT;
-       if (fk.control.flags & FLOW_DIS_IS_FRAGMENT)
-               return -EPROTONOSUPPORT;
+       if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) {
+               rc = -EPROTONOSUPPORT;
+               goto out_clear;
+       }
 
-       req = kmalloc(sizeof(*req), GFP_ATOMIC);
-       if (!req)
-               return -ENOMEM;
+       if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) {
+               rc = -EPROTONOSUPPORT;
+               goto out_clear;
+       }
+       if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) {
+               rc = -EPROTONOSUPPORT;
+               goto out_clear;
+       }
 
+       req = efx->rps_slot + slot_idx;
        efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT,
                           efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
                           rxq_index);
@@ -927,12 +948,45 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
        req->spec.rem_port = fk.ports.src;
        req->spec.loc_port = fk.ports.dst;
 
+       if (efx->rps_hash_table) {
+               /* Add it to ARFS hash table */
+               spin_lock(&efx->rps_hash_lock);
+               rule = efx_rps_hash_add(efx, &req->spec, &new);
+               if (!rule) {
+                       rc = -ENOMEM;
+                       goto out_unlock;
+               }
+               if (new)
+                       rule->arfs_id = efx->rps_next_id++ % RPS_NO_FILTER;
+               rc = rule->arfs_id;
+               /* Skip if existing or pending filter already does the right thing */
+               if (!new && rule->rxq_index == rxq_index &&
+                   rule->filter_id >= EFX_ARFS_FILTER_ID_PENDING)
+                       goto out_unlock;
+               rule->rxq_index = rxq_index;
+               rule->filter_id = EFX_ARFS_FILTER_ID_PENDING;
+               spin_unlock(&efx->rps_hash_lock);
+       } else {
+               /* Without an ARFS hash table, we just use arfs_id 0 for all
+                * filters.  This means if multiple flows hash to the same
+                * flow_id, all but the most recently touched will be eligible
+                * for expiry.
+                */
+               rc = 0;
+       }
+
+       /* Queue the request */
        dev_hold(req->net_dev = net_dev);
        INIT_WORK(&req->work, efx_filter_rfs_work);
        req->rxq_index = rxq_index;
        req->flow_id = flow_id;
        schedule_work(&req->work);
-       return 0;
+       return rc;
+out_unlock:
+       spin_unlock(&efx->rps_hash_lock);
+out_clear:
+       clear_bit(slot_idx, &efx->rps_slot_map);
+       return rc;
 }
 
 bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned int quota)
index c7bff596c6655c6f4b3b1f9235952e29fcd8fe4f..dedd40613090d19daef8837ff3bc938055c87fcc 100644 (file)
@@ -347,7 +347,7 @@ enum power_event {
 #define MTL_RX_OVERFLOW_INT            BIT(16)
 
 /* Default operating mode of the MAC */
-#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | GMAC_CONFIG_ACS | \
+#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | \
                        GMAC_CONFIG_BE | GMAC_CONFIG_DCRS)
 
 /* To dump the core regs excluding  the Address Registers */
index a3af92ebbca8aca253ae0108c55679a41f427c86..517b1f6736a8357b1631fa4308349b29e242caff 100644 (file)
@@ -31,13 +31,6 @@ static void dwmac4_core_init(struct mac_device_info *hw,
 
        value |= GMAC_CORE_INIT;
 
-       /* Clear ACS bit because Ethernet switch tagging formats such as
-        * Broadcom tags can look like invalid LLC/SNAP packets and cause the
-        * hardware to truncate packets on reception.
-        */
-       if (netdev_uses_dsa(dev))
-               value &= ~GMAC_CONFIG_ACS;
-
        if (mtu > 1500)
                value |= GMAC_CONFIG_2K;
        if (mtu > 2000)
index 9a16931ce39d14c43ecb950cf46779c7197f0a22..b65e2d144698db0384bbd1e8ba804bea3623f997 100644 (file)
@@ -3495,8 +3495,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 
                        /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
                         * Type frames (LLC/LLC-SNAP)
+                        *
+                        * llc_snap is never checked in GMAC >= 4, so this ACS
+                        * feature is always disabled and packets need to be
+                        * stripped manually.
                         */
-                       if (unlikely(status != llc_snap))
+                       if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) ||
+                           unlikely(status != llc_snap))
                                frame_len -= ETH_FCS_LEN;
 
                        if (netif_msg_rx_status(priv)) {
index 30371274409d7e5704989302939866a3ac1c6ca7..74f828412055196756aa811a57b592e43f46912b 100644 (file)
@@ -129,7 +129,7 @@ do {                                                                \
 
 #define RX_PRIORITY_MAPPING    0x76543210
 #define TX_PRIORITY_MAPPING    0x33221100
-#define CPDMA_TX_PRIORITY_MAP  0x01234567
+#define CPDMA_TX_PRIORITY_MAP  0x76543210
 
 #define CPSW_VLAN_AWARE                BIT(1)
 #define CPSW_RX_VLAN_ENCAP     BIT(2)
index 9cbb0c8a896aff9d192850ad15734dc2872c0dfb..7de88b33d5b96d7f18a5f7c242a54c935b587086 100644 (file)
@@ -3277,7 +3277,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 
        err = netdev_upper_dev_link(real_dev, dev, extack);
        if (err < 0)
-               goto put_dev;
+               goto unregister;
 
        /* need to be already registered so that ->init has run and
         * the MAC addr is set
@@ -3316,8 +3316,7 @@ del_dev:
        macsec_del_dev(macsec);
 unlink:
        netdev_upper_dev_unlink(real_dev, dev);
-put_dev:
-       dev_put(real_dev);
+unregister:
        unregister_netdevice(dev);
        return err;
 }
index c22e8e38324793024d05ce6df15fc9274a5d7fdc..25e2a099b71c198b0c008df09f12a66f1f9f1d90 100644 (file)
@@ -1393,6 +1393,15 @@ static int m88e1318_set_wol(struct phy_device *phydev,
                if (err < 0)
                        goto error;
 
+               /* If WOL event happened once, the LED[2] interrupt pin
+                * will not be cleared unless we reading the interrupt status
+                * register. If interrupts are in use, the normal interrupt
+                * handling will clear the WOL event. Clear the WOL event
+                * before enabling it if !phy_interrupt_is_valid()
+                */
+               if (!phy_interrupt_is_valid(phydev))
+                       phy_read(phydev, MII_M1011_IEVENT);
+
                /* Enable the WOL interrupt */
                err = __phy_modify(phydev, MII_88E1318S_PHY_CSIER, 0,
                                   MII_88E1318S_PHY_CSIER_WOL_EIE);
index 0f293ef289356b1639da4a6619b176b9f6c56da6..a97ac8c12c4cc227176fc013296676856979bdaa 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 #include <linux/microchipphy.h>
+#include <linux/delay.h>
 
 #define DRIVER_AUTHOR  "WOOJUNG HUH <woojung.huh@microchip.com>"
 #define DRIVER_DESC    "Microchip LAN88XX PHY driver"
@@ -30,6 +31,16 @@ struct lan88xx_priv {
        __u32   wolopts;
 };
 
+static int lan88xx_read_page(struct phy_device *phydev)
+{
+       return __phy_read(phydev, LAN88XX_EXT_PAGE_ACCESS);
+}
+
+static int lan88xx_write_page(struct phy_device *phydev, int page)
+{
+       return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page);
+}
+
 static int lan88xx_phy_config_intr(struct phy_device *phydev)
 {
        int rc;
@@ -66,6 +77,150 @@ static int lan88xx_suspend(struct phy_device *phydev)
        return 0;
 }
 
+static int lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr,
+                             u32 data)
+{
+       int val, save_page, ret = 0;
+       u16 buf;
+
+       /* Save current page */
+       save_page = phy_save_page(phydev);
+       if (save_page < 0) {
+               pr_warn("Failed to get current page\n");
+               goto err;
+       }
+
+       /* Switch to TR page */
+       lan88xx_write_page(phydev, LAN88XX_EXT_PAGE_ACCESS_TR);
+
+       ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA,
+                         (data & 0xFFFF));
+       if (ret < 0) {
+               pr_warn("Failed to write TR low data\n");
+               goto err;
+       }
+
+       ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA,
+                         (data & 0x00FF0000) >> 16);
+       if (ret < 0) {
+               pr_warn("Failed to write TR high data\n");
+               goto err;
+       }
+
+       /* Config control bits [15:13] of register */
+       buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */
+       buf |= 0x8000; /* Set [15] to Packet transmit */
+
+       ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf);
+       if (ret < 0) {
+               pr_warn("Failed to write data in reg\n");
+               goto err;
+       }
+
+       usleep_range(1000, 2000);/* Wait for Data to be written */
+       val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR);
+       if (!(val & 0x8000))
+               pr_warn("TR Register[0x%X] configuration failed\n", regaddr);
+err:
+       return phy_restore_page(phydev, save_page, ret);
+}
+
+static void lan88xx_config_TR_regs(struct phy_device *phydev)
+{
+       int err;
+
+       /* Get access to Channel 0x1, Node 0xF , Register 0x01.
+        * Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf,
+        * MrvlTrFix1000Kp, MasterEnableTR bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0F82]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x06.
+        * Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv,
+        * SSTrKp1000Mas bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x168C]\n");
+
+       /* Get access to Channel b'10, Node b'1111, Register 0x11.
+        * Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh
+        * bits
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x17A2]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x10.
+        * Write 24-bit value 0xEEFFDD to register. Setting
+        * eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000,
+        * eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A0]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x13.
+        * Write 24-bit value 0x071448 to register. Setting
+        * slv_lpi_tr_tmr_val1, slv_lpi_tr_tmr_val2 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A6, 0x071448);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A6]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x12.
+        * Write 24-bit value 0x13132F to register. Setting
+        * slv_sigdet_timer_val1, slv_sigdet_timer_val2 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A4, 0x13132F);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A4]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x14.
+        * Write 24-bit value 0x0 to register. Setting eee_3level_delay,
+        * eee_TrKf_freeze_delay bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A8, 0x0);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A8]\n");
+
+       /* Get access to Channel b'01, Node b'1111, Register 0x34.
+        * Write 24-bit value 0x91B06C to register. Setting
+        * FastMseSearchThreshLong1000, FastMseSearchThreshShort1000,
+        * FastMseSearchUpdGain1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0FE8, 0x91B06C);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0FE8]\n");
+
+       /* Get access to Channel b'01, Node b'1111, Register 0x3E.
+        * Write 24-bit value 0xC0A028 to register. Setting
+        * FastMseKp2ThreshLong1000, FastMseKp2ThreshShort1000,
+        * FastMseKp2UpdGain1000, FastMseKp2ExitEn1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0FFC, 0xC0A028);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0FFC]\n");
+
+       /* Get access to Channel b'01, Node b'1111, Register 0x35.
+        * Write 24-bit value 0x041600 to register. Setting
+        * FastMseSearchPhShNum1000, FastMseSearchClksPerPh1000,
+        * FastMsePhChangeDelay1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0FEA, 0x041600);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0FEA]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x03.
+        * Write 24-bit value 0x000004 to register. Setting TrFreeze bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x1686, 0x000004);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x1686]\n");
+}
+
 static int lan88xx_probe(struct phy_device *phydev)
 {
        struct device *dev = &phydev->mdio.dev;
@@ -132,6 +287,25 @@ static void lan88xx_set_mdix(struct phy_device *phydev)
        phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_0);
 }
 
+static int lan88xx_config_init(struct phy_device *phydev)
+{
+       int val;
+
+       genphy_config_init(phydev);
+       /*Zerodetect delay enable */
+       val = phy_read_mmd(phydev, MDIO_MMD_PCS,
+                          PHY_ARDENNES_MMD_DEV_3_PHY_CFG);
+       val |= PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_;
+
+       phy_write_mmd(phydev, MDIO_MMD_PCS, PHY_ARDENNES_MMD_DEV_3_PHY_CFG,
+                     val);
+
+       /* Config DSP registers */
+       lan88xx_config_TR_regs(phydev);
+
+       return 0;
+}
+
 static int lan88xx_config_aneg(struct phy_device *phydev)
 {
        lan88xx_set_mdix(phydev);
@@ -151,7 +325,7 @@ static struct phy_driver microchip_phy_driver[] = {
        .probe          = lan88xx_probe,
        .remove         = lan88xx_remove,
 
-       .config_init    = genphy_config_init,
+       .config_init    = lan88xx_config_init,
        .config_aneg    = lan88xx_config_aneg,
 
        .ack_interrupt  = lan88xx_phy_ack_interrupt,
@@ -160,6 +334,8 @@ static struct phy_driver microchip_phy_driver[] = {
        .suspend        = lan88xx_suspend,
        .resume         = genphy_resume,
        .set_wol        = lan88xx_set_wol,
+       .read_page      = lan88xx_read_page,
+       .write_page     = lan88xx_write_page,
 } };
 
 module_phy_driver(microchip_phy_driver);
index 1483bc7b01e1a019e81ea98b06804f5a4361a3af..7df07337d69c90a1f1fe1ddd6611645d3ce751ee 100644 (file)
@@ -620,6 +620,10 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
        lock_sock(sk);
 
        error = -EINVAL;
+
+       if (sockaddr_len != sizeof(struct sockaddr_pppox))
+               goto end;
+
        if (sp->sa_protocol != PX_PROTO_OE)
                goto end;
 
index a6c6ce19eeee7cd2899946655f3a6deca90cbe08..ddb6bf85a59c689c9593a0a85d2bf0b2a93eba3c 100644 (file)
@@ -261,6 +261,17 @@ static void __team_option_inst_mark_removed_port(struct team *team,
        }
 }
 
+static bool __team_option_inst_tmp_find(const struct list_head *opts,
+                                       const struct team_option_inst *needle)
+{
+       struct team_option_inst *opt_inst;
+
+       list_for_each_entry(opt_inst, opts, tmp_list)
+               if (opt_inst == needle)
+                       return true;
+       return false;
+}
+
 static int __team_options_register(struct team *team,
                                   const struct team_option *option,
                                   size_t option_count)
@@ -1061,14 +1072,11 @@ static void team_port_leave(struct team *team, struct team_port *port)
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
+static int __team_port_enable_netpoll(struct team_port *port)
 {
        struct netpoll *np;
        int err;
 
-       if (!team->dev->npinfo)
-               return 0;
-
        np = kzalloc(sizeof(*np), GFP_KERNEL);
        if (!np)
                return -ENOMEM;
@@ -1082,6 +1090,14 @@ static int team_port_enable_netpoll(struct team *team, struct team_port *port)
        return err;
 }
 
+static int team_port_enable_netpoll(struct team_port *port)
+{
+       if (!port->team->dev->npinfo)
+               return 0;
+
+       return __team_port_enable_netpoll(port);
+}
+
 static void team_port_disable_netpoll(struct team_port *port)
 {
        struct netpoll *np = port->np;
@@ -1096,7 +1112,7 @@ static void team_port_disable_netpoll(struct team_port *port)
        kfree(np);
 }
 #else
-static int team_port_enable_netpoll(struct team *team, struct team_port *port)
+static int team_port_enable_netpoll(struct team_port *port)
 {
        return 0;
 }
@@ -1210,7 +1226,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
                goto err_vids_add;
        }
 
-       err = team_port_enable_netpoll(team, port);
+       err = team_port_enable_netpoll(port);
        if (err) {
                netdev_err(dev, "Failed to enable netpoll on device %s\n",
                           portname);
@@ -1907,7 +1923,7 @@ static int team_netpoll_setup(struct net_device *dev,
 
        mutex_lock(&team->lock);
        list_for_each_entry(port, &team->port_list, list) {
-               err = team_port_enable_netpoll(team, port);
+               err = __team_port_enable_netpoll(port);
                if (err) {
                        __team_netpoll_cleanup(team);
                        break;
@@ -2568,6 +2584,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
                        if (err)
                                goto team_put;
                        opt_inst->changed = true;
+
+                       /* dumb/evil user-space can send us duplicate opt,
+                        * keep only the last one
+                        */
+                       if (__team_option_inst_tmp_find(&opt_inst_list,
+                                                       opt_inst))
+                               continue;
+
                        list_add(&opt_inst->tmp_list, &opt_inst_list);
                }
                if (!opt_found) {
index 28583aa0c17df6fdbeb4f30625f258dcd69855d0..ef33950a45d909b34dfe937396873ece728314f6 100644 (file)
@@ -1102,12 +1102,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
                goto drop;
 
        len = run_ebpf_filter(tun, skb, len);
-
-       /* Trim extra bytes since we may insert vlan proto & TCI
-        * in tun_put_user().
-        */
-       len -= skb_vlan_tag_present(skb) ? sizeof(struct veth) : 0;
-       if (len <= 0 || pskb_trim(skb, len))
+       if (len == 0 || pskb_trim(skb, len))
                goto drop;
 
        if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))
index ca066b785e9f550b27e24412c6ac9bcdd6ecdc97..c853e7410f5aae3ba1447a81bc42fd525bc4dd43 100644 (file)
@@ -1107,6 +1107,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1435, 0xd181, 3)},    /* Wistron NeWeb D18Q1 */
        {QMI_FIXED_INTF(0x1435, 0xd181, 4)},    /* Wistron NeWeb D18Q1 */
        {QMI_FIXED_INTF(0x1435, 0xd181, 5)},    /* Wistron NeWeb D18Q1 */
+       {QMI_FIXED_INTF(0x1435, 0xd191, 4)},    /* Wistron NeWeb D19Q1 */
        {QMI_FIXED_INTF(0x16d8, 0x6003, 0)},    /* CMOTech 6003 */
        {QMI_FIXED_INTF(0x16d8, 0x6007, 0)},    /* CMOTech CHE-628S */
        {QMI_FIXED_INTF(0x16d8, 0x6008, 0)},    /* CMOTech CMU-301 */
index 7b187ec7411ec053d9825b3774fe4036ea4e59f8..770422e953f75e1e9a1bb3a317d83f8070e6ae36 100644 (file)
@@ -147,6 +147,17 @@ struct receive_queue {
        struct xdp_rxq_info xdp_rxq;
 };
 
+/* Control VQ buffers: protected by the rtnl lock */
+struct control_buf {
+       struct virtio_net_ctrl_hdr hdr;
+       virtio_net_ctrl_ack status;
+       struct virtio_net_ctrl_mq mq;
+       u8 promisc;
+       u8 allmulti;
+       __virtio16 vid;
+       __virtio64 offloads;
+};
+
 struct virtnet_info {
        struct virtio_device *vdev;
        struct virtqueue *cvq;
@@ -192,14 +203,7 @@ struct virtnet_info {
        struct hlist_node node;
        struct hlist_node node_dead;
 
-       /* Control VQ buffers: protected by the rtnl lock */
-       struct virtio_net_ctrl_hdr ctrl_hdr;
-       virtio_net_ctrl_ack ctrl_status;
-       struct virtio_net_ctrl_mq ctrl_mq;
-       u8 ctrl_promisc;
-       u8 ctrl_allmulti;
-       u16 ctrl_vid;
-       u64 ctrl_offloads;
+       struct control_buf *ctrl;
 
        /* Ethtool settings */
        u8 duplex;
@@ -1269,7 +1273,9 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
 {
        struct receive_queue *rq =
                container_of(napi, struct receive_queue, napi);
-       unsigned int received;
+       struct virtnet_info *vi = rq->vq->vdev->priv;
+       struct send_queue *sq;
+       unsigned int received, qp;
        bool xdp_xmit = false;
 
        virtnet_poll_cleantx(rq);
@@ -1280,8 +1286,13 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
        if (received < budget)
                virtqueue_napi_complete(napi, rq->vq, received);
 
-       if (xdp_xmit)
+       if (xdp_xmit) {
+               qp = vi->curr_queue_pairs - vi->xdp_queue_pairs +
+                    smp_processor_id();
+               sq = &vi->sq[qp];
+               virtqueue_kick(sq->vq);
                xdp_do_flush_map();
+       }
 
        return received;
 }
@@ -1454,25 +1465,25 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
        /* Caller should know better */
        BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
 
-       vi->ctrl_status = ~0;
-       vi->ctrl_hdr.class = class;
-       vi->ctrl_hdr.cmd = cmd;
+       vi->ctrl->status = ~0;
+       vi->ctrl->hdr.class = class;
+       vi->ctrl->hdr.cmd = cmd;
        /* Add header */
-       sg_init_one(&hdr, &vi->ctrl_hdr, sizeof(vi->ctrl_hdr));
+       sg_init_one(&hdr, &vi->ctrl->hdr, sizeof(vi->ctrl->hdr));
        sgs[out_num++] = &hdr;
 
        if (out)
                sgs[out_num++] = out;
 
        /* Add return status. */
-       sg_init_one(&stat, &vi->ctrl_status, sizeof(vi->ctrl_status));
+       sg_init_one(&stat, &vi->ctrl->status, sizeof(vi->ctrl->status));
        sgs[out_num] = &stat;
 
        BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
        virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
 
        if (unlikely(!virtqueue_kick(vi->cvq)))
-               return vi->ctrl_status == VIRTIO_NET_OK;
+               return vi->ctrl->status == VIRTIO_NET_OK;
 
        /* Spin for a response, the kick causes an ioport write, trapping
         * into the hypervisor, so the request should be handled immediately.
@@ -1481,7 +1492,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
               !virtqueue_is_broken(vi->cvq))
                cpu_relax();
 
-       return vi->ctrl_status == VIRTIO_NET_OK;
+       return vi->ctrl->status == VIRTIO_NET_OK;
 }
 
 static int virtnet_set_mac_address(struct net_device *dev, void *p)
@@ -1593,8 +1604,8 @@ static int _virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
        if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ))
                return 0;
 
-       vi->ctrl_mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
-       sg_init_one(&sg, &vi->ctrl_mq, sizeof(vi->ctrl_mq));
+       vi->ctrl->mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
+       sg_init_one(&sg, &vi->ctrl->mq, sizeof(vi->ctrl->mq));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
                                  VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg)) {
@@ -1653,22 +1664,22 @@ static void virtnet_set_rx_mode(struct net_device *dev)
        if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
                return;
 
-       vi->ctrl_promisc = ((dev->flags & IFF_PROMISC) != 0);
-       vi->ctrl_allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+       vi->ctrl->promisc = ((dev->flags & IFF_PROMISC) != 0);
+       vi->ctrl->allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
 
-       sg_init_one(sg, &vi->ctrl_promisc, sizeof(vi->ctrl_promisc));
+       sg_init_one(sg, &vi->ctrl->promisc, sizeof(vi->ctrl->promisc));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
                                  VIRTIO_NET_CTRL_RX_PROMISC, sg))
                dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
-                        vi->ctrl_promisc ? "en" : "dis");
+                        vi->ctrl->promisc ? "en" : "dis");
 
-       sg_init_one(sg, &vi->ctrl_allmulti, sizeof(vi->ctrl_allmulti));
+       sg_init_one(sg, &vi->ctrl->allmulti, sizeof(vi->ctrl->allmulti));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
                                  VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
                dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
-                        vi->ctrl_allmulti ? "en" : "dis");
+                        vi->ctrl->allmulti ? "en" : "dis");
 
        uc_count = netdev_uc_count(dev);
        mc_count = netdev_mc_count(dev);
@@ -1714,8 +1725,8 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev,
        struct virtnet_info *vi = netdev_priv(dev);
        struct scatterlist sg;
 
-       vi->ctrl_vid = vid;
-       sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid));
+       vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
+       sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
                                  VIRTIO_NET_CTRL_VLAN_ADD, &sg))
@@ -1729,8 +1740,8 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev,
        struct virtnet_info *vi = netdev_priv(dev);
        struct scatterlist sg;
 
-       vi->ctrl_vid = vid;
-       sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid));
+       vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
+       sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
                                  VIRTIO_NET_CTRL_VLAN_DEL, &sg))
@@ -2126,9 +2137,9 @@ static int virtnet_restore_up(struct virtio_device *vdev)
 static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads)
 {
        struct scatterlist sg;
-       vi->ctrl_offloads = cpu_to_virtio64(vi->vdev, offloads);
+       vi->ctrl->offloads = cpu_to_virtio64(vi->vdev, offloads);
 
-       sg_init_one(&sg, &vi->ctrl_offloads, sizeof(vi->ctrl_offloads));
+       sg_init_one(&sg, &vi->ctrl->offloads, sizeof(vi->ctrl->offloads));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_GUEST_OFFLOADS,
                                  VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, &sg)) {
@@ -2351,6 +2362,7 @@ static void virtnet_free_queues(struct virtnet_info *vi)
 
        kfree(vi->rq);
        kfree(vi->sq);
+       kfree(vi->ctrl);
 }
 
 static void _free_receive_bufs(struct virtnet_info *vi)
@@ -2543,6 +2555,9 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
 {
        int i;
 
+       vi->ctrl = kzalloc(sizeof(*vi->ctrl), GFP_KERNEL);
+       if (!vi->ctrl)
+               goto err_ctrl;
        vi->sq = kzalloc(sizeof(*vi->sq) * vi->max_queue_pairs, GFP_KERNEL);
        if (!vi->sq)
                goto err_sq;
@@ -2571,6 +2586,8 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
 err_rq:
        kfree(vi->sq);
 err_sq:
+       kfree(vi->ctrl);
+err_ctrl:
        return -ENOMEM;
 }
 
index e04937f44f33313eb3eebf3bc1ea598686965950..9ebe2a689966d056a1b9a94e5ea557f0d0f9a55e 100644 (file)
@@ -1218,6 +1218,7 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
        union {
                void *ptr;
                struct ethhdr *eth;
+               struct vlan_ethhdr *veth;
                struct iphdr *ipv4;
                struct ipv6hdr *ipv6;
                struct tcphdr *tcp;
@@ -1228,16 +1229,24 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
        if (unlikely(sizeof(struct iphdr) + sizeof(struct tcphdr) > maplen))
                return 0;
 
+       if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
+           skb->protocol == cpu_to_be16(ETH_P_8021AD))
+               hlen = sizeof(struct vlan_ethhdr);
+       else
+               hlen = sizeof(struct ethhdr);
+
        hdr.eth = eth_hdr(skb);
        if (gdesc->rcd.v4) {
-               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP));
-               hdr.ptr += sizeof(struct ethhdr);
+               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP) &&
+                      hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IP));
+               hdr.ptr += hlen;
                BUG_ON(hdr.ipv4->protocol != IPPROTO_TCP);
                hlen = hdr.ipv4->ihl << 2;
                hdr.ptr += hdr.ipv4->ihl << 2;
        } else if (gdesc->rcd.v6) {
-               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6));
-               hdr.ptr += sizeof(struct ethhdr);
+               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6) &&
+                      hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IPV6));
+               hdr.ptr += hlen;
                /* Use an estimated value, since we also need to handle
                 * TSO case.
                 */
index 59ec34052a651ee831bbcbacee467965c5aaba36..a3326463b71f1e26cd74b33b4480044f57ec4f31 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.4.13.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.14.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01040d00
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040e00
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index 85997184e04734d09538176a2a0798145e1435b6..9d36473dc2a24f2100d4e748cb5540ce14931c0c 100644 (file)
@@ -103,8 +103,7 @@ config NVDIMM_DAX
          Select Y if unsure
 
 config OF_PMEM
-       # FIXME: make tristate once OF_NUMA dependency removed
-       bool "Device-tree support for persistent memory regions"
+       tristate "Device-tree support for persistent memory regions"
        depends on OF
        default LIBNVDIMM
        help
index e00d45522b80e80fb4de68a8c506a3c8e68e6548..8d348b22ba453a58938d9fa921dd890109a4c7de 100644 (file)
@@ -88,9 +88,9 @@ int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd)
 int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)
 {
        struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
+       int rc = validate_dimm(ndd), cmd_rc = 0;
        struct nd_cmd_get_config_data_hdr *cmd;
        struct nvdimm_bus_descriptor *nd_desc;
-       int rc = validate_dimm(ndd);
        u32 max_cmd_size, config_size;
        size_t offset;
 
@@ -124,9 +124,11 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)
                cmd->in_offset = offset;
                rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
                                ND_CMD_GET_CONFIG_DATA, cmd,
-                               cmd->in_length + sizeof(*cmd), NULL);
-               if (rc || cmd->status) {
-                       rc = -ENXIO;
+                               cmd->in_length + sizeof(*cmd), &cmd_rc);
+               if (rc < 0)
+                       break;
+               if (cmd_rc < 0) {
+                       rc = cmd_rc;
                        break;
                }
                memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length);
@@ -140,9 +142,9 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)
 int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
                void *buf, size_t len)
 {
-       int rc = validate_dimm(ndd);
        size_t max_cmd_size, buf_offset;
        struct nd_cmd_set_config_hdr *cmd;
+       int rc = validate_dimm(ndd), cmd_rc = 0;
        struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
        struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
 
@@ -164,7 +166,6 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
        for (buf_offset = 0; len; len -= cmd->in_length,
                        buf_offset += cmd->in_length) {
                size_t cmd_size;
-               u32 *status;
 
                cmd->in_offset = offset + buf_offset;
                cmd->in_length = min(max_cmd_size, len);
@@ -172,12 +173,13 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
 
                /* status is output in the last 4-bytes of the command buffer */
                cmd_size = sizeof(*cmd) + cmd->in_length + sizeof(u32);
-               status = ((void *) cmd) + cmd_size - sizeof(u32);
 
                rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
-                               ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, NULL);
-               if (rc || *status) {
-                       rc = rc ? rc : -ENXIO;
+                               ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, &cmd_rc);
+               if (rc < 0)
+                       break;
+               if (cmd_rc < 0) {
+                       rc = cmd_rc;
                        break;
                }
        }
index 85013bad35de4e176f82f253723f91600c084ea3..0a701837dfc0b9bd6c011f5ee092feb101a15acb 100644 (file)
@@ -67,7 +67,7 @@ static int of_pmem_region_probe(struct platform_device *pdev)
                 */
                memset(&ndr_desc, 0, sizeof(ndr_desc));
                ndr_desc.attr_groups = region_attr_groups;
-               ndr_desc.numa_node = of_node_to_nid(np);
+               ndr_desc.numa_node = dev_to_node(&pdev->dev);
                ndr_desc.res = &pdev->resource[i];
                ndr_desc.of_node = np;
                set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
index 84aa9d6763753029f45c39483c9b84ca59299409..6da20b9688f7419aae4f806798eaa137c8c4f649 100644 (file)
@@ -942,7 +942,7 @@ int __init early_init_dt_scan_chosen_stdout(void)
        int offset;
        const char *p, *q, *options = NULL;
        int l;
-       const struct earlycon_id *match;
+       const struct earlycon_id **p_match;
        const void *fdt = initial_boot_params;
 
        offset = fdt_path_offset(fdt, "/chosen");
@@ -969,7 +969,10 @@ int __init early_init_dt_scan_chosen_stdout(void)
                return 0;
        }
 
-       for (match = __earlycon_table; match < __earlycon_table_end; match++) {
+       for (p_match = __earlycon_table; p_match < __earlycon_table_end;
+            p_match++) {
+               const struct earlycon_id *match = *p_match;
+
                if (!match->compatible[0])
                        continue;
 
index a6b88c7f6e3ed1446a1384a049fc73821da50b24..d2970a009eb59a854d91187fcece5c9b1ffda7b9 100644 (file)
@@ -486,7 +486,7 @@ static int kirin_pcie_probe(struct platform_device *pdev)
                return ret;
 
        kirin_pcie->gpio_id_reset = of_get_named_gpio(dev->of_node,
-                                                     "reset-gpio", 0);
+                                                     "reset-gpios", 0);
        if (kirin_pcie->gpio_id_reset < 0)
                return -ENODEV;
 
index b04d37b3c5deea7b2aafdf34f636adb720a978bd..9abf549631b4d4ebed2ef0207225658150c3c151 100644 (file)
@@ -29,6 +29,7 @@
 #define     PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT      5
 #define     PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE             (0 << 11)
 #define     PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT     12
+#define     PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ             0x2
 #define PCIE_CORE_LINK_CTRL_STAT_REG                           0xd0
 #define     PCIE_CORE_LINK_L0S_ENTRY                           BIT(0)
 #define     PCIE_CORE_LINK_TRAINING                            BIT(5)
 #define PCIE_ISR1_MASK_REG                     (CONTROL_BASE_ADDR + 0x4C)
 #define     PCIE_ISR1_POWER_STATE_CHANGE       BIT(4)
 #define     PCIE_ISR1_FLUSH                    BIT(5)
-#define     PCIE_ISR1_ALL_MASK                 GENMASK(5, 4)
+#define     PCIE_ISR1_INTX_ASSERT(val)         BIT(8 + (val))
+#define     PCIE_ISR1_ALL_MASK                 GENMASK(11, 4)
 #define PCIE_MSI_ADDR_LOW_REG                  (CONTROL_BASE_ADDR + 0x50)
 #define PCIE_MSI_ADDR_HIGH_REG                 (CONTROL_BASE_ADDR + 0x54)
 #define PCIE_MSI_STATUS_REG                    (CONTROL_BASE_ADDR + 0x58)
 #define PCIE_CONFIG_WR_TYPE0                   0xa
 #define PCIE_CONFIG_WR_TYPE1                   0xb
 
-/* PCI_BDF shifts 8bit, so we need extra 4bit shift */
-#define PCIE_BDF(dev)                          (dev << 4)
 #define PCIE_CONF_BUS(bus)                     (((bus) & 0xff) << 20)
 #define PCIE_CONF_DEV(dev)                     (((dev) & 0x1f) << 15)
 #define PCIE_CONF_FUNC(fun)                    (((fun) & 0x7)  << 12)
@@ -296,7 +296,8 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
        reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
                (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
                PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE |
-               PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT;
+               (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ <<
+                PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT);
        advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
 
        /* Program PCIe Control 2 to disable strict ordering */
@@ -437,7 +438,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
        u32 reg;
        int ret;
 
-       if (PCI_SLOT(devfn) != 0) {
+       if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) {
                *val = 0xffffffff;
                return PCIBIOS_DEVICE_NOT_FOUND;
        }
@@ -456,7 +457,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
        advk_writel(pcie, reg, PIO_CTRL);
 
        /* Program the address registers */
-       reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where);
+       reg = PCIE_CONF_ADDR(bus->number, devfn, where);
        advk_writel(pcie, reg, PIO_ADDR_LS);
        advk_writel(pcie, 0, PIO_ADDR_MS);
 
@@ -491,7 +492,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
        int offset;
        int ret;
 
-       if (PCI_SLOT(devfn) != 0)
+       if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        if (where % size)
@@ -609,9 +610,9 @@ static void advk_pcie_irq_mask(struct irq_data *d)
        irq_hw_number_t hwirq = irqd_to_hwirq(d);
        u32 mask;
 
-       mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
-       mask |= PCIE_ISR0_INTX_ASSERT(hwirq);
-       advk_writel(pcie, mask, PCIE_ISR0_MASK_REG);
+       mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
+       mask |= PCIE_ISR1_INTX_ASSERT(hwirq);
+       advk_writel(pcie, mask, PCIE_ISR1_MASK_REG);
 }
 
 static void advk_pcie_irq_unmask(struct irq_data *d)
@@ -620,9 +621,9 @@ static void advk_pcie_irq_unmask(struct irq_data *d)
        irq_hw_number_t hwirq = irqd_to_hwirq(d);
        u32 mask;
 
-       mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
-       mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq);
-       advk_writel(pcie, mask, PCIE_ISR0_MASK_REG);
+       mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
+       mask &= ~PCIE_ISR1_INTX_ASSERT(hwirq);
+       advk_writel(pcie, mask, PCIE_ISR1_MASK_REG);
 }
 
 static int advk_pcie_irq_map(struct irq_domain *h,
@@ -765,29 +766,35 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 
 static void advk_pcie_handle_int(struct advk_pcie *pcie)
 {
-       u32 val, mask, status;
+       u32 isr0_val, isr0_mask, isr0_status;
+       u32 isr1_val, isr1_mask, isr1_status;
        int i, virq;
 
-       val = advk_readl(pcie, PCIE_ISR0_REG);
-       mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
-       status = val & ((~mask) & PCIE_ISR0_ALL_MASK);
+       isr0_val = advk_readl(pcie, PCIE_ISR0_REG);
+       isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+       isr0_status = isr0_val & ((~isr0_mask) & PCIE_ISR0_ALL_MASK);
+
+       isr1_val = advk_readl(pcie, PCIE_ISR1_REG);
+       isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
+       isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
 
-       if (!status) {
-               advk_writel(pcie, val, PCIE_ISR0_REG);
+       if (!isr0_status && !isr1_status) {
+               advk_writel(pcie, isr0_val, PCIE_ISR0_REG);
+               advk_writel(pcie, isr1_val, PCIE_ISR1_REG);
                return;
        }
 
        /* Process MSI interrupts */
-       if (status & PCIE_ISR0_MSI_INT_PENDING)
+       if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
                advk_pcie_handle_msi(pcie);
 
        /* Process legacy interrupts */
        for (i = 0; i < PCI_NUM_INTX; i++) {
-               if (!(status & PCIE_ISR0_INTX_ASSERT(i)))
+               if (!(isr1_status & PCIE_ISR1_INTX_ASSERT(i)))
                        continue;
 
-               advk_writel(pcie, PCIE_ISR0_INTX_ASSERT(i),
-                           PCIE_ISR0_REG);
+               advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i),
+                           PCIE_ISR1_REG);
 
                virq = irq_find_mapping(pcie->irq_domain, i);
                generic_handle_irq(virq);
index 6ace47099fc59451422daaf7d38c52f470c9c500..b9a131137e64b86be6660d9d94225e5ff0b8aeb9 100644 (file)
@@ -958,10 +958,11 @@ static int pci_pm_freeze(struct device *dev)
         * devices should not be touched during freeze/thaw transitions,
         * however.
         */
-       if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND))
+       if (!dev_pm_smart_suspend_and_suspended(dev)) {
                pm_runtime_resume(dev);
+               pci_dev->state_saved = false;
+       }
 
-       pci_dev->state_saved = false;
        if (pm->freeze) {
                int error;
 
index e597655a5643b6bc92be2a40ed3fa2b11bd093dd..a04197ce767dfe62fd504ab99c84102d510e0b6a 100644 (file)
@@ -5273,11 +5273,11 @@ void pcie_print_link_status(struct pci_dev *dev)
        bw_avail = pcie_bandwidth_available(dev, &limiting_dev, &speed, &width);
 
        if (bw_avail >= bw_cap)
-               pci_info(dev, "%u.%03u Gb/s available bandwidth (%s x%d link)\n",
+               pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth (%s x%d link)\n",
                         bw_cap / 1000, bw_cap % 1000,
                         PCIE_SPEED2STR(speed_cap), width_cap);
        else
-               pci_info(dev, "%u.%03u Gb/s available bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n",
+               pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n",
                         bw_avail / 1000, bw_avail % 1000,
                         PCIE_SPEED2STR(speed), width,
                         limiting_dev ? pci_name(limiting_dev) : "<unknown>",
index 9d27016c899ed29e49bb6395bc8686323ea2cd90..0434ab7b649709cd6fcbf5192ca697b6f0148982 100644 (file)
@@ -740,10 +740,7 @@ static int do_dma_request(struct mport_dma_req *req,
        tx->callback = dma_xfer_callback;
        tx->callback_param = req;
 
-       req->dmach = chan;
-       req->sync = sync;
        req->status = DMA_IN_PROGRESS;
-       init_completion(&req->req_comp);
        kref_get(&req->refcount);
 
        cookie = dmaengine_submit(tx);
@@ -831,13 +828,20 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode,
        if (!req)
                return -ENOMEM;
 
-       kref_init(&req->refcount);
-
        ret = get_dma_channel(priv);
        if (ret) {
                kfree(req);
                return ret;
        }
+       chan = priv->dmach;
+
+       kref_init(&req->refcount);
+       init_completion(&req->req_comp);
+       req->dir = dir;
+       req->filp = filp;
+       req->priv = priv;
+       req->dmach = chan;
+       req->sync = sync;
 
        /*
         * If parameter loc_addr != NULL, we are transferring data from/to
@@ -925,11 +929,6 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode,
                                xfer->offset, xfer->length);
        }
 
-       req->dir = dir;
-       req->filp = filp;
-       req->priv = priv;
-       chan = priv->dmach;
-
        nents = dma_map_sg(chan->device->dev,
                           req->sgt.sgl, req->sgt.nents, dir);
        if (nents == 0) {
index 304e891e35fcb060a8ff26f78122fa3c63a1eb87..60f2250fd96bec2cec1dd33f652edaac474d2182 100644 (file)
@@ -57,7 +57,7 @@ static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms)
 
 static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 {
-       long rc = OPAL_BUSY;
+       s64 rc = OPAL_BUSY;
        int retries = 10;
        u32 y_m_d;
        u64 h_m_s_ms;
@@ -66,13 +66,17 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       msleep(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else if (retries-- && (rc == OPAL_HARDWARE
-                                      || rc == OPAL_INTERNAL_ERROR))
-                       msleep(10);
-               else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT)
-                       break;
+               } else if (rc == OPAL_BUSY) {
+                       msleep(OPAL_BUSY_DELAY_MS);
+               } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) {
+                       if (retries--) {
+                               msleep(10); /* Wait 10ms before retry */
+                               rc = OPAL_BUSY; /* go around again */
+                       }
+               }
        }
 
        if (rc != OPAL_SUCCESS)
@@ -87,21 +91,26 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 
 static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm)
 {
-       long rc = OPAL_BUSY;
+       s64 rc = OPAL_BUSY;
        int retries = 10;
        u32 y_m_d = 0;
        u64 h_m_s_ms = 0;
 
        tm_to_opal(tm, &y_m_d, &h_m_s_ms);
+
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_write(y_m_d, h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       msleep(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else if (retries-- && (rc == OPAL_HARDWARE
-                                      || rc == OPAL_INTERNAL_ERROR))
-                       msleep(10);
-               else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT)
-                       break;
+               } else if (rc == OPAL_BUSY) {
+                       msleep(OPAL_BUSY_DELAY_MS);
+               } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) {
+                       if (retries--) {
+                               msleep(10); /* Wait 10ms before retry */
+                               rc = OPAL_BUSY; /* go around again */
+                       }
+               }
        }
 
        return rc == OPAL_SUCCESS ? 0 : -EIO;
index 62f5f04d8f615e393c88824606f58d13801c5e6b..5e963fe0e38d4c2125c43ae801ca7e9b28d98d07 100644 (file)
@@ -592,13 +592,22 @@ static int _schedule_lcu_update(struct alias_lcu *lcu,
 int dasd_alias_add_device(struct dasd_device *device)
 {
        struct dasd_eckd_private *private = device->private;
-       struct alias_lcu *lcu;
+       __u8 uaddr = private->uid.real_unit_addr;
+       struct alias_lcu *lcu = private->lcu;
        unsigned long flags;
        int rc;
 
-       lcu = private->lcu;
        rc = 0;
        spin_lock_irqsave(&lcu->lock, flags);
+       /*
+        * Check if device and lcu type differ. If so, the uac data may be
+        * outdated and needs to be updated.
+        */
+       if (private->uid.type !=  lcu->uac->unit[uaddr].ua_type) {
+               lcu->flags |= UPDATE_PENDING;
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+                             "uid type mismatch - trigger rescan");
+       }
        if (!(lcu->flags & UPDATE_PENDING)) {
                rc = _add_device_to_lcu(lcu, device, device);
                if (rc)
index f035c2f25d35a8c5aa12cb0552aaf3484edb2798..131f1989f6f3dff0345250c71943f5ac338af19c 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/vtoc.h>
-#include <asm/diag.h>
 
 #include "dasd_int.h"
 #include "dasd_diag.h"
index 5f8d9ea69ebdb87aef031dd01220bd5895e3bb89..eceba3858cefbbe0b2ce46df46751f4d53bc7122 100644 (file)
@@ -18,7 +18,7 @@ int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
  * Used to keep track of the size of the event masks. Qemu until version 2.11
  * only supports 4 and needs a workaround.
  */
-bool sclp_mask_compat_mode;
+bool sclp_mask_compat_mode __section(.data);
 
 void sclp_early_wait_irq(void)
 {
index 6652a49a49b17210228fcdd674faa6e81baffd06..9029804dcd225b85d5609c8af6c6ebc95522f12e 100644 (file)
@@ -452,6 +452,7 @@ static void chsc_process_sei_link_incident(struct chsc_sei_nt0_area *sei_area)
 
 static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area)
 {
+       struct channel_path *chp;
        struct chp_link link;
        struct chp_id chpid;
        int status;
@@ -464,10 +465,17 @@ static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area)
        chpid.id = sei_area->rsid;
        /* allocate a new channel path structure, if needed */
        status = chp_get_status(chpid);
-       if (status < 0)
-               chp_new(chpid);
-       else if (!status)
+       if (!status)
                return;
+
+       if (status < 0) {
+               chp_new(chpid);
+       } else {
+               chp = chpid_to_chp(chpid);
+               mutex_lock(&chp->lock);
+               chp_update_desc(chp);
+               mutex_unlock(&chp->lock);
+       }
        memset(&link, 0, sizeof(struct chp_link));
        link.chpid = chpid;
        if ((sei_area->vf & 0xc0) != 0) {
index ff6963ad6e393f658feb887f6e8ce5f4eeac62cd..3c800642134e4330d62bb8c0053df62618840ff3 100644 (file)
@@ -20,12 +20,12 @@ static int fsm_io_helper(struct vfio_ccw_private *private)
        int ccode;
        __u8 lpm;
        unsigned long flags;
+       int ret;
 
        sch = private->sch;
 
        spin_lock_irqsave(sch->lock, flags);
        private->state = VFIO_CCW_STATE_BUSY;
-       spin_unlock_irqrestore(sch->lock, flags);
 
        orb = cp_get_orb(&private->cp, (u32)(addr_t)sch, sch->lpm);
 
@@ -38,10 +38,12 @@ static int fsm_io_helper(struct vfio_ccw_private *private)
                 * Initialize device status information
                 */
                sch->schib.scsw.cmd.actl |= SCSW_ACTL_START_PEND;
-               return 0;
+               ret = 0;
+               break;
        case 1:         /* Status pending */
        case 2:         /* Busy */
-               return -EBUSY;
+               ret = -EBUSY;
+               break;
        case 3:         /* Device/path not operational */
        {
                lpm = orb->cmd.lpm;
@@ -51,13 +53,16 @@ static int fsm_io_helper(struct vfio_ccw_private *private)
                        sch->lpm = 0;
 
                if (cio_update_schib(sch))
-                       return -ENODEV;
-
-               return sch->lpm ? -EACCES : -ENODEV;
+                       ret = -ENODEV;
+               else
+                       ret = sch->lpm ? -EACCES : -ENODEV;
+               break;
        }
        default:
-               return ccode;
+               ret = ccode;
        }
+       spin_unlock_irqrestore(sch->lock, flags);
+       return ret;
 }
 
 static void fsm_notoper(struct vfio_ccw_private *private,
index 4326715dc13eb18af4c69cc233f279ab264fae36..78b98b3e7efaf3893d0451ca6524220c94a26994 100644 (file)
@@ -557,7 +557,6 @@ enum qeth_prot_versions {
 enum qeth_cmd_buffer_state {
        BUF_STATE_FREE,
        BUF_STATE_LOCKED,
-       BUF_STATE_PROCESSED,
 };
 
 enum qeth_cq {
@@ -601,7 +600,6 @@ struct qeth_channel {
        struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO];
        atomic_t irq_pending;
        int io_buf_no;
-       int buf_no;
 };
 
 /**
index 04fefa5bb08d168b7beefeeef62b1190aab84232..dffd820731f2a53f9a5c58f0f9da78df72c2a0cf 100644 (file)
@@ -706,7 +706,6 @@ void qeth_clear_ipacmd_list(struct qeth_card *card)
                qeth_put_reply(reply);
        }
        spin_unlock_irqrestore(&card->lock, flags);
-       atomic_set(&card->write.irq_pending, 0);
 }
 EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
 
@@ -818,7 +817,6 @@ void qeth_clear_cmd_buffers(struct qeth_channel *channel)
 
        for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++)
                qeth_release_buffer(channel, &channel->iob[cnt]);
-       channel->buf_no = 0;
        channel->io_buf_no = 0;
 }
 EXPORT_SYMBOL_GPL(qeth_clear_cmd_buffers);
@@ -924,7 +922,6 @@ static int qeth_setup_channel(struct qeth_channel *channel)
                        kfree(channel->iob[cnt].data);
                return -ENOMEM;
        }
-       channel->buf_no = 0;
        channel->io_buf_no = 0;
        atomic_set(&channel->irq_pending, 0);
        spin_lock_init(&channel->iob_lock);
@@ -1100,16 +1097,9 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
 {
        int rc;
        int cstat, dstat;
-       struct qeth_cmd_buffer *buffer;
+       struct qeth_cmd_buffer *iob = NULL;
        struct qeth_channel *channel;
        struct qeth_card *card;
-       struct qeth_cmd_buffer *iob;
-       __u8 index;
-
-       if (__qeth_check_irb_error(cdev, intparm, irb))
-               return;
-       cstat = irb->scsw.cmd.cstat;
-       dstat = irb->scsw.cmd.dstat;
 
        card = CARD_FROM_CDEV(cdev);
        if (!card)
@@ -1127,6 +1117,19 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                channel = &card->data;
                QETH_CARD_TEXT(card, 5, "data");
        }
+
+       if (qeth_intparm_is_iob(intparm))
+               iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
+
+       if (__qeth_check_irb_error(cdev, intparm, irb)) {
+               /* IO was terminated, free its resources. */
+               if (iob)
+                       qeth_release_buffer(iob->channel, iob);
+               atomic_set(&channel->irq_pending, 0);
+               wake_up(&card->wait_q);
+               return;
+       }
+
        atomic_set(&channel->irq_pending, 0);
 
        if (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC))
@@ -1150,6 +1153,10 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                /* we don't have to handle this further */
                intparm = 0;
        }
+
+       cstat = irb->scsw.cmd.cstat;
+       dstat = irb->scsw.cmd.dstat;
+
        if ((dstat & DEV_STAT_UNIT_EXCEP) ||
            (dstat & DEV_STAT_UNIT_CHECK) ||
            (cstat)) {
@@ -1182,25 +1189,15 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                channel->state = CH_STATE_RCD_DONE;
                goto out;
        }
-       if (intparm) {
-               buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
-               buffer->state = BUF_STATE_PROCESSED;
-       }
        if (channel == &card->data)
                return;
        if (channel == &card->read &&
            channel->state == CH_STATE_UP)
                __qeth_issue_next_read(card);
 
-       iob = channel->iob;
-       index = channel->buf_no;
-       while (iob[index].state == BUF_STATE_PROCESSED) {
-               if (iob[index].callback != NULL)
-                       iob[index].callback(channel, iob + index);
+       if (iob && iob->callback)
+               iob->callback(iob->channel, iob);
 
-               index = (index + 1) % QETH_CMD_BUFFER_NO;
-       }
-       channel->buf_no = index;
 out:
        wake_up(&card->wait_q);
        return;
@@ -1870,8 +1867,8 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel,
                   atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
        QETH_DBF_TEXT(SETUP, 6, "noirqpnd");
        spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
-       rc = ccw_device_start(channel->ccwdev,
-                             &channel->ccw, (addr_t) iob, 0, 0);
+       rc = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
+                                     (addr_t) iob, 0, 0, QETH_TIMEOUT);
        spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
 
        if (rc) {
@@ -1888,7 +1885,6 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel,
        if (channel->state != CH_STATE_UP) {
                rc = -ETIME;
                QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
-               qeth_clear_cmd_buffers(channel);
        } else
                rc = 0;
        return rc;
@@ -1942,8 +1938,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel,
                   atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
        QETH_DBF_TEXT(SETUP, 6, "noirqpnd");
        spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
-       rc = ccw_device_start(channel->ccwdev,
-                             &channel->ccw, (addr_t) iob, 0, 0);
+       rc = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
+                                     (addr_t) iob, 0, 0, QETH_TIMEOUT);
        spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
 
        if (rc) {
@@ -1964,7 +1960,6 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel,
                QETH_DBF_MESSAGE(2, "%s IDX activate timed out\n",
                        dev_name(&channel->ccwdev->dev));
                QETH_DBF_TEXT_(SETUP, 2, "2err%d", -ETIME);
-               qeth_clear_cmd_buffers(channel);
                return -ETIME;
        }
        return qeth_idx_activate_get_answer(channel, idx_reply_cb);
@@ -2166,8 +2161,8 @@ int qeth_send_control_data(struct qeth_card *card, int len,
 
        QETH_CARD_TEXT(card, 6, "noirqpnd");
        spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
-       rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
-                             (addr_t) iob, 0, 0);
+       rc = ccw_device_start_timeout(CARD_WDEV(card), &card->write.ccw,
+                                     (addr_t) iob, 0, 0, event_timeout);
        spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
        if (rc) {
                QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: "
@@ -2199,8 +2194,6 @@ int qeth_send_control_data(struct qeth_card *card, int len,
                }
        }
 
-       if (reply->rc == -EIO)
-               goto error;
        rc = reply->rc;
        qeth_put_reply(reply);
        return rc;
@@ -2211,10 +2204,6 @@ time_err:
        list_del_init(&reply->list);
        spin_unlock_irqrestore(&reply->card->lock, flags);
        atomic_inc(&reply->received);
-error:
-       atomic_set(&card->write.irq_pending, 0);
-       qeth_release_buffer(iob->channel, iob);
-       card->write.buf_no = (card->write.buf_no + 1) % QETH_CMD_BUFFER_NO;
        rc = reply->rc;
        qeth_put_reply(reply);
        return rc;
@@ -3033,28 +3022,23 @@ static int qeth_send_startlan(struct qeth_card *card)
        return rc;
 }
 
-static int qeth_default_setadapterparms_cb(struct qeth_card *card,
-               struct qeth_reply *reply, unsigned long data)
+static int qeth_setadpparms_inspect_rc(struct qeth_ipa_cmd *cmd)
 {
-       struct qeth_ipa_cmd *cmd;
-
-       QETH_CARD_TEXT(card, 4, "defadpcb");
-
-       cmd = (struct qeth_ipa_cmd *) data;
-       if (cmd->hdr.return_code == 0)
+       if (!cmd->hdr.return_code)
                cmd->hdr.return_code =
                        cmd->data.setadapterparms.hdr.return_code;
-       return 0;
+       return cmd->hdr.return_code;
 }
 
 static int qeth_query_setadapterparms_cb(struct qeth_card *card,
                struct qeth_reply *reply, unsigned long data)
 {
-       struct qeth_ipa_cmd *cmd;
+       struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
 
        QETH_CARD_TEXT(card, 3, "quyadpcb");
+       if (qeth_setadpparms_inspect_rc(cmd))
+               return 0;
 
-       cmd = (struct qeth_ipa_cmd *) data;
        if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) {
                card->info.link_type =
                      cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
@@ -3062,7 +3046,7 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card,
        }
        card->options.adp.supported_funcs =
                cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds;
-       return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
+       return 0;
 }
 
 static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
@@ -3154,22 +3138,20 @@ EXPORT_SYMBOL_GPL(qeth_query_ipassists);
 static int qeth_query_switch_attributes_cb(struct qeth_card *card,
                                struct qeth_reply *reply, unsigned long data)
 {
-       struct qeth_ipa_cmd *cmd;
-       struct qeth_switch_info *sw_info;
+       struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
        struct qeth_query_switch_attributes *attrs;
+       struct qeth_switch_info *sw_info;
 
        QETH_CARD_TEXT(card, 2, "qswiatcb");
-       cmd = (struct qeth_ipa_cmd *) data;
-       sw_info = (struct qeth_switch_info *)reply->param;
-       if (cmd->data.setadapterparms.hdr.return_code == 0) {
-               attrs = &cmd->data.setadapterparms.data.query_switch_attributes;
-               sw_info->capabilities = attrs->capabilities;
-               sw_info->settings = attrs->settings;
-               QETH_CARD_TEXT_(card, 2, "%04x%04x", sw_info->capabilities,
-                                                       sw_info->settings);
-       }
-       qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
+       if (qeth_setadpparms_inspect_rc(cmd))
+               return 0;
 
+       sw_info = (struct qeth_switch_info *)reply->param;
+       attrs = &cmd->data.setadapterparms.data.query_switch_attributes;
+       sw_info->capabilities = attrs->capabilities;
+       sw_info->settings = attrs->settings;
+       QETH_CARD_TEXT_(card, 2, "%04x%04x", sw_info->capabilities,
+                       sw_info->settings);
        return 0;
 }
 
@@ -4207,16 +4189,13 @@ EXPORT_SYMBOL_GPL(qeth_do_send_packet);
 static int qeth_setadp_promisc_mode_cb(struct qeth_card *card,
                struct qeth_reply *reply, unsigned long data)
 {
-       struct qeth_ipa_cmd *cmd;
+       struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
        struct qeth_ipacmd_setadpparms *setparms;
 
        QETH_CARD_TEXT(card, 4, "prmadpcb");
 
-       cmd = (struct qeth_ipa_cmd *) data;
        setparms = &(cmd->data.setadapterparms);
-
-       qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
-       if (cmd->hdr.return_code) {
+       if (qeth_setadpparms_inspect_rc(cmd)) {
                QETH_CARD_TEXT_(card, 4, "prmrc%x", cmd->hdr.return_code);
                setparms->data.mode = SET_PROMISC_MODE_OFF;
        }
@@ -4286,18 +4265,18 @@ EXPORT_SYMBOL_GPL(qeth_get_stats);
 static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
                struct qeth_reply *reply, unsigned long data)
 {
-       struct qeth_ipa_cmd *cmd;
+       struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
 
        QETH_CARD_TEXT(card, 4, "chgmaccb");
+       if (qeth_setadpparms_inspect_rc(cmd))
+               return 0;
 
-       cmd = (struct qeth_ipa_cmd *) data;
        if (!card->options.layer2 ||
            !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
                ether_addr_copy(card->dev->dev_addr,
                                cmd->data.setadapterparms.data.change_addr.addr);
                card->info.mac_bits |= QETH_LAYER2_MAC_READ;
        }
-       qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
        return 0;
 }
 
@@ -4328,13 +4307,15 @@ EXPORT_SYMBOL_GPL(qeth_setadpparms_change_macaddr);
 static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
                struct qeth_reply *reply, unsigned long data)
 {
-       struct qeth_ipa_cmd *cmd;
+       struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
        struct qeth_set_access_ctrl *access_ctrl_req;
        int fallback = *(int *)reply->param;
 
        QETH_CARD_TEXT(card, 4, "setaccb");
+       if (cmd->hdr.return_code)
+               return 0;
+       qeth_setadpparms_inspect_rc(cmd);
 
-       cmd = (struct qeth_ipa_cmd *) data;
        access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
        QETH_DBF_TEXT_(SETUP, 2, "setaccb");
        QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
@@ -4407,7 +4388,6 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
                        card->options.isolation = card->options.prev_isolation;
                break;
        }
-       qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
        return 0;
 }
 
@@ -4695,14 +4675,15 @@ out:
 static int qeth_setadpparms_query_oat_cb(struct qeth_card *card,
                struct qeth_reply *reply, unsigned long data)
 {
-       struct qeth_ipa_cmd *cmd;
+       struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
        struct qeth_qoat_priv *priv;
        char *resdata;
        int resdatalen;
 
        QETH_CARD_TEXT(card, 3, "qoatcb");
+       if (qeth_setadpparms_inspect_rc(cmd))
+               return 0;
 
-       cmd = (struct qeth_ipa_cmd *)data;
        priv = (struct qeth_qoat_priv *)reply->param;
        resdatalen = cmd->data.setadapterparms.hdr.cmdlength;
        resdata = (char *)data + 28;
@@ -4796,21 +4777,18 @@ out:
 static int qeth_query_card_info_cb(struct qeth_card *card,
                                   struct qeth_reply *reply, unsigned long data)
 {
-       struct qeth_ipa_cmd *cmd;
+       struct carrier_info *carrier_info = (struct carrier_info *)reply->param;
+       struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
        struct qeth_query_card_info *card_info;
-       struct carrier_info *carrier_info;
 
        QETH_CARD_TEXT(card, 2, "qcrdincb");
-       carrier_info = (struct carrier_info *)reply->param;
-       cmd = (struct qeth_ipa_cmd *)data;
-       card_info = &cmd->data.setadapterparms.data.card_info;
-       if (cmd->data.setadapterparms.hdr.return_code == 0) {
-               carrier_info->card_type = card_info->card_type;
-               carrier_info->port_mode = card_info->port_mode;
-               carrier_info->port_speed = card_info->port_speed;
-       }
+       if (qeth_setadpparms_inspect_rc(cmd))
+               return 0;
 
-       qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
+       card_info = &cmd->data.setadapterparms.data.card_info;
+       carrier_info->card_type = card_info->card_type;
+       carrier_info->port_mode = card_info->port_mode;
+       carrier_info->port_speed = card_info->port_speed;
        return 0;
 }
 
@@ -4857,7 +4835,7 @@ int qeth_vm_request_mac(struct qeth_card *card)
                goto out;
        }
 
-       ccw_device_get_id(CARD_DDEV(card), &id);
+       ccw_device_get_id(CARD_RDEV(card), &id);
        request->resp_buf_len = sizeof(*response);
        request->resp_version = DIAG26C_VERSION2;
        request->op_code = DIAG26C_GET_MAC;
@@ -6563,10 +6541,14 @@ static int __init qeth_core_init(void)
        mutex_init(&qeth_mod_mutex);
 
        qeth_wq = create_singlethread_workqueue("qeth_wq");
+       if (!qeth_wq) {
+               rc = -ENOMEM;
+               goto out_err;
+       }
 
        rc = qeth_register_dbf_views();
        if (rc)
-               goto out_err;
+               goto dbf_err;
        qeth_core_root_dev = root_device_register("qeth");
        rc = PTR_ERR_OR_ZERO(qeth_core_root_dev);
        if (rc)
@@ -6603,6 +6585,8 @@ slab_err:
        root_device_unregister(qeth_core_root_dev);
 register_err:
        qeth_unregister_dbf_views();
+dbf_err:
+       destroy_workqueue(qeth_wq);
 out_err:
        pr_err("Initializing the qeth device driver failed\n");
        return rc;
index 619f897b4bb0cef7be641f6e45c8f31a1502409c..f4d1ec0b8f5a2018a6fbfaf61bd2a19792aa9aac 100644 (file)
@@ -35,6 +35,18 @@ extern unsigned char IPA_PDU_HEADER[];
 #define QETH_HALT_CHANNEL_PARM -11
 #define QETH_RCD_PARM -12
 
+static inline bool qeth_intparm_is_iob(unsigned long intparm)
+{
+       switch (intparm) {
+       case QETH_CLEAR_CHANNEL_PARM:
+       case QETH_HALT_CHANNEL_PARM:
+       case QETH_RCD_PARM:
+       case 0:
+               return false;
+       }
+       return true;
+}
+
 /*****************************************************************************/
 /* IP Assist related definitions                                             */
 /*****************************************************************************/
index 50a313806dde2a03137451390cc1358b10634bf5..b8079f2a65b3c636f0e1932437db72add1826df5 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/list.h>
 #include <linux/hash.h>
 #include <linux/hashtable.h>
-#include <linux/string.h>
 #include <asm/setup.h>
 #include "qeth_core.h"
 #include "qeth_l2.h"
@@ -122,13 +121,10 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
        QETH_CARD_TEXT(card, 2, "L2Setmac");
        rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC);
        if (rc == 0) {
-               card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
-               ether_addr_copy(card->dev->dev_addr, mac);
                dev_info(&card->gdev->dev,
-                       "MAC address %pM successfully registered on device %s\n",
-                       card->dev->dev_addr, card->dev->name);
+                        "MAC address %pM successfully registered on device %s\n",
+                        mac, card->dev->name);
        } else {
-               card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
                switch (rc) {
                case -EEXIST:
                        dev_warn(&card->gdev->dev,
@@ -143,19 +139,6 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
        return rc;
 }
 
-static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
-{
-       int rc;
-
-       QETH_CARD_TEXT(card, 2, "L2Delmac");
-       if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
-               return 0;
-       rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC);
-       if (rc == 0)
-               card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
-       return rc;
-}
-
 static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac)
 {
        enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ?
@@ -520,6 +503,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
 {
        struct sockaddr *addr = p;
        struct qeth_card *card = dev->ml_priv;
+       u8 old_addr[ETH_ALEN];
        int rc = 0;
 
        QETH_CARD_TEXT(card, 3, "setmac");
@@ -531,14 +515,35 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
                return -EOPNOTSUPP;
        }
        QETH_CARD_HEX(card, 3, addr->sa_data, ETH_ALEN);
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
        if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
                QETH_CARD_TEXT(card, 3, "setmcREC");
                return -ERESTARTSYS;
        }
-       rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
-       if (!rc || (rc == -ENOENT))
-               rc = qeth_l2_send_setmac(card, addr->sa_data);
-       return rc ? -EINVAL : 0;
+
+       if (!qeth_card_hw_is_reachable(card)) {
+               ether_addr_copy(dev->dev_addr, addr->sa_data);
+               return 0;
+       }
+
+       /* don't register the same address twice */
+       if (ether_addr_equal_64bits(dev->dev_addr, addr->sa_data) &&
+           (card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
+               return 0;
+
+       /* add the new address, switch over, drop the old */
+       rc = qeth_l2_send_setmac(card, addr->sa_data);
+       if (rc)
+               return rc;
+       ether_addr_copy(old_addr, dev->dev_addr);
+       ether_addr_copy(dev->dev_addr, addr->sa_data);
+
+       if (card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)
+               qeth_l2_remove_mac(card, old_addr);
+       card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
+       return 0;
 }
 
 static void qeth_promisc_to_bridge(struct qeth_card *card)
@@ -1068,8 +1073,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
                goto out_remove;
        }
 
-       if (card->info.type != QETH_CARD_TYPE_OSN)
-               qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
+       if (card->info.type != QETH_CARD_TYPE_OSN &&
+           !qeth_l2_send_setmac(card, card->dev->dev_addr))
+               card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
 
        if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
                if (card->info.hwtrap &&
@@ -1339,8 +1345,8 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len,
        qeth_prepare_control_data(card, len, iob);
        QETH_CARD_TEXT(card, 6, "osnoirqp");
        spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
-       rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
-                             (addr_t) iob, 0, 0);
+       rc = ccw_device_start_timeout(CARD_WDEV(card), &card->write.ccw,
+                                     (addr_t) iob, 0, 0, QETH_IPA_TIMEOUT);
        spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
        if (rc) {
                QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: "
index 3b0c8b8a7634d18df62ece8f94936ed39666a2af..066b5c3aaae6676986fdcd7ab7fe712ff97c1b57 100644 (file)
@@ -176,7 +176,7 @@ static struct device_driver smsg_driver = {
 
 static void __exit smsg_exit(void)
 {
-       cpcmd("SET SMSG IUCV", NULL, 0, NULL);
+       cpcmd("SET SMSG OFF", NULL, 0, NULL);
        device_unregister(smsg_dev);
        iucv_unregister(&smsg_handler, 1);
        driver_unregister(&smsg_driver);
index c44d7c7ffc920e9cfb35c521c6012cddfccb7b8a..1754f55e2facfb4b21169a7c97ee514392c9eaa8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
index abddde11982bbb11be7d4cf848de6d9e289a9790..98597b59c12ab6eb944ffa21107f10178c03e024 100644 (file)
@@ -296,7 +296,7 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
                  "Number of Abort FW Timeouts: %lld\n"
                  "Number of Abort IO NOT Found: %lld\n"
 
-                 "Abord issued times: \n"
+                 "Abort issued times: \n"
                  "            < 6 sec : %lld\n"
                  "     6 sec - 20 sec : %lld\n"
                  "    20 sec - 30 sec : %lld\n"
index edb7be786c6501602195b25285dda78ceb9ea537..9e8de1462593aa7371104354e0ac6b9f540ae57a 100644 (file)
@@ -291,7 +291,7 @@ sci_mpc_agent_validate_phy_configuration(struct isci_host *ihost,
                 * Note: We have not moved the current phy_index so we will actually
                 *       compare the startting phy with itself.
                 *       This is expected and required to add the phy to the port. */
-               while (phy_index < SCI_MAX_PHYS) {
+               for (; phy_index < SCI_MAX_PHYS; phy_index++) {
                        if ((phy_mask & (1 << phy_index)) == 0)
                                continue;
                        sci_phy_get_sas_address(&ihost->phys[phy_index],
@@ -311,7 +311,6 @@ sci_mpc_agent_validate_phy_configuration(struct isci_host *ihost,
                                              &ihost->phys[phy_index]);
 
                        assigned_phy_mask |= (1 << phy_index);
-                       phy_index++;
                }
 
        }
index ce97cde3b41cd174e5c29ef8145b8938b9dc9609..f4d988dd1e9d1a8389f4486a9b08bdfe9eb31a84 100644 (file)
@@ -1124,12 +1124,12 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
                goto fail_fw_init;
        }
 
-       ret = 0;
+       return 0;
 
 fail_fw_init:
        dev_err(&instance->pdev->dev,
-               "Init cmd return status %s for SCSI host %d\n",
-               ret ? "FAILED" : "SUCCESS", instance->host->host_no);
+               "Init cmd return status FAILED for SCSI host %d\n",
+               instance->host->host_no);
 
        return ret;
 }
index 9ef5e3b810f6e0f9682c3577e61005af9658e999..656c98e116a902da2c230c2026d3b2632548e2f6 100644 (file)
@@ -234,11 +234,13 @@ static const char *sdebug_version_date = "20180128";
 #define F_INV_OP               0x200
 #define F_FAKE_RW              0x400
 #define F_M_ACCESS             0x800   /* media access */
-#define F_LONG_DELAY           0x1000
+#define F_SSU_DELAY            0x1000
+#define F_SYNC_DELAY           0x2000
 
 #define FF_RESPOND (F_RL_WLUN_OK | F_SKIP_UA | F_DELAY_OVERR)
 #define FF_MEDIA_IO (F_M_ACCESS | F_FAKE_RW)
 #define FF_SA (F_SA_HIGH | F_SA_LOW)
+#define F_LONG_DELAY           (F_SSU_DELAY | F_SYNC_DELAY)
 
 #define SDEBUG_MAX_PARTS 4
 
@@ -510,7 +512,7 @@ static const struct opcode_info_t release_iarr[] = {
 };
 
 static const struct opcode_info_t sync_cache_iarr[] = {
-       {0, 0x91, 0, F_LONG_DELAY | F_M_ACCESS, resp_sync_cache, NULL,
+       {0, 0x91, 0, F_SYNC_DELAY | F_M_ACCESS, resp_sync_cache, NULL,
            {16,  0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff, 0x3f, 0xc7} },     /* SYNC_CACHE (16) */
 };
@@ -553,7 +555,7 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
            resp_write_dt0, write_iarr,                 /* WRITE(16) */
                {16,  0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7} },
-       {0, 0x1b, 0, F_LONG_DELAY, resp_start_stop, NULL,/* START STOP UNIT */
+       {0, 0x1b, 0, F_SSU_DELAY, resp_start_stop, NULL,/* START STOP UNIT */
            {6,  0x1, 0, 0xf, 0xf7, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
        {ARRAY_SIZE(sa_in_16_iarr), 0x9e, 0x10, F_SA_LOW | F_D_IN,
            resp_readcap16, sa_in_16_iarr, /* SA_IN(16), READ CAPACITY(16) */
@@ -606,7 +608,7 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
            resp_write_same_10, write_same_iarr,        /* WRITE SAME(10) */
                {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0,
                 0, 0, 0, 0, 0} },
-       {ARRAY_SIZE(sync_cache_iarr), 0x35, 0, F_LONG_DELAY | F_M_ACCESS,
+       {ARRAY_SIZE(sync_cache_iarr), 0x35, 0, F_SYNC_DELAY | F_M_ACCESS,
            resp_sync_cache, sync_cache_iarr,
            {10,  0x7, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0,
             0, 0, 0, 0} },                     /* SYNC_CACHE (10) */
@@ -667,6 +669,7 @@ static bool sdebug_strict = DEF_STRICT;
 static bool sdebug_any_injecting_opt;
 static bool sdebug_verbose;
 static bool have_dif_prot;
+static bool write_since_sync;
 static bool sdebug_statistics = DEF_STATISTICS;
 
 static unsigned int sdebug_store_sectors;
@@ -1607,6 +1610,7 @@ static int resp_start_stop(struct scsi_cmnd *scp,
 {
        unsigned char *cmd = scp->cmnd;
        int power_cond, stop;
+       bool changing;
 
        power_cond = (cmd[4] & 0xf0) >> 4;
        if (power_cond) {
@@ -1614,8 +1618,12 @@ static int resp_start_stop(struct scsi_cmnd *scp,
                return check_condition_result;
        }
        stop = !(cmd[4] & 1);
+       changing = atomic_read(&devip->stopped) == !stop;
        atomic_xchg(&devip->stopped, stop);
-       return (cmd[1] & 0x1) ? SDEG_RES_IMMED_MASK : 0; /* check IMMED bit */
+       if (!changing || cmd[1] & 0x1)  /* state unchanged or IMMED set */
+               return SDEG_RES_IMMED_MASK;
+       else
+               return 0;
 }
 
 static sector_t get_sdebug_capacity(void)
@@ -2473,6 +2481,7 @@ static int do_device_access(struct scsi_cmnd *scmd, u32 sg_skip, u64 lba,
        if (do_write) {
                sdb = scsi_out(scmd);
                dir = DMA_TO_DEVICE;
+               write_since_sync = true;
        } else {
                sdb = scsi_in(scmd);
                dir = DMA_FROM_DEVICE;
@@ -3583,6 +3592,7 @@ static int resp_get_lba_status(struct scsi_cmnd *scp,
 static int resp_sync_cache(struct scsi_cmnd *scp,
                           struct sdebug_dev_info *devip)
 {
+       int res = 0;
        u64 lba;
        u32 num_blocks;
        u8 *cmd = scp->cmnd;
@@ -3598,7 +3608,11 @@ static int resp_sync_cache(struct scsi_cmnd *scp,
                mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0);
                return check_condition_result;
        }
-       return (cmd[1] & 0x2) ? SDEG_RES_IMMED_MASK : 0; /* check IMMED bit */
+       if (!write_since_sync || cmd[1] & 0x2)
+               res = SDEG_RES_IMMED_MASK;
+       else            /* delay if write_since_sync and IMMED clear */
+               write_since_sync = false;
+       return res;
 }
 
 #define RL_BUCKET_ELEMS 8
@@ -5777,13 +5791,14 @@ fini:
                return schedule_resp(scp, devip, errsts, pfp, 0, 0);
        else if ((sdebug_jdelay || sdebug_ndelay) && (flags & F_LONG_DELAY)) {
                /*
-                * If any delay is active, want F_LONG_DELAY to be at least 1
+                * If any delay is active, for F_SSU_DELAY want at least 1
                 * second and if sdebug_jdelay>0 want a long delay of that
-                * many seconds.
+                * many seconds; for F_SYNC_DELAY want 1/20 of that.
                 */
                int jdelay = (sdebug_jdelay < 2) ? 1 : sdebug_jdelay;
+               int denom = (flags & F_SYNC_DELAY) ? 20 : 1;
 
-               jdelay = mult_frac(USER_HZ * jdelay, HZ, USER_HZ);
+               jdelay = mult_frac(USER_HZ * jdelay, HZ, denom * USER_HZ);
                return schedule_resp(scp, devip, errsts, pfp, jdelay, 0);
        } else
                return schedule_resp(scp, devip, errsts, pfp, sdebug_jdelay,
index f4b52b44b966c98edc18549f37c1fe603737aaa1..65f6c94f2e9b3fa0be7104fa53048a0c61579701 100644 (file)
@@ -2322,6 +2322,12 @@ iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp)
        return nlmsg_multicast(nls, skb, 0, group, gfp);
 }
 
+static int
+iscsi_unicast_skb(struct sk_buff *skb, u32 portid)
+{
+       return nlmsg_unicast(nls, skb, portid);
+}
+
 int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
                   char *data, uint32_t data_size)
 {
@@ -2524,14 +2530,11 @@ void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
 EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);
 
 static int
-iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
-                   void *payload, int size)
+iscsi_if_send_reply(u32 portid, int type, void *payload, int size)
 {
        struct sk_buff  *skb;
        struct nlmsghdr *nlh;
        int len = nlmsg_total_size(size);
-       int flags = multi ? NLM_F_MULTI : 0;
-       int t = done ? NLMSG_DONE : type;
 
        skb = alloc_skb(len, GFP_ATOMIC);
        if (!skb) {
@@ -2539,10 +2542,9 @@ iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
                return -ENOMEM;
        }
 
-       nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0);
-       nlh->nlmsg_flags = flags;
+       nlh = __nlmsg_put(skb, 0, 0, type, (len - sizeof(*nlh)), 0);
        memcpy(nlmsg_data(nlh), payload, size);
-       return iscsi_multicast_skb(skb, group, GFP_ATOMIC);
+       return iscsi_unicast_skb(skb, portid);
 }
 
 static int
@@ -3470,6 +3472,7 @@ static int
 iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 {
        int err = 0;
+       u32 portid;
        struct iscsi_uevent *ev = nlmsg_data(nlh);
        struct iscsi_transport *transport = NULL;
        struct iscsi_internal *priv;
@@ -3490,10 +3493,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
        if (!try_module_get(transport->owner))
                return -EINVAL;
 
+       portid = NETLINK_CB(skb).portid;
+
        switch (nlh->nlmsg_type) {
        case ISCSI_UEVENT_CREATE_SESSION:
                err = iscsi_if_create_session(priv, ep, ev,
-                                             NETLINK_CB(skb).portid,
+                                             portid,
                                              ev->u.c_session.initial_cmdsn,
                                              ev->u.c_session.cmds_max,
                                              ev->u.c_session.queue_depth);
@@ -3506,7 +3511,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
                }
 
                err = iscsi_if_create_session(priv, ep, ev,
-                                       NETLINK_CB(skb).portid,
+                                       portid,
                                        ev->u.c_bound_session.initial_cmdsn,
                                        ev->u.c_bound_session.cmds_max,
                                        ev->u.c_bound_session.queue_depth);
@@ -3664,6 +3669,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 static void
 iscsi_if_rx(struct sk_buff *skb)
 {
+       u32 portid = NETLINK_CB(skb).portid;
+
        mutex_lock(&rx_queue_mutex);
        while (skb->len >= NLMSG_HDRLEN) {
                int err;
@@ -3699,8 +3706,8 @@ iscsi_if_rx(struct sk_buff *skb)
                                break;
                        if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
                                break;
-                       err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
-                               nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
+                       err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
+                                                 ev, sizeof(*ev));
                } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
                skb_pull(skb, rlen);
        }
index a6201e696ab9c5a20e0e75e1ee9b3a7b87c14461..9421d987773051e72af159ce1b4cc1f5f961e2a6 100644 (file)
@@ -2121,6 +2121,8 @@ sd_spinup_disk(struct scsi_disk *sdkp)
                                break;  /* standby */
                        if (sshdr.asc == 4 && sshdr.ascq == 0xc)
                                break;  /* unavailable */
+                       if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
+                               break;  /* sanitize in progress */
                        /*
                         * Issue command to spin up drive when not ready
                         */
index 41df75eea57be7362e1be8f737d1bae9bac91977..210407cd2341bf9bb89f5831939d4c0a204af485 100644 (file)
@@ -400,8 +400,10 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf)
  *
  * Check that all zones of the device are equal. The last zone can however
  * be smaller. The zone size must also be a power of two number of LBAs.
+ *
+ * Returns the zone size in bytes upon success or an error code upon failure.
  */
-static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
+static s64 sd_zbc_check_zone_size(struct scsi_disk *sdkp)
 {
        u64 zone_blocks = 0;
        sector_t block = 0;
@@ -412,8 +414,6 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
        int ret;
        u8 same;
 
-       sdkp->zone_blocks = 0;
-
        /* Get a buffer */
        buf = kmalloc(SD_ZBC_BUF_SIZE, GFP_KERNEL);
        if (!buf)
@@ -445,16 +445,17 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
 
                /* Parse zone descriptors */
                while (rec < buf + buf_len) {
-                       zone_blocks = get_unaligned_be64(&rec[8]);
-                       if (sdkp->zone_blocks == 0) {
-                               sdkp->zone_blocks = zone_blocks;
-                       } else if (zone_blocks != sdkp->zone_blocks &&
-                                  (block + zone_blocks < sdkp->capacity
-                                   || zone_blocks > sdkp->zone_blocks)) {
-                               zone_blocks = 0;
+                       u64 this_zone_blocks = get_unaligned_be64(&rec[8]);
+
+                       if (zone_blocks == 0) {
+                               zone_blocks = this_zone_blocks;
+                       } else if (this_zone_blocks != zone_blocks &&
+                                  (block + this_zone_blocks < sdkp->capacity
+                                   || this_zone_blocks > zone_blocks)) {
+                               this_zone_blocks = 0;
                                goto out;
                        }
-                       block += zone_blocks;
+                       block += this_zone_blocks;
                        rec += 64;
                }
 
@@ -467,8 +468,6 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
 
        } while (block < sdkp->capacity);
 
-       zone_blocks = sdkp->zone_blocks;
-
 out:
        if (!zone_blocks) {
                if (sdkp->first_scan)
@@ -488,8 +487,7 @@ out:
                                  "Zone size too large\n");
                ret = -ENODEV;
        } else {
-               sdkp->zone_blocks = zone_blocks;
-               sdkp->zone_shift = ilog2(zone_blocks);
+               ret = zone_blocks;
        }
 
 out_free:
@@ -500,15 +498,14 @@ out_free:
 
 /**
  * sd_zbc_alloc_zone_bitmap - Allocate a zone bitmap (one bit per zone).
- * @sdkp: The disk of the bitmap
+ * @nr_zones: Number of zones to allocate space for.
+ * @numa_node: NUMA node to allocate the memory from.
  */
-static inline unsigned long *sd_zbc_alloc_zone_bitmap(struct scsi_disk *sdkp)
+static inline unsigned long *
+sd_zbc_alloc_zone_bitmap(u32 nr_zones, int numa_node)
 {
-       struct request_queue *q = sdkp->disk->queue;
-
-       return kzalloc_node(BITS_TO_LONGS(sdkp->nr_zones)
-                           * sizeof(unsigned long),
-                           GFP_KERNEL, q->node);
+       return kzalloc_node(BITS_TO_LONGS(nr_zones) * sizeof(unsigned long),
+                           GFP_KERNEL, numa_node);
 }
 
 /**
@@ -516,6 +513,7 @@ static inline unsigned long *sd_zbc_alloc_zone_bitmap(struct scsi_disk *sdkp)
  * @sdkp: disk used
  * @buf: report reply buffer
  * @buflen: length of @buf
+ * @zone_shift: logarithm base 2 of the number of blocks in a zone
  * @seq_zones_bitmap: bitmap of sequential zones to set
  *
  * Parse reported zone descriptors in @buf to identify sequential zones and
@@ -525,7 +523,7 @@ static inline unsigned long *sd_zbc_alloc_zone_bitmap(struct scsi_disk *sdkp)
  * Return the LBA after the last zone reported.
  */
 static sector_t sd_zbc_get_seq_zones(struct scsi_disk *sdkp, unsigned char *buf,
-                                    unsigned int buflen,
+                                    unsigned int buflen, u32 zone_shift,
                                     unsigned long *seq_zones_bitmap)
 {
        sector_t lba, next_lba = sdkp->capacity;
@@ -544,7 +542,7 @@ static sector_t sd_zbc_get_seq_zones(struct scsi_disk *sdkp, unsigned char *buf,
                if (type != ZBC_ZONE_TYPE_CONV &&
                    cond != ZBC_ZONE_COND_READONLY &&
                    cond != ZBC_ZONE_COND_OFFLINE)
-                       set_bit(lba >> sdkp->zone_shift, seq_zones_bitmap);
+                       set_bit(lba >> zone_shift, seq_zones_bitmap);
                next_lba = lba + get_unaligned_be64(&rec[8]);
                rec += 64;
        }
@@ -553,12 +551,16 @@ static sector_t sd_zbc_get_seq_zones(struct scsi_disk *sdkp, unsigned char *buf,
 }
 
 /**
- * sd_zbc_setup_seq_zones_bitmap - Initialize the disk seq zone bitmap.
+ * sd_zbc_setup_seq_zones_bitmap - Initialize a seq zone bitmap.
  * @sdkp: target disk
+ * @zone_shift: logarithm base 2 of the number of blocks in a zone
+ * @nr_zones: number of zones to set up a seq zone bitmap for
  *
  * Allocate a zone bitmap and initialize it by identifying sequential zones.
  */
-static int sd_zbc_setup_seq_zones_bitmap(struct scsi_disk *sdkp)
+static unsigned long *
+sd_zbc_setup_seq_zones_bitmap(struct scsi_disk *sdkp, u32 zone_shift,
+                             u32 nr_zones)
 {
        struct request_queue *q = sdkp->disk->queue;
        unsigned long *seq_zones_bitmap;
@@ -566,9 +568,9 @@ static int sd_zbc_setup_seq_zones_bitmap(struct scsi_disk *sdkp)
        unsigned char *buf;
        int ret = -ENOMEM;
 
-       seq_zones_bitmap = sd_zbc_alloc_zone_bitmap(sdkp);
+       seq_zones_bitmap = sd_zbc_alloc_zone_bitmap(nr_zones, q->node);
        if (!seq_zones_bitmap)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        buf = kmalloc(SD_ZBC_BUF_SIZE, GFP_KERNEL);
        if (!buf)
@@ -579,7 +581,7 @@ static int sd_zbc_setup_seq_zones_bitmap(struct scsi_disk *sdkp)
                if (ret)
                        goto out;
                lba = sd_zbc_get_seq_zones(sdkp, buf, SD_ZBC_BUF_SIZE,
-                                          seq_zones_bitmap);
+                                          zone_shift, seq_zones_bitmap);
        }
 
        if (lba != sdkp->capacity) {
@@ -591,12 +593,9 @@ out:
        kfree(buf);
        if (ret) {
                kfree(seq_zones_bitmap);
-               return ret;
+               return ERR_PTR(ret);
        }
-
-       q->seq_zones_bitmap = seq_zones_bitmap;
-
-       return 0;
+       return seq_zones_bitmap;
 }
 
 static void sd_zbc_cleanup(struct scsi_disk *sdkp)
@@ -612,44 +611,64 @@ static void sd_zbc_cleanup(struct scsi_disk *sdkp)
        q->nr_zones = 0;
 }
 
-static int sd_zbc_setup(struct scsi_disk *sdkp)
+static int sd_zbc_setup(struct scsi_disk *sdkp, u32 zone_blocks)
 {
        struct request_queue *q = sdkp->disk->queue;
+       u32 zone_shift = ilog2(zone_blocks);
+       u32 nr_zones;
        int ret;
 
-       /* READ16/WRITE16 is mandatory for ZBC disks */
-       sdkp->device->use_16_for_rw = 1;
-       sdkp->device->use_10_for_rw = 0;
-
        /* chunk_sectors indicates the zone size */
-       blk_queue_chunk_sectors(sdkp->disk->queue,
-                       logical_to_sectors(sdkp->device, sdkp->zone_blocks));
-       sdkp->nr_zones =
-               round_up(sdkp->capacity, sdkp->zone_blocks) >> sdkp->zone_shift;
+       blk_queue_chunk_sectors(q,
+                       logical_to_sectors(sdkp->device, zone_blocks));
+       nr_zones = round_up(sdkp->capacity, zone_blocks) >> zone_shift;
 
        /*
         * Initialize the device request queue information if the number
         * of zones changed.
         */
-       if (sdkp->nr_zones != q->nr_zones) {
-
-               sd_zbc_cleanup(sdkp);
-
-               q->nr_zones = sdkp->nr_zones;
-               if (sdkp->nr_zones) {
-                       q->seq_zones_wlock = sd_zbc_alloc_zone_bitmap(sdkp);
-                       if (!q->seq_zones_wlock) {
+       if (nr_zones != sdkp->nr_zones || nr_zones != q->nr_zones) {
+               unsigned long *seq_zones_wlock = NULL, *seq_zones_bitmap = NULL;
+               size_t zone_bitmap_size;
+
+               if (nr_zones) {
+                       seq_zones_wlock = sd_zbc_alloc_zone_bitmap(nr_zones,
+                                                                  q->node);
+                       if (!seq_zones_wlock) {
                                ret = -ENOMEM;
                                goto err;
                        }
 
-                       ret = sd_zbc_setup_seq_zones_bitmap(sdkp);
-                       if (ret) {
-                               sd_zbc_cleanup(sdkp);
+                       seq_zones_bitmap = sd_zbc_setup_seq_zones_bitmap(sdkp,
+                                                       zone_shift, nr_zones);
+                       if (IS_ERR(seq_zones_bitmap)) {
+                               ret = PTR_ERR(seq_zones_bitmap);
+                               kfree(seq_zones_wlock);
                                goto err;
                        }
                }
-
+               zone_bitmap_size = BITS_TO_LONGS(nr_zones) *
+                       sizeof(unsigned long);
+               blk_mq_freeze_queue(q);
+               if (q->nr_zones != nr_zones) {
+                       /* READ16/WRITE16 is mandatory for ZBC disks */
+                       sdkp->device->use_16_for_rw = 1;
+                       sdkp->device->use_10_for_rw = 0;
+
+                       sdkp->zone_blocks = zone_blocks;
+                       sdkp->zone_shift = zone_shift;
+                       sdkp->nr_zones = nr_zones;
+                       q->nr_zones = nr_zones;
+                       swap(q->seq_zones_wlock, seq_zones_wlock);
+                       swap(q->seq_zones_bitmap, seq_zones_bitmap);
+               } else if (memcmp(q->seq_zones_bitmap, seq_zones_bitmap,
+                                 zone_bitmap_size) != 0) {
+                       memcpy(q->seq_zones_bitmap, seq_zones_bitmap,
+                              zone_bitmap_size);
+               }
+               blk_mq_unfreeze_queue(q);
+               kfree(seq_zones_wlock);
+               kfree(seq_zones_bitmap);
        }
 
        return 0;
@@ -661,6 +680,7 @@ err:
 
 int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)
 {
+       int64_t zone_blocks;
        int ret;
 
        if (!sd_is_zoned(sdkp))
@@ -697,12 +717,16 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)
         * Check zone size: only devices with a constant zone size (except
         * an eventual last runt zone) that is a power of 2 are supported.
         */
-       ret = sd_zbc_check_zone_size(sdkp);
-       if (ret)
+       zone_blocks = sd_zbc_check_zone_size(sdkp);
+       ret = -EFBIG;
+       if (zone_blocks != (u32)zone_blocks)
+               goto err;
+       ret = zone_blocks;
+       if (ret < 0)
                goto err;
 
        /* The drive satisfies the kernel restrictions: set it up */
-       ret = sd_zbc_setup(sdkp);
+       ret = sd_zbc_setup(sdkp, zone_blocks);
        if (ret)
                goto err;
 
index 8c51d628b52edfd7e891182919fab16b469b0f3c..a2ec0bc9e9fac01f0f30237540b2d5ea1d4a3f2f 100644 (file)
@@ -1722,11 +1722,14 @@ static int storvsc_probe(struct hv_device *device,
                max_targets = STORVSC_MAX_TARGETS;
                max_channels = STORVSC_MAX_CHANNELS;
                /*
-                * On Windows8 and above, we support sub-channels for storage.
+                * On Windows8 and above, we support sub-channels for storage
+                * on SCSI and FC controllers.
                 * The number of sub-channels offerred is based on the number of
                 * VCPUs in the guest.
                 */
-               max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
+               if (!dev_is_ide)
+                       max_sub_channels =
+                               (num_cpus - 1) / storvsc_vcpus_per_sub_channel;
        }
 
        scsi_driver.can_queue = (max_outstanding_req_per_channel *
index c5b1bf1cadcb043390b3e8c6657f38692bea0774..00e79057f870dfa67303dc3ed7bff96ba874f329 100644 (file)
@@ -276,6 +276,35 @@ static inline void ufshcd_remove_non_printable(char *val)
                *val = ' ';
 }
 
+static void ufshcd_add_cmd_upiu_trace(struct ufs_hba *hba, unsigned int tag,
+               const char *str)
+{
+       struct utp_upiu_req *rq = hba->lrb[tag].ucd_req_ptr;
+
+       trace_ufshcd_upiu(dev_name(hba->dev), str, &rq->header, &rq->sc.cdb);
+}
+
+static void ufshcd_add_query_upiu_trace(struct ufs_hba *hba, unsigned int tag,
+               const char *str)
+{
+       struct utp_upiu_req *rq = hba->lrb[tag].ucd_req_ptr;
+
+       trace_ufshcd_upiu(dev_name(hba->dev), str, &rq->header, &rq->qr);
+}
+
+static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag,
+               const char *str)
+{
+       struct utp_task_req_desc *descp;
+       struct utp_upiu_task_req *task_req;
+       int off = (int)tag - hba->nutrs;
+
+       descp = &hba->utmrdl_base_addr[off];
+       task_req = (struct utp_upiu_task_req *)descp->task_req_upiu;
+       trace_ufshcd_upiu(dev_name(hba->dev), str, &task_req->header,
+                       &task_req->input_param1);
+}
+
 static void ufshcd_add_command_trace(struct ufs_hba *hba,
                unsigned int tag, const char *str)
 {
@@ -285,6 +314,9 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba,
        struct ufshcd_lrb *lrbp;
        int transfer_len = -1;
 
+       /* trace UPIU also */
+       ufshcd_add_cmd_upiu_trace(hba, tag, str);
+
        if (!trace_ufshcd_command_enabled())
                return;
 
@@ -2550,6 +2582,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 
        hba->dev_cmd.complete = &wait;
 
+       ufshcd_add_query_upiu_trace(hba, tag, "query_send");
        /* Make sure descriptors are ready before ringing the doorbell */
        wmb();
        spin_lock_irqsave(hba->host->host_lock, flags);
@@ -2559,6 +2592,9 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 
        err = ufshcd_wait_for_dev_cmd(hba, lrbp, timeout);
 
+       ufshcd_add_query_upiu_trace(hba, tag,
+                       err ? "query_complete_err" : "query_complete");
+
 out_put_tag:
        ufshcd_put_dev_cmd_tag(hba, tag);
        wake_up(&hba->dev_cmd.tag_wq);
@@ -5443,11 +5479,14 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
 
        spin_unlock_irqrestore(host->host_lock, flags);
 
+       ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_send");
+
        /* wait until the task management command is completed */
        err = wait_event_timeout(hba->tm_wq,
                        test_bit(free_slot, &hba->tm_condition),
                        msecs_to_jiffies(TM_CMD_TIMEOUT));
        if (!err) {
+               ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete_err");
                dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n",
                                __func__, tm_function);
                if (ufshcd_clear_tm_cmd(hba, free_slot))
@@ -5456,6 +5495,7 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
                err = -ETIMEDOUT;
        } else {
                err = ufshcd_task_req_compl(hba, free_slot, tm_response);
+               ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete");
        }
 
        clear_bit(free_slot, &hba->tm_condition);
index 884419c37e8419c8e2a955e4406f75d68e1e1298..457ea1f8db309cb90ea2eef0feefe64be56e3f70 100644 (file)
@@ -183,7 +183,7 @@ static u16 slim_slicesize(int code)
                0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7
        };
 
-       clamp(code, 1, (int)ARRAY_SIZE(sizetocode));
+       code = clamp(code, 1, (int)ARRAY_SIZE(sizetocode));
 
        return sizetocode[code - 1];
 }
index fe96a8b956fbd54424bea059af5b0be1240c91b3..f7ed1187518b9d2b47bedd29ae6b5a1e3ab566fd 100644 (file)
@@ -45,7 +45,7 @@ struct rpi_power_domains {
 struct rpi_power_domain_packet {
        u32 domain;
        u32 on;
-} __packet;
+};
 
 /*
  * Asks the firmware to enable or disable power on a specific power
index 6b5300ca44a67a8bcd75a5ad0149504220a2984e..885f5fcead777e7526f9c0e3b363bf9ca8584784 100644 (file)
@@ -1390,7 +1390,7 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
        }
 
        if (hif_drv->usr_conn_req.ies) {
-               conn_info.req_ies = kmemdup(conn_info.req_ies,
+               conn_info.req_ies = kmemdup(hif_drv->usr_conn_req.ies,
                                            hif_drv->usr_conn_req.ies_len,
                                            GFP_KERNEL);
                if (conn_info.req_ies)
index 07c814c42648faa00d7bca39ad339d7ef916ec99..60429011292a2c4c2fa4104a90414ae948f956a7 100644 (file)
@@ -427,8 +427,8 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd)
 {
        struct se_device *dev = cmd->se_dev;
        struct scatterlist *sg = &cmd->t_data_sg[0];
-       unsigned char *buf, zero = 0x00, *p = &zero;
-       int rc, ret;
+       unsigned char *buf, *not_zero;
+       int ret;
 
        buf = kmap(sg_page(sg)) + sg->offset;
        if (!buf)
@@ -437,10 +437,10 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd)
         * Fall back to block_execute_write_same() slow-path if
         * incoming WRITE_SAME payload does not contain zeros.
         */
-       rc = memcmp(buf, p, cmd->data_length);
+       not_zero = memchr_inv(buf, 0x00, cmd->data_length);
        kunmap(sg_page(sg));
 
-       if (rc)
+       if (not_zero)
                return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
        ret = blkdev_issue_zeroout(bdev,
index 0d99b242e82e3f84da25a47564f96db60be4b5f5..6cb933ecc084029f420fb2e13784a01f9c97e434 100644 (file)
@@ -890,6 +890,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
                        bytes = min(bytes, data_len);
 
                        if (!bio) {
+new_bio:
                                nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages);
                                nr_pages -= nr_vecs;
                                /*
@@ -931,6 +932,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
                                 * be allocated with pscsi_get_bio() above.
                                 */
                                bio = NULL;
+                               goto new_bio;
                        }
 
                        data_len -= bytes;
index 3b3e1f6632d71c1aae24d690679b4b53673ce148..1dbe27c9946c16578a6ad0f82313c4adf797aef0 100644 (file)
@@ -121,6 +121,9 @@ struct gsm_dlci {
        struct mutex mutex;
 
        /* Link layer */
+       int mode;
+#define DLCI_MODE_ABM          0       /* Normal Asynchronous Balanced Mode */
+#define DLCI_MODE_ADM          1       /* Asynchronous Disconnected Mode */
        spinlock_t lock;        /* Protects the internal state */
        struct timer_list t1;   /* Retransmit timer for SABM and UA */
        int retries;
@@ -1364,7 +1367,13 @@ retry:
        ctrl->data = data;
        ctrl->len = clen;
        gsm->pending_cmd = ctrl;
-       gsm->cretries = gsm->n2;
+
+       /* If DLCI0 is in ADM mode skip retries, it won't respond */
+       if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
+               gsm->cretries = 1;
+       else
+               gsm->cretries = gsm->n2;
+
        mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
        gsm_control_transmit(gsm, ctrl);
        spin_unlock_irqrestore(&gsm->control_lock, flags);
@@ -1472,6 +1481,7 @@ static void gsm_dlci_t1(struct timer_list *t)
                        if (debug & 8)
                                pr_info("DLCI %d opening in ADM mode.\n",
                                        dlci->addr);
+                       dlci->mode = DLCI_MODE_ADM;
                        gsm_dlci_open(dlci);
                } else {
                        gsm_dlci_close(dlci);
@@ -2861,11 +2871,22 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
 static int gsm_carrier_raised(struct tty_port *port)
 {
        struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
+       struct gsm_mux *gsm = dlci->gsm;
+
        /* Not yet open so no carrier info */
        if (dlci->state != DLCI_OPEN)
                return 0;
        if (debug & 2)
                return 1;
+
+       /*
+        * Basic mode with control channel in ADM mode may not respond
+        * to CMD_MSC at all and modem_rx is empty.
+        */
+       if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM &&
+           !dlci->modem_rx)
+               return 1;
+
        return dlci->modem_rx & TIOCM_CD;
 }
 
index a24278380fec2a6a67b2513514f08ecd6688dfe2..22683393a0f2c3f7b6054d367823a3f99f4df103 100644 (file)
@@ -169,7 +169,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
  */
 int __init setup_earlycon(char *buf)
 {
-       const struct earlycon_id *match;
+       const struct earlycon_id **p_match;
 
        if (!buf || !buf[0])
                return -EINVAL;
@@ -177,7 +177,9 @@ int __init setup_earlycon(char *buf)
        if (early_con.flags & CON_ENABLED)
                return -EALREADY;
 
-       for (match = __earlycon_table; match < __earlycon_table_end; match++) {
+       for (p_match = __earlycon_table; p_match < __earlycon_table_end;
+            p_match++) {
+               const struct earlycon_id *match = *p_match;
                size_t len = strlen(match->name);
 
                if (strncmp(buf, match->name, len))
index 91f3a1a5cb7fa81ac82a2289e792fc5c908df9b2..c2fc6bef7a6f28a6fc3fe9f18782c555bdb35a35 100644 (file)
@@ -316,7 +316,7 @@ static u32 imx_uart_readl(struct imx_port *sport, u32 offset)
                 * differ from the value that was last written. As it only
                 * clears after being set, reread conditionally.
                 */
-               if (sport->ucr2 & UCR2_SRST)
+               if (!(sport->ucr2 & UCR2_SRST))
                        sport->ucr2 = readl(sport->port.membase + offset);
                return sport->ucr2;
                break;
@@ -1833,6 +1833,11 @@ static int imx_uart_rs485_config(struct uart_port *port,
                rs485conf->flags &= ~SER_RS485_ENABLED;
 
        if (rs485conf->flags & SER_RS485_ENABLED) {
+               /* Enable receiver if low-active RTS signal is requested */
+               if (sport->have_rtscts &&  !sport->have_rtsgpio &&
+                   !(rs485conf->flags & SER_RS485_RTS_ON_SEND))
+                       rs485conf->flags |= SER_RS485_RX_DURING_TX;
+
                /* disable transmitter */
                ucr2 = imx_uart_readl(sport, UCR2);
                if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
@@ -2265,6 +2270,18 @@ static int imx_uart_probe(struct platform_device *pdev)
            (!sport->have_rtscts && !sport->have_rtsgpio))
                dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
 
+       /*
+        * If using the i.MX UART RTS/CTS control then the RTS (CTS_B)
+        * signal cannot be set low during transmission in case the
+        * receiver is off (limitation of the i.MX UART IP).
+        */
+       if (sport->port.rs485.flags & SER_RS485_ENABLED &&
+           sport->have_rtscts && !sport->have_rtsgpio &&
+           (!(sport->port.rs485.flags & SER_RS485_RTS_ON_SEND) &&
+            !(sport->port.rs485.flags & SER_RS485_RX_DURING_TX)))
+               dev_err(&pdev->dev,
+                       "low-active RTS not possible when receiver is off, enabling receiver\n");
+
        imx_uart_rs485_config(&sport->port, &sport->port.rs485);
 
        /* Disable interrupts before requesting them */
index 750e5645dc857c7ba63bd0a848e9f6055fac988c..f503fab1e2685f2451d540ed18d5f474a71581b4 100644 (file)
@@ -495,7 +495,6 @@ static void mvebu_uart_set_termios(struct uart_port *port,
                termios->c_iflag |= old->c_iflag & ~(INPCK | IGNPAR);
                termios->c_cflag &= CREAD | CBAUD;
                termios->c_cflag |= old->c_cflag & ~(CREAD | CBAUD);
-               termios->c_lflag = old->c_lflag;
        }
 
        spin_unlock_irqrestore(&port->lock, flags);
index 65ff669373d4a0325ffd97a04f070ee3e389217a..a1b3eb04cb32c78f17ccd32698ced4a459091869 100644 (file)
@@ -1022,6 +1022,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
        struct qcom_geni_serial_port *port;
        struct uart_port *uport;
        struct resource *res;
+       int irq;
 
        if (pdev->dev.of_node)
                line = of_alias_get_id(pdev->dev.of_node, "serial");
@@ -1061,11 +1062,12 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
        port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS;
        port->tx_fifo_width = DEF_FIFO_WIDTH_BITS;
 
-       uport->irq = platform_get_irq(pdev, 0);
-       if (uport->irq < 0) {
-               dev_err(&pdev->dev, "Failed to get IRQ %d\n", uport->irq);
-               return uport->irq;
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "Failed to get IRQ %d\n", irq);
+               return irq;
        }
+       uport->irq = irq;
 
        uport->private_data = &qcom_geni_console_driver;
        platform_set_drvdata(pdev, port);
index abcb4d09a2d866d05b7af3c1ff5d3f68492514c1..bd72dd843338dc9a3aecaacaa04dc7b2fc2442db 100644 (file)
@@ -1181,7 +1181,7 @@ static int __init cdns_early_console_setup(struct earlycon_device *device,
        /* only set baud if specified on command line - otherwise
         * assume it has been initialized by a boot loader.
         */
-       if (device->baud) {
+       if (port->uartclk && device->baud) {
                u32 cd = 0, bdiv = 0;
                u32 mr;
                int div8;
index 63114ea35ec1b8f3620ec888155b929ed1915200..7c838b90a31d636865ce99a84466967d57b777aa 100644 (file)
@@ -2816,7 +2816,10 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
 
        kref_init(&tty->kref);
        tty->magic = TTY_MAGIC;
-       tty_ldisc_init(tty);
+       if (tty_ldisc_init(tty)) {
+               kfree(tty);
+               return NULL;
+       }
        tty->session = NULL;
        tty->pgrp = NULL;
        mutex_init(&tty->legacy_mutex);
index 050f4d650891763f96800244869821afb9d1586e..fb7329ab2b37a85f0682805d2fe996f6279df64b 100644 (file)
@@ -176,12 +176,11 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
                        return ERR_CAST(ldops);
        }
 
-       ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
-       if (ld == NULL) {
-               put_ldops(ldops);
-               return ERR_PTR(-ENOMEM);
-       }
-
+       /*
+        * There is no way to handle allocation failure of only 16 bytes.
+        * Let's simplify error handling and save more memory.
+        */
+       ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
        ld->ops = ldops;
        ld->tty = tty;
 
@@ -527,19 +526,16 @@ static int tty_ldisc_failto(struct tty_struct *tty, int ld)
 static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
 {
        /* There is an outstanding reference here so this is safe */
-       old = tty_ldisc_get(tty, old->ops->num);
-       WARN_ON(IS_ERR(old));
-       tty->ldisc = old;
-       tty_set_termios_ldisc(tty, old->ops->num);
-       if (tty_ldisc_open(tty, old) < 0) {
-               tty_ldisc_put(old);
+       if (tty_ldisc_failto(tty, old->ops->num) < 0) {
+               const char *name = tty_name(tty);
+
+               pr_warn("Falling back ldisc for %s.\n", name);
                /* The traditional behaviour is to fall back to N_TTY, we
                   want to avoid falling back to N_NULL unless we have no
                   choice to avoid the risk of breaking anything */
                if (tty_ldisc_failto(tty, N_TTY) < 0 &&
                    tty_ldisc_failto(tty, N_NULL) < 0)
-                       panic("Couldn't open N_NULL ldisc for %s.",
-                             tty_name(tty));
+                       panic("Couldn't open N_NULL ldisc for %s.", name);
        }
 }
 
@@ -824,12 +820,13 @@ EXPORT_SYMBOL_GPL(tty_ldisc_release);
  *     the tty structure is not completely set up when this call is made.
  */
 
-void tty_ldisc_init(struct tty_struct *tty)
+int tty_ldisc_init(struct tty_struct *tty)
 {
        struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
        if (IS_ERR(ld))
-               panic("n_tty: init_tty");
+               return PTR_ERR(ld);
        tty->ldisc = ld;
+       return 0;
 }
 
 /**
index f695a7e8c314585c8b0df8ab88f44d897986839b..c690d100adcd075b2999b82443b08e4ce03c2b53 100644 (file)
@@ -19,7 +19,7 @@
  * # echo -n "ed963694-e847-4b2a-85af-bc9cfc11d6f3" \
  *    > /sys/bus/vmbus/drivers/uio_hv_generic/bind
  */
-
+#define DEBUG 1
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/device.h>
@@ -94,10 +94,11 @@ hv_uio_irqcontrol(struct uio_info *info, s32 irq_state)
  */
 static void hv_uio_channel_cb(void *context)
 {
-       struct hv_uio_private_data *pdata = context;
-       struct hv_device *dev = pdata->device;
+       struct vmbus_channel *chan = context;
+       struct hv_device *hv_dev = chan->device_obj;
+       struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
 
-       dev->channel->inbound.ring_buffer->interrupt_mask = 1;
+       chan->inbound.ring_buffer->interrupt_mask = 1;
        virt_mb();
 
        uio_event_notify(&pdata->info);
@@ -121,78 +122,46 @@ static void hv_uio_rescind(struct vmbus_channel *channel)
        uio_event_notify(&pdata->info);
 }
 
-/*
- * Handle fault when looking for sub channel ring buffer
- * Subchannel ring buffer is same as resource 0 which is main ring buffer
- * This is derived from uio_vma_fault
+/* Sysfs API to allow mmap of the ring buffers
+ * The ring buffer is allocated as contiguous memory by vmbus_open
  */
-static int hv_uio_vma_fault(struct vm_fault *vmf)
-{
-       struct vm_area_struct *vma = vmf->vma;
-       void *ring_buffer = vma->vm_private_data;
-       struct page *page;
-       void *addr;
-
-       addr = ring_buffer + (vmf->pgoff << PAGE_SHIFT);
-       page = virt_to_page(addr);
-       get_page(page);
-       vmf->page = page;
-       return 0;
-}
-
-static const struct vm_operations_struct hv_uio_vm_ops = {
-       .fault = hv_uio_vma_fault,
-};
-
-/* Sysfs API to allow mmap of the ring buffers */
 static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
                            struct bin_attribute *attr,
                            struct vm_area_struct *vma)
 {
        struct vmbus_channel *channel
                = container_of(kobj, struct vmbus_channel, kobj);
-       unsigned long requested_pages, actual_pages;
-
-       if (vma->vm_end < vma->vm_start)
-               return -EINVAL;
-
-       /* only allow 0 for now */
-       if (vma->vm_pgoff > 0)
-               return -EINVAL;
+       struct hv_device *dev = channel->primary_channel->device_obj;
+       u16 q_idx = channel->offermsg.offer.sub_channel_index;
 
-       requested_pages = vma_pages(vma);
-       actual_pages = 2 * HV_RING_SIZE;
-       if (requested_pages > actual_pages)
-               return -EINVAL;
+       dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n",
+               q_idx, vma_pages(vma), vma->vm_pgoff);
 
-       vma->vm_private_data = channel->ringbuffer_pages;
-       vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
-       vma->vm_ops = &hv_uio_vm_ops;
-       return 0;
+       return vm_iomap_memory(vma, virt_to_phys(channel->ringbuffer_pages),
+                              channel->ringbuffer_pagecount << PAGE_SHIFT);
 }
 
-static struct bin_attribute ring_buffer_bin_attr __ro_after_init = {
+static const struct bin_attribute ring_buffer_bin_attr = {
        .attr = {
                .name = "ring",
                .mode = 0600,
-               /* size is set at init time */
        },
+       .size = 2 * HV_RING_SIZE * PAGE_SIZE,
        .mmap = hv_uio_ring_mmap,
 };
 
-/* Callback from VMBUS subystem when new channel created. */
+/* Callback from VMBUS subsystem when new channel created. */
 static void
 hv_uio_new_channel(struct vmbus_channel *new_sc)
 {
        struct hv_device *hv_dev = new_sc->primary_channel->device_obj;
        struct device *device = &hv_dev->device;
-       struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
        const size_t ring_bytes = HV_RING_SIZE * PAGE_SIZE;
        int ret;
 
        /* Create host communication ring */
        ret = vmbus_open(new_sc, ring_bytes, ring_bytes, NULL, 0,
-                        hv_uio_channel_cb, pdata);
+                        hv_uio_channel_cb, new_sc);
        if (ret) {
                dev_err(device, "vmbus_open subchannel failed: %d\n", ret);
                return;
@@ -234,7 +203,7 @@ hv_uio_probe(struct hv_device *dev,
 
        ret = vmbus_open(dev->channel, HV_RING_SIZE * PAGE_SIZE,
                         HV_RING_SIZE * PAGE_SIZE, NULL, 0,
-                        hv_uio_channel_cb, pdata);
+                        hv_uio_channel_cb, dev->channel);
        if (ret)
                goto fail;
 
@@ -326,6 +295,11 @@ hv_uio_probe(struct hv_device *dev,
        vmbus_set_chn_rescind_callback(dev->channel, hv_uio_rescind);
        vmbus_set_sc_create_callback(dev->channel, hv_uio_new_channel);
 
+       ret = sysfs_create_bin_file(&dev->channel->kobj, &ring_buffer_bin_attr);
+       if (ret)
+               dev_notice(&dev->device,
+                          "sysfs create ring bin file failed; %d\n", ret);
+
        hv_set_drvdata(dev, pdata);
 
        return 0;
index 75f7fb151f713b737a5d9a3a5b07a77de68bdf25..987fc5ba63211bb5829a8f38629e86ab6022a094 100644 (file)
@@ -207,5 +207,6 @@ config USB_ULPI_BUS
 
 config USB_ROLE_SWITCH
        tristate
+       select USB_COMMON
 
 endif # USB_SUPPORT
index 777036ae63674af94e845a78e0cf75e607f8ba68..0a42c5df3c0fb3971c538689697dd52644f443dd 100644 (file)
@@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
                hcd->state = HC_STATE_SUSPENDED;
 
                if (!PMSG_IS_AUTO(msg))
-                       usb_phy_roothub_power_off(hcd->phy_roothub);
+                       usb_phy_roothub_suspend(hcd->self.sysdev,
+                                               hcd->phy_roothub);
 
                /* Did we race with a root-hub wakeup event? */
                if (rhdev->do_remote_wakeup) {
@@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
        }
 
        if (!PMSG_IS_AUTO(msg)) {
-               status = usb_phy_roothub_power_on(hcd->phy_roothub);
+               status = usb_phy_roothub_resume(hcd->self.sysdev,
+                                               hcd->phy_roothub);
                if (status)
                        return status;
        }
@@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
                }
        } else {
                hcd->state = old_state;
-               usb_phy_roothub_power_off(hcd->phy_roothub);
+               usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub);
                dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
                                "resume", status);
                if (status != -ESHUTDOWN)
@@ -2377,6 +2379,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
 
        spin_lock_irqsave (&hcd_root_hub_lock, flags);
        if (hcd->rh_registered) {
+               pm_wakeup_event(&hcd->self.root_hub->dev, 0);
                set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
                queue_work(pm_wq, &hcd->wakeup_work);
        }
@@ -2758,12 +2761,16 @@ int usb_add_hcd(struct usb_hcd *hcd,
        }
 
        if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
-               hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
+               hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev);
                if (IS_ERR(hcd->phy_roothub)) {
                        retval = PTR_ERR(hcd->phy_roothub);
-                       goto err_phy_roothub_init;
+                       goto err_phy_roothub_alloc;
                }
 
+               retval = usb_phy_roothub_init(hcd->phy_roothub);
+               if (retval)
+                       goto err_phy_roothub_alloc;
+
                retval = usb_phy_roothub_power_on(hcd->phy_roothub);
                if (retval)
                        goto err_usb_phy_roothub_power_on;
@@ -2936,7 +2943,7 @@ err_create_buf:
        usb_phy_roothub_power_off(hcd->phy_roothub);
 err_usb_phy_roothub_power_on:
        usb_phy_roothub_exit(hcd->phy_roothub);
-err_phy_roothub_init:
+err_phy_roothub_alloc:
        if (hcd->remove_phy && hcd->usb_phy) {
                usb_phy_shutdown(hcd->usb_phy);
                usb_put_phy(hcd->usb_phy);
index f6ea16e9f6bb975a09e296f2493a5a687828d920..aa9968d90a48c301e6af566d00a20139397e1742 100644 (file)
@@ -653,12 +653,17 @@ void usb_wakeup_notification(struct usb_device *hdev,
                unsigned int portnum)
 {
        struct usb_hub *hub;
+       struct usb_port *port_dev;
 
        if (!hdev)
                return;
 
        hub = usb_hub_to_struct_hub(hdev);
        if (hub) {
+               port_dev = hub->ports[portnum - 1];
+               if (port_dev && port_dev->child)
+                       pm_wakeup_event(&port_dev->child->dev, 0);
+
                set_bit(portnum, hub->wakeup_bits);
                kick_hub_wq(hub);
        }
@@ -3434,8 +3439,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
 
        /* Skip the initial Clear-Suspend step for a remote wakeup */
        status = hub_port_status(hub, port1, &portstatus, &portchange);
-       if (status == 0 && !port_is_suspended(hub, portstatus))
+       if (status == 0 && !port_is_suspended(hub, portstatus)) {
+               if (portchange & USB_PORT_STAT_C_SUSPEND)
+                       pm_wakeup_event(&udev->dev, 0);
                goto SuspendCleared;
+       }
 
        /* see 7.1.7.7; affects power usage, but not budgeting */
        if (hub_is_superspeed(hub->hdev))
index 09b7c43c0ea4c69e365f22274bb8c36a984d49d2..9879767452a23e6a0c1ceeea65cfc0b8874fa65a 100644 (file)
@@ -19,19 +19,6 @@ struct usb_phy_roothub {
        struct list_head        list;
 };
 
-static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
-{
-       struct usb_phy_roothub *roothub_entry;
-
-       roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
-       if (!roothub_entry)
-               return ERR_PTR(-ENOMEM);
-
-       INIT_LIST_HEAD(&roothub_entry->list);
-
-       return roothub_entry;
-}
-
 static int usb_phy_roothub_add_phy(struct device *dev, int index,
                                   struct list_head *list)
 {
@@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index,
                        return PTR_ERR(phy);
        }
 
-       roothub_entry = usb_phy_roothub_alloc(dev);
-       if (IS_ERR(roothub_entry))
-               return PTR_ERR(roothub_entry);
+       roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
+       if (!roothub_entry)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&roothub_entry->list);
 
        roothub_entry->phy = phy;
 
@@ -56,28 +45,44 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index,
        return 0;
 }
 
-struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
+struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
 {
        struct usb_phy_roothub *phy_roothub;
-       struct usb_phy_roothub *roothub_entry;
-       struct list_head *head;
        int i, num_phys, err;
 
+       if (!IS_ENABLED(CONFIG_GENERIC_PHY))
+               return NULL;
+
        num_phys = of_count_phandle_with_args(dev->of_node, "phys",
                                              "#phy-cells");
        if (num_phys <= 0)
                return NULL;
 
-       phy_roothub = usb_phy_roothub_alloc(dev);
-       if (IS_ERR(phy_roothub))
-               return phy_roothub;
+       phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL);
+       if (!phy_roothub)
+               return ERR_PTR(-ENOMEM);
+
+       INIT_LIST_HEAD(&phy_roothub->list);
 
        for (i = 0; i < num_phys; i++) {
                err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list);
                if (err)
-                       goto err_out;
+                       return ERR_PTR(err);
        }
 
+       return phy_roothub;
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc);
+
+int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub)
+{
+       struct usb_phy_roothub *roothub_entry;
+       struct list_head *head;
+       int err;
+
+       if (!phy_roothub)
+               return 0;
+
        head = &phy_roothub->list;
 
        list_for_each_entry(roothub_entry, head, list) {
@@ -86,14 +91,13 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
                        goto err_exit_phys;
        }
 
-       return phy_roothub;
+       return 0;
 
 err_exit_phys:
        list_for_each_entry_continue_reverse(roothub_entry, head, list)
                phy_exit(roothub_entry->phy);
 
-err_out:
-       return ERR_PTR(err);
+       return err;
 }
 EXPORT_SYMBOL_GPL(usb_phy_roothub_init);
 
@@ -111,7 +115,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub)
        list_for_each_entry(roothub_entry, head, list) {
                err = phy_exit(roothub_entry->phy);
                if (err)
-                       ret = ret;
+                       ret = err;
        }
 
        return ret;
@@ -156,3 +160,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub)
                phy_power_off(roothub_entry->phy);
 }
 EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off);
+
+int usb_phy_roothub_suspend(struct device *controller_dev,
+                           struct usb_phy_roothub *phy_roothub)
+{
+       usb_phy_roothub_power_off(phy_roothub);
+
+       /* keep the PHYs initialized so the device can wake up the system */
+       if (device_may_wakeup(controller_dev))
+               return 0;
+
+       return usb_phy_roothub_exit(phy_roothub);
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend);
+
+int usb_phy_roothub_resume(struct device *controller_dev,
+                          struct usb_phy_roothub *phy_roothub)
+{
+       int err;
+
+       /* if the device can't wake up the system _exit was called */
+       if (!device_may_wakeup(controller_dev)) {
+               err = usb_phy_roothub_init(phy_roothub);
+               if (err)
+                       return err;
+       }
+
+       err = usb_phy_roothub_power_on(phy_roothub);
+
+       /* undo _init if _power_on failed */
+       if (err && !device_may_wakeup(controller_dev))
+               usb_phy_roothub_exit(phy_roothub);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_resume);
index 6fde59bfbff8ace58bebb50bc88348eab03a1ca2..88a3c037e9df59194ba94d3ecd7ec3e2626ccb33 100644 (file)
@@ -1,7 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * USB roothub wrapper
+ *
+ * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ */
+
+#ifndef __USB_CORE_PHY_H_
+#define __USB_CORE_PHY_H_
+
+struct device;
 struct usb_phy_roothub;
 
-struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev);
+struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev);
+
+int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub);
 int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub);
 
 int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub);
 void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub);
+
+int usb_phy_roothub_suspend(struct device *controller_dev,
+                           struct usb_phy_roothub *phy_roothub);
+int usb_phy_roothub_resume(struct device *controller_dev,
+                          struct usb_phy_roothub *phy_roothub);
+
+#endif /* __USB_CORE_PHY_H_ */
index 920f48a49a87021a513b4e395a903044a558abf5..c55def2f1320f92c6c0c652fc94c7056165ee467 100644 (file)
@@ -186,6 +186,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x03f0, 0x0701), .driver_info =
                        USB_QUIRK_STRING_FETCH_255 },
 
+       /* HP v222w 16GB Mini USB Drive */
+       { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },
+
        /* Creative SB Audigy 2 NX */
        { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
 
index 48779c44c361d98db9f25ce3609860d243beea9f..eb494ec547e806e9d5656f072160d58bf68a0d17 100644 (file)
@@ -320,9 +320,11 @@ int xhci_dbc_tty_register_driver(struct xhci_hcd *xhci)
 
 void xhci_dbc_tty_unregister_driver(void)
 {
-       tty_unregister_driver(dbc_tty_driver);
-       put_tty_driver(dbc_tty_driver);
-       dbc_tty_driver = NULL;
+       if (dbc_tty_driver) {
+               tty_unregister_driver(dbc_tty_driver);
+               put_tty_driver(dbc_tty_driver);
+               dbc_tty_driver = NULL;
+       }
 }
 
 static void dbc_rx_push(unsigned long _port)
index f17b7eab66cf9e51edec5b573a60ac909f6dc0b3..85ffda85f8ab39043c5323a3799420d14c98baa8 100644 (file)
@@ -126,7 +126,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
                xhci->quirks |= XHCI_AMD_PLL_FIX;
 
-       if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43bb)
+       if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+               (pdev->device == 0x15e0 ||
+                pdev->device == 0x15e1 ||
+                pdev->device == 0x43bb))
                xhci->quirks |= XHCI_SUSPEND_DELAY;
 
        if (pdev->vendor == PCI_VENDOR_ID_AMD)
index df327dcc2bac3b934399360ed32b504c7fbeabc1..c1b22fc64e387a3bf7f836729de1ddcd2676d8fc 100644 (file)
@@ -157,6 +157,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
        struct resource         *res;
        struct usb_hcd          *hcd;
        struct clk              *clk;
+       struct clk              *reg_clk;
        int                     ret;
        int                     irq;
 
@@ -226,17 +227,27 @@ static int xhci_plat_probe(struct platform_device *pdev)
        hcd->rsrc_len = resource_size(res);
 
        /*
-        * Not all platforms have a clk so it is not an error if the
-        * clock does not exists.
+        * Not all platforms have clks so it is not an error if the
+        * clock do not exist.
         */
+       reg_clk = devm_clk_get(&pdev->dev, "reg");
+       if (!IS_ERR(reg_clk)) {
+               ret = clk_prepare_enable(reg_clk);
+               if (ret)
+                       goto put_hcd;
+       } else if (PTR_ERR(reg_clk) == -EPROBE_DEFER) {
+               ret = -EPROBE_DEFER;
+               goto put_hcd;
+       }
+
        clk = devm_clk_get(&pdev->dev, NULL);
        if (!IS_ERR(clk)) {
                ret = clk_prepare_enable(clk);
                if (ret)
-                       goto put_hcd;
+                       goto disable_reg_clk;
        } else if (PTR_ERR(clk) == -EPROBE_DEFER) {
                ret = -EPROBE_DEFER;
-               goto put_hcd;
+               goto disable_reg_clk;
        }
 
        xhci = hcd_to_xhci(hcd);
@@ -252,6 +263,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
        device_wakeup_enable(hcd->self.controller);
 
        xhci->clk = clk;
+       xhci->reg_clk = reg_clk;
        xhci->main_hcd = hcd;
        xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
                        dev_name(&pdev->dev), hcd);
@@ -320,8 +332,10 @@ put_usb3_hcd:
        usb_put_hcd(xhci->shared_hcd);
 
 disable_clk:
-       if (!IS_ERR(clk))
-               clk_disable_unprepare(clk);
+       clk_disable_unprepare(clk);
+
+disable_reg_clk:
+       clk_disable_unprepare(reg_clk);
 
 put_hcd:
        usb_put_hcd(hcd);
@@ -338,6 +352,7 @@ static int xhci_plat_remove(struct platform_device *dev)
        struct usb_hcd  *hcd = platform_get_drvdata(dev);
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        struct clk *clk = xhci->clk;
+       struct clk *reg_clk = xhci->reg_clk;
 
        xhci->xhc_state |= XHCI_STATE_REMOVING;
 
@@ -347,8 +362,8 @@ static int xhci_plat_remove(struct platform_device *dev)
        usb_remove_hcd(hcd);
        usb_put_hcd(xhci->shared_hcd);
 
-       if (!IS_ERR(clk))
-               clk_disable_unprepare(clk);
+       clk_disable_unprepare(clk);
+       clk_disable_unprepare(reg_clk);
        usb_put_hcd(hcd);
 
        pm_runtime_set_suspended(&dev->dev);
@@ -420,7 +435,6 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
 static struct platform_driver usb_xhci_driver = {
        .probe  = xhci_plat_probe,
        .remove = xhci_plat_remove,
-       .shutdown       = usb_hcd_platform_shutdown,
        .driver = {
                .name = "xhci-hcd",
                .pm = &xhci_plat_pm_ops,
index 05c909b04f14c544c0ac7a8fba3a8c1bdd3a41f2..6dfc4867dbcf23ec34cecfd0658f93dae242500d 100644 (file)
@@ -1729,8 +1729,9 @@ struct xhci_hcd {
        int             page_shift;
        /* msi-x vectors */
        int             msix_count;
-       /* optional clock */
+       /* optional clocks */
        struct clk              *clk;
+       struct clk              *reg_clk;
        /* data structures */
        struct xhci_device_context_array *dcbaa;
        struct xhci_ring        *cmd_ring;
index 05a679d5e3a2b5487a852330edafd58ccba60b32..6a60bc0490c5270e8434e4d94e36e4120db215f6 100644 (file)
@@ -451,7 +451,6 @@ static int dsps_musb_init(struct musb *musb)
        if (!rev)
                return -ENODEV;
 
-       usb_phy_init(musb->xceiv);
        if (IS_ERR(musb->phy))  {
                musb->phy = NULL;
        } else {
@@ -501,7 +500,6 @@ static int dsps_musb_exit(struct musb *musb)
        struct dsps_glue *glue = dev_get_drvdata(dev->parent);
 
        del_timer_sync(&musb->dev_timer);
-       usb_phy_shutdown(musb->xceiv);
        phy_power_off(musb->phy);
        phy_exit(musb->phy);
        debugfs_remove_recursive(glue->dbgfs_root);
index 3a8451a15f7f735acb90886a1ee3521ebbb7b39f..4fa372c845e1529e600d0d8408de7fc3627671b3 100644 (file)
@@ -2754,6 +2754,7 @@ int musb_host_setup(struct musb *musb, int power_budget)
        hcd->self.otg_port = 1;
        musb->xceiv->otg->host = &hcd->self;
        hcd->power_budget = 2 * (power_budget ? : 250);
+       hcd->skip_phy_initialization = 1;
 
        ret = usb_add_hcd(hcd, 0, 0);
        if (ret < 0)
index a646820f5a78f0ae67551ff0b55b1b7e13c5f797..533f127c30ad846f236170f36a61a127ea9db6ab 100644 (file)
@@ -62,6 +62,7 @@ config USB_SERIAL_SIMPLE
                - Fundamental Software dongle.
                - Google USB serial devices
                - HP4x calculators
+               - Libtransistor USB console
                - a number of Motorola phones
                - Motorola Tetra devices
                - Novatel Wireless GPS receivers
index de1e759dd51220880ca364f9e1920af360f5e88d..eb6c26cbe5792b0e535c77b9e2e245b700071458 100644 (file)
@@ -214,6 +214,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
        { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
        { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
+       { USB_DEVICE(0x3923, 0x7A0B) }, /* National Instruments USB Serial Console */
        { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
        { } /* Terminating Entry */
 };
index 87202ad5a50dfb4d8afe865ce57a7b5fbe0d6b8b..7ea221d42dbadbbef33bb1e02ae35775d5765d62 100644 (file)
@@ -1898,7 +1898,8 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
                return ftdi_jtag_probe(serial);
 
        if (udev->product &&
-               (!strcmp(udev->product, "BeagleBone/XDS100V2") ||
+               (!strcmp(udev->product, "Arrow USB Blaster") ||
+                !strcmp(udev->product, "BeagleBone/XDS100V2") ||
                 !strcmp(udev->product, "SNAP Connect E10")))
                return ftdi_jtag_probe(serial);
 
index 4ef79e29cb26031f4ccf100e34de453d41c031d4..40864c2bd9dc0ad73e8c5dd0701f621c4302712c 100644 (file)
@@ -63,6 +63,11 @@ DEVICE(flashloader, FLASHLOADER_IDS);
                                        0x01) }
 DEVICE(google, GOOGLE_IDS);
 
+/* Libtransistor USB console */
+#define LIBTRANSISTOR_IDS()                    \
+       { USB_DEVICE(0x1209, 0x8b00) }
+DEVICE(libtransistor, LIBTRANSISTOR_IDS);
+
 /* ViVOpay USB Serial Driver */
 #define VIVOPAY_IDS()                  \
        { USB_DEVICE(0x1d5f, 0x1004) }  /* ViVOpay 8800 */
@@ -110,6 +115,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
        &funsoft_device,
        &flashloader_device,
        &google_device,
+       &libtransistor_device,
        &vivopay_device,
        &moto_modem_device,
        &motorola_tetra_device,
@@ -126,6 +132,7 @@ static const struct usb_device_id id_table[] = {
        FUNSOFT_IDS(),
        FLASHLOADER_IDS(),
        GOOGLE_IDS(),
+       LIBTRANSISTOR_IDS(),
        VIVOPAY_IDS(),
        MOTO_IDS(),
        MOTOROLA_TETRA_IDS(),
index b57891c1fd31a7e70b14ada774f824d30b36196e..7afbea5122077b3dd0cbe217ad7c839837f499b4 100644 (file)
@@ -5,6 +5,6 @@ obj-$(CONFIG_TYPEC_UCSI)        += typec_ucsi.o
 
 typec_ucsi-y                   := ucsi.o
 
-typec_ucsi-$(CONFIG_FTRACE)    += trace.o
+typec_ucsi-$(CONFIG_TRACING)   += trace.o
 
 obj-$(CONFIG_UCSI_ACPI)                += ucsi_acpi.o
index bf0977fbd100a72b2384d52a91c114dbbf694813..bd5cca5632b395def6384ec233d8ba5926e81c93 100644 (file)
@@ -28,7 +28,7 @@
  * difficult to estimate the time it takes for the system to process the command
  * before it is actually passed to the PPM.
  */
-#define UCSI_TIMEOUT_MS                1000
+#define UCSI_TIMEOUT_MS                5000
 
 /*
  * UCSI_SWAP_TIMEOUT_MS - Timeout for role swap requests
index c31c8402a0c55ddd2f4b463ebabd28be6438f490..d41d0cdeec0f2a1861d8d42385a9719789cab558 100644 (file)
@@ -186,7 +186,12 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf,
        if (!bid)
                return -ENODEV;
 
+       /* device_attach() callers should hold parent lock for USB */
+       if (bid->udev->dev.parent)
+               device_lock(bid->udev->dev.parent);
        ret = device_attach(&bid->udev->dev);
+       if (bid->udev->dev.parent)
+               device_unlock(bid->udev->dev.parent);
        if (ret < 0) {
                dev_err(&bid->udev->dev, "rebind failed\n");
                return ret;
index 473fb8a872893caa3494fe9a4a85b60600bdfd28..bf8afe9b5883850325fb70fc3873bff20237040b 100644 (file)
@@ -243,7 +243,7 @@ enum usbip_side {
 #define        VUDC_EVENT_ERROR_USB    (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
 #define        VUDC_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
 
-#define        VDEV_EVENT_REMOVED      (USBIP_EH_SHUTDOWN | USBIP_EH_BYE)
+#define        VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
 #define        VDEV_EVENT_DOWN         (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define        VDEV_EVENT_ERROR_TCP    (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define        VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
index 5b4c0864ad92ae6ac40e19b5b10f30667bc09207..5d88917c963149b0ba1daa02cc4da4e84ca3c106 100644 (file)
@@ -91,10 +91,6 @@ static void event_handler(struct work_struct *work)
                        unset_event(ud, USBIP_EH_UNUSABLE);
                }
 
-               /* Stop the error handler. */
-               if (ud->event & USBIP_EH_BYE)
-                       usbip_dbg_eh("removed %p\n", ud);
-
                wake_up(&ud->eh_waitq);
        }
 }
index 20e3d4609583848f8a14271d5c4bf3ffb8776123..d11f3f8dad4045e9c51bce1789b9473b60237f61 100644 (file)
@@ -354,6 +354,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                usbip_dbg_vhci_rh(" ClearHubFeature\n");
                break;
        case ClearPortFeature:
+               if (rhport < 0)
+                       goto error;
                switch (wValue) {
                case USB_PORT_FEAT_SUSPEND:
                        if (hcd->speed == HCD_USB3) {
@@ -511,11 +513,16 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                goto error;
                        }
 
+                       if (rhport < 0)
+                               goto error;
+
                        vhci_hcd->port_status[rhport] |= USB_PORT_STAT_SUSPEND;
                        break;
                case USB_PORT_FEAT_POWER:
                        usbip_dbg_vhci_rh(
                                " SetPortFeature: USB_PORT_FEAT_POWER\n");
+                       if (rhport < 0)
+                               goto error;
                        if (hcd->speed == HCD_USB3)
                                vhci_hcd->port_status[rhport] |= USB_SS_PORT_STAT_POWER;
                        else
@@ -524,6 +531,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                case USB_PORT_FEAT_BH_PORT_RESET:
                        usbip_dbg_vhci_rh(
                                " SetPortFeature: USB_PORT_FEAT_BH_PORT_RESET\n");
+                       if (rhport < 0)
+                               goto error;
                        /* Applicable only for USB3.0 hub */
                        if (hcd->speed != HCD_USB3) {
                                pr_err("USB_PORT_FEAT_BH_PORT_RESET req not "
@@ -534,6 +543,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                case USB_PORT_FEAT_RESET:
                        usbip_dbg_vhci_rh(
                                " SetPortFeature: USB_PORT_FEAT_RESET\n");
+                       if (rhport < 0)
+                               goto error;
                        /* if it's already enabled, disable */
                        if (hcd->speed == HCD_USB3) {
                                vhci_hcd->port_status[rhport] = 0;
@@ -554,6 +565,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                default:
                        usbip_dbg_vhci_rh(" SetPortFeature: default %d\n",
                                          wValue);
+                       if (rhport < 0)
+                               goto error;
                        if (hcd->speed == HCD_USB3) {
                                if ((vhci_hcd->port_status[rhport] &
                                     USB_SS_PORT_STAT_POWER) != 0) {
index 190dbf8cfcb564f3c36c5504472b4dfec8070f51..2f3856a95856be43bcbfc6a4c3865f7099045368 100644 (file)
@@ -114,7 +114,7 @@ static void vbg_guest_mappings_init(struct vbg_dev *gdev)
        }
 
 out:
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        kfree(pages);
 }
 
@@ -144,7 +144,7 @@ static void vbg_guest_mappings_exit(struct vbg_dev *gdev)
 
        rc = vbg_req_perform(gdev, req);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        if (rc < 0) {
                vbg_err("%s error: %d\n", __func__, rc);
@@ -214,8 +214,8 @@ static int vbg_report_guest_info(struct vbg_dev *gdev)
        ret = vbg_status_code_to_errno(rc);
 
 out_free:
-       kfree(req2);
-       kfree(req1);
+       vbg_req_free(req2, sizeof(*req2));
+       vbg_req_free(req1, sizeof(*req1));
        return ret;
 }
 
@@ -245,7 +245,7 @@ static int vbg_report_driver_status(struct vbg_dev *gdev, bool active)
        if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */
                rc = VINF_SUCCESS;
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return vbg_status_code_to_errno(rc);
 }
@@ -431,7 +431,7 @@ static int vbg_heartbeat_host_config(struct vbg_dev *gdev, bool enabled)
        rc = vbg_req_perform(gdev, req);
        do_div(req->interval_ns, 1000000); /* ns -> ms */
        gdev->heartbeat_interval_ms = req->interval_ns;
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return vbg_status_code_to_errno(rc);
 }
@@ -454,12 +454,6 @@ static int vbg_heartbeat_init(struct vbg_dev *gdev)
        if (ret < 0)
                return ret;
 
-       /*
-        * Preallocate the request to use it from the timer callback because:
-        *    1) on Windows vbg_req_alloc must be called at IRQL <= APC_LEVEL
-        *       and the timer callback runs at DISPATCH_LEVEL;
-        *    2) avoid repeated allocations.
-        */
        gdev->guest_heartbeat_req = vbg_req_alloc(
                                        sizeof(*gdev->guest_heartbeat_req),
                                        VMMDEVREQ_GUEST_HEARTBEAT);
@@ -481,8 +475,8 @@ static void vbg_heartbeat_exit(struct vbg_dev *gdev)
 {
        del_timer_sync(&gdev->heartbeat_timer);
        vbg_heartbeat_host_config(gdev, false);
-       kfree(gdev->guest_heartbeat_req);
-
+       vbg_req_free(gdev->guest_heartbeat_req,
+                    sizeof(*gdev->guest_heartbeat_req));
 }
 
 /**
@@ -543,7 +537,7 @@ static int vbg_reset_host_event_filter(struct vbg_dev *gdev,
        if (rc < 0)
                vbg_err("%s error, rc: %d\n", __func__, rc);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return vbg_status_code_to_errno(rc);
 }
 
@@ -617,7 +611,7 @@ static int vbg_set_session_event_filter(struct vbg_dev *gdev,
 
 out:
        mutex_unlock(&gdev->session_mutex);
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return ret;
 }
@@ -642,7 +636,7 @@ static int vbg_reset_host_capabilities(struct vbg_dev *gdev)
        if (rc < 0)
                vbg_err("%s error, rc: %d\n", __func__, rc);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return vbg_status_code_to_errno(rc);
 }
 
@@ -712,7 +706,7 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
 
 out:
        mutex_unlock(&gdev->session_mutex);
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return ret;
 }
@@ -733,8 +727,10 @@ static int vbg_query_host_version(struct vbg_dev *gdev)
 
        rc = vbg_req_perform(gdev, req);
        ret = vbg_status_code_to_errno(rc);
-       if (ret)
+       if (ret) {
+               vbg_err("%s error: %d\n", __func__, rc);
                goto out;
+       }
 
        snprintf(gdev->host_version, sizeof(gdev->host_version), "%u.%u.%ur%u",
                 req->major, req->minor, req->build, req->revision);
@@ -749,7 +745,7 @@ static int vbg_query_host_version(struct vbg_dev *gdev)
        }
 
 out:
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return ret;
 }
 
@@ -847,11 +843,16 @@ int vbg_core_init(struct vbg_dev *gdev, u32 fixed_events)
        return 0;
 
 err_free_reqs:
-       kfree(gdev->mouse_status_req);
-       kfree(gdev->ack_events_req);
-       kfree(gdev->cancel_req);
-       kfree(gdev->mem_balloon.change_req);
-       kfree(gdev->mem_balloon.get_req);
+       vbg_req_free(gdev->mouse_status_req,
+                    sizeof(*gdev->mouse_status_req));
+       vbg_req_free(gdev->ack_events_req,
+                    sizeof(*gdev->ack_events_req));
+       vbg_req_free(gdev->cancel_req,
+                    sizeof(*gdev->cancel_req));
+       vbg_req_free(gdev->mem_balloon.change_req,
+                    sizeof(*gdev->mem_balloon.change_req));
+       vbg_req_free(gdev->mem_balloon.get_req,
+                    sizeof(*gdev->mem_balloon.get_req));
        return ret;
 }
 
@@ -872,11 +873,16 @@ void vbg_core_exit(struct vbg_dev *gdev)
        vbg_reset_host_capabilities(gdev);
        vbg_core_set_mouse_status(gdev, 0);
 
-       kfree(gdev->mouse_status_req);
-       kfree(gdev->ack_events_req);
-       kfree(gdev->cancel_req);
-       kfree(gdev->mem_balloon.change_req);
-       kfree(gdev->mem_balloon.get_req);
+       vbg_req_free(gdev->mouse_status_req,
+                    sizeof(*gdev->mouse_status_req));
+       vbg_req_free(gdev->ack_events_req,
+                    sizeof(*gdev->ack_events_req));
+       vbg_req_free(gdev->cancel_req,
+                    sizeof(*gdev->cancel_req));
+       vbg_req_free(gdev->mem_balloon.change_req,
+                    sizeof(*gdev->mem_balloon.change_req));
+       vbg_req_free(gdev->mem_balloon.get_req,
+                    sizeof(*gdev->mem_balloon.get_req));
 }
 
 /**
@@ -1415,7 +1421,7 @@ static int vbg_ioctl_write_core_dump(struct vbg_dev *gdev,
        req->flags = dump->u.in.flags;
        dump->hdr.rc = vbg_req_perform(gdev, req);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return 0;
 }
 
@@ -1513,7 +1519,7 @@ int vbg_core_set_mouse_status(struct vbg_dev *gdev, u32 features)
        if (rc < 0)
                vbg_err("%s error, rc: %d\n", __func__, rc);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return vbg_status_code_to_errno(rc);
 }
 
index 6c784bf4fa6d50c23ff4c32067d5892aca7b5adb..7ad9ec45bfa9d649627f45e9410aebff43cd22c7 100644 (file)
@@ -171,4 +171,13 @@ irqreturn_t vbg_core_isr(int irq, void *dev_id);
 
 void vbg_linux_mouse_event(struct vbg_dev *gdev);
 
+/* Private (non exported) functions form vboxguest_utils.c */
+void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type);
+void vbg_req_free(void *req, size_t len);
+int vbg_req_perform(struct vbg_dev *gdev, void *req);
+int vbg_hgcm_call32(
+       struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms,
+       struct vmmdev_hgcm_function_parameter32 *parm32, u32 parm_count,
+       int *vbox_status);
+
 #endif
index 82e280d38cc2e1bd1da2b2e6847b3174b5854548..398d2269323471305088762ba92ed9da3d53d9af 100644 (file)
@@ -87,6 +87,7 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
        struct vbg_session *session = filp->private_data;
        size_t returned_size, size;
        struct vbg_ioctl_hdr hdr;
+       bool is_vmmdev_req;
        int ret = 0;
        void *buf;
 
@@ -106,8 +107,17 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
        if (size > SZ_16M)
                return -E2BIG;
 
-       /* __GFP_DMA32 because IOCTL_VMMDEV_REQUEST passes this to the host */
-       buf = kmalloc(size, GFP_KERNEL | __GFP_DMA32);
+       /*
+        * IOCTL_VMMDEV_REQUEST needs the buffer to be below 4G to avoid
+        * the need for a bounce-buffer and another copy later on.
+        */
+       is_vmmdev_req = (req & ~IOCSIZE_MASK) == VBG_IOCTL_VMMDEV_REQUEST(0) ||
+                        req == VBG_IOCTL_VMMDEV_REQUEST_BIG;
+
+       if (is_vmmdev_req)
+               buf = vbg_req_alloc(size, VBG_IOCTL_HDR_TYPE_DEFAULT);
+       else
+               buf = kmalloc(size, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
@@ -132,7 +142,10 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
                ret = -EFAULT;
 
 out:
-       kfree(buf);
+       if (is_vmmdev_req)
+               vbg_req_free(buf, size);
+       else
+               kfree(buf);
 
        return ret;
 }
index 0f0dab8023cf6dfd5cd47ecc507cae0a2df550d8..bf4474214b4d31bb708c3d9c302d6ce415e17c7a 100644 (file)
@@ -65,8 +65,9 @@ VBG_LOG(vbg_debug, pr_debug);
 void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type)
 {
        struct vmmdev_request_header *req;
+       int order = get_order(PAGE_ALIGN(len));
 
-       req = kmalloc(len, GFP_KERNEL | __GFP_DMA32);
+       req = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order);
        if (!req)
                return NULL;
 
@@ -82,6 +83,14 @@ void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type)
        return req;
 }
 
+void vbg_req_free(void *req, size_t len)
+{
+       if (!req)
+               return;
+
+       free_pages((unsigned long)req, get_order(PAGE_ALIGN(len)));
+}
+
 /* Note this function returns a VBox status code, not a negative errno!! */
 int vbg_req_perform(struct vbg_dev *gdev, void *req)
 {
@@ -137,7 +146,7 @@ int vbg_hgcm_connect(struct vbg_dev *gdev,
                rc = hgcm_connect->header.result;
        }
 
-       kfree(hgcm_connect);
+       vbg_req_free(hgcm_connect, sizeof(*hgcm_connect));
 
        *vbox_status = rc;
        return 0;
@@ -166,7 +175,7 @@ int vbg_hgcm_disconnect(struct vbg_dev *gdev, u32 client_id, int *vbox_status)
        if (rc >= 0)
                rc = hgcm_disconnect->header.result;
 
-       kfree(hgcm_disconnect);
+       vbg_req_free(hgcm_disconnect, sizeof(*hgcm_disconnect));
 
        *vbox_status = rc;
        return 0;
@@ -623,7 +632,7 @@ int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function,
        }
 
        if (!leak_it)
-               kfree(call);
+               vbg_req_free(call, size);
 
 free_bounce_bufs:
        if (bounce_bufs) {
index a5b8eb21201fd0cefb9918acee38cbdf49307ed3..1abe4d021fd27171bae9fb7a289c72916f041486 100644 (file)
@@ -55,6 +55,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
 #define   WDT_CTRL_WDT_INTR            BIT(2)
 #define   WDT_CTRL_RESET_SYSTEM                BIT(1)
 #define   WDT_CTRL_ENABLE              BIT(0)
+#define WDT_TIMEOUT_STATUS     0x10
+#define   WDT_TIMEOUT_STATUS_BOOT_SECONDARY    BIT(1)
 
 /*
  * WDT_RESET_WIDTH controls the characteristics of the external pulse (if
@@ -192,6 +194,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
        struct device_node *np;
        const char *reset_type;
        u32 duration;
+       u32 status;
        int ret;
 
        wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
@@ -307,6 +310,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
                writel(duration - 1, wdt->base + WDT_RESET_WIDTH);
        }
 
+       status = readl(wdt->base + WDT_TIMEOUT_STATUS);
+       if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
+               wdt->wdd.bootstatus = WDIOF_CARDRESET;
+
        ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
        if (ret) {
                dev_err(&pdev->dev, "failed to register\n");
index 6b8c6ddfe30b3185fccaa91c05a8d4f49925ab21..514db5cc159511254f62c2eb86714a2ecddb978f 100644 (file)
@@ -121,7 +121,8 @@ static int rwdt_restart(struct watchdog_device *wdev, unsigned long action,
 }
 
 static const struct watchdog_info rwdt_ident = {
-       .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+       .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
+               WDIOF_CARDRESET,
        .identity = "Renesas WDT Watchdog",
 };
 
@@ -197,9 +198,10 @@ static int rwdt_probe(struct platform_device *pdev)
                return PTR_ERR(clk);
 
        pm_runtime_enable(&pdev->dev);
-
        pm_runtime_get_sync(&pdev->dev);
        priv->clk_rate = clk_get_rate(clk);
+       priv->wdev.bootstatus = (readb_relaxed(priv->base + RWTCSRA) &
+                               RWTCSRA_WOVF) ? WDIOF_CARDRESET : 0;
        pm_runtime_put(&pdev->dev);
 
        if (!priv->clk_rate) {
index 43d0cbb7ba0b9dfe8c662df42332c212f8997932..814cdf539b0f6ac6eb17cc4e5ab5a4208ea7837c 100644 (file)
@@ -299,7 +299,7 @@ static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd,
                if (sch311x_wdt_set_heartbeat(new_timeout))
                        return -EINVAL;
                sch311x_wdt_keepalive();
-               /* Fall */
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
        default:
index 20e2bba10400910cfbd86a68d3d6f988b9d77dec..672b61a7f9a363a1b4b403b66c505e6d2d0978e0 100644 (file)
@@ -427,7 +427,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        return -EINVAL;
 
                wdt_keepalive();
-               /* Fall */
+               /* Fall through */
 
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, uarg.i);
index db0da7ea4fd8d8c12514f1f8552b1f425c84d9bc..93c5b610e2648ad9f2e87a8612b4f85389bd253c 100644 (file)
@@ -178,7 +178,7 @@ static long wafwdt_ioctl(struct file *file, unsigned int cmd,
                timeout = new_timeout;
                wafwdt_stop();
                wafwdt_start();
-               /* Fall */
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
 
index 89d9744ece613759757fc5bd880b656376b6357c..ed593d1042a6e04bda8a7ac2225bc6a0fd26e17f 100644 (file)
@@ -95,7 +95,7 @@ int xen_pcibk_config_quirks_init(struct pci_dev *dev)
        struct xen_pcibk_config_quirk *quirk;
        int ret = 0;
 
-       quirk = kzalloc(sizeof(*quirk), GFP_ATOMIC);
+       quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
        if (!quirk) {
                ret = -ENOMEM;
                goto out;
index 9e480fdebe1f059419e8864c473e3c6ee2f02cb4..59661db144e51e8ede24258a6823f2491a3ec397 100644 (file)
@@ -71,7 +71,7 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
 
        dev_dbg(&dev->dev, "pcistub_device_alloc\n");
 
-       psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
+       psdev = kzalloc(sizeof(*psdev), GFP_KERNEL);
        if (!psdev)
                return NULL;
 
@@ -364,7 +364,7 @@ static int pcistub_init_device(struct pci_dev *dev)
         * here and then to call kfree(pci_get_drvdata(psdev->dev)).
         */
        dev_data = kzalloc(sizeof(*dev_data) +  strlen(DRV_NAME "[]")
-                               + strlen(pci_name(dev)) + 1, GFP_ATOMIC);
+                               + strlen(pci_name(dev)) + 1, GFP_KERNEL);
        if (!dev_data) {
                err = -ENOMEM;
                goto out;
@@ -577,7 +577,7 @@ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id)
                }
 
                if (!match) {
-                       pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_ATOMIC);
+                       pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
                        if (!pci_dev_id) {
                                err = -ENOMEM;
                                goto out;
@@ -1149,7 +1149,7 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func,
        }
        dev = psdev->dev;
 
-       field = kzalloc(sizeof(*field), GFP_ATOMIC);
+       field = kzalloc(sizeof(*field), GFP_KERNEL);
        if (!field) {
                err = -ENOMEM;
                goto out;
index 0d6d9264d6a9ec47c5af4f0be618bdb51a7f0c7e..c3e201025ef015b49703cf311e71f1d1f041ec6e 100644 (file)
@@ -403,7 +403,7 @@ static int xenbus_command_reply(struct xenbus_file_priv *u,
 {
        struct {
                struct xsd_sockmsg hdr;
-               const char body[16];
+               char body[16];
        } msg;
        int rc;
 
@@ -412,6 +412,7 @@ static int xenbus_command_reply(struct xenbus_file_priv *u,
        msg.hdr.len = strlen(reply) + 1;
        if (msg.hdr.len > sizeof(msg.body))
                return -E2BIG;
+       memcpy(&msg.body, reply, msg.hdr.len);
 
        mutex_lock(&u->reply_mutex);
        rc = queue_reply(&u->read_buffers, &msg, sizeof(msg.hdr) + msg.hdr.len);
index e23be63998a809189c4b967072f9e2eeaa95b42f..629c74986cff4ad1535fcc3c814b6150011c5dec 100644 (file)
@@ -428,8 +428,15 @@ static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
                }
                write_sequnlock(&net->fs_lock);
 
-               if (deleted)
+               if (deleted) {
+                       write_seqlock(&net->fs_addr_lock);
+                       if (!hlist_unhashed(&server->addr4_link))
+                               hlist_del_rcu(&server->addr4_link);
+                       if (!hlist_unhashed(&server->addr6_link))
+                               hlist_del_rcu(&server->addr6_link);
+                       write_sequnlock(&net->fs_addr_lock);
                        afs_destroy_server(net, server);
+               }
        }
 }
 
index 82e8f6edfb48d0e8670dd58e3fbdcfb4b5ceb85d..b12e37f275307f04e4465d1c7b80d7342b4b9f15 100644 (file)
@@ -749,7 +749,7 @@ static int autofs4_dir_mkdir(struct inode *dir,
 
        autofs4_del_active(dentry);
 
-       inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555);
+       inode = autofs4_get_inode(dir->i_sb, S_IFDIR | mode);
        if (!inode)
                return -ENOMEM;
        d_add(dentry, inode);
index 41e04183e4ce84a38e18a3997eb6708c3e8234f6..4ad6f669fe34b21ec592cdd25b7b284fb0f74398 100644 (file)
@@ -377,10 +377,10 @@ static unsigned long elf_map(struct file *filep, unsigned long addr,
        } else
                map_addr = vm_mmap(filep, addr, size, prot, type, off);
 
-       if ((type & MAP_FIXED_NOREPLACE) && BAD_ADDR(map_addr))
-               pr_info("%d (%s): Uhuuh, elf segment at %p requested but the memory is mapped already\n",
-                               task_pid_nr(current), current->comm,
-                               (void *)addr);
+       if ((type & MAP_FIXED_NOREPLACE) &&
+           PTR_ERR((void *)map_addr) == -EEXIST)
+               pr_info("%d (%s): Uhuuh, elf segment at %px requested but the memory is mapped already\n",
+                       task_pid_nr(current), current->comm, (void *)addr);
 
        return(map_addr);
 }
index 5474ef14d6e6797c8bdf3699c9d209fb5760498c..2771cc56a622f50cdf834a291aa4f43a86798cb7 100644 (file)
@@ -459,6 +459,25 @@ struct btrfs_block_rsv {
        unsigned short full;
        unsigned short type;
        unsigned short failfast;
+
+       /*
+        * Qgroup equivalent for @size @reserved
+        *
+        * Unlike normal @size/@reserved for inode rsv, qgroup doesn't care
+        * about things like csum size nor how many tree blocks it will need to
+        * reserve.
+        *
+        * Qgroup cares more about net change of the extent usage.
+        *
+        * So for one newly inserted file extent, in worst case it will cause
+        * leaf split and level increase, nodesize for each file extent is
+        * already too much.
+        *
+        * In short, qgroup_size/reserved is the upper limit of possible needed
+        * qgroup metadata reservation.
+        */
+       u64 qgroup_rsv_size;
+       u64 qgroup_rsv_reserved;
 };
 
 /*
@@ -714,6 +733,12 @@ struct btrfs_delayed_root;
  */
 #define BTRFS_FS_EXCL_OP                       16
 
+/*
+ * To info transaction_kthread we need an immediate commit so it doesn't
+ * need to wait for commit_interval
+ */
+#define BTRFS_FS_NEED_ASYNC_COMMIT             17
+
 struct btrfs_fs_info {
        u8 fsid[BTRFS_FSID_SIZE];
        u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
index 06ec8ab6d9ba593cc63dd58b6edea72584116e24..a8d492dbd3e7c100715011a9ddad8a22d82932dd 100644 (file)
@@ -556,6 +556,12 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
        dst_rsv = &fs_info->delayed_block_rsv;
 
        num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
+
+       /*
+        * Here we migrate space rsv from transaction rsv, since have already
+        * reserved space when starting a transaction.  So no need to reserve
+        * qgroup space here.
+        */
        ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
        if (!ret) {
                trace_btrfs_space_reservation(fs_info, "delayed_item",
@@ -577,7 +583,10 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
                return;
 
        rsv = &fs_info->delayed_block_rsv;
-       btrfs_qgroup_convert_reserved_meta(root, item->bytes_reserved);
+       /*
+        * Check btrfs_delayed_item_reserve_metadata() to see why we don't need
+        * to release/reserve qgroup space.
+        */
        trace_btrfs_space_reservation(fs_info, "delayed_item",
                                      item->key.objectid, item->bytes_reserved,
                                      0);
@@ -602,9 +611,6 @@ static int btrfs_delayed_inode_reserve_metadata(
 
        num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
 
-       ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true);
-       if (ret < 0)
-               return ret;
        /*
         * btrfs_dirty_inode will update the inode under btrfs_join_transaction
         * which doesn't reserve space for speed.  This is a problem since we
@@ -616,6 +622,10 @@ static int btrfs_delayed_inode_reserve_metadata(
         */
        if (!src_rsv || (!trans->bytes_reserved &&
                         src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) {
+               ret = btrfs_qgroup_reserve_meta_prealloc(root,
+                               fs_info->nodesize, true);
+               if (ret < 0)
+                       return ret;
                ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes,
                                          BTRFS_RESERVE_NO_FLUSH);
                /*
@@ -634,6 +644,8 @@ static int btrfs_delayed_inode_reserve_metadata(
                                                      "delayed_inode",
                                                      btrfs_ino(inode),
                                                      num_bytes, 1);
+               } else {
+                       btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize);
                }
                return ret;
        }
index 9e98295de7ce2f24fb009c99102081c49f2c4ba2..e1b0651686f7c4e988766d927c669306560c468d 100644 (file)
@@ -540,8 +540,10 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
                     struct btrfs_delayed_ref_head *head_ref,
                     struct btrfs_qgroup_extent_record *qrecord,
                     u64 bytenr, u64 num_bytes, u64 ref_root, u64 reserved,
-                    int action, int is_data, int *qrecord_inserted_ret,
+                    int action, int is_data, int is_system,
+                    int *qrecord_inserted_ret,
                     int *old_ref_mod, int *new_ref_mod)
+
 {
        struct btrfs_delayed_ref_head *existing;
        struct btrfs_delayed_ref_root *delayed_refs;
@@ -585,6 +587,7 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
        head_ref->ref_mod = count_mod;
        head_ref->must_insert_reserved = must_insert_reserved;
        head_ref->is_data = is_data;
+       head_ref->is_system = is_system;
        head_ref->ref_tree = RB_ROOT;
        INIT_LIST_HEAD(&head_ref->ref_add_list);
        RB_CLEAR_NODE(&head_ref->href_node);
@@ -772,6 +775,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
        struct btrfs_delayed_ref_root *delayed_refs;
        struct btrfs_qgroup_extent_record *record = NULL;
        int qrecord_inserted;
+       int is_system = (ref_root == BTRFS_CHUNK_TREE_OBJECTID);
 
        BUG_ON(extent_op && extent_op->is_data);
        ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
@@ -800,8 +804,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
         */
        head_ref = add_delayed_ref_head(fs_info, trans, head_ref, record,
                                        bytenr, num_bytes, 0, 0, action, 0,
-                                       &qrecord_inserted, old_ref_mod,
-                                       new_ref_mod);
+                                       is_system, &qrecord_inserted,
+                                       old_ref_mod, new_ref_mod);
 
        add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
                             num_bytes, parent, ref_root, level, action);
@@ -868,7 +872,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
         */
        head_ref = add_delayed_ref_head(fs_info, trans, head_ref, record,
                                        bytenr, num_bytes, ref_root, reserved,
-                                       action, 1, &qrecord_inserted,
+                                       action, 1, 0, &qrecord_inserted,
                                        old_ref_mod, new_ref_mod);
 
        add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
@@ -898,9 +902,14 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
        delayed_refs = &trans->transaction->delayed_refs;
        spin_lock(&delayed_refs->lock);
 
+       /*
+        * extent_ops just modify the flags of an extent and they don't result
+        * in ref count changes, hence it's safe to pass false/0 for is_system
+        * argument
+        */
        add_delayed_ref_head(fs_info, trans, head_ref, NULL, bytenr,
                             num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD,
-                            extent_op->is_data, NULL, NULL, NULL);
+                            extent_op->is_data, 0, NULL, NULL, NULL);
 
        spin_unlock(&delayed_refs->lock);
        return 0;
index 741869dbc316b7593851355b55f532d217aa22aa..7f00db50bd242d0a29f35c430339950b90588697 100644 (file)
@@ -127,6 +127,7 @@ struct btrfs_delayed_ref_head {
         */
        unsigned int must_insert_reserved:1;
        unsigned int is_data:1;
+       unsigned int is_system:1;
        unsigned int processing:1;
 };
 
index 4ac8b1d21bafd07e00a686d6c15228f6be6aef72..60caa68c3618d5a072f332be97e7db4ea7ba67b0 100644 (file)
@@ -1824,6 +1824,7 @@ static int transaction_kthread(void *arg)
 
                now = get_seconds();
                if (cur->state < TRANS_STATE_BLOCKED &&
+                   !test_bit(BTRFS_FS_NEED_ASYNC_COMMIT, &fs_info->flags) &&
                    (now < cur->start_time ||
                     now - cur->start_time < fs_info->commit_interval)) {
                        spin_unlock(&fs_info->trans_lock);
index 75cfb80d25518692c2b159fee0df477adb71d39a..e2f16b68fcbf4d2a941a9e988b9505820edd280e 100644 (file)
@@ -2601,13 +2601,19 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans,
        trace_run_delayed_ref_head(fs_info, head, 0);
 
        if (head->total_ref_mod < 0) {
-               struct btrfs_block_group_cache *cache;
+               struct btrfs_space_info *space_info;
+               u64 flags;
 
-               cache = btrfs_lookup_block_group(fs_info, head->bytenr);
-               ASSERT(cache);
-               percpu_counter_add(&cache->space_info->total_bytes_pinned,
+               if (head->is_data)
+                       flags = BTRFS_BLOCK_GROUP_DATA;
+               else if (head->is_system)
+                       flags = BTRFS_BLOCK_GROUP_SYSTEM;
+               else
+                       flags = BTRFS_BLOCK_GROUP_METADATA;
+               space_info = __find_space_info(fs_info, flags);
+               ASSERT(space_info);
+               percpu_counter_add(&space_info->total_bytes_pinned,
                                   -head->num_bytes);
-               btrfs_put_block_group(cache);
 
                if (head->is_data) {
                        spin_lock(&delayed_refs->lock);
@@ -5559,14 +5565,18 @@ again:
 
 static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
                                    struct btrfs_block_rsv *block_rsv,
-                                   struct btrfs_block_rsv *dest, u64 num_bytes)
+                                   struct btrfs_block_rsv *dest, u64 num_bytes,
+                                   u64 *qgroup_to_release_ret)
 {
        struct btrfs_space_info *space_info = block_rsv->space_info;
+       u64 qgroup_to_release = 0;
        u64 ret;
 
        spin_lock(&block_rsv->lock);
-       if (num_bytes == (u64)-1)
+       if (num_bytes == (u64)-1) {
                num_bytes = block_rsv->size;
+               qgroup_to_release = block_rsv->qgroup_rsv_size;
+       }
        block_rsv->size -= num_bytes;
        if (block_rsv->reserved >= block_rsv->size) {
                num_bytes = block_rsv->reserved - block_rsv->size;
@@ -5575,6 +5585,13 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
        } else {
                num_bytes = 0;
        }
+       if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
+               qgroup_to_release = block_rsv->qgroup_rsv_reserved -
+                                   block_rsv->qgroup_rsv_size;
+               block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;
+       } else {
+               qgroup_to_release = 0;
+       }
        spin_unlock(&block_rsv->lock);
 
        ret = num_bytes;
@@ -5597,6 +5614,8 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
                        space_info_add_old_bytes(fs_info, space_info,
                                                 num_bytes);
        }
+       if (qgroup_to_release_ret)
+               *qgroup_to_release_ret = qgroup_to_release;
        return ret;
 }
 
@@ -5738,17 +5757,21 @@ static int btrfs_inode_rsv_refill(struct btrfs_inode *inode,
        struct btrfs_root *root = inode->root;
        struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
        u64 num_bytes = 0;
+       u64 qgroup_num_bytes = 0;
        int ret = -ENOSPC;
 
        spin_lock(&block_rsv->lock);
        if (block_rsv->reserved < block_rsv->size)
                num_bytes = block_rsv->size - block_rsv->reserved;
+       if (block_rsv->qgroup_rsv_reserved < block_rsv->qgroup_rsv_size)
+               qgroup_num_bytes = block_rsv->qgroup_rsv_size -
+                                  block_rsv->qgroup_rsv_reserved;
        spin_unlock(&block_rsv->lock);
 
        if (num_bytes == 0)
                return 0;
 
-       ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true);
+       ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_num_bytes, true);
        if (ret)
                return ret;
        ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
@@ -5756,7 +5779,13 @@ static int btrfs_inode_rsv_refill(struct btrfs_inode *inode,
                block_rsv_add_bytes(block_rsv, num_bytes, 0);
                trace_btrfs_space_reservation(root->fs_info, "delalloc",
                                              btrfs_ino(inode), num_bytes, 1);
-       }
+
+               /* Don't forget to increase qgroup_rsv_reserved */
+               spin_lock(&block_rsv->lock);
+               block_rsv->qgroup_rsv_reserved += qgroup_num_bytes;
+               spin_unlock(&block_rsv->lock);
+       } else
+               btrfs_qgroup_free_meta_prealloc(root, qgroup_num_bytes);
        return ret;
 }
 
@@ -5777,20 +5806,23 @@ static void btrfs_inode_rsv_release(struct btrfs_inode *inode, bool qgroup_free)
        struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
        struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
        u64 released = 0;
+       u64 qgroup_to_release = 0;
 
        /*
         * Since we statically set the block_rsv->size we just want to say we
         * are releasing 0 bytes, and then we'll just get the reservation over
         * the size free'd.
         */
-       released = block_rsv_release_bytes(fs_info, block_rsv, global_rsv, 0);
+       released = block_rsv_release_bytes(fs_info, block_rsv, global_rsv, 0,
+                                          &qgroup_to_release);
        if (released > 0)
                trace_btrfs_space_reservation(fs_info, "delalloc",
                                              btrfs_ino(inode), released, 0);
        if (qgroup_free)
-               btrfs_qgroup_free_meta_prealloc(inode->root, released);
+               btrfs_qgroup_free_meta_prealloc(inode->root, qgroup_to_release);
        else
-               btrfs_qgroup_convert_reserved_meta(inode->root, released);
+               btrfs_qgroup_convert_reserved_meta(inode->root,
+                                                  qgroup_to_release);
 }
 
 void btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
@@ -5802,7 +5834,7 @@ void btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
        if (global_rsv == block_rsv ||
            block_rsv->space_info != global_rsv->space_info)
                global_rsv = NULL;
-       block_rsv_release_bytes(fs_info, block_rsv, global_rsv, num_bytes);
+       block_rsv_release_bytes(fs_info, block_rsv, global_rsv, num_bytes, NULL);
 }
 
 static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
@@ -5882,7 +5914,7 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info)
 static void release_global_block_rsv(struct btrfs_fs_info *fs_info)
 {
        block_rsv_release_bytes(fs_info, &fs_info->global_block_rsv, NULL,
-                               (u64)-1);
+                               (u64)-1, NULL);
        WARN_ON(fs_info->trans_block_rsv.size > 0);
        WARN_ON(fs_info->trans_block_rsv.reserved > 0);
        WARN_ON(fs_info->chunk_block_rsv.size > 0);
@@ -5906,7 +5938,7 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
        WARN_ON_ONCE(!list_empty(&trans->new_bgs));
 
        block_rsv_release_bytes(fs_info, &fs_info->chunk_block_rsv, NULL,
-                               trans->chunk_bytes_reserved);
+                               trans->chunk_bytes_reserved, NULL);
        trans->chunk_bytes_reserved = 0;
 }
 
@@ -6011,6 +6043,7 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
 {
        struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
        u64 reserve_size = 0;
+       u64 qgroup_rsv_size = 0;
        u64 csum_leaves;
        unsigned outstanding_extents;
 
@@ -6023,9 +6056,17 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
                                                 inode->csum_bytes);
        reserve_size += btrfs_calc_trans_metadata_size(fs_info,
                                                       csum_leaves);
+       /*
+        * For qgroup rsv, the calculation is very simple:
+        * account one nodesize for each outstanding extent
+        *
+        * This is overestimating in most cases.
+        */
+       qgroup_rsv_size = outstanding_extents * fs_info->nodesize;
 
        spin_lock(&block_rsv->lock);
        block_rsv->size = reserve_size;
+       block_rsv->qgroup_rsv_size = qgroup_rsv_size;
        spin_unlock(&block_rsv->lock);
 }
 
@@ -8403,7 +8444,7 @@ static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
                            struct btrfs_block_rsv *block_rsv, u32 blocksize)
 {
        block_rsv_add_bytes(block_rsv, blocksize, 0);
-       block_rsv_release_bytes(fs_info, block_rsv, NULL, 0);
+       block_rsv_release_bytes(fs_info, block_rsv, NULL, 0, NULL);
 }
 
 /*
index 0167a9c97c9c2933ccaf8f2456b22a525915f18d..f660ba1e5e58ef30f5c72555d7408b686e507e0e 100644 (file)
@@ -1748,7 +1748,7 @@ again:
                        unlock_extent_cached(&BTRFS_I(inode)->io_tree,
                                             lockstart, lockend, &cached_state);
                btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes,
-                                              (ret != 0));
+                                              true);
                if (ret) {
                        btrfs_drop_pages(pages, num_pages);
                        break;
index e064c49c9a9a01a49a9a862bbacd6d16de25594e..d241285a0d2a8dea0ff858f58a5590c18298f2b0 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/uio.h>
 #include <linux/magic.h>
 #include <linux/iversion.h>
+#include <asm/unaligned.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -5905,11 +5906,13 @@ static int btrfs_filldir(void *addr, int entries, struct dir_context *ctx)
                struct dir_entry *entry = addr;
                char *name = (char *)(entry + 1);
 
-               ctx->pos = entry->offset;
-               if (!dir_emit(ctx, name, entry->name_len, entry->ino,
-                             entry->type))
+               ctx->pos = get_unaligned(&entry->offset);
+               if (!dir_emit(ctx, name, get_unaligned(&entry->name_len),
+                                        get_unaligned(&entry->ino),
+                                        get_unaligned(&entry->type)))
                        return 1;
-               addr += sizeof(struct dir_entry) + entry->name_len;
+               addr += sizeof(struct dir_entry) +
+                       get_unaligned(&entry->name_len);
                ctx->pos++;
        }
        return 0;
@@ -5999,14 +6002,15 @@ again:
                }
 
                entry = addr;
-               entry->name_len = name_len;
+               put_unaligned(name_len, &entry->name_len);
                name_ptr = (char *)(entry + 1);
                read_extent_buffer(leaf, name_ptr, (unsigned long)(di + 1),
                                   name_len);
-               entry->type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
+               put_unaligned(btrfs_filetype_table[btrfs_dir_type(leaf, di)],
+                               &entry->type);
                btrfs_dir_item_key_to_cpu(leaf, di, &location);
-               entry->ino = location.objectid;
-               entry->offset = found_key.offset;
+               put_unaligned(location.objectid, &entry->ino);
+               put_unaligned(found_key.offset, &entry->offset);
                entries++;
                addr += sizeof(struct dir_entry) + name_len;
                total_len += sizeof(struct dir_entry) + name_len;
index 124276bba8cf310074e9b1d1134c6463e3a98853..21a831d3d087418bc2e4db884f4fd6a25e9df4e5 100644 (file)
@@ -189,9 +189,10 @@ void btrfs_print_leaf(struct extent_buffer *l)
        fs_info = l->fs_info;
        nr = btrfs_header_nritems(l);
 
-       btrfs_info(fs_info, "leaf %llu total ptrs %d free space %d",
-                  btrfs_header_bytenr(l), nr,
-                  btrfs_leaf_free_space(fs_info, l));
+       btrfs_info(fs_info,
+                  "leaf %llu gen %llu total ptrs %d free space %d owner %llu",
+                  btrfs_header_bytenr(l), btrfs_header_generation(l), nr,
+                  btrfs_leaf_free_space(fs_info, l), btrfs_header_owner(l));
        for (i = 0 ; i < nr ; i++) {
                item = btrfs_item_nr(i);
                btrfs_item_key_to_cpu(l, &key, i);
@@ -325,7 +326,7 @@ void btrfs_print_leaf(struct extent_buffer *l)
        }
 }
 
-void btrfs_print_tree(struct extent_buffer *c)
+void btrfs_print_tree(struct extent_buffer *c, bool follow)
 {
        struct btrfs_fs_info *fs_info;
        int i; u32 nr;
@@ -342,15 +343,19 @@ void btrfs_print_tree(struct extent_buffer *c)
                return;
        }
        btrfs_info(fs_info,
-                  "node %llu level %d total ptrs %d free spc %u",
-                  btrfs_header_bytenr(c), level, nr,
-                  (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr);
+                  "node %llu level %d gen %llu total ptrs %d free spc %u owner %llu",
+                  btrfs_header_bytenr(c), level, btrfs_header_generation(c),
+                  nr, (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr,
+                  btrfs_header_owner(c));
        for (i = 0; i < nr; i++) {
                btrfs_node_key_to_cpu(c, &key, i);
-               pr_info("\tkey %d (%llu %u %llu) block %llu\n",
+               pr_info("\tkey %d (%llu %u %llu) block %llu gen %llu\n",
                       i, key.objectid, key.type, key.offset,
-                      btrfs_node_blockptr(c, i));
+                      btrfs_node_blockptr(c, i),
+                      btrfs_node_ptr_generation(c, i));
        }
+       if (!follow)
+               return;
        for (i = 0; i < nr; i++) {
                struct btrfs_key first_key;
                struct extent_buffer *next;
@@ -372,7 +377,7 @@ void btrfs_print_tree(struct extent_buffer *c)
                if (btrfs_header_level(next) !=
                       level - 1)
                        BUG();
-               btrfs_print_tree(next);
+               btrfs_print_tree(next, follow);
                free_extent_buffer(next);
        }
 }
index 4a98481688f4398e728886be775a0a2a128d8044..e6bb38fd75ad88b38681055c542c73c0c76ba132 100644 (file)
@@ -7,6 +7,6 @@
 #define BTRFS_PRINT_TREE_H
 
 void btrfs_print_leaf(struct extent_buffer *l);
-void btrfs_print_tree(struct extent_buffer *c);
+void btrfs_print_tree(struct extent_buffer *c, bool follow);
 
 #endif
index 09c7e4fd550f4d10b8febcc745e0ba4138d9f35b..9fb758d5077a8441e994df53652fe32f771c2a49 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/btrfs.h>
+#include <linux/sizes.h>
 
 #include "ctree.h"
 #include "transaction.h"
@@ -2375,8 +2376,21 @@ out:
        return ret;
 }
 
-static bool qgroup_check_limits(const struct btrfs_qgroup *qg, u64 num_bytes)
+/*
+ * Two limits to commit transaction in advance.
+ *
+ * For RATIO, it will be 1/RATIO of the remaining limit
+ * (excluding data and prealloc meta) as threshold.
+ * For SIZE, it will be in byte unit as threshold.
+ */
+#define QGROUP_PERTRANS_RATIO          32
+#define QGROUP_PERTRANS_SIZE           SZ_32M
+static bool qgroup_check_limits(struct btrfs_fs_info *fs_info,
+                               const struct btrfs_qgroup *qg, u64 num_bytes)
 {
+       u64 limit;
+       u64 threshold;
+
        if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
            qgroup_rsv_total(qg) + (s64)qg->rfer + num_bytes > qg->max_rfer)
                return false;
@@ -2385,6 +2399,31 @@ static bool qgroup_check_limits(const struct btrfs_qgroup *qg, u64 num_bytes)
            qgroup_rsv_total(qg) + (s64)qg->excl + num_bytes > qg->max_excl)
                return false;
 
+       /*
+        * Even if we passed the check, it's better to check if reservation
+        * for meta_pertrans is pushing us near limit.
+        * If there is too much pertrans reservation or it's near the limit,
+        * let's try commit transaction to free some, using transaction_kthread
+        */
+       if ((qg->lim_flags & (BTRFS_QGROUP_LIMIT_MAX_RFER |
+                             BTRFS_QGROUP_LIMIT_MAX_EXCL))) {
+               if (qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL)
+                       limit = qg->max_excl;
+               else
+                       limit = qg->max_rfer;
+               threshold = (limit - qg->rsv.values[BTRFS_QGROUP_RSV_DATA] -
+                           qg->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC]) /
+                           QGROUP_PERTRANS_RATIO;
+               threshold = min_t(u64, threshold, QGROUP_PERTRANS_SIZE);
+
+               /*
+                * Use transaction_kthread to commit transaction, so we no
+                * longer need to bother nested transaction nor lock context.
+                */
+               if (qg->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS] > threshold)
+                       btrfs_commit_transaction_locksafe(fs_info);
+       }
+
        return true;
 }
 
@@ -2434,7 +2473,7 @@ static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes, bool enforce,
 
                qg = unode_aux_to_qgroup(unode);
 
-               if (enforce && !qgroup_check_limits(qg, num_bytes)) {
+               if (enforce && !qgroup_check_limits(fs_info, qg, num_bytes)) {
                        ret = -EDQUOT;
                        goto out;
                }
index 63fdcab64b016061c9d42cc86f47e8079f3b4634..c944b4769e3c7c5a966e421b5c9c9b4635cab2ac 100644 (file)
@@ -2267,6 +2267,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         */
        cur_trans->state = TRANS_STATE_COMPLETED;
        wake_up(&cur_trans->commit_wait);
+       clear_bit(BTRFS_FS_NEED_ASYNC_COMMIT, &fs_info->flags);
 
        spin_lock(&fs_info->trans_lock);
        list_del_init(&cur_trans->list);
index c88fccd80bc5c940228a00cc2ce1f88e3d1c9806..d8c0826bc2c7e9aee6ff263884e4621d492f9c1f 100644 (file)
@@ -199,6 +199,20 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root);
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans);
 int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
                                   int wait_for_unblock);
+
+/*
+ * Try to commit transaction asynchronously, so this is safe to call
+ * even holding a spinlock.
+ *
+ * It's done by informing transaction_kthread to commit transaction without
+ * waiting for commit interval.
+ */
+static inline void btrfs_commit_transaction_locksafe(
+               struct btrfs_fs_info *fs_info)
+{
+       set_bit(BTRFS_FS_NEED_ASYNC_COMMIT, &fs_info->flags);
+       wake_up_process(fs_info->transaction_kthread);
+}
 int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans);
 int btrfs_should_end_transaction(struct btrfs_trans_handle *trans);
 void btrfs_throttle(struct btrfs_fs_info *fs_info);
index 8bf60250309e359ffd6a34f89c75991b3a1c3c48..ae056927080d28cf3eff14697ded16acdf33f38d 100644 (file)
@@ -669,13 +669,15 @@ void ceph_fill_file_time(struct inode *inode, int issued,
                      CEPH_CAP_FILE_BUFFER|
                      CEPH_CAP_AUTH_EXCL|
                      CEPH_CAP_XATTR_EXCL)) {
-               if (timespec_compare(ctime, &inode->i_ctime) > 0) {
+               if (ci->i_version == 0 ||
+                   timespec_compare(ctime, &inode->i_ctime) > 0) {
                        dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
                             inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
                             ctime->tv_sec, ctime->tv_nsec);
                        inode->i_ctime = *ctime;
                }
-               if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
+               if (ci->i_version == 0 ||
+                   ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
                        /* the MDS did a utimes() */
                        dout("mtime %ld.%09ld -> %ld.%09ld "
                             "tw %d -> %d\n",
@@ -795,7 +797,6 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
        new_issued = ~issued & le32_to_cpu(info->cap.caps);
 
        /* update inode */
-       ci->i_version = le64_to_cpu(info->version);
        inode->i_rdev = le32_to_cpu(info->rdev);
        inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
 
@@ -868,6 +869,9 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
                xattr_blob = NULL;
        }
 
+       /* finally update i_version */
+       ci->i_version = le64_to_cpu(info->version);
+
        inode->i_mapping->a_ops = &ceph_aops;
 
        switch (inode->i_mode & S_IFMT) {
index 7e72348639e4bcbf523ec4bec3a589fbcd643c7c..315f7e63e7cca3b64eed882e8dc0c5fefbebe645 100644 (file)
@@ -228,7 +228,15 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
 
 static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci)
 {
-       return (ci->i_max_files || ci->i_max_bytes);
+       bool ret = false;
+       spin_lock(&ci->i_ceph_lock);
+       if ((ci->i_max_files || ci->i_max_bytes) &&
+           ci->i_vino.snap == CEPH_NOSNAP &&
+           ci->i_snap_realm &&
+           ci->i_snap_realm->ino == ci->i_vino.ino)
+               ret = true;
+       spin_unlock(&ci->i_ceph_lock);
+       return ret;
 }
 
 static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val,
@@ -1008,14 +1016,19 @@ int __ceph_setxattr(struct inode *inode, const char *name,
        char *newval = NULL;
        struct ceph_inode_xattr *xattr = NULL;
        int required_blob_size;
+       bool check_realm = false;
        bool lock_snap_rwsem = false;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
 
        vxattr = ceph_match_vxattr(inode, name);
-       if (vxattr && vxattr->readonly)
-               return -EOPNOTSUPP;
+       if (vxattr) {
+               if (vxattr->readonly)
+                       return -EOPNOTSUPP;
+               if (value && !strncmp(vxattr->name, "ceph.quota", 10))
+                       check_realm = true;
+       }
 
        /* pass any unhandled ceph.* xattrs through to the MDS */
        if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN))
@@ -1109,6 +1122,15 @@ do_sync_unlocked:
                err = -EBUSY;
        } else {
                err = ceph_sync_setxattr(inode, name, value, size, flags);
+               if (err >= 0 && check_realm) {
+                       /* check if snaprealm was created for quota inode */
+                       spin_lock(&ci->i_ceph_lock);
+                       if ((ci->i_max_files || ci->i_max_bytes) &&
+                           !(ci->i_snap_realm &&
+                             ci->i_snap_realm->ino == ci->i_vino.ino))
+                               err = -EOPNOTSUPP;
+                       spin_unlock(&ci->i_ceph_lock);
+               }
        }
 out:
        ceph_free_cap_flush(prealloc_cf);
index fe5567655662cefc4edb7b52d071012e3b355f02..0e74690d11bc8e33c0472565860043175dc25995 100644 (file)
@@ -54,7 +54,7 @@ do {                                                          \
                pr_debug_ ## ratefunc("%s: "                    \
                                fmt, __FILE__, ##__VA_ARGS__);  \
        } else if ((type) & VFS) {                              \
-               pr_err_ ## ratefunc("CuIFS VFS: "               \
+               pr_err_ ## ratefunc("CIFS VFS: "                \
                                 fmt, ##__VA_ARGS__);           \
        } else if ((type) & NOISY && (NOISY != 0)) {            \
                pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__);      \
index 6d3e40d7029c47c6abd7264e8a8aa0cf526f4ee5..1529a088383d048554cfd129de7b8898aa12f6e1 100644 (file)
@@ -455,6 +455,9 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
                server->sign = true;
        }
 
+       if (cifs_rdma_enabled(server) && server->sign)
+               cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
+
        return 0;
 }
 
index e8830f076a7f16a056f7eec3cf025e0e30bff9e8..a5aa158d535a70a2247419152d01b64d553c1596 100644 (file)
@@ -2959,6 +2959,22 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                }
        }
 
+       if (volume_info->seal) {
+               if (ses->server->vals->protocol_id == 0) {
+                       cifs_dbg(VFS,
+                                "SMB3 or later required for encryption\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               } else if (tcon->ses->server->capabilities &
+                                       SMB2_GLOBAL_CAP_ENCRYPTION)
+                       tcon->seal = true;
+               else {
+                       cifs_dbg(VFS, "Encryption is not supported on share\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               }
+       }
+
        /*
         * BB Do we need to wrap session_mutex around this TCon call and Unix
         * SetFS as we do on SessSetup and reconnect?
@@ -3007,22 +3023,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                tcon->use_resilient = true;
        }
 
-       if (volume_info->seal) {
-               if (ses->server->vals->protocol_id == 0) {
-                       cifs_dbg(VFS,
-                                "SMB3 or later required for encryption\n");
-                       rc = -EOPNOTSUPP;
-                       goto out_fail;
-               } else if (tcon->ses->server->capabilities &
-                                       SMB2_GLOBAL_CAP_ENCRYPTION)
-                       tcon->seal = true;
-               else {
-                       cifs_dbg(VFS, "Encryption is not supported on share\n");
-                       rc = -EOPNOTSUPP;
-                       goto out_fail;
-               }
-       }
-
        /*
         * We can have only one retry value for a connection to a share so for
         * resources mounted more than once to the same server share the last
index 81ba6e0d88d8f3ec1d1c8b2e81e695819537c921..925844343038aaa04b479fcdd2063c9ddfb811a0 100644 (file)
@@ -684,6 +684,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
                goto mknod_out;
        }
 
+       if (!S_ISCHR(mode) && !S_ISBLK(mode))
+               goto mknod_out;
+
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
                goto mknod_out;
 
@@ -692,10 +695,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
 
        buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
        if (buf == NULL) {
-               kfree(full_path);
                rc = -ENOMEM;
-               free_xid(xid);
-               return rc;
+               goto mknod_out;
        }
 
        if (backup_cred(cifs_sb))
@@ -742,7 +743,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
                pdev->minor = cpu_to_le64(MINOR(device_number));
                rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
                                                        &bytes_written, iov, 1);
-       } /* else if (S_ISFIFO) */
+       }
        tcon->ses->server->ops->close(xid, tcon, &fid);
        d_drop(direntry);
 
index 4bcd4e838b475071f6e054ab9c89891dbef3d6fe..23fd430fe74a6f111b5832cce72a1bc212c4ac96 100644 (file)
@@ -3462,7 +3462,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
  * If the page is mmap'ed into a process' page tables, then we need to make
  * sure that it doesn't change while being written back.
  */
-static int
+static vm_fault_t
 cifs_page_mkwrite(struct vm_fault *vmf)
 {
        struct page *page = vmf->page;
index b4ae932ea13448aa31509142c72ec71a360eb967..b76b85881dcc668e87f99ee55b6bb4463f25510e 100644 (file)
@@ -252,9 +252,14 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
        wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
        wsize = min_t(unsigned int, wsize, server->max_write);
 #ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->rdma)
-               wsize = min_t(unsigned int,
+       if (server->rdma) {
+               if (server->sign)
+                       wsize = min_t(unsigned int,
+                               wsize, server->smbd_conn->max_fragmented_send_size);
+               else
+                       wsize = min_t(unsigned int,
                                wsize, server->smbd_conn->max_readwrite_size);
+       }
 #endif
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
                wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
@@ -272,9 +277,14 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
        rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
        rsize = min_t(unsigned int, rsize, server->max_read);
 #ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->rdma)
-               rsize = min_t(unsigned int,
+       if (server->rdma) {
+               if (server->sign)
+                       rsize = min_t(unsigned int,
+                               rsize, server->smbd_conn->max_fragmented_recv_size);
+               else
+                       rsize = min_t(unsigned int,
                                rsize, server->smbd_conn->max_readwrite_size);
+       }
 #endif
 
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
@@ -1452,7 +1462,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
        struct kvec err_iov = {NULL, 0};
-       struct smb2_err_rsp *err_buf = NULL;
+       struct smb2_err_rsp *err_buf;
        struct smb2_symlink_err_rsp *symlink;
        unsigned int sub_len;
        unsigned int sub_offset;
@@ -1476,7 +1486,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 
        rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_iov);
 
-       if (!rc || !err_buf) {
+       if (!rc || !err_iov.iov_base) {
                kfree(utf16_path);
                return -ENOENT;
        }
index 0f044c4a2dc9b5b625e9cae21d34344692b76d23..60db51bae0e3a88cec2147cf9d7e709bebb0c7fd 100644 (file)
@@ -383,10 +383,10 @@ static void
 build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
 {
        pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
-       pneg_ctxt->DataLength = cpu_to_le16(6);
-       pneg_ctxt->CipherCount = cpu_to_le16(2);
-       pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
-       pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM;
+       pneg_ctxt->DataLength = cpu_to_le16(4); /* Cipher Count + le16 cipher */
+       pneg_ctxt->CipherCount = cpu_to_le16(1);
+/* pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;*/ /* not supported yet */
+       pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_CCM;
 }
 
 static void
@@ -444,6 +444,7 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server,
                return -EINVAL;
        }
        server->cipher_type = ctxt->Ciphers[0];
+       server->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
        return 0;
 }
 
@@ -2590,7 +2591,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
         * If we want to do a RDMA write, fill in and append
         * smbd_buffer_descriptor_v1 to the end of read request
         */
-       if (server->rdma && rdata &&
+       if (server->rdma && rdata && !server->sign &&
                rdata->bytes >= server->smbd_conn->rdma_readwrite_threshold) {
 
                struct smbd_buffer_descriptor_v1 *v1;
@@ -2968,7 +2969,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
         * If we want to do a server RDMA read, fill in and append
         * smbd_buffer_descriptor_v1 to the end of write request
         */
-       if (server->rdma && wdata->bytes >=
+       if (server->rdma && !server->sign && wdata->bytes >=
                server->smbd_conn->rdma_readwrite_threshold) {
 
                struct smbd_buffer_descriptor_v1 *v1;
index 6093e5142b2bc3792cf40afb7f7abbc02b60bbb4..d28f358022c507cc0dc55dbebb382ed29dec708d 100644 (file)
@@ -297,7 +297,7 @@ struct smb2_encryption_neg_context {
        __le16  DataLength;
        __le32  Reserved;
        __le16  CipherCount; /* AES-128-GCM and AES-128-CCM */
-       __le16  Ciphers[2]; /* Ciphers[0] since only one used now */
+       __le16  Ciphers[1]; /* Ciphers[0] since only one used now */
 } __packed;
 
 struct smb2_negotiate_rsp {
index 5008af546dd16d6e276953b24b354cd7bb54796d..c62f7c95683c513213bc786152f78b60a2f8fbd6 100644 (file)
@@ -1028,7 +1028,7 @@ static int smbd_post_send(struct smbd_connection *info,
        for (i = 0; i < request->num_sge; i++) {
                log_rdma_send(INFO,
                        "rdma_request sge[%d] addr=%llu length=%u\n",
-                       i, request->sge[0].addr, request->sge[0].length);
+                       i, request->sge[i].addr, request->sge[i].length);
                ib_dma_sync_single_for_device(
                        info->id->device,
                        request->sge[i].addr,
@@ -2086,7 +2086,7 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
        int start, i, j;
        int max_iov_size =
                info->max_send_size - sizeof(struct smbd_data_transfer);
-       struct kvec iov[SMBDIRECT_MAX_SGE];
+       struct kvec *iov;
        int rc;
 
        info->smbd_send_pending++;
@@ -2096,32 +2096,20 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
        }
 
        /*
-        * This usually means a configuration error
-        * We use RDMA read/write for packet size > rdma_readwrite_threshold
-        * as long as it's properly configured we should never get into this
-        * situation
-        */
-       if (rqst->rq_nvec + rqst->rq_npages > SMBDIRECT_MAX_SGE) {
-               log_write(ERR, "maximum send segment %x exceeding %x\n",
-                        rqst->rq_nvec + rqst->rq_npages, SMBDIRECT_MAX_SGE);
-               rc = -EINVAL;
-               goto done;
-       }
-
-       /*
-        * Remove the RFC1002 length defined in MS-SMB2 section 2.1
-        * It is used only for TCP transport
+        * Skip the RFC1002 length defined in MS-SMB2 section 2.1
+        * It is used only for TCP transport in the iov[0]
         * In future we may want to add a transport layer under protocol
         * layer so this will only be issued to TCP transport
         */
-       iov[0].iov_base = (char *)rqst->rq_iov[0].iov_base + 4;
-       iov[0].iov_len = rqst->rq_iov[0].iov_len - 4;
-       buflen += iov[0].iov_len;
+
+       if (rqst->rq_iov[0].iov_len != 4) {
+               log_write(ERR, "expected the pdu length in 1st iov, but got %zu\n", rqst->rq_iov[0].iov_len);
+               return -EINVAL;
+       }
+       iov = &rqst->rq_iov[1];
 
        /* total up iov array first */
-       for (i = 1; i < rqst->rq_nvec; i++) {
-               iov[i].iov_base = rqst->rq_iov[i].iov_base;
-               iov[i].iov_len = rqst->rq_iov[i].iov_len;
+       for (i = 0; i < rqst->rq_nvec-1; i++) {
                buflen += iov[i].iov_len;
        }
 
@@ -2139,6 +2127,10 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
                goto done;
        }
 
+       cifs_dbg(FYI, "Sending smb (RDMA): smb_len=%u\n", buflen);
+       for (i = 0; i < rqst->rq_nvec-1; i++)
+               dump_smb(iov[i].iov_base, iov[i].iov_len);
+
        remaining_data_length = buflen;
 
        log_write(INFO, "rqst->rq_nvec=%d rqst->rq_npages=%d rq_pagesz=%d "
@@ -2194,12 +2186,14 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
                                                goto done;
                                }
                                i++;
+                               if (i == rqst->rq_nvec-1)
+                                       break;
                        }
                        start = i;
                        buflen = 0;
                } else {
                        i++;
-                       if (i == rqst->rq_nvec) {
+                       if (i == rqst->rq_nvec-1) {
                                /* send out all remaining vecs */
                                remaining_data_length -= buflen;
                                log_write(INFO,
index 8f6f25918229d9aeb680173a87cf9d684d2eb5c8..927226a2122f4dde57955fe805013d14fd6237df 100644 (file)
@@ -753,7 +753,7 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
                goto out;
 
 #ifdef CONFIG_CIFS_SMB311
-       if (ses->status == CifsNew)
+       if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
                smb311_update_preauth_hash(ses, rqst->rq_iov+1,
                                           rqst->rq_nvec-1);
 #endif
@@ -798,7 +798,7 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
                *resp_buf_type = CIFS_SMALL_BUFFER;
 
 #ifdef CONFIG_CIFS_SMB311
-       if (ses->status == CifsNew) {
+       if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
                struct kvec iov = {
                        .iov_base = buf + 4,
                        .iov_len = get_rfc1002_length(buf)
@@ -834,8 +834,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
        if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
                new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
                                  GFP_KERNEL);
-               if (!new_iov)
+               if (!new_iov) {
+                       /* otherwise cifs_send_recv below sets resp_buf_type */
+                       *resp_buf_type = CIFS_NO_BUFFER;
                        return -ENOMEM;
+               }
        } else
                new_iov = s_iov;
 
index 846ca150d52e9259e5ded67abfe708a9f5c4084e..4dd842f728465591cc7982d635f544c0084b064a 100644 (file)
@@ -1997,6 +1997,16 @@ out:
        return rc;
 }
 
+static bool is_dot_dotdot(const char *name, size_t name_size)
+{
+       if (name_size == 1 && name[0] == '.')
+               return true;
+       else if (name_size == 2 && name[0] == '.' && name[1] == '.')
+               return true;
+
+       return false;
+}
+
 /**
  * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext
  * @plaintext_name: The plaintext name
@@ -2021,13 +2031,21 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
        size_t packet_size;
        int rc = 0;
 
-       if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
-           && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
-           && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)
-           && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX,
-                       ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) {
-               const char *orig_name = name;
-               size_t orig_name_size = name_size;
+       if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) &&
+           !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)) {
+               if (is_dot_dotdot(name, name_size)) {
+                       rc = ecryptfs_copy_filename(plaintext_name,
+                                                   plaintext_name_size,
+                                                   name, name_size);
+                       goto out;
+               }
+
+               if (name_size <= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE ||
+                   strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX,
+                           ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)) {
+                       rc = -EINVAL;
+                       goto out;
+               }
 
                name += ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
                name_size -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
@@ -2047,12 +2065,9 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
                                                  decoded_name,
                                                  decoded_name_size);
                if (rc) {
-                       printk(KERN_INFO "%s: Could not parse tag 70 packet "
-                              "from filename; copying through filename "
-                              "as-is\n", __func__);
-                       rc = ecryptfs_copy_filename(plaintext_name,
-                                                   plaintext_name_size,
-                                                   orig_name, orig_name_size);
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "%s: Could not parse tag 70 packet from filename\n",
+                                       __func__);
                        goto out_free;
                }
        } else {
index c74ed3ca3372f8b8e91ed9da35de617c7b25ce08..b76a9853325e7034a0c40f4d6099bfb83ef21c94 100644 (file)
@@ -82,17 +82,28 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
                                                  buf->sb, lower_name,
                                                  lower_namelen);
        if (rc) {
-               printk(KERN_ERR "%s: Error attempting to decode and decrypt "
-                      "filename [%s]; rc = [%d]\n", __func__, lower_name,
-                      rc);
-               goto out;
+               if (rc != -EINVAL) {
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
+                                       __func__, lower_name, rc);
+                       return rc;
+               }
+
+               /* Mask -EINVAL errors as these are most likely due a plaintext
+                * filename present in the lower filesystem despite filename
+                * encryption being enabled. One unavoidable example would be
+                * the "lost+found" dentry in the root directory of an Ext4
+                * filesystem.
+                */
+               return 0;
        }
+
        buf->caller->pos = buf->ctx.pos;
        rc = !dir_emit(buf->caller, name, name_size, ino, d_type);
        kfree(name);
        if (!rc)
                buf->entries_written++;
-out:
+
        return rc;
 }
 
index 847904aa63a9a6554d592dbf0710c7eff7954f49..97d17eaeba0731fb5d755c7a3106af1abaf2cff0 100644 (file)
@@ -395,8 +395,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
 
        mount_crypt_stat = &ecryptfs_superblock_to_private(
                                ecryptfs_dentry->d_sb)->mount_crypt_stat;
-       if (mount_crypt_stat
-           && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) {
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
                rc = ecryptfs_encrypt_and_encode_filename(
                        &encrypted_and_encoded_name, &len,
                        mount_crypt_stat, name, len);
index c89a58cfc991c235f1420a4901df877dc7557939..e74fe84d0886879c04cc26297f0e8b27db8281a6 100644 (file)
@@ -1880,7 +1880,7 @@ find_next_matching_auth_tok:
                candidate_auth_tok = &auth_tok_list_item->auth_tok;
                if (unlikely(ecryptfs_verbosity > 0)) {
                        ecryptfs_printk(KERN_DEBUG,
-                                       "Considering cadidate auth tok:\n");
+                                       "Considering candidate auth tok:\n");
                        ecryptfs_dump_auth_tok(candidate_auth_tok);
                }
                rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig,
index 09640220fda8a5388c84fcd31e63b251b478bb8e..047c327a6b233d22c1dd266f5d67a2e9f0643419 100644 (file)
@@ -88,11 +88,11 @@ out_unlock:
  * The default page_lock and i_size verification done by non-DAX fault paths
  * is sufficient because ext2 doesn't support hole punching.
  */
-static int ext2_dax_fault(struct vm_fault *vmf)
+static vm_fault_t ext2_dax_fault(struct vm_fault *vmf)
 {
        struct inode *inode = file_inode(vmf->vma->vm_file);
        struct ext2_inode_info *ei = EXT2_I(inode);
-       int ret;
+       vm_fault_t ret;
 
        if (vmf->flags & FAULT_FLAG_WRITE) {
                sb_start_pagefault(inode->i_sb);
index a33d8fb1bf2a7fc3ac13459e526fb9ec88373db3..508b905d744d752bfa671f4a8a09ea066ad8c25a 100644 (file)
@@ -321,6 +321,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        ext4_grpblk_t offset;
        ext4_grpblk_t next_zero_bit;
+       ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb);
        ext4_fsblk_t blk;
        ext4_fsblk_t group_first_block;
 
@@ -338,7 +339,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        /* check whether block bitmap block number is set */
        blk = ext4_block_bitmap(sb, desc);
        offset = blk - group_first_block;
-       if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
+       if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
            !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
                /* bad block bitmap */
                return blk;
@@ -346,7 +347,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        /* check whether the inode bitmap block number is set */
        blk = ext4_inode_bitmap(sb, desc);
        offset = blk - group_first_block;
-       if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
+       if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
            !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
                /* bad block bitmap */
                return blk;
@@ -354,8 +355,8 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        /* check whether the inode table block number is set */
        blk = ext4_inode_table(sb, desc);
        offset = blk - group_first_block;
-       if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
-           EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= sb->s_blocksize)
+       if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
+           EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit)
                return blk;
        next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
                        EXT4_B2C(sbi, offset + sbi->s_itb_per_group),
index 0a7315961bac6ebbca0c2bfe83cc3aba8fc5c807..c969275ce3ee7469167a6921e8fa22e4c91ed3a2 100644 (file)
@@ -5329,8 +5329,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
        stop = le32_to_cpu(extent->ee_block);
 
        /*
-        * In case of left shift, Don't start shifting extents until we make
-        * sure the hole is big enough to accommodate the shift.
+       * For left shifts, make sure the hole on the left is big enough to
+       * accommodate the shift.  For right shifts, make sure the last extent
+       * won't be shifted beyond EXT_MAX_BLOCKS.
        */
        if (SHIFT == SHIFT_LEFT) {
                path = ext4_find_extent(inode, start - 1, &path,
@@ -5350,9 +5351,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
 
                if ((start == ex_start && shift > ex_start) ||
                    (shift > start - ex_end)) {
-                       ext4_ext_drop_refs(path);
-                       kfree(path);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out;
+               }
+       } else {
+               if (shift > EXT_MAX_BLOCKS -
+                   (stop + ext4_ext_get_actual_len(extent))) {
+                       ret = -EINVAL;
+                       goto out;
                }
        }
 
index 185f7e61f4cfe00531e71e772a519af005f6bd69..eb104e8476f040e61253a6676c93e882e5a22314 100644 (file)
@@ -5886,5 +5886,6 @@ static void __exit ext4_exit_fs(void)
 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
 MODULE_DESCRIPTION("Fourth Extended Filesystem");
 MODULE_LICENSE("GPL");
+MODULE_SOFTDEP("pre: crc32c");
 module_init(ext4_init_fs)
 module_exit(ext4_exit_fs)
index 4b12ba70a895d8a359692f63459860f2e1dcd24c..47d7c151fcbaf78882e20f8c6ecc3601b1bcb46d 100644 (file)
@@ -745,11 +745,12 @@ int inode_congested(struct inode *inode, int cong_bits)
         */
        if (inode && inode_to_wb_is_valid(inode)) {
                struct bdi_writeback *wb;
-               bool locked, congested;
+               struct wb_lock_cookie lock_cookie = {};
+               bool congested;
 
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &lock_cookie);
                congested = wb_congested(wb, cong_bits);
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &lock_cookie);
                return congested;
        }
 
index 9bb2fe35799d3d306fde5b06ff699af753d66aff..10205ececc2741fc849ddfc3d9a9b68a8f62b916 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/bio.h>
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/zlib.h>
 
@@ -59,7 +60,7 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start,
                                >> bufshift;
        int haveblocks;
        blkcnt_t blocknum;
-       struct buffer_head *bhs[needblocks + 1];
+       struct buffer_head **bhs;
        int curbh, curpage;
 
        if (block_size > deflateBound(1UL << zisofs_block_shift)) {
@@ -80,7 +81,11 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start,
 
        /* Because zlib is not thread-safe, do all the I/O at the top. */
        blocknum = block_start >> bufshift;
-       memset(bhs, 0, (needblocks + 1) * sizeof(struct buffer_head *));
+       bhs = kcalloc(needblocks + 1, sizeof(*bhs), GFP_KERNEL);
+       if (!bhs) {
+               *errp = -ENOMEM;
+               return 0;
+       }
        haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks);
        ll_rw_block(REQ_OP_READ, 0, haveblocks, bhs);
 
@@ -190,6 +195,7 @@ z_eio:
 b_eio:
        for (i = 0; i < haveblocks; i++)
                brelse(bhs[i]);
+       kfree(bhs);
        return stream.total_out;
 }
 
@@ -305,7 +311,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
        unsigned int zisofs_pages_per_cblock =
                PAGE_SHIFT <= zisofs_block_shift ?
                (1 << (zisofs_block_shift - PAGE_SHIFT)) : 0;
-       struct page *pages[max_t(unsigned, zisofs_pages_per_cblock, 1)];
+       struct page **pages;
        pgoff_t index = page->index, end_index;
 
        end_index = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -330,6 +336,12 @@ static int zisofs_readpage(struct file *file, struct page *page)
                full_page = 0;
                pcount = 1;
        }
+       pages = kcalloc(max_t(unsigned int, zisofs_pages_per_cblock, 1),
+                                       sizeof(*pages), GFP_KERNEL);
+       if (!pages) {
+               unlock_page(page);
+               return -ENOMEM;
+       }
        pages[full_page] = page;
 
        for (i = 0; i < pcount; i++, index++) {
@@ -357,6 +369,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
        }                       
 
        /* At this point, err contains 0 or -EIO depending on the "critical" page */
+       kfree(pages);
        return err;
 }
 
index bc258a4402f6afbc921a508db37f95002f2ff7f0..ec3fba7d492f483e14accbfd98d5b63550f2591c 100644 (file)
@@ -394,7 +394,10 @@ static int parse_options(char *options, struct iso9660_options *popt)
                        break;
 #ifdef CONFIG_JOLIET
                case Opt_iocharset:
+                       kfree(popt->iocharset);
                        popt->iocharset = match_strdup(&args[0]);
+                       if (!popt->iocharset)
+                               return 0;
                        break;
 #endif
                case Opt_map_a:
index ac311037d7a59b03d6403a65c56c7978697463c6..8aa453784402bbed8d33aa76d025071bf6523c75 100644 (file)
@@ -532,6 +532,7 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type,
         */
        ret = start_this_handle(journal, handle, GFP_NOFS);
        if (ret < 0) {
+               handle->h_journal = journal;
                jbd2_journal_free_reserved(handle);
                return ret;
        }
index f60dee7faf0373f12bdfcf7f3d5f3883ec86b16e..87bdf0f4cba117fc7c987080b9b901d7614ebfd3 100644 (file)
@@ -342,7 +342,7 @@ static void jffs2_put_super (struct super_block *sb)
 static void jffs2_kill_sb(struct super_block *sb)
 {
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-       if (!sb_rdonly(sb))
+       if (c && !sb_rdonly(sb))
                jffs2_stop_garbage_collect_thread(c);
        kill_mtd_super(sb);
        kfree(c);
index e398f32d754103bf76550e84d76d215647be9d38..5f75969adff18ef9e2390648d93e7dec214913c3 100644 (file)
@@ -1089,7 +1089,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
                        goto out_free;
        }
 
-       mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED);
+       mnt->mnt.mnt_flags = old->mnt.mnt_flags;
+       mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);
        /* Don't allow unprivileged users to change mount flags */
        if (flag & CL_UNPRIVILEGED) {
                mnt->mnt.mnt_flags |= MNT_LOCK_ATIME;
@@ -2814,7 +2815,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
                mnt_flags |= MNT_NODIRATIME;
        if (flags & MS_STRICTATIME)
                mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
-       if (flags & SB_RDONLY)
+       if (flags & MS_RDONLY)
                mnt_flags |= MNT_READONLY;
 
        /* The default atime for remount is preservation */
index d51e1bb781cfd3df2d50488e34d40a334c8175a0..d94e8031fe5fb8e95a168a475ad0069df3016465 100644 (file)
@@ -92,7 +92,7 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
                                       u32 event_mask,
                                       const void *data, int data_type)
 {
-       __u32 marks_mask, marks_ignored_mask;
+       __u32 marks_mask = 0, marks_ignored_mask = 0;
        const struct path *path = data;
 
        pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p"
@@ -108,24 +108,20 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
            !d_can_lookup(path->dentry))
                return false;
 
-       if (inode_mark && vfsmnt_mark) {
-               marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
-               marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
-       } else if (inode_mark) {
-               /*
-                * if the event is for a child and this inode doesn't care about
-                * events on the child, don't send it!
-                */
-               if ((event_mask & FS_EVENT_ON_CHILD) &&
-                   !(inode_mark->mask & FS_EVENT_ON_CHILD))
-                       return false;
-               marks_mask = inode_mark->mask;
-               marks_ignored_mask = inode_mark->ignored_mask;
-       } else if (vfsmnt_mark) {
-               marks_mask = vfsmnt_mark->mask;
-               marks_ignored_mask = vfsmnt_mark->ignored_mask;
-       } else {
-               BUG();
+       /*
+        * if the event is for a child and this inode doesn't care about
+        * events on the child, don't send it!
+        */
+       if (inode_mark &&
+           (!(event_mask & FS_EVENT_ON_CHILD) ||
+            (inode_mark->mask & FS_EVENT_ON_CHILD))) {
+               marks_mask |= inode_mark->mask;
+               marks_ignored_mask |= inode_mark->ignored_mask;
+       }
+
+       if (vfsmnt_mark) {
+               marks_mask |= vfsmnt_mark->mask;
+               marks_ignored_mask |= vfsmnt_mark->ignored_mask;
        }
 
        if (d_is_dir(path->dentry) &&
index 219b269c737e6e0d85f05fb142e712c918d34dfc..613ec7e5a46582e4e2e03b1d623e9822017ddc5a 100644 (file)
@@ -192,8 +192,9 @@ static int send_to_group(struct inode *to_tell,
                         struct fsnotify_iter_info *iter_info)
 {
        struct fsnotify_group *group = NULL;
-       __u32 inode_test_mask = 0;
-       __u32 vfsmount_test_mask = 0;
+       __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
+       __u32 marks_mask = 0;
+       __u32 marks_ignored_mask = 0;
 
        if (unlikely(!inode_mark && !vfsmount_mark)) {
                BUG();
@@ -213,29 +214,25 @@ static int send_to_group(struct inode *to_tell,
        /* does the inode mark tell us to do something? */
        if (inode_mark) {
                group = inode_mark->group;
-               inode_test_mask = (mask & ~FS_EVENT_ON_CHILD);
-               inode_test_mask &= inode_mark->mask;
-               inode_test_mask &= ~inode_mark->ignored_mask;
+               marks_mask |= inode_mark->mask;
+               marks_ignored_mask |= inode_mark->ignored_mask;
        }
 
        /* does the vfsmount_mark tell us to do something? */
        if (vfsmount_mark) {
-               vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD);
                group = vfsmount_mark->group;
-               vfsmount_test_mask &= vfsmount_mark->mask;
-               vfsmount_test_mask &= ~vfsmount_mark->ignored_mask;
-               if (inode_mark)
-                       vfsmount_test_mask &= ~inode_mark->ignored_mask;
+               marks_mask |= vfsmount_mark->mask;
+               marks_ignored_mask |= vfsmount_mark->ignored_mask;
        }
 
        pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
-                " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
+                " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
                 " data=%p data_is=%d cookie=%d\n",
-                __func__, group, to_tell, mask, inode_mark,
-                inode_test_mask, vfsmount_mark, vfsmount_test_mask, data,
+                __func__, group, to_tell, mask, inode_mark, vfsmount_mark,
+                marks_mask, marks_ignored_mask, data,
                 data_is, cookie);
 
-       if (!inode_test_mask && !vfsmount_test_mask)
+       if (!(test_mask & marks_mask & ~marks_ignored_mask))
                return 0;
 
        return group->ops->handle_event(group, to_tell, inode_mark,
index 3ae5fdba0225b5670491b9cbfbf68be7bccf84a9..10796d3fe27d38f4793375deda306ac3187668d3 100644 (file)
@@ -579,6 +579,11 @@ void orangefs_kill_sb(struct super_block *sb)
        /* provided sb cleanup */
        kill_anon_super(sb);
 
+       if (!ORANGEFS_SB(sb)) {
+               mutex_lock(&orangefs_request_mutex);
+               mutex_unlock(&orangefs_request_mutex);
+               return;
+       }
        /*
         * issue the unmount to userspace to tell it to remove the
         * dynamic mount info it has for this superblock
index eafa39a3a88cb479eaca9d164e05cc4dbca1db70..1b2ede6abcdfc97f1ab87244a18e0cb4c9035e5f 100644 (file)
@@ -1693,6 +1693,12 @@ void task_dump_owner(struct task_struct *task, umode_t mode,
        kuid_t uid;
        kgid_t gid;
 
+       if (unlikely(task->flags & PF_KTHREAD)) {
+               *ruid = GLOBAL_ROOT_UID;
+               *rgid = GLOBAL_ROOT_GID;
+               return;
+       }
+
        /* Default to the tasks effective ownership */
        rcu_read_lock();
        cred = __task_cred(task);
index a000d7547479e8849acbea6dea406dc5b2bb7c46..b572cc865b928635c413f0d14d68b1ed46d5c7bf 100644 (file)
@@ -24,7 +24,7 @@ static int loadavg_proc_show(struct seq_file *m, void *v)
                LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
                LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
                nr_running(), nr_threads,
-               idr_get_cursor(&task_active_pid_ns(current)->idr));
+               idr_get_cursor(&task_active_pid_ns(current)->idr) - 1);
        return 0;
 }
 
index 65ae54659833888142d376835d9b4a8a70c7218e..c486ad4b43f00857a254cfcedeebfa2884162b52 100644 (file)
@@ -1310,9 +1310,11 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
 #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
                else if (is_swap_pmd(pmd)) {
                        swp_entry_t entry = pmd_to_swp_entry(pmd);
+                       unsigned long offset = swp_offset(entry);
 
+                       offset += (addr & ~PMD_MASK) >> PAGE_SHIFT;
                        frame = swp_type(entry) |
-                               (swp_offset(entry) << MAX_SWAPFILES_SHIFT);
+                               (offset << MAX_SWAPFILES_SHIFT);
                        flags |= PM_SWAP;
                        if (pmd_swp_soft_dirty(pmd))
                                flags |= PM_SOFT_DIRTY;
@@ -1332,6 +1334,8 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
                                break;
                        if (pm->show_pfn && (flags & PM_PRESENT))
                                frame++;
+                       else if (flags & PM_SWAP)
+                               frame += (1 << MAX_SWAPFILES_SHIFT);
                }
                spin_unlock(ptl);
                return err;
index 020c597ef9b6e66a74f786d70302238d32dc729a..d88231e3b2be3ec1bc1f85c3c2fd92973e312c15 100644 (file)
@@ -2966,7 +2966,7 @@ static int __init dquot_init(void)
                        NULL);
 
        order = 0;
-       dquot_hash = (struct hlist_head *)__get_free_pages(GFP_ATOMIC, order);
+       dquot_hash = (struct hlist_head *)__get_free_pages(GFP_KERNEL, order);
        if (!dquot_hash)
                panic("Cannot create dquot hash table");
 
index 5fa9a8d8d865c46a77d4a0e8fb7b05499809840f..122c402049a25b29c5ed1e9aa0ef6ace1f657e6c 100644 (file)
@@ -167,6 +167,7 @@ static void destroy_unused_super(struct super_block *s)
        security_sb_free(s);
        put_user_ns(s->s_user_ns);
        kfree(s->s_subtype);
+       free_prealloced_shrinker(&s->s_shrink);
        /* no delays needed */
        destroy_super_work(&s->destroy_work);
 }
@@ -252,6 +253,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
        s->s_shrink.count_objects = super_cache_count;
        s->s_shrink.batch = 1024;
        s->s_shrink.flags = SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE;
+       if (prealloc_shrinker(&s->s_shrink))
+               goto fail;
        return s;
 
 fail:
@@ -518,11 +521,7 @@ retry:
        hlist_add_head(&s->s_instances, &type->fs_supers);
        spin_unlock(&sb_lock);
        get_filesystem(type);
-       err = register_shrinker(&s->s_shrink);
-       if (err) {
-               deactivate_locked_super(s);
-               s = ERR_PTR(err);
-       }
+       register_shrinker_prepared(&s->s_shrink);
        return s;
 }
 
index f897e55f2cd07f57de7b01f2db92063ce7faa7a8..16a8ad21b77eda926b8bef4e004a7f280939af84 100644 (file)
@@ -28,6 +28,9 @@
 
 #include "udf_sb.h"
 
+#define SURROGATE_MASK 0xfffff800
+#define SURROGATE_PAIR 0x0000d800
+
 static int udf_uni2char_utf8(wchar_t uni,
                             unsigned char *out,
                             int boundlen)
@@ -37,6 +40,9 @@ static int udf_uni2char_utf8(wchar_t uni,
        if (boundlen <= 0)
                return -ENAMETOOLONG;
 
+       if ((uni & SURROGATE_MASK) == SURROGATE_PAIR)
+               return -EINVAL;
+
        if (uni < 0x80) {
                out[u_len++] = (unsigned char)uni;
        } else if (uni < 0x800) {
index ce4a34a2751d6ebe3ee0806d88ff58adf1023061..35a124400d60a11a468ec298335835a2666f087c 100644 (file)
@@ -511,7 +511,14 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
                if (args->flags & ATTR_CREATE)
                        return retval;
                retval = xfs_attr_shortform_remove(args);
-               ASSERT(retval == 0);
+               if (retval)
+                       return retval;
+               /*
+                * Since we have removed the old attr, clear ATTR_REPLACE so
+                * that the leaf format add routine won't trip over the attr
+                * not being around.
+                */
+               args->flags &= ~ATTR_REPLACE;
        }
 
        if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
index 6a7c2f03ea11a123bcd04fbc70be96cbc897382f..040eeda8426ff7d996b87f144282303b26cc39b0 100644 (file)
@@ -725,12 +725,16 @@ xfs_bmap_extents_to_btree(
        *logflagsp = 0;
        if ((error = xfs_alloc_vextent(&args))) {
                xfs_iroot_realloc(ip, -1, whichfork);
+               ASSERT(ifp->if_broot == NULL);
+               XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
                xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
                return error;
        }
 
        if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) {
                xfs_iroot_realloc(ip, -1, whichfork);
+               ASSERT(ifp->if_broot == NULL);
+               XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
                xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
                return -ENOSPC;
        }
index ef68b1de006a7ecedd7eabe41551165b0d3beffb..1201107eabc632c91894f52590609045a104eabf 100644 (file)
@@ -466,6 +466,8 @@ xfs_dinode_verify(
                                return __this_address;
                        if (di_size > XFS_DFORK_DSIZE(dip, mp))
                                return __this_address;
+                       if (dip->di_nextents)
+                               return __this_address;
                        /* fall through */
                case XFS_DINODE_FMT_EXTENTS:
                case XFS_DINODE_FMT_BTREE:
@@ -484,12 +486,31 @@ xfs_dinode_verify(
        if (XFS_DFORK_Q(dip)) {
                switch (dip->di_aformat) {
                case XFS_DINODE_FMT_LOCAL:
+                       if (dip->di_anextents)
+                               return __this_address;
+               /* fall through */
                case XFS_DINODE_FMT_EXTENTS:
                case XFS_DINODE_FMT_BTREE:
                        break;
                default:
                        return __this_address;
                }
+       } else {
+               /*
+                * If there is no fork offset, this may be a freshly-made inode
+                * in a new disk cluster, in which case di_aformat is zeroed.
+                * Otherwise, such an inode must be in EXTENTS format; this goes
+                * for freed inodes as well.
+                */
+               switch (dip->di_aformat) {
+               case 0:
+               case XFS_DINODE_FMT_EXTENTS:
+                       break;
+               default:
+                       return __this_address;
+               }
+               if (dip->di_anextents)
+                       return __this_address;
        }
 
        /* only version 3 or greater inodes are extensively verified here */
index 299aee4b7b0b35b14df223cc7d92efecdd026d1f..eed073cc47783411b09d9efcc8e23f6d272bb666 100644 (file)
@@ -778,22 +778,26 @@ xfs_file_fallocate(
                if (error)
                        goto out_unlock;
        } else if (mode & FALLOC_FL_INSERT_RANGE) {
-               unsigned int blksize_mask = i_blocksize(inode) - 1;
+               unsigned int    blksize_mask = i_blocksize(inode) - 1;
+               loff_t          isize = i_size_read(inode);
 
-               new_size = i_size_read(inode) + len;
                if (offset & blksize_mask || len & blksize_mask) {
                        error = -EINVAL;
                        goto out_unlock;
                }
 
-               /* check the new inode size does not wrap through zero */
-               if (new_size > inode->i_sb->s_maxbytes) {
+               /*
+                * New inode size must not exceed ->s_maxbytes, accounting for
+                * possible signed overflow.
+                */
+               if (inode->i_sb->s_maxbytes - isize < len) {
                        error = -EFBIG;
                        goto out_unlock;
                }
+               new_size = isize + len;
 
                /* Offset should be less than i_size */
-               if (offset >= i_size_read(inode)) {
+               if (offset >= isize) {
                        error = -EINVAL;
                        goto out_unlock;
                }
index 278841c75b97b0f55431e75c3a172a041f43f94b..af240573e48295687e4403b0bcc11875d5da2e82 100644 (file)
 #endif
 
 #ifdef CONFIG_SERIAL_EARLYCON
-#define EARLYCON_TABLE() STRUCT_ALIGN();                       \
+#define EARLYCON_TABLE() . = ALIGN(8);                         \
                         VMLINUX_SYMBOL(__earlycon_table) = .;  \
                         KEEP(*(__earlycon_table))              \
                         VMLINUX_SYMBOL(__earlycon_table_end) = .;
index 562fa7df263704503ea14c8be2127597cb8d8589..98e63d870139db0c9956f4446d3e298eb2964e7a 100644 (file)
@@ -19,7 +19,7 @@
 #define DRM_HDCP_RI_LEN                                2
 #define DRM_HDCP_V_PRIME_PART_LEN              4
 #define DRM_HDCP_V_PRIME_NUM_PARTS             5
-#define DRM_HDCP_NUM_DOWNSTREAM(x)             (x & 0x3f)
+#define DRM_HDCP_NUM_DOWNSTREAM(x)             (x & 0x7f)
 #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x)       (x & BIT(3))
 #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x)                (x & BIT(7))
 
index e518e4e3dfb50a83520a3b8100c3c27899c15bdf..4b1548129fa2b3e2b87565ec02d9dd5adb80ccb2 100644 (file)
@@ -37,10 +37,15 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm)
         * Our PSCI implementation stays the same across versions from
         * v0.2 onward, only adding the few mandatory functions (such
         * as FEATURES with 1.0) that are required by newer
-        * revisions. It is thus safe to return the latest.
+        * revisions. It is thus safe to return the latest, unless
+        * userspace has instructed us otherwise.
         */
-       if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
+       if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) {
+               if (vcpu->kvm->arch.psci_version)
+                       return vcpu->kvm->arch.psci_version;
+
                return KVM_ARM_PSCI_LATEST;
+       }
 
        return KVM_ARM_PSCI_0_1;
 }
@@ -48,4 +53,11 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm)
 
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
+struct kvm_one_reg;
+
+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+
 #endif /* __KVM_ARM_PSCI_H__ */
index bfe86b54f6c149a6c8718f13417ecf7a796b7193..0bd432a4d7bd00ce376292720edd104d617c80c2 100644 (file)
@@ -223,6 +223,11 @@ static inline void set_bdi_congested(struct backing_dev_info *bdi, int sync)
        set_wb_congested(bdi->wb.congested, sync);
 }
 
+struct wb_lock_cookie {
+       bool locked;
+       unsigned long flags;
+};
+
 #ifdef CONFIG_CGROUP_WRITEBACK
 
 /**
index f6be4b0b6c18d2b76308f1eac441a4e6c223f8ac..72ca0f3d39f3039b0cda57c2a350c941075bdd62 100644 (file)
@@ -347,7 +347,7 @@ static inline struct bdi_writeback *inode_to_wb(const struct inode *inode)
 /**
  * unlocked_inode_to_wb_begin - begin unlocked inode wb access transaction
  * @inode: target inode
- * @lockedp: temp bool output param, to be passed to the end function
+ * @cookie: output param, to be passed to the end function
  *
  * The caller wants to access the wb associated with @inode but isn't
  * holding inode->i_lock, the i_pages lock or wb->list_lock.  This
@@ -355,12 +355,12 @@ static inline struct bdi_writeback *inode_to_wb(const struct inode *inode)
  * association doesn't change until the transaction is finished with
  * unlocked_inode_to_wb_end().
  *
- * The caller must call unlocked_inode_to_wb_end() with *@lockdep
- * afterwards and can't sleep during transaction.  IRQ may or may not be
- * disabled on return.
+ * The caller must call unlocked_inode_to_wb_end() with *@cookie afterwards and
+ * can't sleep during the transaction.  IRQs may or may not be disabled on
+ * return.
  */
 static inline struct bdi_writeback *
-unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
+unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
 {
        rcu_read_lock();
 
@@ -368,10 +368,10 @@ unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
         * Paired with store_release in inode_switch_wb_work_fn() and
         * ensures that we see the new wb if we see cleared I_WB_SWITCH.
         */
-       *lockedp = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
+       cookie->locked = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
 
-       if (unlikely(*lockedp))
-               xa_lock_irq(&inode->i_mapping->i_pages);
+       if (unlikely(cookie->locked))
+               xa_lock_irqsave(&inode->i_mapping->i_pages, cookie->flags);
 
        /*
         * Protected by either !I_WB_SWITCH + rcu_read_lock() or the i_pages
@@ -383,12 +383,13 @@ unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
 /**
  * unlocked_inode_to_wb_end - end inode wb access transaction
  * @inode: target inode
- * @locked: *@lockedp from unlocked_inode_to_wb_begin()
+ * @cookie: @cookie from unlocked_inode_to_wb_begin()
  */
-static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
+static inline void unlocked_inode_to_wb_end(struct inode *inode,
+                                           struct wb_lock_cookie *cookie)
 {
-       if (unlikely(locked))
-               xa_unlock_irq(&inode->i_mapping->i_pages);
+       if (unlikely(cookie->locked))
+               xa_unlock_irqrestore(&inode->i_mapping->i_pages, cookie->flags);
 
        rcu_read_unlock();
 }
@@ -435,12 +436,13 @@ static inline struct bdi_writeback *inode_to_wb(struct inode *inode)
 }
 
 static inline struct bdi_writeback *
-unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
+unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
 {
        return inode_to_wb(inode);
 }
 
-static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
+static inline void unlocked_inode_to_wb_end(struct inode *inode,
+                                           struct wb_lock_cookie *cookie)
 {
 }
 
index e3986f4b34615fa7c50c6d412976594ebc3a7fdf..ebc34a5686dc7cd0bfc31b7d1220724282f51b0f 100644 (file)
@@ -9,6 +9,9 @@
 struct blk_mq_tags;
 struct blk_flush_queue;
 
+/**
+ * struct blk_mq_hw_ctx - State for a hardware queue facing the hardware block device
+ */
 struct blk_mq_hw_ctx {
        struct {
                spinlock_t              lock;
index 9af3e0f430bcbedd114f40c8be05f91dfe03a2cf..5c4eee04319174a291a6e76378e18c105da87fda 100644 (file)
@@ -605,6 +605,11 @@ struct request_queue {
         * initialized by the low level device driver (e.g. scsi/sd.c).
         * Stacking drivers (device mappers) may or may not initialize
         * these fields.
+        *
+        * Reads of this information must be protected with blk_queue_enter() /
+        * blk_queue_exit(). Modifying this information is only allowed while
+        * no requests are being processed. See also blk_mq_freeze_queue() and
+        * blk_mq_unfreeze_queue().
         */
        unsigned int            nr_zones;
        unsigned long           *seq_zones_bitmap;
@@ -737,6 +742,7 @@ bool blk_queue_flag_test_and_clear(unsigned int flag, struct request_queue *q);
 #define blk_queue_quiesced(q)  test_bit(QUEUE_FLAG_QUIESCED, &(q)->queue_flags)
 #define blk_queue_preempt_only(q)                              \
        test_bit(QUEUE_FLAG_PREEMPT_ONLY, &(q)->queue_flags)
+#define blk_queue_fua(q)       test_bit(QUEUE_FLAG_FUA, &(q)->queue_flags)
 
 extern int blk_set_preempt_only(struct request_queue *q);
 extern void blk_clear_preempt_only(struct request_queue *q);
index 95a7abd0ee9283670a6c3b9c67f9becd98dff0f5..486e65e3db2653002350b6d0ab4137a8d1376d9c 100644 (file)
@@ -339,8 +339,8 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
 void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *progs,
                                struct bpf_prog *old_prog);
 int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
-                            __u32 __user *prog_ids, u32 request_cnt,
-                            __u32 __user *prog_cnt);
+                            u32 *prog_ids, u32 request_cnt,
+                            u32 *prog_cnt);
 int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
                        struct bpf_prog *exclude_prog,
                        struct bpf_prog *include_prog,
index ceb96ecab96e255be42cecc015be8c0e01b4f710..7d98e263e048d988ab77a202b8eb8e81e9194931 100644 (file)
@@ -25,6 +25,9 @@
 #define __SANITIZE_ADDRESS__
 #endif
 
+#undef __no_sanitize_address
+#define __no_sanitize_address __attribute__((no_sanitize("address")))
+
 /* Clang doesn't have a way to turn it off per-function, yet. */
 #ifdef __noretpoline
 #undef __noretpoline
index edfeaba954295a76c1c842253004404365436208..a1a959ba24ffada75e13de61aa570490a988c8d4 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef _LINUX_CORESIGHT_PMU_H
index 0059b99e1f25db0ef52d09bf50e1239e2fbf14e9..477956990f5e3dc703df3154ef06ed3a5e3264d0 100644 (file)
@@ -256,7 +256,9 @@ enum probe_type {
  *             automatically.
  * @pm:                Power management operations of the device which matched
  *             this driver.
- * @coredump:  Called through sysfs to initiate a device coredump.
+ * @coredump:  Called when sysfs entry is written to. The device driver
+ *             is expected to call the dev_coredump API resulting in a
+ *             uevent.
  * @p:         Driver core's private data, no one other than the driver
  *             core can touch this.
  *
@@ -288,7 +290,7 @@ struct device_driver {
        const struct attribute_group **groups;
 
        const struct dev_pm_ops *pm;
-       int (*coredump) (struct device *dev);
+       void (*coredump) (struct device *dev);
 
        struct driver_private *p;
 };
index ebe41811ed34164a9a7000fee9a3a45f55d2480c..b32cd2062f1876585f7ad36d1394a14811b6f3b3 100644 (file)
@@ -310,6 +310,8 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
  *     fields should be ignored (use %__ETHTOOL_LINK_MODE_MASK_NBITS
  *     instead of the latter), any change to them will be overwritten
  *     by kernel. Returns a negative error code or zero.
+ * @get_fecparam: Get the network device Forward Error Correction parameters.
+ * @set_fecparam: Set the network device Forward Error Correction parameters.
  *
  * All operations are optional (i.e. the function pointer may be set
  * to %NULL) and callers must take this into account.  Callers must
index 9f1edb92c97ed00e410911ee9664ac7125e48271..e64c0294f50bf82dd50d447e37a5c77f86eabc26 100644 (file)
@@ -217,12 +217,10 @@ struct fsnotify_mark_connector {
        union { /* Object pointer [lock] */
                struct inode *inode;
                struct vfsmount *mnt;
-       };
-       union {
-               struct hlist_head list;
                /* Used listing heads to free after srcu period expires */
                struct fsnotify_mark_connector *destroy_next;
        };
+       struct hlist_head list;
 };
 
 /*
@@ -248,7 +246,7 @@ struct fsnotify_mark {
        /* Group this mark is for. Set on mark creation, stable until last ref
         * is dropped */
        struct fsnotify_group *group;
-       /* List of marks by group->i_fsnotify_marks. Also reused for queueing
+       /* List of marks by group->marks_list. Also reused for queueing
         * mark into destroy_list when it's waiting for the end of SRCU period
         * before it can be freed. [group->mark_mutex] */
        struct list_head g_list;
index 8da3e1f48195be58641820fa0c5f85a7a6a833e9..26240a22978a4cedf80cad5fa26c026b07ce5aad 100644 (file)
@@ -516,6 +516,12 @@ enum hid_type {
        HID_TYPE_USBNONE
 };
 
+enum hid_battery_status {
+       HID_BATTERY_UNKNOWN = 0,
+       HID_BATTERY_QUERIED,            /* Kernel explicitly queried battery strength */
+       HID_BATTERY_REPORTED,           /* Device sent unsolicited battery strength report */
+};
+
 struct hid_driver;
 struct hid_ll_driver;
 
@@ -558,7 +564,8 @@ struct hid_device {                                                 /* device report descriptor */
        __s32 battery_max;
        __s32 battery_report_type;
        __s32 battery_report_id;
-       bool battery_reported;
+       enum hid_battery_status battery_status;
+       bool battery_avoid_query;
 #endif
 
        unsigned int status;                                            /* see STAT flags above */
index a2656c3ebe81cafaff88dc2329897b4a22d89edd..3892e9c8b2deb7993c11c1ac171375c7ba6e9e09 100644 (file)
@@ -161,9 +161,11 @@ struct hrtimer_clock_base {
 enum  hrtimer_base_type {
        HRTIMER_BASE_MONOTONIC,
        HRTIMER_BASE_REALTIME,
+       HRTIMER_BASE_BOOTTIME,
        HRTIMER_BASE_TAI,
        HRTIMER_BASE_MONOTONIC_SOFT,
        HRTIMER_BASE_REALTIME_SOFT,
+       HRTIMER_BASE_BOOTTIME_SOFT,
        HRTIMER_BASE_TAI_SOFT,
        HRTIMER_MAX_CLOCK_BASES,
 };
index d11f41d5269f4c3882589dab7c06e53d22a4444f..78a5a90b42672314a4e33fe4ee0840850fdb1e06 100644 (file)
@@ -663,7 +663,7 @@ static inline bool skb_vlan_tagged(const struct sk_buff *skb)
  * Returns true if the skb is tagged with multiple vlan headers, regardless
  * of whether it is hardware accelerated or not.
  */
-static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
+static inline bool skb_vlan_tagged_multi(struct sk_buff *skb)
 {
        __be16 protocol = skb->protocol;
 
@@ -673,6 +673,9 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
                if (likely(!eth_type_vlan(protocol)))
                        return false;
 
+               if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
+                       return false;
+
                veh = (struct vlan_ethhdr *)skb->data;
                protocol = veh->h_vlan_encapsulated_proto;
        }
@@ -690,7 +693,7 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
  *
  * Returns features without unsafe ones if the skb has multiple tags.
  */
-static inline netdev_features_t vlan_features_check(const struct sk_buff *skb,
+static inline netdev_features_t vlan_features_check(struct sk_buff *skb,
                                                    netdev_features_t features)
 {
        if (skb_vlan_tagged_multi(skb)) {
index 4754f01c1abbd5197da9b9f1dcd0526b31e155f2..aec44b1d9582cf29bc6c8d3a50829aaee2bf0995 100644 (file)
@@ -186,13 +186,20 @@ static inline bool klp_have_reliable_stack(void)
               IS_ENABLED(CONFIG_HAVE_RELIABLE_STACKTRACE);
 }
 
+typedef int (*klp_shadow_ctor_t)(void *obj,
+                                void *shadow_data,
+                                void *ctor_data);
+typedef void (*klp_shadow_dtor_t)(void *obj, void *shadow_data);
+
 void *klp_shadow_get(void *obj, unsigned long id);
-void *klp_shadow_alloc(void *obj, unsigned long id, void *data,
-                      size_t size, gfp_t gfp_flags);
-void *klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
-                             size_t size, gfp_t gfp_flags);
-void klp_shadow_free(void *obj, unsigned long id);
-void klp_shadow_free_all(unsigned long id);
+void *klp_shadow_alloc(void *obj, unsigned long id,
+                      size_t size, gfp_t gfp_flags,
+                      klp_shadow_ctor_t ctor, void *ctor_data);
+void *klp_shadow_get_or_alloc(void *obj, unsigned long id,
+                             size_t size, gfp_t gfp_flags,
+                             klp_shadow_ctor_t ctor, void *ctor_data);
+void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor);
+void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor);
 
 #else /* !CONFIG_LIVEPATCH */
 
index eb492d47f7171fe4c6a18e2fbbc6f9234085ca5d..8f9c90379732b3a14ad7510ee1dad294f6d7feb9 100644 (file)
 #define        LAN88XX_MMD3_CHIP_ID                    (32877)
 #define        LAN88XX_MMD3_CHIP_REV                   (32878)
 
+/* DSP registers */
+#define PHY_ARDENNES_MMD_DEV_3_PHY_CFG         (0x806A)
+#define PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_      (0x2000)
+#define LAN88XX_EXT_PAGE_ACCESS_TR             (0x52B5)
+#define LAN88XX_EXT_PAGE_TR_CR                 16
+#define LAN88XX_EXT_PAGE_TR_LOW_DATA           17
+#define LAN88XX_EXT_PAGE_TR_HIGH_DATA          18
+
 #endif /* _MICROCHIPPHY_H */
index b63fa457febd8d5d379ffe891e981ea2c8e912c8..3529683f691ef90c10f8ba89211341ceb60a1fe1 100644 (file)
@@ -85,6 +85,7 @@ struct flchip {
        unsigned int write_suspended:1;
        unsigned int erase_suspended:1;
        unsigned long in_progress_block_addr;
+       unsigned long in_progress_block_mask;
 
        struct mutex mutex;
        wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
index 1d356105f25a1680b05a6119fa1d9efba578b6b6..b4c9fda9d8335bd3b20611d9684645dce3f8532c 100644 (file)
@@ -351,10 +351,10 @@ struct earlycon_id {
        char    name[16];
        char    compatible[128];
        int     (*setup)(struct earlycon_device *, const char *options);
-} __aligned(32);
+};
 
-extern const struct earlycon_id __earlycon_table[];
-extern const struct earlycon_id __earlycon_table_end[];
+extern const struct earlycon_id *__earlycon_table[];
+extern const struct earlycon_id *__earlycon_table_end[];
 
 #if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
 #define EARLYCON_USED_OR_UNUSED        __used
@@ -362,12 +362,19 @@ extern const struct earlycon_id __earlycon_table_end[];
 #define EARLYCON_USED_OR_UNUSED        __maybe_unused
 #endif
 
-#define OF_EARLYCON_DECLARE(_name, compat, fn)                         \
-       static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \
-            EARLYCON_USED_OR_UNUSED __section(__earlycon_table)        \
+#define _OF_EARLYCON_DECLARE(_name, compat, fn, unique_id)             \
+       static const struct earlycon_id unique_id                       \
+            EARLYCON_USED_OR_UNUSED __initconst                        \
                = { .name = __stringify(_name),                         \
                    .compatible = compat,                               \
-                   .setup = fn  }
+                   .setup = fn  };                                     \
+       static const struct earlycon_id EARLYCON_USED_OR_UNUSED         \
+               __section(__earlycon_table)                             \
+               * const __PASTE(__p, unique_id) = &unique_id
+
+#define OF_EARLYCON_DECLARE(_name, compat, fn)                         \
+       _OF_EARLYCON_DECLARE(_name, compat, fn,                         \
+                            __UNIQUE_ID(__earlycon_##_name))
 
 #define EARLYCON_DECLARE(_name, fn)    OF_EARLYCON_DECLARE(_name, "", fn)
 
index 388ff2936a8716d6c90f6ced8a7a8193a6957e06..6794490f25b2bd80cfb6fc4c8dec7067e824e100 100644 (file)
@@ -75,6 +75,9 @@ struct shrinker {
 #define SHRINKER_NUMA_AWARE    (1 << 0)
 #define SHRINKER_MEMCG_AWARE   (1 << 1)
 
-extern int register_shrinker(struct shrinker *);
-extern void unregister_shrinker(struct shrinker *);
+extern int prealloc_shrinker(struct shrinker *shrinker);
+extern void register_shrinker_prepared(struct shrinker *shrinker);
+extern int register_shrinker(struct shrinker *shrinker);
+extern void unregister_shrinker(struct shrinker *shrinker);
+extern void free_prealloced_shrinker(struct shrinker *shrinker);
 #endif
index e8f0f852968f1326edb7b261708d5a5cee49f030..c0c5c5b73dc0b0949043881e247a90aff5cf8a03 100644 (file)
@@ -50,9 +50,9 @@ partial_name_hash(unsigned long c, unsigned long prevhash)
  * losing bits).  This also has the property (wanted by the dcache)
  * that the msbits make a good hash table index.
  */
-static inline unsigned long end_name_hash(unsigned long hash)
+static inline unsigned int end_name_hash(unsigned long hash)
 {
-       return __hash_32((unsigned int)hash);
+       return hash_long(hash, 32);
 }
 
 /*
index 0494db3fd9e8b6ee743b846db6f8b3f10c0cb2bf..13770cfe33ad8f7a5d084c1774ac170f6c7a8229 100644 (file)
@@ -62,7 +62,7 @@ struct ts_config
        int                     flags;
 
        /**
-        * get_next_block - fetch next block of data
+        * @get_next_block: fetch next block of data
         * @consumed: number of bytes consumed by the caller
         * @dst: destination buffer
         * @conf: search configuration
@@ -79,7 +79,7 @@ struct ts_config
                                                  struct ts_state *state);
 
        /**
-        * finish - finalize/clean a series of get_next_block() calls
+        * @finish: finalize/clean a series of get_next_block() calls
         * @conf: search configuration
         * @state: search state
         *
index 34f053a150a969bf03805cd56ee7f5487e041642..cf2862bd134a400b99136aaf2ec1357bd79ba3d2 100644 (file)
@@ -43,11 +43,7 @@ enum {
 #define THREAD_ALIGN   THREAD_SIZE
 #endif
 
-#if IS_ENABLED(CONFIG_DEBUG_STACK_USAGE) || IS_ENABLED(CONFIG_DEBUG_KMEMLEAK)
-# define THREADINFO_GFP                (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
-#else
-# define THREADINFO_GFP                (GFP_KERNEL_ACCOUNT)
-#endif
+#define THREADINFO_GFP         (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
 
 /*
  * flag set/clear/test wrappers
index 45bc6b37649294788e1061f8dd626c5609e167b9..53604b087f2c0b24993ea357b42103a8e07a4971 100644 (file)
@@ -60,6 +60,81 @@ struct ti_emif_pm_functions {
        u32 abort_sr;
 } __packed __aligned(8);
 
+static inline void ti_emif_asm_offsets(void)
+{
+       DEFINE(EMIF_SDCFG_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_sdcfg_val));
+       DEFINE(EMIF_TIMING1_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_timing1_val));
+       DEFINE(EMIF_TIMING2_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_timing2_val));
+       DEFINE(EMIF_TIMING3_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_timing3_val));
+       DEFINE(EMIF_REF_CTRL_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ref_ctrl_val));
+       DEFINE(EMIF_ZQCFG_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_zqcfg_val));
+       DEFINE(EMIF_PMCR_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_pmcr_val));
+       DEFINE(EMIF_PMCR_SHDW_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_pmcr_shdw_val));
+       DEFINE(EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_rd_wr_level_ramp_ctrl));
+       DEFINE(EMIF_RD_WR_EXEC_THRESH_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_rd_wr_exec_thresh));
+       DEFINE(EMIF_COS_CONFIG_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_cos_config));
+       DEFINE(EMIF_PRIORITY_TO_COS_MAPPING_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_priority_to_cos_mapping));
+       DEFINE(EMIF_CONNECT_ID_SERV_1_MAP_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_connect_id_serv_1_map));
+       DEFINE(EMIF_CONNECT_ID_SERV_2_MAP_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_connect_id_serv_2_map));
+       DEFINE(EMIF_OCP_CONFIG_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ocp_config_val));
+       DEFINE(EMIF_LPDDR2_NVM_TIM_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim));
+       DEFINE(EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim_shdw));
+       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val));
+       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val_shdw));
+       DEFINE(EMIF_DDR_PHY_CTLR_1_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ddr_phy_ctlr_1));
+       DEFINE(EMIF_EXT_PHY_CTRL_VALS_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ext_phy_ctrl_vals));
+       DEFINE(EMIF_REGS_AMX3_SIZE, sizeof(struct emif_regs_amx3));
+
+       BLANK();
+
+       DEFINE(EMIF_PM_BASE_ADDR_VIRT_OFFSET,
+              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_virt));
+       DEFINE(EMIF_PM_BASE_ADDR_PHYS_OFFSET,
+              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_phys));
+       DEFINE(EMIF_PM_CONFIG_OFFSET,
+              offsetof(struct ti_emif_pm_data, ti_emif_sram_config));
+       DEFINE(EMIF_PM_REGS_VIRT_OFFSET,
+              offsetof(struct ti_emif_pm_data, regs_virt));
+       DEFINE(EMIF_PM_REGS_PHYS_OFFSET,
+              offsetof(struct ti_emif_pm_data, regs_phys));
+       DEFINE(EMIF_PM_DATA_SIZE, sizeof(struct ti_emif_pm_data));
+
+       BLANK();
+
+       DEFINE(EMIF_PM_SAVE_CONTEXT_OFFSET,
+              offsetof(struct ti_emif_pm_functions, save_context));
+       DEFINE(EMIF_PM_RESTORE_CONTEXT_OFFSET,
+              offsetof(struct ti_emif_pm_functions, restore_context));
+       DEFINE(EMIF_PM_ENTER_SR_OFFSET,
+              offsetof(struct ti_emif_pm_functions, enter_sr));
+       DEFINE(EMIF_PM_EXIT_SR_OFFSET,
+              offsetof(struct ti_emif_pm_functions, exit_sr));
+       DEFINE(EMIF_PM_ABORT_SR_OFFSET,
+              offsetof(struct ti_emif_pm_functions, abort_sr));
+       DEFINE(EMIF_PM_FUNCTIONS_SIZE, sizeof(struct ti_emif_pm_functions));
+}
+
 struct gen_pool;
 
 int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst);
index 4b3dca173e8959a307785a1a1459654eadf62838..7acb953298a73118028ae04052fab9249529380f 100644 (file)
@@ -52,7 +52,6 @@ struct tk_read_base {
  * @offs_real:         Offset clock monotonic -> clock realtime
  * @offs_boot:         Offset clock monotonic -> clock boottime
  * @offs_tai:          Offset clock monotonic -> clock tai
- * @time_suspended:    Accumulated suspend time
  * @tai_offset:                The current UTC to TAI offset in seconds
  * @clock_was_set_seq: The sequence number of clock was set events
  * @cs_was_changed_seq:        The sequence number of clocksource change events
@@ -95,7 +94,6 @@ struct timekeeper {
        ktime_t                 offs_real;
        ktime_t                 offs_boot;
        ktime_t                 offs_tai;
-       ktime_t                 time_suspended;
        s32                     tai_offset;
        unsigned int            clock_was_set_seq;
        u8                      cs_was_changed_seq;
index 9737fbec7019bd02b9f6bf0ef9d34e1dc67fdaaa..588a0e4b1ab9336674b2bbc4f1fd0465b4d4a845 100644 (file)
@@ -33,25 +33,20 @@ extern void ktime_get_ts64(struct timespec64 *ts);
 extern time64_t ktime_get_seconds(void);
 extern time64_t __ktime_get_real_seconds(void);
 extern time64_t ktime_get_real_seconds(void);
-extern void ktime_get_active_ts64(struct timespec64 *ts);
 
 extern int __getnstimeofday64(struct timespec64 *tv);
 extern void getnstimeofday64(struct timespec64 *tv);
 extern void getboottime64(struct timespec64 *ts);
 
-#define ktime_get_real_ts64(ts)                getnstimeofday64(ts)
-
-/* Clock BOOTTIME compatibility wrappers */
-static inline void get_monotonic_boottime64(struct timespec64 *ts)
-{
-       ktime_get_ts64(ts);
-}
+#define ktime_get_real_ts64(ts)        getnstimeofday64(ts)
 
 /*
  * ktime_t based interfaces
  */
+
 enum tk_offsets {
        TK_OFFS_REAL,
+       TK_OFFS_BOOT,
        TK_OFFS_TAI,
        TK_OFFS_MAX,
 };
@@ -62,10 +57,6 @@ extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
 extern ktime_t ktime_get_raw(void);
 extern u32 ktime_get_resolution_ns(void);
 
-/* Clock BOOTTIME compatibility wrappers */
-static inline ktime_t ktime_get_boottime(void) { return ktime_get(); }
-static inline u64 ktime_get_boot_ns(void) { return ktime_get(); }
-
 /**
  * ktime_get_real - get the real (wall-) time in ktime_t format
  */
@@ -74,6 +65,17 @@ static inline ktime_t ktime_get_real(void)
        return ktime_get_with_offset(TK_OFFS_REAL);
 }
 
+/**
+ * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
+ *
+ * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
+ * time spent in suspend.
+ */
+static inline ktime_t ktime_get_boottime(void)
+{
+       return ktime_get_with_offset(TK_OFFS_BOOT);
+}
+
 /**
  * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
  */
@@ -100,6 +102,11 @@ static inline u64 ktime_get_real_ns(void)
        return ktime_to_ns(ktime_get_real());
 }
 
+static inline u64 ktime_get_boot_ns(void)
+{
+       return ktime_to_ns(ktime_get_boottime());
+}
+
 static inline u64 ktime_get_tai_ns(void)
 {
        return ktime_to_ns(ktime_get_clocktai());
@@ -112,11 +119,17 @@ static inline u64 ktime_get_raw_ns(void)
 
 extern u64 ktime_get_mono_fast_ns(void);
 extern u64 ktime_get_raw_fast_ns(void);
+extern u64 ktime_get_boot_fast_ns(void);
 extern u64 ktime_get_real_fast_ns(void);
 
 /*
  * timespec64 interfaces utilizing the ktime based ones
  */
+static inline void get_monotonic_boottime64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_boottime());
+}
+
 static inline void timekeeping_clocktai64(struct timespec64 *ts)
 {
        *ts = ktime_to_timespec64(ktime_get_clocktai());
index af4114d5dc1751235fe99fbd70b79ae5cca73ccd..3616b4becb594012cdd6280b10d297ecebb7d04f 100644 (file)
@@ -9,9 +9,6 @@
 extern void do_gettimeofday(struct timeval *tv);
 unsigned long get_seconds(void);
 
-/* does not take xtime_lock */
-struct timespec __current_kernel_time(void);
-
 static inline struct timespec current_kernel_time(void)
 {
        struct timespec64 now = current_kernel_time64();
index 2448f9cc48a3120222d29f8110069c626b428543..7b066fd38248bb48466fa53c0e6462d2af76dc33 100644 (file)
@@ -8,8 +8,6 @@
 #include <linux/debugobjects.h>
 #include <linux/stringify.h>
 
-struct tvec_base;
-
 struct timer_list {
        /*
         * All fields that change during normal runtime grouped to the
index 47f8af22f2168f0376d77068ecbc2df930ae8f79..1dd587ba6d882bb882b44680ec1acebb314c4364 100644 (file)
@@ -701,7 +701,7 @@ extern int tty_unregister_ldisc(int disc);
 extern int tty_set_ldisc(struct tty_struct *tty, int disc);
 extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
 extern void tty_ldisc_release(struct tty_struct *tty);
-extern void tty_ldisc_init(struct tty_struct *tty);
+extern int __must_check tty_ldisc_init(struct tty_struct *tty);
 extern void tty_ldisc_deinit(struct tty_struct *tty);
 extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p,
                                 char *f, int count);
index c71def6b310f3edb0b11ccc485be7d770b919831..a240ed2a0372c20281e03a45fe49dea6a2fd60a3 100644 (file)
@@ -24,24 +24,6 @@ __printf(1, 2) void vbg_debug(const char *fmt, ...);
 #define vbg_debug pr_debug
 #endif
 
-/**
- * Allocate memory for generic request and initialize the request header.
- *
- * Return: the allocated memory
- * @len:               Size of memory block required for the request.
- * @req_type:          The generic request type.
- */
-void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type);
-
-/**
- * Perform a generic request.
- *
- * Return: VBox status code
- * @gdev:              The Guest extension device.
- * @req:               Pointer to the request structure.
- */
-int vbg_req_perform(struct vbg_dev *gdev, void *req);
-
 int vbg_hgcm_connect(struct vbg_dev *gdev,
                     struct vmmdev_hgcm_service_location *loc,
                     u32 *client_id, int *vbox_status);
@@ -52,11 +34,6 @@ int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function,
                  u32 timeout_ms, struct vmmdev_hgcm_function_parameter *parms,
                  u32 parm_count, int *vbox_status);
 
-int vbg_hgcm_call32(
-       struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms,
-       struct vmmdev_hgcm_function_parameter32 *parm32, u32 parm_count,
-       int *vbox_status);
-
 /**
  * Convert a VirtualBox status code to a standard Linux kernel return value.
  * Return: 0 or negative errno value.
index 988c7355bc22753373ab3f543cb922962f4451e7..fa1b5da2804e6041df3b8f47e5ce0c7ddf828a54 100644 (file)
@@ -157,6 +157,9 @@ int virtio_device_freeze(struct virtio_device *dev);
 int virtio_device_restore(struct virtio_device *dev);
 #endif
 
+#define virtio_device_for_each_vq(vdev, vq) \
+       list_for_each_entry(vq, &vdev->vqs, list)
+
 /**
  * virtio_driver - operations for a virtio I/O driver
  * @driver: underlying device driver (populate name and owner).
index 44b9c00f72232c31d3cf478c901e7b164748bb04..e117617e3c347af5eec412ebd8cbb2271de22b56 100644 (file)
@@ -12,7 +12,8 @@
 void *ife_encode(struct sk_buff *skb, u16 metalen);
 void *ife_decode(struct sk_buff *skb, u16 *metalen);
 
-void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 *totlen);
+void *ife_tlv_meta_decode(void *skbdata, const void *ifehdr_end, u16 *attrtype,
+                         u16 *dlen, u16 *totlen);
 int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen,
                        const void *dval);
 
index 5c40f118c0fad6448796579b01acba5f77e1e4fa..df528a6235487d3678ffdccb28facf977a1e7098 100644 (file)
@@ -97,6 +97,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
 
 struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
                          struct proto *prot, int kern);
+void llc_sk_stop_all_timers(struct sock *sk, bool sync);
 void llc_sk_free(struct sock *sk);
 
 void llc_sk_reset(struct sock *sk);
index 04e0679767f633f3ba80c962299914ec7f727957..e03bd9d41fa8fd693fa9bcf88620bc2db887980d 100644 (file)
@@ -11,8 +11,6 @@ struct scsi_sense_hdr;
 extern void scsi_print_command(struct scsi_cmnd *);
 extern size_t __scsi_format_command(char *, size_t,
                                   const unsigned char *, size_t);
-extern void scsi_show_extd_sense(const struct scsi_device *, const char *,
-                                unsigned char, unsigned char);
 extern void scsi_print_sense_hdr(const struct scsi_device *, const char *,
                                 const struct scsi_sense_hdr *);
 extern void scsi_print_sense(const struct scsi_cmnd *);
index 50df5b28d2c9df6eb0cffb217104cdf8ee59e9ed..8ee8991aa099af3a1c9d8435bab12821dfef8928 100644 (file)
@@ -143,13 +143,13 @@ struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
 static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag,
                                        void *data, size_t len)
 {
-       return 0;
+       return -ENOSYS;
 }
 
 static inline int rpi_firmware_property_list(struct rpi_firmware *fw,
                                             void *data, size_t tag_size)
 {
-       return 0;
+       return -ENOSYS;
 }
 
 static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
index ca13a44ae9d44e971a977e489244b831ac83040c..6011a58d3e2086886278b8f42582bfdc52784fd0 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/wait.h>
+#include <linux/nospec.h>
 #include <sound/asound.h>
 
 #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
@@ -148,12 +149,14 @@ int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
 
 static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
-       return id->numid - kctl->id.numid;
+       unsigned int ioff = id->numid - kctl->id.numid;
+       return array_index_nospec(ioff, kctl->count);
 }
 
 static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
-       return id->index - kctl->id.index;
+       unsigned int ioff = id->index - kctl->id.index;
+       return array_index_nospec(ioff, kctl->count);
 }
 
 static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
index bf6f82673492ca252c6537b1bd3817e7987840ef..f8260e5c79ad31d6e825cc796c15f686bcca25ef 100644 (file)
@@ -257,6 +257,33 @@ TRACE_EVENT(ufshcd_command,
        )
 );
 
+TRACE_EVENT(ufshcd_upiu,
+       TP_PROTO(const char *dev_name, const char *str, void *hdr, void *tsf),
+
+       TP_ARGS(dev_name, str, hdr, tsf),
+
+       TP_STRUCT__entry(
+               __string(dev_name, dev_name)
+               __string(str, str)
+               __array(unsigned char, hdr, 12)
+               __array(unsigned char, tsf, 16)
+       ),
+
+       TP_fast_assign(
+               __assign_str(dev_name, dev_name);
+               __assign_str(str, str);
+               memcpy(__entry->hdr, hdr, sizeof(__entry->hdr));
+               memcpy(__entry->tsf, tsf, sizeof(__entry->tsf));
+       ),
+
+       TP_printk(
+               "%s: %s: HDR:%s, CDB:%s",
+               __get_str(str), __get_str(dev_name),
+               __print_hex(__entry->hdr, sizeof(__entry->hdr)),
+               __print_hex(__entry->tsf, sizeof(__entry->tsf))
+       )
+);
+
 #endif /* if !defined(_TRACE_UFS_H) || defined(TRACE_HEADER_MULTI_READ) */
 
 /* This part must be outside protection */
index 1065006c9bf5890abdf99f9a4c444552af5542d1..b02c41e53d5616a3124e16dbec17250654a790b4 100644 (file)
@@ -676,6 +676,13 @@ struct kvm_ioeventfd {
        __u8  pad[36];
 };
 
+#define KVM_X86_DISABLE_EXITS_MWAIT          (1 << 0)
+#define KVM_X86_DISABLE_EXITS_HTL            (1 << 1)
+#define KVM_X86_DISABLE_EXITS_PAUSE          (1 << 2)
+#define KVM_X86_DISABLE_VALID_EXITS          (KVM_X86_DISABLE_EXITS_MWAIT | \
+                                              KVM_X86_DISABLE_EXITS_HTL | \
+                                              KVM_X86_DISABLE_EXITS_PAUSE)
+
 /* for KVM_ENABLE_CAP */
 struct kvm_enable_cap {
        /* in */
index 912b85b52344b31aa405b546b5d1160a61a52df1..b8e288a1f7409012d50e464e7993b96d4c404610 100644 (file)
@@ -650,11 +650,23 @@ struct perf_event_mmap_page {
 #define PERF_RECORD_MISC_COMM_EXEC             (1 << 13)
 #define PERF_RECORD_MISC_SWITCH_OUT            (1 << 13)
 /*
- * Indicates that the content of PERF_SAMPLE_IP points to
- * the actual instruction that triggered the event. See also
- * perf_event_attr::precise_ip.
+ * These PERF_RECORD_MISC_* flags below are safely reused
+ * for the following events:
+ *
+ *   PERF_RECORD_MISC_EXACT_IP           - PERF_RECORD_SAMPLE of precise events
+ *   PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events
+ *
+ *
+ * PERF_RECORD_MISC_EXACT_IP:
+ *   Indicates that the content of PERF_SAMPLE_IP points to
+ *   the actual instruction that triggered the event. See also
+ *   perf_event_attr::precise_ip.
+ *
+ * PERF_RECORD_MISC_SWITCH_OUT_PREEMPT:
+ *   Indicates that thread was preempted in TASK_RUNNING state.
  */
 #define PERF_RECORD_MISC_EXACT_IP              (1 << 14)
+#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT    (1 << 14)
 /*
  * Reserve the last bit to indicate some extended misc field
  */
index c34f4490d025ff6802aca2ef6bd2237906f889b2..26ee91300e3ecbb2d5f8c18db6231343c09944bd 100644 (file)
@@ -35,6 +35,9 @@
 /* Clear the entropy pool and associated counters.  (Superuser only.) */
 #define RNDCLEARPOOL   _IO( 'R', 0x06 )
 
+/* Reseed CRNG.  (Superuser only.) */
+#define RNDRESEEDCRNG  _IO( 'R', 0x07 )
+
 struct rand_pool_info {
        int     entropy_count;
        int     buf_size;
index 0f272818a4d27846ef96881c266d9713bbadb094..6b58371b1f0d5a1405328c5e4c43c15bc9588f9a 100644 (file)
@@ -780,24 +780,6 @@ enum {
        NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
 };
 
-/* proc/sys/net/irda */
-enum {
-       NET_IRDA_DISCOVERY=1,
-       NET_IRDA_DEVNAME=2,
-       NET_IRDA_DEBUG=3,
-       NET_IRDA_FAST_POLL=4,
-       NET_IRDA_DISCOVERY_SLOTS=5,
-       NET_IRDA_DISCOVERY_TIMEOUT=6,
-       NET_IRDA_SLOT_TIMEOUT=7,
-       NET_IRDA_MAX_BAUD_RATE=8,
-       NET_IRDA_MIN_TX_TURN_TIME=9,
-       NET_IRDA_MAX_TX_DATA_SIZE=10,
-       NET_IRDA_MAX_TX_WINDOW=11,
-       NET_IRDA_MAX_NOREPLY_TIME=12,
-       NET_IRDA_WARN_NOREPLY_TIME=13,
-       NET_IRDA_LAP_KEEPALIVE_TIME=14,
-};
-
 
 /* CTL_FS names: */
 enum
index 16a296612ba4b0df2359c67aa9c899bec6f719c6..4c0338ea308a67b3f7dfe179651c7a55322ce6fb 100644 (file)
@@ -73,7 +73,6 @@ struct __kernel_old_timeval {
  */
 #define CLOCK_SGI_CYCLE                        10
 #define CLOCK_TAI                      11
-#define CLOCK_MONOTONIC_ACTIVE         12
 
 #define MAX_CLOCKS                     16
 #define CLOCKS_MASK                    (CLOCK_REALTIME | CLOCK_MONOTONIC)
index 40297a3181ed8244fbb4492b34c0feed55612739..13b8cb563892b7ca66a6268738b452c8428f006c 100644 (file)
@@ -57,6 +57,21 @@ struct virtio_balloon_config {
 #define VIRTIO_BALLOON_S_HTLB_PGFAIL   9  /* Hugetlb page allocation failures */
 #define VIRTIO_BALLOON_S_NR       10
 
+#define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { \
+       VIRTIO_BALLOON_S_NAMES_prefix "swap-in", \
+       VIRTIO_BALLOON_S_NAMES_prefix "swap-out", \
+       VIRTIO_BALLOON_S_NAMES_prefix "major-faults", \
+       VIRTIO_BALLOON_S_NAMES_prefix "minor-faults", \
+       VIRTIO_BALLOON_S_NAMES_prefix "free-memory", \
+       VIRTIO_BALLOON_S_NAMES_prefix "total-memory", \
+       VIRTIO_BALLOON_S_NAMES_prefix "available-memory", \
+       VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", \
+       VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", \
+       VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures" \
+}
+
+#define VIRTIO_BALLOON_S_NAMES VIRTIO_BALLOON_S_NAMES_WITH_PREFIX("")
+
 /*
  * Memory statistics structure.
  * Driver fills an array of these structures and passes to device.
index 5c918276835eb0729c5c5e9ef488e94a5c8afc3e..78bb5d9f8d83f140de11beda1ffbfcb1f5d47a0a 100644 (file)
 #include "ring.h"
 #include "../grant_table.h"
 
+/*
+ ******************************************************************************
+ *                           Protocol version
+ ******************************************************************************
+ */
+#define XENSND_PROTOCOL_VERSION        2
+
 /*
  ******************************************************************************
  *                  Feature and Parameter Negotiation
  *
  * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"
  * /local/domain/1/device/vsnd/0/0/0/event-channel = "15"
+ * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386"
+ * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215"
  *
  *------------------------------ Stream 1, capture ----------------------------
  *
  *
  * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384"
  * /local/domain/1/device/vsnd/0/0/1/event-channel = "13"
+ * /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384"
+ * /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213"
  *
  *------------------------------- PCM device 1 --------------------------------
  *
  *
  * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387"
  * /local/domain/1/device/vsnd/0/1/0/event-channel = "151"
+ * /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387"
+ * /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351"
  *
  *------------------------------- PCM device 2 --------------------------------
  *
  *
  * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389"
  * /local/domain/1/device/vsnd/0/2/0/event-channel = "152"
+ * /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389"
+ * /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452"
  *
  ******************************************************************************
  *                            Backend XenBus Nodes
  *      The Xen grant reference granting permission for the backend to map
  *      a sole page in a single page sized ring buffer.
  *
+ *--------------------- Stream Event Transport Parameters ---------------------
+ *
+ * This communication path is used to deliver asynchronous events from backend
+ * to frontend, set up per stream.
+ *
+ * evt-event-channel
+ *      Values:         <uint32_t>
+ *
+ *      The identifier of the Xen event channel used to signal activity
+ *      in the ring buffer.
+ *
+ * evt-ring-ref
+ *      Values:         <uint32_t>
+ *
+ *      The Xen grant reference granting permission for the backend to map
+ *      a sole page in a single page sized ring buffer.
+ *
  ******************************************************************************
  *                               STATE DIAGRAMS
  ******************************************************************************
 #define XENSND_OP_GET_VOLUME           5
 #define XENSND_OP_MUTE                 6
 #define XENSND_OP_UNMUTE               7
+#define XENSND_OP_TRIGGER              8
+#define XENSND_OP_HW_PARAM_QUERY       9
+
+#define XENSND_OP_TRIGGER_START                0
+#define XENSND_OP_TRIGGER_PAUSE                1
+#define XENSND_OP_TRIGGER_STOP         2
+#define XENSND_OP_TRIGGER_RESUME       3
+
+/*
+ ******************************************************************************
+ *                                 EVENT CODES
+ ******************************************************************************
+ */
+#define XENSND_EVT_CUR_POS             0
 
 /*
  ******************************************************************************
 #define XENSND_FIELD_VCARD_LONG_NAME   "long-name"
 #define XENSND_FIELD_RING_REF          "ring-ref"
 #define XENSND_FIELD_EVT_CHNL          "event-channel"
+#define XENSND_FIELD_EVT_RING_REF      "evt-ring-ref"
+#define XENSND_FIELD_EVT_EVT_CHNL      "evt-event-channel"
 #define XENSND_FIELD_DEVICE_NAME       "name"
 #define XENSND_FIELD_TYPE              "type"
 #define XENSND_FIELD_STREAM_UNIQUE_ID  "unique-id"
  *
  *---------------------------------- Requests ---------------------------------
  *
- * All request packets have the same length (32 octets)
+ * All request packets have the same length (64 octets)
  * All request packets have common header:
  *         0                1                 2               3        octet
  * +----------------+----------------+----------------+----------------+
  * +----------------+----------------+----------------+----------------+
  * |                           gref_directory                          | 24
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 28
+ * |                             period_sz                             | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * pcm_rate - uint32_t, stream data rate, Hz
  * pcm_channels - uint8_t, number of channels of this stream,
  *   [channels-min; channels-max]
  * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * period_sz - uint32_t, event period size, octets
+ *   This is the requested value of the period at which frontend would
+ *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
+ *   stream position advances during playback/capture.
+ *   It shows how many octets are expected to be played/captured before
+ *   sending such an event.
+ *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
+ *
  * gref_directory - grant_ref_t, a reference to the first shared page
  *   describing shared buffer references. At least one page exists. If shared
  *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
@@ -585,6 +643,7 @@ struct xensnd_open_req {
        uint16_t reserved;
        uint32_t buffer_sz;
        grant_ref_t gref_directory;
+       uint32_t period_sz;
 };
 
 /*
@@ -632,7 +691,7 @@ struct xensnd_page_directory {
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * Request read/write - used for read (for capture) or write (for playback):
@@ -650,7 +709,7 @@ struct xensnd_page_directory {
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write
@@ -673,9 +732,11 @@ struct xensnd_rw_req {
  * +----------------+----------------+----------------+----------------+
  * |                              length                               | 16
  * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * operation - XENSND_OP_SET_VOLUME for volume set
@@ -713,9 +774,11 @@ struct xensnd_rw_req {
  * +----------------+----------------+----------------+----------------+
  * |                              length                               | 16
  * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute
@@ -743,32 +806,213 @@ struct xensnd_rw_req {
  *
  * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME,
  * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE.
+ *
+ * Request stream running state change - trigger PCM stream running state
+ * to start, stop, pause or resume:
+ *
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |   _OP_TRIGGER  |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      type      |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, XENSND_OP_TRIGGER_XXX value
  */
 
+struct xensnd_trigger_req {
+       uint8_t type;
+};
+
 /*
- *---------------------------------- Responses --------------------------------
+ * Request stream parameter ranges: request intervals and
+ *   masks of supported ranges for stream configuration values.
  *
- * All response packets have the same length (32 octets)
+ *   Sound device configuration for a particular stream is a limited subset
+ *   of the multidimensional configuration available on XenStore, e.g.
+ *   once the frame rate has been selected there is a limited supported range
+ *   for sample rates becomes available (which might be the same set configured
+ *   on XenStore or less). For example, selecting 96kHz sample rate may limit
+ *   number of channels available for such configuration from 4 to 2, etc.
+ *   Thus, each call to XENSND_OP_HW_PARAM_QUERY may reduce configuration
+ *   space making it possible to iteratively get the final stream configuration,
+ *   used in XENSND_OP_OPEN request.
+ *
+ *   See response format for this request.
  *
- * Response for all requests:
  *         0                1                 2               3        octet
  * +----------------+----------------+----------------+----------------+
- * |               id                |    operation   |    reserved    | 4
+ * |               id                | _HW_PARAM_QUERY|    reserved    | 4
  * +----------------+----------------+----------------+----------------+
- * |                              status                               | 8
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask low 32-bit                       | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask high 32-bit                      | 16
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 12
+ * |                              min rate                             | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                              max rate                             | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                            min channels                           | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                            max channels                           | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                         min buffer frames                         | 36
+ * +----------------+----------------+----------------+----------------+
+ * |                         max buffer frames                         | 40
+ * +----------------+----------------+----------------+----------------+
+ * |                         min period frames                         | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                         max period frames                         | 48
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 52
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * formats - uint64_t, bit mask representing values of the parameter
+ *     made as bitwise OR of (1 << XENSND_PCM_FORMAT_XXX) values
+ *
+ * For interval parameters:
+ *   min - uint32_t, minimum value of the parameter
+ *   max - uint32_t, maximum value of the parameter
+ *
+ * Frame is defined as a product of the number of channels by the
+ * number of octets per one sample.
+ */
+
+struct xensnd_query_hw_param {
+       uint64_t formats;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } rates;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } channels;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } buffer;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } period;
+};
+
+/*
+ *---------------------------------- Responses --------------------------------
+ *
+ * All response packets have the same length (64 octets)
+ *
+ * All response packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
  * +----------------+----------------+----------------+----------------+
  *
  * id - uint16_t, copied from the request
  * operation - uint8_t, XENSND_OP_* - copied from request
  * status - int32_t, response status, zero on success and -XEN_EXX on failure
+ *
+ *
+ * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask low 32-bit                       | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask high 32-bit                      | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                              min rate                             | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                              max rate                             | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                            min channels                           | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                            max channels                           | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                         min buffer frames                         | 36
+ * +----------------+----------------+----------------+----------------+
+ * |                         max buffer frames                         | 40
+ * +----------------+----------------+----------------+----------------+
+ * |                         min period frames                         | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                         max period frames                         | 48
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 52
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Meaning of the values in this response is the same as for
+ * XENSND_OP_HW_PARAM_QUERY request.
+ */
+
+/*
+ *----------------------------------- Events ----------------------------------
+ *
+ * Events are sent via shared page allocated by the front and propagated by
+ *   evt-event-channel/evt-ring-ref XenStore entries
+ * All event packets have the same length (64 octets)
+ * All event packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |      type      |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * id - uint16_t, event id, may be used by front
+ * type - uint8_t, type of the event
+ *
+ *
+ * Current stream position - event from back to front when stream's
+ *   playback/capture position has advanced:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |   _EVT_CUR_POS |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                         position low 32-bit                       | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                         position high 32-bit                      | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * position - current value of stream's playback/capture position, octets
+ *
  */
 
+struct xensnd_cur_pos_evt {
+       uint64_t position;
+};
+
 struct xensnd_req {
        uint16_t id;
        uint8_t operation;
@@ -776,7 +1020,9 @@ struct xensnd_req {
        union {
                struct xensnd_open_req open;
                struct xensnd_rw_req rw;
-               uint8_t reserved[24];
+               struct xensnd_trigger_req trigger;
+               struct xensnd_query_hw_param hw_param;
+               uint8_t reserved[56];
        } op;
 };
 
@@ -785,9 +1031,53 @@ struct xensnd_resp {
        uint8_t operation;
        uint8_t reserved;
        int32_t status;
-       uint8_t reserved1[24];
+       union {
+               struct xensnd_query_hw_param hw_param;
+               uint8_t reserved1[56];
+       } resp;
+};
+
+struct xensnd_evt {
+       uint16_t id;
+       uint8_t type;
+       uint8_t reserved[5];
+       union {
+               struct xensnd_cur_pos_evt cur_pos;
+               uint8_t reserved[56];
+       } op;
 };
 
 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp);
 
+/*
+ ******************************************************************************
+ *                        Back to front events delivery
+ ******************************************************************************
+ * In order to deliver asynchronous events from back to front a shared page is
+ * allocated by front and its granted reference propagated to back via
+ * XenStore entries (evt-ring-ref/evt-event-channel).
+ * This page has a common header used by both front and back to synchronize
+ * access and control event's ring buffer, while back being a producer of the
+ * events and front being a consumer. The rest of the page after the header
+ * is used for event packets.
+ *
+ * Upon reception of an event(s) front may confirm its reception
+ * for either each event, group of events or none.
+ */
+
+struct xensnd_event_page {
+       uint32_t in_cons;
+       uint32_t in_prod;
+       uint8_t reserved[56];
+};
+
+#define XENSND_EVENT_PAGE_SIZE XEN_PAGE_SIZE
+#define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page))
+#define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS)
+#define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt))
+#define XENSND_IN_RING(page) \
+       ((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS))
+#define XENSND_IN_RING_REF(page, idx) \
+       (XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN])
+
 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */
index d315b393abdd0f7dfa67abd706e0f973c3ef2c5a..ba03ec39efb399846c375c1fcf2b93dfd2fd8a1d 100644 (file)
@@ -1572,13 +1572,32 @@ int bpf_prog_array_length(struct bpf_prog_array __rcu *progs)
        return cnt;
 }
 
+static bool bpf_prog_array_copy_core(struct bpf_prog **prog,
+                                    u32 *prog_ids,
+                                    u32 request_cnt)
+{
+       int i = 0;
+
+       for (; *prog; prog++) {
+               if (*prog == &dummy_bpf_prog.prog)
+                       continue;
+               prog_ids[i] = (*prog)->aux->id;
+               if (++i == request_cnt) {
+                       prog++;
+                       break;
+               }
+       }
+
+       return !!(*prog);
+}
+
 int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
                                __u32 __user *prog_ids, u32 cnt)
 {
        struct bpf_prog **prog;
        unsigned long err = 0;
-       u32 i = 0, *ids;
        bool nospc;
+       u32 *ids;
 
        /* users of this function are doing:
         * cnt = bpf_prog_array_length();
@@ -1595,16 +1614,7 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
                return -ENOMEM;
        rcu_read_lock();
        prog = rcu_dereference(progs)->progs;
-       for (; *prog; prog++) {
-               if (*prog == &dummy_bpf_prog.prog)
-                       continue;
-               ids[i] = (*prog)->aux->id;
-               if (++i == cnt) {
-                       prog++;
-                       break;
-               }
-       }
-       nospc = !!(*prog);
+       nospc = bpf_prog_array_copy_core(prog, ids, cnt);
        rcu_read_unlock();
        err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
        kfree(ids);
@@ -1683,22 +1693,25 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
 }
 
 int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
-                            __u32 __user *prog_ids, u32 request_cnt,
-                            __u32 __user *prog_cnt)
+                            u32 *prog_ids, u32 request_cnt,
+                            u32 *prog_cnt)
 {
+       struct bpf_prog **prog;
        u32 cnt = 0;
 
        if (array)
                cnt = bpf_prog_array_length(array);
 
-       if (copy_to_user(prog_cnt, &cnt, sizeof(cnt)))
-               return -EFAULT;
+       *prog_cnt = cnt;
 
        /* return early if user requested only program count or nothing to copy */
        if (!request_cnt || !cnt)
                return 0;
 
-       return bpf_prog_array_copy_to_user(array, prog_ids, request_cnt);
+       /* this function is called under trace/bpf_trace.c: bpf_event_mutex */
+       prog = rcu_dereference_check(array, 1)->progs;
+       return bpf_prog_array_copy_core(prog, prog_ids, request_cnt) ? -ENOSPC
+                                                                    : 0;
 }
 
 static void bpf_prog_free_deferred(struct work_struct *work)
index 8dd9210d7db7851da0eb79b950803fedff9d89f3..a3b21385e9476298eb0b33df7dceb242a7d1e104 100644 (file)
@@ -1442,9 +1442,6 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
            attr->value_size != 4 || attr->map_flags & ~SOCK_CREATE_FLAG_MASK)
                return ERR_PTR(-EINVAL);
 
-       if (attr->value_size > KMALLOC_MAX_SIZE)
-               return ERR_PTR(-E2BIG);
-
        err = bpf_tcp_ulp_register();
        if (err && err != -EEXIST)
                return ERR_PTR(err);
index 772a43fea825c498156c4972c66ee81686abecbe..c187aa3df3c8b789c23cceaf5214bc033fa3e2c9 100644 (file)
@@ -119,23 +119,20 @@ int get_callchain_buffers(int event_max_stack)
                goto exit;
        }
 
-       if (count > 1) {
-               /* If the allocation failed, give up */
-               if (!callchain_cpus_entries)
-                       err = -ENOMEM;
-               /*
-                * If requesting per event more than the global cap,
-                * return a different error to help userspace figure
-                * this out.
-                *
-                * And also do it here so that we have &callchain_mutex held.
-                */
-               if (event_max_stack > sysctl_perf_event_max_stack)
-                       err = -EOVERFLOW;
+       /*
+        * If requesting per event more than the global cap,
+        * return a different error to help userspace figure
+        * this out.
+        *
+        * And also do it here so that we have &callchain_mutex held.
+        */
+       if (event_max_stack > sysctl_perf_event_max_stack) {
+               err = -EOVERFLOW;
                goto exit;
        }
 
-       err = alloc_callchain_buffers();
+       if (count == 1)
+               err = alloc_callchain_buffers();
 exit:
        if (err)
                atomic_dec(&nr_callchain_events);
index 2d5fe26551f8775f2e537c667a12345c8c8a8e0d..67612ce359adc45efe1a721ced1d7c4a78aff75d 100644 (file)
@@ -7587,6 +7587,10 @@ static void perf_event_switch(struct task_struct *task,
                },
        };
 
+       if (!sched_in && task->state == TASK_RUNNING)
+               switch_event.event_id.header.misc |=
+                               PERF_RECORD_MISC_SWITCH_OUT_PREEMPT;
+
        perf_iterate_sb(perf_event_switch_output,
                       &switch_event,
                       NULL);
@@ -10205,9 +10209,9 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
                 * __u16 sample size limit.
                 */
                if (attr->sample_stack_user >= USHRT_MAX)
-                       ret = -EINVAL;
+                       return -EINVAL;
                else if (!IS_ALIGNED(attr->sample_stack_user, sizeof(u64)))
-                       ret = -EINVAL;
+                       return -EINVAL;
        }
 
        if (!attr->sample_max_stack)
index 242c8c93d285d08a50b484b8e5e78d43dce5bbd4..a5d21c42acfc8ca2d0e14a0969c9cdc9222fb42d 100644 (file)
@@ -216,10 +216,9 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
                if (!s)
                        continue;
 
-#ifdef CONFIG_DEBUG_KMEMLEAK
                /* Clear stale pointers from reused stack. */
                memset(s->addr, 0, THREAD_SIZE);
-#endif
+
                tsk->stack_vm_area = s;
                return s->addr;
        }
index fdac27588d60a1f7dd8ed0525dc0c643ea0f829f..83958c8144395b64e5e8e3a7e603ff9402175a9c 100644 (file)
@@ -113,8 +113,10 @@ void *klp_shadow_get(void *obj, unsigned long id)
 }
 EXPORT_SYMBOL_GPL(klp_shadow_get);
 
-static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
-                      size_t size, gfp_t gfp_flags, bool warn_on_exist)
+static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id,
+                                      size_t size, gfp_t gfp_flags,
+                                      klp_shadow_ctor_t ctor, void *ctor_data,
+                                      bool warn_on_exist)
 {
        struct klp_shadow *new_shadow;
        void *shadow_data;
@@ -125,18 +127,15 @@ static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
        if (shadow_data)
                goto exists;
 
-       /* Allocate a new shadow variable for use inside the lock below */
+       /*
+        * Allocate a new shadow variable.  Fill it with zeroes by default.
+        * More complex setting can be done by @ctor function.  But it is
+        * called only when the buffer is really used (under klp_shadow_lock).
+        */
        new_shadow = kzalloc(size + sizeof(*new_shadow), gfp_flags);
        if (!new_shadow)
                return NULL;
 
-       new_shadow->obj = obj;
-       new_shadow->id = id;
-
-       /* Initialize the shadow variable if data provided */
-       if (data)
-               memcpy(new_shadow->data, data, size);
-
        /* Look for <obj, id> again under the lock */
        spin_lock_irqsave(&klp_shadow_lock, flags);
        shadow_data = klp_shadow_get(obj, id);
@@ -150,6 +149,22 @@ static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
                goto exists;
        }
 
+       new_shadow->obj = obj;
+       new_shadow->id = id;
+
+       if (ctor) {
+               int err;
+
+               err = ctor(obj, new_shadow->data, ctor_data);
+               if (err) {
+                       spin_unlock_irqrestore(&klp_shadow_lock, flags);
+                       kfree(new_shadow);
+                       pr_err("Failed to construct shadow variable <%p, %lx> (%d)\n",
+                              obj, id, err);
+                       return NULL;
+               }
+       }
+
        /* No <obj, id> found, so attach the newly allocated one */
        hash_add_rcu(klp_shadow_hash, &new_shadow->node,
                     (unsigned long)new_shadow->obj);
@@ -170,26 +185,32 @@ exists:
  * klp_shadow_alloc() - allocate and add a new shadow variable
  * @obj:       pointer to parent object
  * @id:                data identifier
- * @data:      pointer to data to attach to parent
  * @size:      size of attached data
  * @gfp_flags: GFP mask for allocation
+ * @ctor:      custom constructor to initialize the shadow data (optional)
+ * @ctor_data: pointer to any data needed by @ctor (optional)
+ *
+ * Allocates @size bytes for new shadow variable data using @gfp_flags.
+ * The data are zeroed by default.  They are further initialized by @ctor
+ * function if it is not NULL.  The new shadow variable is then added
+ * to the global hashtable.
  *
- * Allocates @size bytes for new shadow variable data using @gfp_flags
- * and copies @size bytes from @data into the new shadow variable's own
- * data space.  If @data is NULL, @size bytes are still allocated, but
- * no copy is performed.  The new shadow variable is then added to the
- * global hashtable.
+ * If an existing <obj, id> shadow variable can be found, this routine will
+ * issue a WARN, exit early and return NULL.
  *
- * If an existing <obj, id> shadow variable can be found, this routine
- * will issue a WARN, exit early and return NULL.
+ * This function guarantees that the constructor function is called only when
+ * the variable did not exist before.  The cost is that @ctor is called
+ * in atomic context under a spin lock.
  *
  * Return: the shadow variable data element, NULL on duplicate or
  * failure.
  */
-void *klp_shadow_alloc(void *obj, unsigned long id, void *data,
-                      size_t size, gfp_t gfp_flags)
+void *klp_shadow_alloc(void *obj, unsigned long id,
+                      size_t size, gfp_t gfp_flags,
+                      klp_shadow_ctor_t ctor, void *ctor_data)
 {
-       return __klp_shadow_get_or_alloc(obj, id, data, size, gfp_flags, true);
+       return __klp_shadow_get_or_alloc(obj, id, size, gfp_flags,
+                                        ctor, ctor_data, true);
 }
 EXPORT_SYMBOL_GPL(klp_shadow_alloc);
 
@@ -197,37 +218,51 @@ EXPORT_SYMBOL_GPL(klp_shadow_alloc);
  * klp_shadow_get_or_alloc() - get existing or allocate a new shadow variable
  * @obj:       pointer to parent object
  * @id:                data identifier
- * @data:      pointer to data to attach to parent
  * @size:      size of attached data
  * @gfp_flags: GFP mask for allocation
+ * @ctor:      custom constructor to initialize the shadow data (optional)
+ * @ctor_data: pointer to any data needed by @ctor (optional)
  *
  * Returns a pointer to existing shadow data if an <obj, id> shadow
  * variable is already present.  Otherwise, it creates a new shadow
  * variable like klp_shadow_alloc().
  *
- * This function guarantees that only one shadow variable exists with
- * the given @id for the given @obj.  It also guarantees that the shadow
- * variable will be initialized by the given @data only when it did not
- * exist before.
+ * This function guarantees that only one shadow variable exists with the given
+ * @id for the given @obj.  It also guarantees that the constructor function
+ * will be called only when the variable did not exist before.  The cost is
+ * that @ctor is called in atomic context under a spin lock.
  *
  * Return: the shadow variable data element, NULL on failure.
  */
-void *klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
-                              size_t size, gfp_t gfp_flags)
+void *klp_shadow_get_or_alloc(void *obj, unsigned long id,
+                             size_t size, gfp_t gfp_flags,
+                             klp_shadow_ctor_t ctor, void *ctor_data)
 {
-       return __klp_shadow_get_or_alloc(obj, id, data, size, gfp_flags, false);
+       return __klp_shadow_get_or_alloc(obj, id, size, gfp_flags,
+                                        ctor, ctor_data, false);
 }
 EXPORT_SYMBOL_GPL(klp_shadow_get_or_alloc);
 
+static void klp_shadow_free_struct(struct klp_shadow *shadow,
+                                  klp_shadow_dtor_t dtor)
+{
+       hash_del_rcu(&shadow->node);
+       if (dtor)
+               dtor(shadow->obj, shadow->data);
+       kfree_rcu(shadow, rcu_head);
+}
+
 /**
  * klp_shadow_free() - detach and free a <obj, id> shadow variable
  * @obj:       pointer to parent object
  * @id:                data identifier
+ * @dtor:      custom callback that can be used to unregister the variable
+ *             and/or free data that the shadow variable points to (optional)
  *
  * This function releases the memory for this <obj, id> shadow variable
  * instance, callers should stop referencing it accordingly.
  */
-void klp_shadow_free(void *obj, unsigned long id)
+void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
 {
        struct klp_shadow *shadow;
        unsigned long flags;
@@ -239,8 +274,7 @@ void klp_shadow_free(void *obj, unsigned long id)
                               (unsigned long)obj) {
 
                if (klp_shadow_match(shadow, obj, id)) {
-                       hash_del_rcu(&shadow->node);
-                       kfree_rcu(shadow, rcu_head);
+                       klp_shadow_free_struct(shadow, dtor);
                        break;
                }
        }
@@ -252,11 +286,13 @@ EXPORT_SYMBOL_GPL(klp_shadow_free);
 /**
  * klp_shadow_free_all() - detach and free all <*, id> shadow variables
  * @id:                data identifier
+ * @dtor:      custom callback that can be used to unregister the variable
+ *             and/or free data that the shadow variable points to (optional)
  *
  * This function releases the memory for all <*, id> shadow variable
  * instances, callers should stop referencing them accordingly.
  */
-void klp_shadow_free_all(unsigned long id)
+void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
 {
        struct klp_shadow *shadow;
        unsigned long flags;
@@ -266,10 +302,8 @@ void klp_shadow_free_all(unsigned long id)
 
        /* Delete all <*, id> from hash */
        hash_for_each(klp_shadow_hash, i, shadow, node) {
-               if (klp_shadow_match(shadow, shadow->obj, id)) {
-                       hash_del_rcu(&shadow->node);
-                       kfree_rcu(shadow, rcu_head);
-               }
+               if (klp_shadow_match(shadow, shadow->obj, id))
+                       klp_shadow_free_struct(shadow, dtor);
        }
 
        spin_unlock_irqrestore(&klp_shadow_lock, flags);
index a6e43a5806a11391b6606b42cc972b13f9eb3828..ce8066b881782f9db47c7fc85d8659e1b9cfe9ac 100644 (file)
@@ -1472,7 +1472,8 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
 {
        struct module_sect_attr *sattr =
                container_of(mattr, struct module_sect_attr, mattr);
-       return sprintf(buf, "0x%pK\n", (void *)sattr->address);
+       return sprintf(buf, "0x%px\n", kptr_restrict < 2 ?
+                      (void *)sattr->address : NULL);
 }
 
 static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
index e8c0dab4fd653a84d316c458a1db767995b02b47..07148b4974516cec45b934e5ed5881e1554e7af0 100644 (file)
@@ -704,24 +704,6 @@ static const struct bin_table bin_net_netfilter_table[] = {
        {}
 };
 
-static const struct bin_table bin_net_irda_table[] = {
-       { CTL_INT,      NET_IRDA_DISCOVERY,             "discovery" },
-       { CTL_STR,      NET_IRDA_DEVNAME,               "devname" },
-       { CTL_INT,      NET_IRDA_DEBUG,                 "debug" },
-       { CTL_INT,      NET_IRDA_FAST_POLL,             "fast_poll_increase" },
-       { CTL_INT,      NET_IRDA_DISCOVERY_SLOTS,       "discovery_slots" },
-       { CTL_INT,      NET_IRDA_DISCOVERY_TIMEOUT,     "discovery_timeout" },
-       { CTL_INT,      NET_IRDA_SLOT_TIMEOUT,          "slot_timeout" },
-       { CTL_INT,      NET_IRDA_MAX_BAUD_RATE,         "max_baud_rate" },
-       { CTL_INT,      NET_IRDA_MIN_TX_TURN_TIME,      "min_tx_turn_time" },
-       { CTL_INT,      NET_IRDA_MAX_TX_DATA_SIZE,      "max_tx_data_size" },
-       { CTL_INT,      NET_IRDA_MAX_TX_WINDOW,         "max_tx_window" },
-       { CTL_INT,      NET_IRDA_MAX_NOREPLY_TIME,      "max_noreply_time" },
-       { CTL_INT,      NET_IRDA_WARN_NOREPLY_TIME,     "warn_noreply_time" },
-       { CTL_INT,      NET_IRDA_LAP_KEEPALIVE_TIME,    "lap_keepalive_time" },
-       {}
-};
-
 static const struct bin_table bin_net_table[] = {
        { CTL_DIR,      NET_CORE,               "core",         bin_net_core_table },
        /* NET_ETHER not used */
@@ -743,7 +725,7 @@ static const struct bin_table bin_net_table[] = {
        { CTL_DIR,      NET_LLC,                "llc",          bin_net_llc_table },
        { CTL_DIR,      NET_NETFILTER,          "netfilter",    bin_net_netfilter_table },
        /* NET_DCCP "dccp" no longer used */
-       { CTL_DIR,      NET_IRDA,               "irda",         bin_net_irda_table },
+       /* NET_IRDA "irda" no longer used */
        { CTL_INT,      2089,                   "nf_conntrack_max" },
        {}
 };
index eda1210ce50f88dd88a53ab9fafbfeef5da021ca..14e858753d7689d96392402ebce61e0116574efa 100644 (file)
@@ -90,6 +90,11 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
                        .clockid = CLOCK_REALTIME,
                        .get_time = &ktime_get_real,
                },
+               {
+                       .index = HRTIMER_BASE_BOOTTIME,
+                       .clockid = CLOCK_BOOTTIME,
+                       .get_time = &ktime_get_boottime,
+               },
                {
                        .index = HRTIMER_BASE_TAI,
                        .clockid = CLOCK_TAI,
@@ -105,6 +110,11 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
                        .clockid = CLOCK_REALTIME,
                        .get_time = &ktime_get_real,
                },
+               {
+                       .index = HRTIMER_BASE_BOOTTIME_SOFT,
+                       .clockid = CLOCK_BOOTTIME,
+                       .get_time = &ktime_get_boottime,
+               },
                {
                        .index = HRTIMER_BASE_TAI_SOFT,
                        .clockid = CLOCK_TAI,
@@ -119,7 +129,7 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
 
        [CLOCK_REALTIME]        = HRTIMER_BASE_REALTIME,
        [CLOCK_MONOTONIC]       = HRTIMER_BASE_MONOTONIC,
-       [CLOCK_BOOTTIME]        = HRTIMER_BASE_MONOTONIC,
+       [CLOCK_BOOTTIME]        = HRTIMER_BASE_BOOTTIME,
        [CLOCK_TAI]             = HRTIMER_BASE_TAI,
 };
 
@@ -571,12 +581,14 @@ __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, unsigned int active_
 static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)
 {
        ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset;
+       ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset;
        ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset;
 
        ktime_t now = ktime_get_update_offsets_now(&base->clock_was_set_seq,
-                                                  offs_real, offs_tai);
+                                           offs_real, offs_boot, offs_tai);
 
        base->clock_base[HRTIMER_BASE_REALTIME_SOFT].offset = *offs_real;
+       base->clock_base[HRTIMER_BASE_BOOTTIME_SOFT].offset = *offs_boot;
        base->clock_base[HRTIMER_BASE_TAI_SOFT].offset = *offs_tai;
 
        return now;
index 2541bd89f20eb95f96d435d21f4eb7c4d1a0cda6..5a6251ac6f7acd183c35a51d9d55fb680fda64dd 100644 (file)
@@ -1205,10 +1205,12 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
                           u64 *newval, u64 *oldval)
 {
        u64 now;
+       int ret;
 
        WARN_ON_ONCE(clock_idx == CPUCLOCK_SCHED);
+       ret = cpu_timer_sample_group(clock_idx, tsk, &now);
 
-       if (oldval && cpu_timer_sample_group(clock_idx, tsk, &now) != -EINVAL) {
+       if (oldval && ret != -EINVAL) {
                /*
                 * We are setting itimer. The *oldval is absolute and we update
                 * it to be relative, *newval argument is relative and we update
index e0dbae98db9d9b11cbcfa6695c850ad8f0c27b87..69a937c3cd81260e8a83942ea0d21750c86fa5be 100644 (file)
@@ -83,8 +83,6 @@ int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
        case CLOCK_BOOTTIME:
                get_monotonic_boottime64(tp);
                break;
-       case CLOCK_MONOTONIC_ACTIVE:
-               ktime_get_active_ts64(tp);
        default:
                return -EINVAL;
        }
index b6899b5060bd8450a20ab8b90b626ddf8327bec7..10b7186d063830b9e45a84146ed243a9f0e80b07 100644 (file)
@@ -252,16 +252,15 @@ static int posix_get_coarse_res(const clockid_t which_clock, struct timespec64 *
        return 0;
 }
 
-static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
+static int posix_get_boottime(const clockid_t which_clock, struct timespec64 *tp)
 {
-       timekeeping_clocktai64(tp);
+       get_monotonic_boottime64(tp);
        return 0;
 }
 
-static int posix_get_monotonic_active(clockid_t which_clock,
-                                     struct timespec64 *tp)
+static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
 {
-       ktime_get_active_ts64(tp);
+       timekeeping_clocktai64(tp);
        return 0;
 }
 
@@ -1317,9 +1316,19 @@ static const struct k_clock clock_tai = {
        .timer_arm              = common_hrtimer_arm,
 };
 
-static const struct k_clock clock_monotonic_active = {
+static const struct k_clock clock_boottime = {
        .clock_getres           = posix_get_hrtimer_res,
-       .clock_get              = posix_get_monotonic_active,
+       .clock_get              = posix_get_boottime,
+       .nsleep                 = common_nsleep,
+       .timer_create           = common_timer_create,
+       .timer_set              = common_timer_set,
+       .timer_get              = common_timer_get,
+       .timer_del              = common_timer_del,
+       .timer_rearm            = common_hrtimer_rearm,
+       .timer_forward          = common_hrtimer_forward,
+       .timer_remaining        = common_hrtimer_remaining,
+       .timer_try_to_cancel    = common_hrtimer_try_to_cancel,
+       .timer_arm              = common_hrtimer_arm,
 };
 
 static const struct k_clock * const posix_clocks[] = {
@@ -1330,11 +1339,10 @@ static const struct k_clock * const posix_clocks[] = {
        [CLOCK_MONOTONIC_RAW]           = &clock_monotonic_raw,
        [CLOCK_REALTIME_COARSE]         = &clock_realtime_coarse,
        [CLOCK_MONOTONIC_COARSE]        = &clock_monotonic_coarse,
-       [CLOCK_BOOTTIME]                = &clock_monotonic,
+       [CLOCK_BOOTTIME]                = &clock_boottime,
        [CLOCK_REALTIME_ALARM]          = &alarm_clock,
        [CLOCK_BOOTTIME_ALARM]          = &alarm_clock,
        [CLOCK_TAI]                     = &clock_tai,
-       [CLOCK_MONOTONIC_ACTIVE]        = &clock_monotonic_active,
 };
 
 static const struct k_clock *clockid_to_kclock(const clockid_t id)
index 099572ca4a8f239a54d88f37ce4ad1418c8aa483..49edc1c4f3e645894f839c40489ab81594a02398 100644 (file)
@@ -419,19 +419,6 @@ void tick_suspend_local(void)
        clockevents_shutdown(td->evtdev);
 }
 
-static void tick_forward_next_period(void)
-{
-       ktime_t delta, now = ktime_get();
-       u64 n;
-
-       delta = ktime_sub(now, tick_next_period);
-       n = ktime_divns(delta, tick_period);
-       tick_next_period += n * tick_period;
-       if (tick_next_period < now)
-               tick_next_period += tick_period;
-       tick_sched_forward_next_period();
-}
-
 /**
  * tick_resume_local - Resume the local tick device
  *
@@ -444,8 +431,6 @@ void tick_resume_local(void)
        struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
        bool broadcast = tick_resume_check_broadcast();
 
-       tick_forward_next_period();
-
        clockevents_tick_resume(td->evtdev);
        if (!broadcast) {
                if (td->mode == TICKDEV_MODE_PERIODIC)
index 21efab7485ca517bf6fd675233d1dd268e3ce252..e277284c2831c9c1dae2219c1a135e1f5dc8945d 100644 (file)
@@ -141,12 +141,6 @@ static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
 static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_possible(); }
 #endif /* !(BROADCAST && ONESHOT) */
 
-#if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS)
-extern void tick_sched_forward_next_period(void);
-#else
-static inline void tick_sched_forward_next_period(void) { }
-#endif
-
 /* NO_HZ_FULL internal */
 #ifdef CONFIG_NO_HZ_FULL
 extern void tick_nohz_init(void);
index c1f518e7aa808a281b5dab69f3961a02b2c14315..6fe615d57ebbbe3b52185ccebb4c041cec0f62b9 100644 (file)
@@ -82,16 +82,15 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
        if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT) ||
                    !tick_device_is_functional(dev)) {
 
-               printk(KERN_INFO "Clockevents: "
-                      "could not switch to one-shot mode:");
+               pr_info("Clockevents: could not switch to one-shot mode:");
                if (!dev) {
-                       printk(" no tick device\n");
+                       pr_cont(" no tick device\n");
                } else {
                        if (!tick_device_is_functional(dev))
-                               printk(" %s is not functional.\n", dev->name);
+                               pr_cont(" %s is not functional.\n", dev->name);
                        else
-                               printk(" %s does not support one-shot mode.\n",
-                                      dev->name);
+                               pr_cont(" %s does not support one-shot mode.\n",
+                                       dev->name);
                }
                return -EINVAL;
        }
index 646645e981f942480d49857fc84ef2d5bcd14791..da9455a6b42ba1f03cbfaf75f427e92f1241d2bb 100644 (file)
@@ -51,15 +51,6 @@ struct tick_sched *tick_get_tick_sched(int cpu)
  */
 static ktime_t last_jiffies_update;
 
-/*
- * Called after resume. Make sure that jiffies are not fast forwarded due to
- * clock monotonic being forwarded by the suspended time.
- */
-void tick_sched_forward_next_period(void)
-{
-       last_jiffies_update = tick_next_period;
-}
-
 /*
  * Must be called with interrupts disabled !
  */
@@ -804,12 +795,12 @@ static void tick_nohz_stop_tick(struct tick_sched *ts, int cpu)
                return;
        }
 
-       hrtimer_set_expires(&ts->sched_timer, tick);
-
-       if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
-               hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED);
-       else
+       if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
+               hrtimer_start(&ts->sched_timer, tick, HRTIMER_MODE_ABS_PINNED);
+       } else {
+               hrtimer_set_expires(&ts->sched_timer, tick);
                tick_program_event(tick, 1);
+       }
 }
 
 static void tick_nohz_retain_tick(struct tick_sched *ts)
index ca90219a1e73783d1ac991515453138233d82607..49cbceef5debc7c06aab4f4f5a2479b291855ee7 100644 (file)
@@ -138,12 +138,7 @@ static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec64 wtm)
 
 static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta)
 {
-       /* Update both bases so mono and raw stay coupled. */
-       tk->tkr_mono.base += delta;
-       tk->tkr_raw.base += delta;
-
-       /* Accumulate time spent in suspend */
-       tk->time_suspended += delta;
+       tk->offs_boot = ktime_add(tk->offs_boot, delta);
 }
 
 /*
@@ -473,6 +468,36 @@ u64 ktime_get_raw_fast_ns(void)
 }
 EXPORT_SYMBOL_GPL(ktime_get_raw_fast_ns);
 
+/**
+ * ktime_get_boot_fast_ns - NMI safe and fast access to boot clock.
+ *
+ * To keep it NMI safe since we're accessing from tracing, we're not using a
+ * separate timekeeper with updates to monotonic clock and boot offset
+ * protected with seqlocks. This has the following minor side effects:
+ *
+ * (1) Its possible that a timestamp be taken after the boot offset is updated
+ * but before the timekeeper is updated. If this happens, the new boot offset
+ * is added to the old timekeeping making the clock appear to update slightly
+ * earlier:
+ *    CPU 0                                        CPU 1
+ *    timekeeping_inject_sleeptime64()
+ *    __timekeeping_inject_sleeptime(tk, delta);
+ *                                                 timestamp();
+ *    timekeeping_update(tk, TK_CLEAR_NTP...);
+ *
+ * (2) On 32-bit systems, the 64-bit boot offset (tk->offs_boot) may be
+ * partially updated.  Since the tk->offs_boot update is a rare event, this
+ * should be a rare occurrence which postprocessing should be able to handle.
+ */
+u64 notrace ktime_get_boot_fast_ns(void)
+{
+       struct timekeeper *tk = &tk_core.timekeeper;
+
+       return (ktime_get_mono_fast_ns() + ktime_to_ns(tk->offs_boot));
+}
+EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns);
+
+
 /*
  * See comment for __ktime_get_fast_ns() vs. timestamp ordering
  */
@@ -764,6 +789,7 @@ EXPORT_SYMBOL_GPL(ktime_get_resolution_ns);
 
 static ktime_t *offsets[TK_OFFS_MAX] = {
        [TK_OFFS_REAL]  = &tk_core.timekeeper.offs_real,
+       [TK_OFFS_BOOT]  = &tk_core.timekeeper.offs_boot,
        [TK_OFFS_TAI]   = &tk_core.timekeeper.offs_tai,
 };
 
@@ -860,39 +886,6 @@ void ktime_get_ts64(struct timespec64 *ts)
 }
 EXPORT_SYMBOL_GPL(ktime_get_ts64);
 
-/**
- * ktime_get_active_ts64 - Get the active non-suspended monotonic clock
- * @ts:                pointer to timespec variable
- *
- * The function calculates the monotonic clock from the realtime clock and
- * the wall_to_monotonic offset, subtracts the accumulated suspend time and
- * stores the result in normalized timespec64 format in the variable
- * pointed to by @ts.
- */
-void ktime_get_active_ts64(struct timespec64 *ts)
-{
-       struct timekeeper *tk = &tk_core.timekeeper;
-       struct timespec64 tomono, tsusp;
-       u64 nsec, nssusp;
-       unsigned int seq;
-
-       WARN_ON(timekeeping_suspended);
-
-       do {
-               seq = read_seqcount_begin(&tk_core.seq);
-               ts->tv_sec = tk->xtime_sec;
-               nsec = timekeeping_get_ns(&tk->tkr_mono);
-               tomono = tk->wall_to_monotonic;
-               nssusp = tk->time_suspended;
-       } while (read_seqcount_retry(&tk_core.seq, seq));
-
-       ts->tv_sec += tomono.tv_sec;
-       ts->tv_nsec = 0;
-       timespec64_add_ns(ts, nsec + tomono.tv_nsec);
-       tsusp = ns_to_timespec64(nssusp);
-       *ts = timespec64_sub(*ts, tsusp);
-}
-
 /**
  * ktime_get_seconds - Get the seconds portion of CLOCK_MONOTONIC
  *
@@ -1593,6 +1586,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
                return;
        }
        tk_xtime_add(tk, delta);
+       tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, *delta));
        tk_update_sleep_time(tk, timespec64_to_ktime(*delta));
        tk_debug_account_sleep_time(delta);
 }
@@ -2125,7 +2119,7 @@ out:
 void getboottime64(struct timespec64 *ts)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
-       ktime_t t = ktime_sub(tk->offs_real, tk->time_suspended);
+       ktime_t t = ktime_sub(tk->offs_real, tk->offs_boot);
 
        *ts = ktime_to_timespec64(t);
 }
@@ -2139,13 +2133,6 @@ unsigned long get_seconds(void)
 }
 EXPORT_SYMBOL(get_seconds);
 
-struct timespec __current_kernel_time(void)
-{
-       struct timekeeper *tk = &tk_core.timekeeper;
-
-       return timespec64_to_timespec(tk_xtime(tk));
-}
-
 struct timespec64 current_kernel_time64(void)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
@@ -2195,6 +2182,7 @@ void do_timer(unsigned long ticks)
  * ktime_get_update_offsets_now - hrtimer helper
  * @cwsseq:    pointer to check and store the clock was set sequence number
  * @offs_real: pointer to storage for monotonic -> realtime offset
+ * @offs_boot: pointer to storage for monotonic -> boottime offset
  * @offs_tai:  pointer to storage for monotonic -> clock tai offset
  *
  * Returns current monotonic time and updates the offsets if the
@@ -2204,7 +2192,7 @@ void do_timer(unsigned long ticks)
  * Called from hrtimer_interrupt() or retrigger_next_event()
  */
 ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
-                                    ktime_t *offs_tai)
+                                    ktime_t *offs_boot, ktime_t *offs_tai)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
        unsigned int seq;
@@ -2221,6 +2209,7 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
                if (*cwsseq != tk->clock_was_set_seq) {
                        *cwsseq = tk->clock_was_set_seq;
                        *offs_real = tk->offs_real;
+                       *offs_boot = tk->offs_boot;
                        *offs_tai = tk->offs_tai;
                }
 
index 79b67f5e0343caf35cf15c3cd99b905d29a31a10..7a9b4eb7a1d5bde85e7a7b1c7747602cdd605975 100644 (file)
@@ -6,6 +6,7 @@
  */
 extern ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq,
                                            ktime_t *offs_real,
+                                           ktime_t *offs_boot,
                                            ktime_t *offs_tai);
 
 extern int timekeeping_valid_for_hres(void);
index d88e96d4e12c013d46d5aaae20d99759895fe187..56ba0f2a01db3beab92f98cace89df33b687705e 100644 (file)
@@ -977,6 +977,7 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)
 {
        struct perf_event_query_bpf __user *uquery = info;
        struct perf_event_query_bpf query = {};
+       u32 *ids, prog_cnt, ids_len;
        int ret;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -985,16 +986,32 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)
                return -EINVAL;
        if (copy_from_user(&query, uquery, sizeof(query)))
                return -EFAULT;
-       if (query.ids_len > BPF_TRACE_MAX_PROGS)
+
+       ids_len = query.ids_len;
+       if (ids_len > BPF_TRACE_MAX_PROGS)
                return -E2BIG;
+       ids = kcalloc(ids_len, sizeof(u32), GFP_USER | __GFP_NOWARN);
+       if (!ids)
+               return -ENOMEM;
+       /*
+        * The above kcalloc returns ZERO_SIZE_PTR when ids_len = 0, which
+        * is required when user only wants to check for uquery->prog_cnt.
+        * There is no need to check for it since the case is handled
+        * gracefully in bpf_prog_array_copy_info.
+        */
 
        mutex_lock(&bpf_event_mutex);
        ret = bpf_prog_array_copy_info(event->tp_event->prog_array,
-                                      uquery->ids,
-                                      query.ids_len,
-                                      &uquery->prog_cnt);
+                                      ids,
+                                      ids_len,
+                                      &prog_cnt);
        mutex_unlock(&bpf_event_mutex);
 
+       if (copy_to_user(&uquery->prog_cnt, &prog_cnt, sizeof(prog_cnt)) ||
+           copy_to_user(uquery->ids, ids, ids_len * sizeof(u32)))
+               ret = -EFAULT;
+
+       kfree(ids);
        return ret;
 }
 
index dfbcf9ee1447645594b06736e2ca9616e6cd93eb..414d7210b2eca7ccb78ac1748a31aefb99414007 100644 (file)
@@ -1165,7 +1165,7 @@ static struct {
        { trace_clock,                  "perf",         1 },
        { ktime_get_mono_fast_ns,       "mono",         1 },
        { ktime_get_raw_fast_ns,        "mono_raw",     1 },
-       { ktime_get_mono_fast_ns,       "boot",         1 },
+       { ktime_get_boot_fast_ns,       "boot",         1 },
        ARCH_TRACE_CLOCKS
 };
 
index 1cd3fb4d70f8d92d5c360038a823a1bac5e1a504..02aed76e0978801428ff33f1b8a421a8deb34f14 100644 (file)
@@ -512,8 +512,6 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
        if (ret == 0)
                tk->tp.flags |= TP_FLAG_REGISTERED;
        else {
-               pr_warn("Could not insert probe at %s+%lu: %d\n",
-                       trace_kprobe_symbol(tk), trace_kprobe_offset(tk), ret);
                if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) {
                        pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
                        ret = 0;
index c0bba30fef0ac1f8bda32af158b5596fcc14ce09..bbfb229aa0675ed73d438ce2700e674891758310 100644 (file)
@@ -84,7 +84,8 @@ again:
                __free_pages(page, page_order);
                page = NULL;
 
-               if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
+               if (IS_ENABLED(CONFIG_ZONE_DMA) &&
+                   dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
                    !(gfp & GFP_DMA)) {
                        gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
                        goto again;
index df782418b333eedea39cdb793c38ad623f96a707..81f9e33aa7e72aa7f3a524ff061aa3c9d48fe1a9 100644 (file)
@@ -111,27 +111,22 @@ EXPORT_SYMBOL(errseq_set);
  * errseq_sample() - Grab current errseq_t value.
  * @eseq: Pointer to errseq_t to be sampled.
  *
- * This function allows callers to sample an errseq_t value, marking it as
- * "seen" if required.
+ * This function allows callers to initialise their errseq_t variable.
+ * If the error has been "seen", new callers will not see an old error.
+ * If there is an unseen error in @eseq, the caller of this function will
+ * see it the next time it checks for an error.
  *
+ * Context: Any context.
  * Return: The current errseq value.
  */
 errseq_t errseq_sample(errseq_t *eseq)
 {
        errseq_t old = READ_ONCE(*eseq);
-       errseq_t new = old;
 
-       /*
-        * For the common case of no errors ever having been set, we can skip
-        * marking the SEEN bit. Once an error has been set, the value will
-        * never go back to zero.
-        */
-       if (old != 0) {
-               new |= ERRSEQ_SEEN;
-               if (old != new)
-                       cmpxchg(eseq, old, new);
-       }
-       return new;
+       /* If nobody has seen this error yet, then we can be the first. */
+       if (!(old & ERRSEQ_SEEN))
+               old = 0;
+       return old;
 }
 EXPORT_SYMBOL(errseq_sample);
 
index e1d1f290bf354540c9148863c931c3f1d38278cf..18989b5b3b56b8b0b59836492606ec99fd3debbe 100644 (file)
@@ -233,13 +233,12 @@ static int kobject_add_internal(struct kobject *kobj)
 
                /* be noisy on error issues */
                if (error == -EEXIST)
-                       WARN(1,
-                            "%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
-                            __func__, kobject_name(kobj));
+                       pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
+                              __func__, kobject_name(kobj));
                else
-                       WARN(1, "%s failed for %s (error: %d parent: %s)\n",
-                            __func__, kobject_name(kobj), error,
-                            parent ? kobject_name(parent) : "'none'");
+                       pr_err("%s failed for %s (error: %d parent: %s)\n",
+                              __func__, kobject_name(kobj), error,
+                              parent ? kobject_name(parent) : "'none'");
        } else
                kobj->state_in_sysfs = 1;
 
index 0b79908dfe892e5bc635408538a8049c844a2888..5939549c0e7bc19b6e4afb7ccf775e2c64b91922 100644 (file)
  *             Pablo Neira Ayuso <pablo@netfilter.org>
  *
  * ==========================================================================
- *
+ */
+
+/**
+ * DOC: ts_intro
  * INTRODUCTION
  *
  *   The textsearch infrastructure provides text searching facilities for
@@ -19,7 +22,9 @@
  *
  * ARCHITECTURE
  *
- *      User
+ * .. code-block:: none
+ *
+ *     User
  *     +----------------+
  *     |        finish()|<--------------(6)-----------------+
  *     |get_next_block()|<--------------(5)---------------+ |
  *     |             (3)|----->| find()/next() |-----------+          |
  *     |             (7)|----->| destroy()     |----------------------+
  *     +----------------+      +---------------+
- *  
- *   (1) User configures a search by calling _prepare() specifying the
- *       search parameters such as the pattern and algorithm name.
+ *
+ *   (1) User configures a search by calling textsearch_prepare() specifying
+ *       the search parameters such as the pattern and algorithm name.
  *   (2) Core requests the algorithm to allocate and initialize a search
  *       configuration according to the specified parameters.
- *   (3) User starts the search(es) by calling _find() or _next() to
- *       fetch subsequent occurrences. A state variable is provided
- *       to the algorithm to store persistent variables.
+ *   (3) User starts the search(es) by calling textsearch_find() or
+ *       textsearch_next() to fetch subsequent occurrences. A state variable
+ *       is provided to the algorithm to store persistent variables.
  *   (4) Core eventually resets the search offset and forwards the find()
  *       request to the algorithm.
  *   (5) Algorithm calls get_next_block() provided by the user continuously
  *       to fetch the data to be searched in block by block.
  *   (6) Algorithm invokes finish() after the last call to get_next_block
  *       to clean up any leftovers from get_next_block. (Optional)
- *   (7) User destroys the configuration by calling _destroy().
+ *   (7) User destroys the configuration by calling textsearch_destroy().
  *   (8) Core notifies the algorithm to destroy algorithm specific
  *       allocations. (Optional)
  *
  *   amount of times and even in parallel as long as a separate struct
  *   ts_state variable is provided to every instance.
  *
- *   The actual search is performed by either calling textsearch_find_-
- *   continuous() for linear data or by providing an own get_next_block()
- *   implementation and calling textsearch_find(). Both functions return
+ *   The actual search is performed by either calling
+ *   textsearch_find_continuous() for linear data or by providing
+ *   an own get_next_block() implementation and
+ *   calling textsearch_find(). Both functions return
  *   the position of the first occurrence of the pattern or UINT_MAX if
  *   no match was found. Subsequent occurrences can be found by calling
  *   textsearch_next() regardless of the linearity of the data.
@@ -72,7 +78,7 @@
  *   Once you're done using a configuration it must be given back via
  *   textsearch_destroy.
  *
- * EXAMPLE
+ * EXAMPLE::
  *
  *   int pos;
  *   struct ts_config *conf;
  *       goto errout;
  *   }
  *
- *   pos = textsearch_find_continuous(conf, &state, example, strlen(example));
+ *   pos = textsearch_find_continuous(conf, \&state, example, strlen(example));
  *   if (pos != UINT_MAX)
- *       panic("Oh my god, dancing chickens at %d\n", pos);
+ *       panic("Oh my god, dancing chickens at \%d\n", pos);
  *
  *   textsearch_destroy(conf);
- * ==========================================================================
  */
+/* ========================================================================== */
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -225,7 +231,7 @@ static unsigned int get_linear_data(unsigned int consumed, const u8 **dst,
  *
  * Returns the position of first occurrence of the pattern or
  * %UINT_MAX if no occurrence was found.
- */ 
+ */
 unsigned int textsearch_find_continuous(struct ts_config *conf,
                                        struct ts_state *state,
                                        const void *data, unsigned int len)
index 9276bdb2343c73884c2be1c11dca5c5c462054ce..0604cb02e6f3b7a3bdbc4eee71a9b0bd413c0212 100644 (file)
@@ -786,7 +786,7 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
        VM_BUG_ON_PAGE(!PageLocked(new), new);
        VM_BUG_ON_PAGE(new->mapping, new);
 
-       error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
+       error = radix_tree_preload(gfp_mask & GFP_RECLAIM_MASK);
        if (!error) {
                struct address_space *mapping = old->mapping;
                void (*freepage)(struct page *);
@@ -842,7 +842,7 @@ static int __add_to_page_cache_locked(struct page *page,
                        return error;
        }
 
-       error = radix_tree_maybe_preload(gfp_mask & ~__GFP_HIGHMEM);
+       error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK);
        if (error) {
                if (!huge)
                        mem_cgroup_cancel_charge(page, memcg, false);
@@ -1585,8 +1585,7 @@ no_page:
                if (fgp_flags & FGP_ACCESSED)
                        __SetPageReferenced(page);
 
-               err = add_to_page_cache_lru(page, mapping, offset,
-                               gfp_mask & GFP_RECLAIM_MASK);
+               err = add_to_page_cache_lru(page, mapping, offset, gfp_mask);
                if (unlikely(err)) {
                        put_page(page);
                        page = NULL;
@@ -2387,7 +2386,7 @@ static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask)
                if (!page)
                        return -ENOMEM;
 
-               ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask & GFP_KERNEL);
+               ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask);
                if (ret == 0)
                        ret = mapping->a_ops->readpage(file, page);
                else if (ret == -EEXIST)
index 14ed6ee5e02fc8bc6acc767de9e42ed464ce5675..a3a1815f8e11810ec1b94cb25d3c5dd6eb30f556 100644 (file)
@@ -2925,7 +2925,10 @@ void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new)
                pmde = maybe_pmd_mkwrite(pmde, vma);
 
        flush_cache_range(vma, mmun_start, mmun_start + HPAGE_PMD_SIZE);
-       page_add_anon_rmap(new, vma, mmun_start, true);
+       if (PageAnon(new))
+               page_add_anon_rmap(new, vma, mmun_start, true);
+       else
+               page_add_file_rmap(new, true);
        set_pmd_at(mm, mmun_start, pvmw->pmd, pmde);
        if (vma->vm_flags & VM_LOCKED)
                mlock_vma_page(new);
index e074f7c637aa4e62d6268d3e765564e6f2a9cde0..2bd3df3d101a777144f7e91895dbcbcdd0e455cc 100644 (file)
@@ -2192,7 +2192,7 @@ static void __memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg,
 {
        struct memcg_kmem_cache_create_work *cw;
 
-       cw = kmalloc(sizeof(*cw), GFP_NOWAIT);
+       cw = kmalloc(sizeof(*cw), GFP_NOWAIT | __GFP_NOWARN);
        if (!cw)
                return;
 
index f65dd69e1fd1a7a1dd7c88679ae8aacabe19aacc..568433023831ae098dd5a9d3c1dd209d7dd04be7 100644 (file)
@@ -472,7 +472,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
        pslot = radix_tree_lookup_slot(&mapping->i_pages,
                                        page_index(page));
 
-       expected_count += 1 + page_has_private(page);
+       expected_count += hpage_nr_pages(page) + page_has_private(page);
        if (page_count(page) != expected_count ||
                radix_tree_deref_slot_protected(pslot,
                                        &mapping->i_pages.xa_lock) != page) {
@@ -505,7 +505,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
         */
        newpage->index = page->index;
        newpage->mapping = page->mapping;
-       get_page(newpage);      /* add cache reference */
+       page_ref_add(newpage, hpage_nr_pages(page)); /* add cache reference */
        if (PageSwapBacked(page)) {
                __SetPageSwapBacked(newpage);
                if (PageSwapCache(page)) {
@@ -524,13 +524,26 @@ int migrate_page_move_mapping(struct address_space *mapping,
        }
 
        radix_tree_replace_slot(&mapping->i_pages, pslot, newpage);
+       if (PageTransHuge(page)) {
+               int i;
+               int index = page_index(page);
+
+               for (i = 0; i < HPAGE_PMD_NR; i++) {
+                       pslot = radix_tree_lookup_slot(&mapping->i_pages,
+                                                      index + i);
+                       radix_tree_replace_slot(&mapping->i_pages, pslot,
+                                               newpage + i);
+               }
+       } else {
+               radix_tree_replace_slot(&mapping->i_pages, pslot, newpage);
+       }
 
        /*
         * Drop cache reference from old page by unfreezing
         * to one less reference.
         * We know this isn't the last reference.
         */
-       page_ref_unfreeze(page, expected_count - 1);
+       page_ref_unfreeze(page, expected_count - hpage_nr_pages(page));
 
        xa_unlock(&mapping->i_pages);
        /* Leave irq disabled to prevent preemption while updating stats */
@@ -1622,6 +1635,9 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
                current_node = NUMA_NO_NODE;
        }
 out_flush:
+       if (list_empty(&pagelist))
+               return err;
+
        /* Make sure we do not overwrite the existing error */
        err1 = do_move_pages_to_node(mm, &pagelist, current_node);
        if (!err1)
index 188f195883b90b40d8371e8e04ff5acd4d9d1526..9d5968d1e8e3360ecd1dd9a095139090a1a1f107 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -100,11 +100,20 @@ pgprot_t protection_map[16] __ro_after_init = {
        __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
 };
 
+#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+       return prot;
+}
+#endif
+
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
-       return __pgprot(pgprot_val(protection_map[vm_flags &
+       pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
                                (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
                        pgprot_val(arch_vm_get_page_prot(vm_flags)));
+
+       return arch_filter_pgprot(ret);
 }
 EXPORT_SYMBOL(vm_get_page_prot);
 
index 5c1a3279e63f865664bafcaf4d3c7f98af697cce..337c6afb3345e1e0d6071a63718f4dc6aac140b7 100644 (file)
@@ -2502,13 +2502,13 @@ void account_page_redirty(struct page *page)
        if (mapping && mapping_cap_account_dirty(mapping)) {
                struct inode *inode = mapping->host;
                struct bdi_writeback *wb;
-               bool locked;
+               struct wb_lock_cookie cookie = {};
 
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &cookie);
                current->nr_dirtied--;
                dec_node_page_state(page, NR_DIRTIED);
                dec_wb_stat(wb, WB_DIRTIED);
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &cookie);
        }
 }
 EXPORT_SYMBOL(account_page_redirty);
@@ -2614,15 +2614,15 @@ void __cancel_dirty_page(struct page *page)
        if (mapping_cap_account_dirty(mapping)) {
                struct inode *inode = mapping->host;
                struct bdi_writeback *wb;
-               bool locked;
+               struct wb_lock_cookie cookie = {};
 
                lock_page_memcg(page);
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &cookie);
 
                if (TestClearPageDirty(page))
                        account_page_cleaned(page, mapping, wb);
 
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &cookie);
                unlock_page_memcg(page);
        } else {
                ClearPageDirty(page);
@@ -2654,7 +2654,7 @@ int clear_page_dirty_for_io(struct page *page)
        if (mapping && mapping_cap_account_dirty(mapping)) {
                struct inode *inode = mapping->host;
                struct bdi_writeback *wb;
-               bool locked;
+               struct wb_lock_cookie cookie = {};
 
                /*
                 * Yes, Virginia, this is indeed insane.
@@ -2691,14 +2691,14 @@ int clear_page_dirty_for_io(struct page *page)
                 * always locked coming in here, so we get the desired
                 * exclusion.
                 */
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &cookie);
                if (TestClearPageDirty(page)) {
                        dec_lruvec_page_state(page, NR_FILE_DIRTY);
                        dec_zone_page_state(page, NR_ZONE_WRITE_PENDING);
                        dec_wb_stat(wb, WB_RECLAIMABLE);
                        ret = 1;
                }
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &cookie);
                return ret;
        }
        return TestClearPageDirty(page);
index f0dd4e4565bc6bc9117fe8ec9b8a2371d7f7f8b4..8d5337fed37b81bcae0e20dad65bf0202e031477 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1374,9 +1374,6 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
                if (!pvmw.pte && (flags & TTU_MIGRATION)) {
                        VM_BUG_ON_PAGE(PageHuge(page) || !PageTransCompound(page), page);
 
-                       if (!PageAnon(page))
-                               continue;
-
                        set_pmd_migration_entry(&pvmw, page);
                        continue;
                }
index 8b920ce3ae02f206f8598d6510986ceef6f0440d..9b697323a88c980b1878e0af68f83b57aeb55c55 100644 (file)
@@ -303,7 +303,7 @@ unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone
 /*
  * Add a shrinker callback to be called from the vm.
  */
-int register_shrinker(struct shrinker *shrinker)
+int prealloc_shrinker(struct shrinker *shrinker)
 {
        size_t size = sizeof(*shrinker->nr_deferred);
 
@@ -313,10 +313,29 @@ int register_shrinker(struct shrinker *shrinker)
        shrinker->nr_deferred = kzalloc(size, GFP_KERNEL);
        if (!shrinker->nr_deferred)
                return -ENOMEM;
+       return 0;
+}
+
+void free_prealloced_shrinker(struct shrinker *shrinker)
+{
+       kfree(shrinker->nr_deferred);
+       shrinker->nr_deferred = NULL;
+}
 
+void register_shrinker_prepared(struct shrinker *shrinker)
+{
        down_write(&shrinker_rwsem);
        list_add_tail(&shrinker->list, &shrinker_list);
        up_write(&shrinker_rwsem);
+}
+
+int register_shrinker(struct shrinker *shrinker)
+{
+       int err = prealloc_shrinker(shrinker);
+
+       if (err)
+               return err;
+       register_shrinker_prepared(shrinker);
        return 0;
 }
 EXPORT_SYMBOL(register_shrinker);
index 032e0fe459408a734f8d10b326bf41f59e9f9606..28a4c3490359ccb5cc8a27e684dcfe56a13e5c40 100644 (file)
@@ -1825,13 +1825,14 @@ static int compat_table_info(const struct ebt_table_info *info,
 {
        unsigned int size = info->entries_size;
        const void *entries = info->entries;
-       int ret;
 
        newinfo->entries_size = size;
-
-       ret = xt_compat_init_offsets(NFPROTO_BRIDGE, info->nentries);
-       if (ret)
-               return ret;
+       if (info->nentries) {
+               int ret = xt_compat_init_offsets(NFPROTO_BRIDGE,
+                                                info->nentries);
+               if (ret)
+                       return ret;
+       }
 
        return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info,
                                                        entries, newinfo);
index 53ecda10b79011064bf2aad6041e50a0089819e1..13e2ae6be620c5a1e6cc6253b50c466cd935f6bd 100644 (file)
@@ -174,7 +174,7 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
                flow == CAIF_CTRLCMD_DEINIT_RSP ? "CLOSE/DEINIT" :
                flow == CAIF_CTRLCMD_INIT_FAIL_RSP ? "OPEN_FAIL" :
                flow == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ?
-                "REMOTE_SHUTDOWN" : "UKNOWN CTRL COMMAND");
+                "REMOTE_SHUTDOWN" : "UNKNOWN CTRL COMMAND");
 
 
 
index fcb40c12b1f838e24b2f2a1a58b632522acab8b4..3b3d33ea9ed830373c08889f3e38d7bc695f313b 100644 (file)
@@ -2569,6 +2569,11 @@ static int try_write(struct ceph_connection *con)
        int ret = 1;
 
        dout("try_write start %p state %lu\n", con, con->state);
+       if (con->state != CON_STATE_PREOPEN &&
+           con->state != CON_STATE_CONNECTING &&
+           con->state != CON_STATE_NEGOTIATING &&
+           con->state != CON_STATE_OPEN)
+               return 0;
 
 more:
        dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
@@ -2594,6 +2599,8 @@ more:
        }
 
 more_kvec:
+       BUG_ON(!con->sock);
+
        /* kvec data queued? */
        if (con->out_kvec_left) {
                ret = write_partial_kvec(con);
index b3dac24412d34cbe2e3616371db9fe9838ce550f..21ac6e3b96bba0f34625d4e8c92afd61042f7c87 100644 (file)
@@ -209,6 +209,14 @@ static void reopen_session(struct ceph_mon_client *monc)
        __open_session(monc);
 }
 
+static void un_backoff(struct ceph_mon_client *monc)
+{
+       monc->hunt_mult /= 2; /* reduce by 50% */
+       if (monc->hunt_mult < 1)
+               monc->hunt_mult = 1;
+       dout("%s hunt_mult now %d\n", __func__, monc->hunt_mult);
+}
+
 /*
  * Reschedule delayed work timer.
  */
@@ -963,6 +971,7 @@ static void delayed_work(struct work_struct *work)
                if (!monc->hunting) {
                        ceph_con_keepalive(&monc->con);
                        __validate_auth(monc);
+                       un_backoff(monc);
                }
 
                if (is_auth &&
@@ -1123,9 +1132,8 @@ static void finish_hunting(struct ceph_mon_client *monc)
                dout("%s found mon%d\n", __func__, monc->cur_mon);
                monc->hunting = false;
                monc->had_a_connection = true;
-               monc->hunt_mult /= 2; /* reduce by 50% */
-               if (monc->hunt_mult < 1)
-                       monc->hunt_mult = 1;
+               un_backoff(monc);
+               __schedule_delayed(monc);
        }
 }
 
index 969462ebb296250fe5f3b7c4621e9ba9720a2dbe..af0558b00c6c7d5831d0b9e5281d2d327e9773a5 100644 (file)
@@ -2969,7 +2969,7 @@ netdev_features_t passthru_features_check(struct sk_buff *skb,
 }
 EXPORT_SYMBOL(passthru_features_check);
 
-static netdev_features_t dflt_features_check(const struct sk_buff *skb,
+static netdev_features_t dflt_features_check(struct sk_buff *skb,
                                             struct net_device *dev,
                                             netdev_features_t features)
 {
index e3e6a3e2ca22a6ee634894e897b089773c820a9c..d884d8f5f0e54328ef46fe94715703287fb93aba 100644 (file)
@@ -839,7 +839,7 @@ void dev_mc_flush(struct net_device *dev)
 EXPORT_SYMBOL(dev_mc_flush);
 
 /**
- *     dev_mc_flush - Init multicast address list
+ *     dev_mc_init - Init multicast address list
  *     @dev: device
  *
  *     Init multicast address list.
index 7b7a14abba28e2b77c6448f1c3d151287afc79ad..ce519861be5992b504c519ca36edb05d2ecc02b7 100644 (file)
@@ -55,7 +55,8 @@ static void neigh_timer_handler(struct timer_list *t);
 static void __neigh_notify(struct neighbour *n, int type, int flags,
                           u32 pid);
 static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid);
-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
+static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
+                                   struct net_device *dev);
 
 #ifdef CONFIG_PROC_FS
 static const struct file_operations neigh_stat_seq_fops;
@@ -291,8 +292,7 @@ int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
 {
        write_lock_bh(&tbl->lock);
        neigh_flush_dev(tbl, dev);
-       pneigh_ifdown(tbl, dev);
-       write_unlock_bh(&tbl->lock);
+       pneigh_ifdown_and_unlock(tbl, dev);
 
        del_timer_sync(&tbl->proxy_timer);
        pneigh_queue_purge(&tbl->proxy_queue);
@@ -681,9 +681,10 @@ int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
        return -ENOENT;
 }
 
-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
+static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
+                                   struct net_device *dev)
 {
-       struct pneigh_entry *n, **np;
+       struct pneigh_entry *n, **np, *freelist = NULL;
        u32 h;
 
        for (h = 0; h <= PNEIGH_HASHMASK; h++) {
@@ -691,16 +692,23 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
                while ((n = *np) != NULL) {
                        if (!dev || n->dev == dev) {
                                *np = n->next;
-                               if (tbl->pdestructor)
-                                       tbl->pdestructor(n);
-                               if (n->dev)
-                                       dev_put(n->dev);
-                               kfree(n);
+                               n->next = freelist;
+                               freelist = n;
                                continue;
                        }
                        np = &n->next;
                }
        }
+       write_unlock_bh(&tbl->lock);
+       while ((n = freelist)) {
+               freelist = n->next;
+               n->next = NULL;
+               if (tbl->pdestructor)
+                       tbl->pdestructor(n);
+               if (n->dev)
+                       dev_put(n->dev);
+               kfree(n);
+       }
        return -ENOENT;
 }
 
@@ -2323,12 +2331,16 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
 
        err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL, NULL);
        if (!err) {
-               if (tb[NDA_IFINDEX])
+               if (tb[NDA_IFINDEX]) {
+                       if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
+                               return -EINVAL;
                        filter_idx = nla_get_u32(tb[NDA_IFINDEX]);
-
-               if (tb[NDA_MASTER])
+               }
+               if (tb[NDA_MASTER]) {
+                       if (nla_len(tb[NDA_MASTER]) != sizeof(u32))
+                               return -EINVAL;
                        filter_master_idx = nla_get_u32(tb[NDA_MASTER]);
-
+               }
                if (filter_idx || filter_master_idx)
                        flags |= NLM_F_DUMP_FILTERED;
        }
index 8396705deffc965ba8ab58aae8ee519f3d441a64..40c851693f77e35a1f573fdbf0bcd86adb94cf13 100644 (file)
@@ -91,9 +91,9 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
 
                        next_opt = memchr(opt, '#', end - opt) ?: end;
                        opt_len = next_opt - opt;
-                       if (!opt_len) {
-                               printk(KERN_WARNING
-                                      "Empty option to dns_resolver key\n");
+                       if (opt_len <= 0 || opt_len > 128) {
+                               pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n",
+                                                   opt_len);
                                return -EINVAL;
                        }
 
@@ -127,10 +127,8 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
                        }
 
                bad_option_value:
-                       printk(KERN_WARNING
-                              "Option '%*.*s' to dns_resolver key:"
-                              " bad/missing value\n",
-                              opt_nlen, opt_nlen, opt);
+                       pr_warn_ratelimited("Option '%*.*s' to dns_resolver key: bad/missing value\n",
+                                           opt_nlen, opt_nlen, opt);
                        return -EINVAL;
                } while (opt = next_opt + 1, opt < end);
        }
index 7d1ec76e7f433a2525581782a0bf14731548d4a8..13bbf8cb6a3961d422d01cf5b16a724d16107419 100644 (file)
@@ -69,6 +69,9 @@ void *ife_decode(struct sk_buff *skb, u16 *metalen)
        int total_pull;
        u16 ifehdrln;
 
+       if (!pskb_may_pull(skb, skb->dev->hard_header_len + IFE_METAHDRLEN))
+               return NULL;
+
        ifehdr = (struct ifeheadr *) (skb->data + skb->dev->hard_header_len);
        ifehdrln = ntohs(ifehdr->metalen);
        total_pull = skb->dev->hard_header_len + ifehdrln;
@@ -92,12 +95,43 @@ struct meta_tlvhdr {
        __be16 len;
 };
 
+static bool __ife_tlv_meta_valid(const unsigned char *skbdata,
+                                const unsigned char *ifehdr_end)
+{
+       const struct meta_tlvhdr *tlv;
+       u16 tlvlen;
+
+       if (unlikely(skbdata + sizeof(*tlv) > ifehdr_end))
+               return false;
+
+       tlv = (const struct meta_tlvhdr *)skbdata;
+       tlvlen = ntohs(tlv->len);
+
+       /* tlv length field is inc header, check on minimum */
+       if (tlvlen < NLA_HDRLEN)
+               return false;
+
+       /* overflow by NLA_ALIGN check */
+       if (NLA_ALIGN(tlvlen) < tlvlen)
+               return false;
+
+       if (unlikely(skbdata + NLA_ALIGN(tlvlen) > ifehdr_end))
+               return false;
+
+       return true;
+}
+
 /* Caller takes care of presenting data in network order
  */
-void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 *totlen)
+void *ife_tlv_meta_decode(void *skbdata, const void *ifehdr_end, u16 *attrtype,
+                         u16 *dlen, u16 *totlen)
 {
-       struct meta_tlvhdr *tlv = (struct meta_tlvhdr *) skbdata;
+       struct meta_tlvhdr *tlv;
+
+       if (!__ife_tlv_meta_valid(skbdata, ifehdr_end))
+               return NULL;
 
+       tlv = (struct meta_tlvhdr *)skbdata;
        *dlen = ntohs(tlv->len) - NLA_HDRLEN;
        *attrtype = ntohs(tlv->type);
 
index 4c11b810a4477c2f657ba6a58cec47809547eee0..83c73bab2c3de90254e11e4126d7cb77ed998f03 100644 (file)
@@ -1109,6 +1109,10 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
        struct ip_options_rcu *opt;
        struct rtable *rt;
 
+       rt = *rtp;
+       if (unlikely(!rt))
+               return -EFAULT;
+
        /*
         * setup for corking.
         */
@@ -1124,9 +1128,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
                cork->flags |= IPCORK_OPT;
                cork->addr = ipc->addr;
        }
-       rt = *rtp;
-       if (unlikely(!rt))
-               return -EFAULT;
+
        /*
         * We steal reference to this route, caller should not release it
         */
index bccc4c2700870b8c7ff592a6bd27acebd9bc6471..9ce1c726185eb21b778d7dd0d87f360b61dcbc77 100644 (file)
@@ -2368,6 +2368,7 @@ void tcp_write_queue_purge(struct sock *sk)
        INIT_LIST_HEAD(&tcp_sk(sk)->tsorted_sent_queue);
        sk_mem_reclaim(sk);
        tcp_clear_all_retrans_hints(tcp_sk(sk));
+       tcp_sk(sk)->packets_out = 0;
 }
 
 int tcp_disconnect(struct sock *sk, int flags)
@@ -2417,7 +2418,6 @@ int tcp_disconnect(struct sock *sk, int flags)
        icsk->icsk_backoff = 0;
        tp->snd_cwnd = 2;
        icsk->icsk_probes_out = 0;
-       tp->packets_out = 0;
        tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_cnt = 0;
        tp->window_clamp = 0;
@@ -2813,8 +2813,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
 #ifdef CONFIG_TCP_MD5SIG
        case TCP_MD5SIG:
        case TCP_MD5SIG_EXT:
-               /* Read the IP->Key mappings from userspace */
-               err = tp->af_specific->md5_parse(sk, optname, optval, optlen);
+               if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))
+                       err = tp->af_specific->md5_parse(sk, optname, optval, optlen);
+               else
+                       err = -EINVAL;
                break;
 #endif
        case TCP_USER_TIMEOUT:
index 367def6ddeda950db841c0b9ccec98787e19e728..e51c644484dc555b933ad4d223988d5721b05c6a 100644 (file)
@@ -3868,11 +3868,8 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th)
        int length = (th->doff << 2) - sizeof(*th);
        const u8 *ptr = (const u8 *)(th + 1);
 
-       /* If the TCP option is too short, we can short cut */
-       if (length < TCPOLEN_MD5SIG)
-               return NULL;
-
-       while (length > 0) {
+       /* If not enough data remaining, we can short cut */
+       while (length >= TCPOLEN_MD5SIG) {
                int opcode = *ptr++;
                int opsize;
 
index ccbfa83e4bb076ce086ff1e4e79c130857c7a1a5..ce77bcc2490c2783604d69778887127d7f405239 100644 (file)
@@ -48,6 +48,34 @@ config NFT_CHAIN_ROUTE_IPV6
          fields such as the source, destination, flowlabel, hop-limit and
          the packet mark.
 
+if NF_NAT_IPV6
+
+config NFT_CHAIN_NAT_IPV6
+       tristate "IPv6 nf_tables nat chain support"
+       help
+         This option enables the "nat" chain for IPv6 in nf_tables. This
+         chain type is used to perform Network Address Translation (NAT)
+         packet transformations such as the source, destination address and
+         source and destination ports.
+
+config NFT_MASQ_IPV6
+       tristate "IPv6 masquerade support for nf_tables"
+       depends on NFT_MASQ
+       select NF_NAT_MASQUERADE_IPV6
+       help
+         This is the expression that provides IPv4 masquerading support for
+         nf_tables.
+
+config NFT_REDIR_IPV6
+       tristate "IPv6 redirect support for nf_tables"
+       depends on NFT_REDIR
+       select NF_NAT_REDIRECT
+       help
+         This is the expression that provides IPv4 redirect support for
+         nf_tables.
+
+endif # NF_NAT_IPV6
+
 config NFT_REJECT_IPV6
        select NF_REJECT_IPV6
        default NFT_REJECT
@@ -107,39 +135,12 @@ config NF_NAT_IPV6
 
 if NF_NAT_IPV6
 
-config NFT_CHAIN_NAT_IPV6
-       depends on NF_TABLES_IPV6
-       tristate "IPv6 nf_tables nat chain support"
-       help
-         This option enables the "nat" chain for IPv6 in nf_tables. This
-         chain type is used to perform Network Address Translation (NAT)
-         packet transformations such as the source, destination address and
-         source and destination ports.
-
 config NF_NAT_MASQUERADE_IPV6
        tristate "IPv6 masquerade support"
        help
          This is the kernel functionality to provide NAT in the masquerade
          flavour (automatic source address selection) for IPv6.
 
-config NFT_MASQ_IPV6
-       tristate "IPv6 masquerade support for nf_tables"
-       depends on NF_TABLES_IPV6
-       depends on NFT_MASQ
-       select NF_NAT_MASQUERADE_IPV6
-       help
-         This is the expression that provides IPv4 masquerading support for
-         nf_tables.
-
-config NFT_REDIR_IPV6
-       tristate "IPv6 redirect support for nf_tables"
-       depends on NF_TABLES_IPV6
-       depends on NFT_REDIR
-       select NF_NAT_REDIRECT
-       help
-         This is the expression that provides IPv4 redirect support for
-         nf_tables.
-
 endif # NF_NAT_IPV6
 
 config IP6_NF_IPTABLES
index 49b954d6d0fa44ea0c4427e2918b3ab9c1610fe0..cde7d8251377c1a115e02c46843d361d3c0b4313 100644 (file)
@@ -3975,6 +3975,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned int mtu)
 
 static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
        [RTA_GATEWAY]           = { .len = sizeof(struct in6_addr) },
+       [RTA_PREFSRC]           = { .len = sizeof(struct in6_addr) },
        [RTA_OIF]               = { .type = NLA_U32 },
        [RTA_IIF]               = { .type = NLA_U32 },
        [RTA_PRIORITY]          = { .type = NLA_U32 },
@@ -3986,6 +3987,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
        [RTA_EXPIRES]           = { .type = NLA_U32 },
        [RTA_UID]               = { .type = NLA_U32 },
        [RTA_MARK]              = { .type = NLA_U32 },
+       [RTA_TABLE]             = { .type = NLA_U32 },
 };
 
 static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
index f343e6f0fc95a89fa5f386430dc161600367338c..5fe13948491968f2121782a4e4c2d3b93abe6e17 100644 (file)
@@ -136,7 +136,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
        isrh->nexthdr = proto;
 
        hdr->daddr = isrh->segments[isrh->first_segment];
-       set_tun_src(net, ip6_dst_idev(dst)->dev, &hdr->daddr, &hdr->saddr);
+       set_tun_src(net, dst->dev, &hdr->daddr, &hdr->saddr);
 
 #ifdef CONFIG_IPV6_SEG6_HMAC
        if (sr_has_hmac(isrh)) {
index 0fbd3ee26165dd1c9d8304a7d31cd31a3d247f41..40261cb68e83686c73a3567062fbf28f4a3d3146 100644 (file)
@@ -183,6 +183,26 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_get);
 
+struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth)
+{
+       const struct l2tp_net *pn = l2tp_pernet(net);
+       struct l2tp_tunnel *tunnel;
+       int count = 0;
+
+       rcu_read_lock_bh();
+       list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+               if (++count > nth) {
+                       l2tp_tunnel_inc_refcount(tunnel);
+                       rcu_read_unlock_bh();
+                       return tunnel;
+               }
+       }
+       rcu_read_unlock_bh();
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_get_nth);
+
 /* Lookup a session. A new reference is held on the returned session. */
 struct l2tp_session *l2tp_session_get(const struct net *net,
                                      struct l2tp_tunnel *tunnel,
@@ -335,26 +355,6 @@ err_tlock:
 }
 EXPORT_SYMBOL_GPL(l2tp_session_register);
 
-struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth)
-{
-       struct l2tp_net *pn = l2tp_pernet(net);
-       struct l2tp_tunnel *tunnel;
-       int count = 0;
-
-       rcu_read_lock_bh();
-       list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
-               if (++count > nth) {
-                       rcu_read_unlock_bh();
-                       return tunnel;
-               }
-       }
-
-       rcu_read_unlock_bh();
-
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(l2tp_tunnel_find_nth);
-
 /*****************************************************************************
  * Receive data handling
  *****************************************************************************/
index ba33cbec71eb2e5dca3cbeb4c3dd93239a12949b..c199020f8a8a315590a53f89aaf9370debcb09db 100644 (file)
@@ -212,6 +212,8 @@ static inline void *l2tp_session_priv(struct l2tp_session *session)
 }
 
 struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id);
+struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth);
+
 void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
 
 struct l2tp_session *l2tp_session_get(const struct net *net,
@@ -220,7 +222,6 @@ struct l2tp_session *l2tp_session_get(const struct net *net,
 struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
 struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
                                                const char *ifname);
-struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth);
 
 int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id,
                       u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg,
index 72e713da4733369788a41a8e69e3c43546453295..7f1e842ef05a6c7eea936f172d98157fa351b198 100644 (file)
@@ -47,7 +47,11 @@ struct l2tp_dfs_seq_data {
 
 static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd)
 {
-       pd->tunnel = l2tp_tunnel_find_nth(pd->net, pd->tunnel_idx);
+       /* Drop reference taken during previous invocation */
+       if (pd->tunnel)
+               l2tp_tunnel_dec_refcount(pd->tunnel);
+
+       pd->tunnel = l2tp_tunnel_get_nth(pd->net, pd->tunnel_idx);
        pd->tunnel_idx++;
 }
 
@@ -96,7 +100,17 @@ static void *l2tp_dfs_seq_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void l2tp_dfs_seq_stop(struct seq_file *p, void *v)
 {
-       /* nothing to do */
+       struct l2tp_dfs_seq_data *pd = v;
+
+       if (!pd || pd == SEQ_START_TOKEN)
+               return;
+
+       /* Drop reference taken by last invocation of l2tp_dfs_next_tunnel() */
+       if (pd->tunnel) {
+               l2tp_tunnel_dec_refcount(pd->tunnel);
+               pd->tunnel = NULL;
+               pd->session = NULL;
+       }
 }
 
 static void l2tp_dfs_seq_tunnel_show(struct seq_file *m, void *v)
index b05dbd9ffcb2b1fea951b724e51ad2a16a265102..6616c9fd292f1ddae6b974bb2d70de7d7dc1bd28 100644 (file)
@@ -487,14 +487,17 @@ static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback
        struct net *net = sock_net(skb->sk);
 
        for (;;) {
-               tunnel = l2tp_tunnel_find_nth(net, ti);
+               tunnel = l2tp_tunnel_get_nth(net, ti);
                if (tunnel == NULL)
                        goto out;
 
                if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                       tunnel, L2TP_CMD_TUNNEL_GET) < 0)
+                                       tunnel, L2TP_CMD_TUNNEL_GET) < 0) {
+                       l2tp_tunnel_dec_refcount(tunnel);
                        goto out;
+               }
+               l2tp_tunnel_dec_refcount(tunnel);
 
                ti++;
        }
@@ -848,7 +851,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
 
        for (;;) {
                if (tunnel == NULL) {
-                       tunnel = l2tp_tunnel_find_nth(net, ti);
+                       tunnel = l2tp_tunnel_get_nth(net, ti);
                        if (tunnel == NULL)
                                goto out;
                }
@@ -856,6 +859,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
                session = l2tp_session_get_nth(tunnel, si);
                if (session == NULL) {
                        ti++;
+                       l2tp_tunnel_dec_refcount(tunnel);
                        tunnel = NULL;
                        si = 0;
                        continue;
@@ -865,6 +869,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                         session, L2TP_CMD_SESSION_GET) < 0) {
                        l2tp_session_dec_refcount(session);
+                       l2tp_tunnel_dec_refcount(tunnel);
                        break;
                }
                l2tp_session_dec_refcount(session);
index 896bbca9bdaab4af19b260129bff488c32f06660..1fd9e145076a01bc98bee4ccb3fff2136ec29d3b 100644 (file)
@@ -619,6 +619,13 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
        lock_sock(sk);
 
        error = -EINVAL;
+
+       if (sockaddr_len != sizeof(struct sockaddr_pppol2tp) &&
+           sockaddr_len != sizeof(struct sockaddr_pppol2tpv3) &&
+           sockaddr_len != sizeof(struct sockaddr_pppol2tpin6) &&
+           sockaddr_len != sizeof(struct sockaddr_pppol2tpv3in6))
+               goto end;
+
        if (sp->sa_protocol != PX_PROTO_OL2TP)
                goto end;
 
@@ -1551,16 +1558,19 @@ struct pppol2tp_seq_data {
 
 static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd)
 {
+       /* Drop reference taken during previous invocation */
+       if (pd->tunnel)
+               l2tp_tunnel_dec_refcount(pd->tunnel);
+
        for (;;) {
-               pd->tunnel = l2tp_tunnel_find_nth(net, pd->tunnel_idx);
+               pd->tunnel = l2tp_tunnel_get_nth(net, pd->tunnel_idx);
                pd->tunnel_idx++;
 
-               if (pd->tunnel == NULL)
-                       break;
+               /* Only accept L2TPv2 tunnels */
+               if (!pd->tunnel || pd->tunnel->version == 2)
+                       return;
 
-               /* Ignore L2TPv3 tunnels */
-               if (pd->tunnel->version < 3)
-                       break;
+               l2tp_tunnel_dec_refcount(pd->tunnel);
        }
 }
 
@@ -1609,7 +1619,17 @@ static void *pppol2tp_seq_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void pppol2tp_seq_stop(struct seq_file *p, void *v)
 {
-       /* nothing to do */
+       struct pppol2tp_seq_data *pd = v;
+
+       if (!pd || pd == SEQ_START_TOKEN)
+               return;
+
+       /* Drop reference taken by last invocation of pppol2tp_next_tunnel() */
+       if (pd->tunnel) {
+               l2tp_tunnel_dec_refcount(pd->tunnel);
+               pd->tunnel = NULL;
+               pd->session = NULL;
+       }
 }
 
 static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
index 01dcc0823d1fd6b94357518a53aaa7cab4308cc8..cb80ebb38311e7db1e91881cdec59bc33724d856 100644 (file)
@@ -199,9 +199,19 @@ static int llc_ui_release(struct socket *sock)
                llc->laddr.lsap, llc->daddr.lsap);
        if (!llc_send_disc(sk))
                llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
-       if (!sock_flag(sk, SOCK_ZAPPED))
+       if (!sock_flag(sk, SOCK_ZAPPED)) {
+               struct llc_sap *sap = llc->sap;
+
+               /* Hold this for release_sock(), so that llc_backlog_rcv()
+                * could still use it.
+                */
+               llc_sap_hold(sap);
                llc_sap_remove_socket(llc->sap, sk);
-       release_sock(sk);
+               release_sock(sk);
+               llc_sap_put(sap);
+       } else {
+               release_sock(sk);
+       }
        if (llc->dev)
                dev_put(llc->dev);
        sock_put(sk);
index 163121192acae1c88f6a81d7a594c189da3678da..4d78375f9872d1a6962aa0e7cda7b913a6e0a7f3 100644 (file)
@@ -1099,14 +1099,7 @@ int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
 
 int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
 {
-       struct llc_sock *llc = llc_sk(sk);
-
-       del_timer(&llc->pf_cycle_timer.timer);
-       del_timer(&llc->ack_timer.timer);
-       del_timer(&llc->rej_sent_timer.timer);
-       del_timer(&llc->busy_state_timer.timer);
-       llc->ack_must_be_send = 0;
-       llc->ack_pf = 0;
+       llc_sk_stop_all_timers(sk, false);
        return 0;
 }
 
index 110e32bcb39976c9e319329f6ca9ba5809614aa8..c0ac522b48a1404c6b06c1ac1d85dae463316768 100644 (file)
@@ -961,6 +961,26 @@ out:
        return sk;
 }
 
+void llc_sk_stop_all_timers(struct sock *sk, bool sync)
+{
+       struct llc_sock *llc = llc_sk(sk);
+
+       if (sync) {
+               del_timer_sync(&llc->pf_cycle_timer.timer);
+               del_timer_sync(&llc->ack_timer.timer);
+               del_timer_sync(&llc->rej_sent_timer.timer);
+               del_timer_sync(&llc->busy_state_timer.timer);
+       } else {
+               del_timer(&llc->pf_cycle_timer.timer);
+               del_timer(&llc->ack_timer.timer);
+               del_timer(&llc->rej_sent_timer.timer);
+               del_timer(&llc->busy_state_timer.timer);
+       }
+
+       llc->ack_must_be_send = 0;
+       llc->ack_pf = 0;
+}
+
 /**
  *     llc_sk_free - Frees a LLC socket
  *     @sk - socket to free
@@ -973,7 +993,7 @@ void llc_sk_free(struct sock *sk)
 
        llc->state = LLC_CONN_OUT_OF_SVC;
        /* Stop all (possibly) running timers */
-       llc_conn_ac_stop_all_timers(sk, NULL);
+       llc_sk_stop_all_timers(sk, true);
 #ifdef DEBUG_LLC_CONN_ALLOC
        printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __func__,
                skb_queue_len(&llc->pdu_unack_q),
index 704b3832dbad33688d8298518ec34c19cb57d847..44d8a55e9721278e8d2e14f058aaeb7af362a6f9 100644 (file)
@@ -594,6 +594,7 @@ config NFT_QUOTA
 config NFT_REJECT
        default m if NETFILTER_ADVANCED=n
        tristate "Netfilter nf_tables reject support"
+       depends on !NF_TABLES_INET || (IPV6!=m || m)
        help
          This option adds the "reject" expression that you can use to
          explicitly deny and notify via TCP reset/ICMP informational errors
index 5ebde4b15810c5c219ad64c1bb0b6378a38d468c..f36098887ad0c4bcfa8c075654be3353ba7565d6 100644 (file)
@@ -2384,11 +2384,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
                        strlcpy(cfg.mcast_ifn, dm->mcast_ifn,
                                sizeof(cfg.mcast_ifn));
                        cfg.syncid = dm->syncid;
-                       rtnl_lock();
-                       mutex_lock(&ipvs->sync_mutex);
                        ret = start_sync_thread(ipvs, &cfg, dm->state);
-                       mutex_unlock(&ipvs->sync_mutex);
-                       rtnl_unlock();
                } else {
                        mutex_lock(&ipvs->sync_mutex);
                        ret = stop_sync_thread(ipvs, dm->state);
@@ -3481,12 +3477,8 @@ static int ip_vs_genl_new_daemon(struct netns_ipvs *ipvs, struct nlattr **attrs)
        if (ipvs->mixed_address_family_dests > 0)
                return -EINVAL;
 
-       rtnl_lock();
-       mutex_lock(&ipvs->sync_mutex);
        ret = start_sync_thread(ipvs, &c,
                                nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]));
-       mutex_unlock(&ipvs->sync_mutex);
-       rtnl_unlock();
        return ret;
 }
 
index fbaf3bd05b2ec9051734849cf1ab0fdf15dea386..001501e25625fcd3f87a22fec4c4e013c90b3b8d 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/kernel.h>
+#include <linux/sched/signal.h>
 
 #include <asm/unaligned.h>             /* Used for ntoh_seq and hton_seq */
 
@@ -1360,15 +1361,9 @@ static void set_mcast_pmtudisc(struct sock *sk, int val)
 /*
  *      Specifiy default interface for outgoing multicasts
  */
-static int set_mcast_if(struct sock *sk, char *ifname)
+static int set_mcast_if(struct sock *sk, struct net_device *dev)
 {
-       struct net_device *dev;
        struct inet_sock *inet = inet_sk(sk);
-       struct net *net = sock_net(sk);
-
-       dev = __dev_get_by_name(net, ifname);
-       if (!dev)
-               return -ENODEV;
 
        if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
                return -EINVAL;
@@ -1396,19 +1391,14 @@ static int set_mcast_if(struct sock *sk, char *ifname)
  *      in the in_addr structure passed in as a parameter.
  */
 static int
-join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
+join_mcast_group(struct sock *sk, struct in_addr *addr, struct net_device *dev)
 {
-       struct net *net = sock_net(sk);
        struct ip_mreqn mreq;
-       struct net_device *dev;
        int ret;
 
        memset(&mreq, 0, sizeof(mreq));
        memcpy(&mreq.imr_multiaddr, addr, sizeof(struct in_addr));
 
-       dev = __dev_get_by_name(net, ifname);
-       if (!dev)
-               return -ENODEV;
        if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
                return -EINVAL;
 
@@ -1423,15 +1413,10 @@ join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
 
 #ifdef CONFIG_IP_VS_IPV6
 static int join_mcast_group6(struct sock *sk, struct in6_addr *addr,
-                            char *ifname)
+                            struct net_device *dev)
 {
-       struct net *net = sock_net(sk);
-       struct net_device *dev;
        int ret;
 
-       dev = __dev_get_by_name(net, ifname);
-       if (!dev)
-               return -ENODEV;
        if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
                return -EINVAL;
 
@@ -1443,24 +1428,18 @@ static int join_mcast_group6(struct sock *sk, struct in6_addr *addr,
 }
 #endif
 
-static int bind_mcastif_addr(struct socket *sock, char *ifname)
+static int bind_mcastif_addr(struct socket *sock, struct net_device *dev)
 {
-       struct net *net = sock_net(sock->sk);
-       struct net_device *dev;
        __be32 addr;
        struct sockaddr_in sin;
 
-       dev = __dev_get_by_name(net, ifname);
-       if (!dev)
-               return -ENODEV;
-
        addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
        if (!addr)
                pr_err("You probably need to specify IP address on "
                       "multicast interface.\n");
 
        IP_VS_DBG(7, "binding socket with (%s) %pI4\n",
-                 ifname, &addr);
+                 dev->name, &addr);
 
        /* Now bind the socket with the address of multicast interface */
        sin.sin_family       = AF_INET;
@@ -1493,7 +1472,8 @@ static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen,
 /*
  *      Set up sending multicast socket over UDP
  */
-static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
+static int make_send_sock(struct netns_ipvs *ipvs, int id,
+                         struct net_device *dev, struct socket **sock_ret)
 {
        /* multicast addr */
        union ipvs_sockaddr mcast_addr;
@@ -1505,9 +1485,10 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
                                  IPPROTO_UDP, &sock);
        if (result < 0) {
                pr_err("Error during creation of socket; terminating\n");
-               return ERR_PTR(result);
+               goto error;
        }
-       result = set_mcast_if(sock->sk, ipvs->mcfg.mcast_ifn);
+       *sock_ret = sock;
+       result = set_mcast_if(sock->sk, dev);
        if (result < 0) {
                pr_err("Error setting outbound mcast interface\n");
                goto error;
@@ -1522,7 +1503,7 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
                set_sock_size(sock->sk, 1, result);
 
        if (AF_INET == ipvs->mcfg.mcast_af)
-               result = bind_mcastif_addr(sock, ipvs->mcfg.mcast_ifn);
+               result = bind_mcastif_addr(sock, dev);
        else
                result = 0;
        if (result < 0) {
@@ -1538,19 +1519,18 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
                goto error;
        }
 
-       return sock;
+       return 0;
 
 error:
-       sock_release(sock);
-       return ERR_PTR(result);
+       return result;
 }
 
 
 /*
  *      Set up receiving multicast socket over UDP
  */
-static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
-                                       int ifindex)
+static int make_receive_sock(struct netns_ipvs *ipvs, int id,
+                            struct net_device *dev, struct socket **sock_ret)
 {
        /* multicast addr */
        union ipvs_sockaddr mcast_addr;
@@ -1562,8 +1542,9 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
                                  IPPROTO_UDP, &sock);
        if (result < 0) {
                pr_err("Error during creation of socket; terminating\n");
-               return ERR_PTR(result);
+               goto error;
        }
+       *sock_ret = sock;
        /* it is equivalent to the REUSEADDR option in user-space */
        sock->sk->sk_reuse = SK_CAN_REUSE;
        result = sysctl_sync_sock_size(ipvs);
@@ -1571,7 +1552,7 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
                set_sock_size(sock->sk, 0, result);
 
        get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
-       sock->sk->sk_bound_dev_if = ifindex;
+       sock->sk->sk_bound_dev_if = dev->ifindex;
        result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
        if (result < 0) {
                pr_err("Error binding to the multicast addr\n");
@@ -1582,21 +1563,20 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
 #ifdef CONFIG_IP_VS_IPV6
        if (ipvs->bcfg.mcast_af == AF_INET6)
                result = join_mcast_group6(sock->sk, &mcast_addr.in6.sin6_addr,
-                                          ipvs->bcfg.mcast_ifn);
+                                          dev);
        else
 #endif
                result = join_mcast_group(sock->sk, &mcast_addr.in.sin_addr,
-                                         ipvs->bcfg.mcast_ifn);
+                                         dev);
        if (result < 0) {
                pr_err("Error joining to the multicast group\n");
                goto error;
        }
 
-       return sock;
+       return 0;
 
 error:
-       sock_release(sock);
-       return ERR_PTR(result);
+       return result;
 }
 
 
@@ -1778,13 +1758,12 @@ static int sync_thread_backup(void *data)
 int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
                      int state)
 {
-       struct ip_vs_sync_thread_data *tinfo;
+       struct ip_vs_sync_thread_data *tinfo = NULL;
        struct task_struct **array = NULL, *task;
-       struct socket *sock;
        struct net_device *dev;
        char *name;
        int (*threadfn)(void *data);
-       int id, count, hlen;
+       int id = 0, count, hlen;
        int result = -ENOMEM;
        u16 mtu, min_mtu;
 
@@ -1792,6 +1771,18 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
        IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n",
                  sizeof(struct ip_vs_sync_conn_v0));
 
+       /* Do not hold one mutex and then to block on another */
+       for (;;) {
+               rtnl_lock();
+               if (mutex_trylock(&ipvs->sync_mutex))
+                       break;
+               rtnl_unlock();
+               mutex_lock(&ipvs->sync_mutex);
+               if (rtnl_trylock())
+                       break;
+               mutex_unlock(&ipvs->sync_mutex);
+       }
+
        if (!ipvs->sync_state) {
                count = clamp(sysctl_sync_ports(ipvs), 1, IPVS_SYNC_PORTS_MAX);
                ipvs->threads_mask = count - 1;
@@ -1810,7 +1801,8 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
        dev = __dev_get_by_name(ipvs->net, c->mcast_ifn);
        if (!dev) {
                pr_err("Unknown mcast interface: %s\n", c->mcast_ifn);
-               return -ENODEV;
+               result = -ENODEV;
+               goto out_early;
        }
        hlen = (AF_INET6 == c->mcast_af) ?
               sizeof(struct ipv6hdr) + sizeof(struct udphdr) :
@@ -1827,26 +1819,30 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
                c->sync_maxlen = mtu - hlen;
 
        if (state == IP_VS_STATE_MASTER) {
+               result = -EEXIST;
                if (ipvs->ms)
-                       return -EEXIST;
+                       goto out_early;
 
                ipvs->mcfg = *c;
                name = "ipvs-m:%d:%d";
                threadfn = sync_thread_master;
        } else if (state == IP_VS_STATE_BACKUP) {
+               result = -EEXIST;
                if (ipvs->backup_threads)
-                       return -EEXIST;
+                       goto out_early;
 
                ipvs->bcfg = *c;
                name = "ipvs-b:%d:%d";
                threadfn = sync_thread_backup;
        } else {
-               return -EINVAL;
+               result = -EINVAL;
+               goto out_early;
        }
 
        if (state == IP_VS_STATE_MASTER) {
                struct ipvs_master_sync_state *ms;
 
+               result = -ENOMEM;
                ipvs->ms = kcalloc(count, sizeof(ipvs->ms[0]), GFP_KERNEL);
                if (!ipvs->ms)
                        goto out;
@@ -1862,39 +1858,38 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
        } else {
                array = kcalloc(count, sizeof(struct task_struct *),
                                GFP_KERNEL);
+               result = -ENOMEM;
                if (!array)
                        goto out;
        }
 
-       tinfo = NULL;
        for (id = 0; id < count; id++) {
-               if (state == IP_VS_STATE_MASTER)
-                       sock = make_send_sock(ipvs, id);
-               else
-                       sock = make_receive_sock(ipvs, id, dev->ifindex);
-               if (IS_ERR(sock)) {
-                       result = PTR_ERR(sock);
-                       goto outtinfo;
-               }
+               result = -ENOMEM;
                tinfo = kmalloc(sizeof(*tinfo), GFP_KERNEL);
                if (!tinfo)
-                       goto outsocket;
+                       goto out;
                tinfo->ipvs = ipvs;
-               tinfo->sock = sock;
+               tinfo->sock = NULL;
                if (state == IP_VS_STATE_BACKUP) {
                        tinfo->buf = kmalloc(ipvs->bcfg.sync_maxlen,
                                             GFP_KERNEL);
                        if (!tinfo->buf)
-                               goto outtinfo;
+                               goto out;
                } else {
                        tinfo->buf = NULL;
                }
                tinfo->id = id;
+               if (state == IP_VS_STATE_MASTER)
+                       result = make_send_sock(ipvs, id, dev, &tinfo->sock);
+               else
+                       result = make_receive_sock(ipvs, id, dev, &tinfo->sock);
+               if (result < 0)
+                       goto out;
 
                task = kthread_run(threadfn, tinfo, name, ipvs->gen, id);
                if (IS_ERR(task)) {
                        result = PTR_ERR(task);
-                       goto outtinfo;
+                       goto out;
                }
                tinfo = NULL;
                if (state == IP_VS_STATE_MASTER)
@@ -1911,20 +1906,20 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
        ipvs->sync_state |= state;
        spin_unlock_bh(&ipvs->sync_buff_lock);
 
+       mutex_unlock(&ipvs->sync_mutex);
+       rtnl_unlock();
+
        /* increase the module use count */
        ip_vs_use_count_inc();
 
        return 0;
 
-outsocket:
-       sock_release(sock);
-
-outtinfo:
-       if (tinfo) {
-               sock_release(tinfo->sock);
-               kfree(tinfo->buf);
-               kfree(tinfo);
-       }
+out:
+       /* We do not need RTNL lock anymore, release it here so that
+        * sock_release below and in the kthreads can use rtnl_lock
+        * to leave the mcast group.
+        */
+       rtnl_unlock();
        count = id;
        while (count-- > 0) {
                if (state == IP_VS_STATE_MASTER)
@@ -1932,13 +1927,23 @@ outtinfo:
                else
                        kthread_stop(array[count]);
        }
-       kfree(array);
-
-out:
        if (!(ipvs->sync_state & IP_VS_STATE_MASTER)) {
                kfree(ipvs->ms);
                ipvs->ms = NULL;
        }
+       mutex_unlock(&ipvs->sync_mutex);
+       if (tinfo) {
+               if (tinfo->sock)
+                       sock_release(tinfo->sock);
+               kfree(tinfo->buf);
+               kfree(tinfo);
+       }
+       kfree(array);
+       return result;
+
+out_early:
+       mutex_unlock(&ipvs->sync_mutex);
+       rtnl_unlock();
        return result;
 }
 
index 8ef21d9f9a00d960ff3f26396b1736cfb1898d36..4b2b3d53acfcabfbe8fd4899f6ed825289387143 100644 (file)
@@ -252,7 +252,7 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
 static inline int expect_matches(const struct nf_conntrack_expect *a,
                                 const struct nf_conntrack_expect *b)
 {
-       return a->master == b->master && a->class == b->class &&
+       return a->master == b->master &&
               nf_ct_tuple_equal(&a->tuple, &b->tuple) &&
               nf_ct_tuple_mask_equal(&a->mask, &b->mask) &&
               net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) &&
@@ -421,6 +421,9 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
        h = nf_ct_expect_dst_hash(net, &expect->tuple);
        hlist_for_each_entry_safe(i, next, &nf_ct_expect_hash[h], hnode) {
                if (expect_matches(i, expect)) {
+                       if (i->class != expect->class)
+                               return -EALREADY;
+
                        if (nf_ct_remove_expect(i))
                                break;
                } else if (expect_clash(i, expect)) {
index 9fe0ddc333fbb263d98e639b1cb869b24e0b619c..277bbfe26478bae483ce7f0543a4977402ca9040 100644 (file)
@@ -9,6 +9,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
+#include <linux/kmemleak.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
@@ -71,6 +72,7 @@ void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
        rcu_read_unlock();
 
        alloc = max(newlen, NF_CT_EXT_PREALLOC);
+       kmemleak_not_leak(old);
        new = __krealloc(old, alloc, gfp);
        if (!new)
                return NULL;
index 4dbb5bad4363ba9f67fea15160bb7b0b88ae9c38..908e51e2dc2b35b1a74a374b00745b0323d21d90 100644 (file)
@@ -938,11 +938,19 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
                                       datalen, rtp_exp, rtcp_exp,
                                       mediaoff, medialen, daddr);
        else {
-               if (nf_ct_expect_related(rtp_exp) == 0) {
-                       if (nf_ct_expect_related(rtcp_exp) != 0)
-                               nf_ct_unexpect_related(rtp_exp);
-                       else
+               /* -EALREADY handling works around end-points that send
+                * SDP messages with identical port but different media type,
+                * we pretend expectation was set up.
+                */
+               int errp = nf_ct_expect_related(rtp_exp);
+
+               if (errp == 0 || errp == -EALREADY) {
+                       int errcp = nf_ct_expect_related(rtcp_exp);
+
+                       if (errcp == 0 || errcp == -EALREADY)
                                ret = NF_ACCEPT;
+                       else if (errp == 0)
+                               nf_ct_unexpect_related(rtp_exp);
                }
        }
        nf_ct_expect_put(rtcp_exp);
index 9134cc429ad485aa86301019f50fb4f5d2172b52..04d4e377258409dbd2b554a139215c6a8c4d8b51 100644 (file)
@@ -2361,41 +2361,46 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
        }
 
        if (nlh->nlmsg_flags & NLM_F_REPLACE) {
-               if (nft_is_active_next(net, old_rule)) {
-                       trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
-                                                  old_rule);
-                       if (trans == NULL) {
-                               err = -ENOMEM;
-                               goto err2;
-                       }
-                       nft_deactivate_next(net, old_rule);
-                       chain->use--;
-                       list_add_tail_rcu(&rule->list, &old_rule->list);
-               } else {
+               if (!nft_is_active_next(net, old_rule)) {
                        err = -ENOENT;
                        goto err2;
                }
-       } else if (nlh->nlmsg_flags & NLM_F_APPEND)
-               if (old_rule)
-                       list_add_rcu(&rule->list, &old_rule->list);
-               else
-                       list_add_tail_rcu(&rule->list, &chain->rules);
-       else {
-               if (old_rule)
-                       list_add_tail_rcu(&rule->list, &old_rule->list);
-               else
-                       list_add_rcu(&rule->list, &chain->rules);
-       }
+               trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
+                                          old_rule);
+               if (trans == NULL) {
+                       err = -ENOMEM;
+                       goto err2;
+               }
+               nft_deactivate_next(net, old_rule);
+               chain->use--;
 
-       if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
-               err = -ENOMEM;
-               goto err3;
+               if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
+                       err = -ENOMEM;
+                       goto err2;
+               }
+
+               list_add_tail_rcu(&rule->list, &old_rule->list);
+       } else {
+               if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
+                       err = -ENOMEM;
+                       goto err2;
+               }
+
+               if (nlh->nlmsg_flags & NLM_F_APPEND) {
+                       if (old_rule)
+                               list_add_rcu(&rule->list, &old_rule->list);
+                       else
+                               list_add_tail_rcu(&rule->list, &chain->rules);
+                } else {
+                       if (old_rule)
+                               list_add_tail_rcu(&rule->list, &old_rule->list);
+                       else
+                               list_add_rcu(&rule->list, &chain->rules);
+               }
        }
        chain->use++;
        return 0;
 
-err3:
-       list_del_rcu(&rule->list);
 err2:
        nf_tables_rule_destroy(&ctx, rule);
 err1:
@@ -3207,18 +3212,20 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
 
        err = ops->init(set, &desc, nla);
        if (err < 0)
-               goto err2;
+               goto err3;
 
        err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
        if (err < 0)
-               goto err3;
+               goto err4;
 
        list_add_tail_rcu(&set->list, &table->sets);
        table->use++;
        return 0;
 
-err3:
+err4:
        ops->destroy(set);
+err3:
+       kfree(set->name);
 err2:
        kvfree(set);
 err1:
@@ -5738,7 +5745,7 @@ static void nft_chain_commit_update(struct nft_trans *trans)
        struct nft_base_chain *basechain;
 
        if (nft_trans_chain_name(trans))
-               strcpy(trans->ctx.chain->name, nft_trans_chain_name(trans));
+               swap(trans->ctx.chain->name, nft_trans_chain_name(trans));
 
        if (!nft_is_base_chain(trans->ctx.chain))
                return;
index 773da82190dc32afc82d9b3a2d792f92660a4612..94df000abb92d657addb2cad35028a2d3f08e024 100644 (file)
@@ -36,11 +36,10 @@ MODULE_ALIAS("ipt_connmark");
 MODULE_ALIAS("ip6t_connmark");
 
 static unsigned int
-connmark_tg_shift(struct sk_buff *skb,
-               const struct xt_connmark_tginfo1 *info,
-               u8 shift_bits, u8 shift_dir)
+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
 {
        enum ip_conntrack_info ctinfo;
+       u_int32_t new_targetmark;
        struct nf_conn *ct;
        u_int32_t newmark;
 
@@ -51,34 +50,39 @@ connmark_tg_shift(struct sk_buff *skb,
        switch (info->mode) {
        case XT_CONNMARK_SET:
                newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
-               if (shift_dir == D_SHIFT_RIGHT)
-                       newmark >>= shift_bits;
+               if (info->shift_dir == D_SHIFT_RIGHT)
+                       newmark >>= info->shift_bits;
                else
-                       newmark <<= shift_bits;
+                       newmark <<= info->shift_bits;
+
                if (ct->mark != newmark) {
                        ct->mark = newmark;
                        nf_conntrack_event_cache(IPCT_MARK, ct);
                }
                break;
        case XT_CONNMARK_SAVE:
-               newmark = (ct->mark & ~info->ctmask) ^
-                         (skb->mark & info->nfmask);
-               if (shift_dir == D_SHIFT_RIGHT)
-                       newmark >>= shift_bits;
+               new_targetmark = (skb->mark & info->nfmask);
+               if (info->shift_dir == D_SHIFT_RIGHT)
+                       new_targetmark >>= info->shift_bits;
                else
-                       newmark <<= shift_bits;
+                       new_targetmark <<= info->shift_bits;
+
+               newmark = (ct->mark & ~info->ctmask) ^
+                         new_targetmark;
                if (ct->mark != newmark) {
                        ct->mark = newmark;
                        nf_conntrack_event_cache(IPCT_MARK, ct);
                }
                break;
        case XT_CONNMARK_RESTORE:
-               newmark = (skb->mark & ~info->nfmask) ^
-                         (ct->mark & info->ctmask);
-               if (shift_dir == D_SHIFT_RIGHT)
-                       newmark >>= shift_bits;
+               new_targetmark = (ct->mark & info->ctmask);
+               if (info->shift_dir == D_SHIFT_RIGHT)
+                       new_targetmark >>= info->shift_bits;
                else
-                       newmark <<= shift_bits;
+                       new_targetmark <<= info->shift_bits;
+
+               newmark = (skb->mark & ~info->nfmask) ^
+                         new_targetmark;
                skb->mark = newmark;
                break;
        }
@@ -89,8 +93,14 @@ static unsigned int
 connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct xt_connmark_tginfo1 *info = par->targinfo;
-
-       return connmark_tg_shift(skb, info, 0, 0);
+       const struct xt_connmark_tginfo2 info2 = {
+               .ctmark = info->ctmark,
+               .ctmask = info->ctmask,
+               .nfmask = info->nfmask,
+               .mode   = info->mode,
+       };
+
+       return connmark_tg_shift(skb, &info2);
 }
 
 static unsigned int
@@ -98,8 +108,7 @@ connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct xt_connmark_tginfo2 *info = par->targinfo;
 
-       return connmark_tg_shift(skb, (const struct xt_connmark_tginfo1 *)info,
-                                info->shift_bits, info->shift_dir);
+       return connmark_tg_shift(skb, info);
 }
 
 static int connmark_tg_check(const struct xt_tgchk_param *par)
index 616cb9c18f88edd759dfb461051670c225978afa..01f3515cada0da4c2b2a7e314a5feb8406993f49 100644 (file)
@@ -329,11 +329,11 @@ static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
        skb_set_queue_mapping(skb, queue_index);
 }
 
-/* register_prot_hook must be invoked with the po->bind_lock held,
+/* __register_prot_hook must be invoked through register_prot_hook
  * or from a context in which asynchronous accesses to the packet
  * socket is not possible (packet_create()).
  */
-static void register_prot_hook(struct sock *sk)
+static void __register_prot_hook(struct sock *sk)
 {
        struct packet_sock *po = pkt_sk(sk);
 
@@ -348,8 +348,13 @@ static void register_prot_hook(struct sock *sk)
        }
 }
 
-/* {,__}unregister_prot_hook() must be invoked with the po->bind_lock
- * held.   If the sync parameter is true, we will temporarily drop
+static void register_prot_hook(struct sock *sk)
+{
+       lockdep_assert_held_once(&pkt_sk(sk)->bind_lock);
+       __register_prot_hook(sk);
+}
+
+/* If the sync parameter is true, we will temporarily drop
  * the po->bind_lock and do a synchronize_net to make sure no
  * asynchronous packet processing paths still refer to the elements
  * of po->prot_hook.  If the sync parameter is false, it is the
@@ -359,6 +364,8 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
 {
        struct packet_sock *po = pkt_sk(sk);
 
+       lockdep_assert_held_once(&po->bind_lock);
+
        po->running = 0;
 
        if (po->fanout)
@@ -3008,6 +3015,7 @@ static int packet_release(struct socket *sock)
 
        packet_flush_mclist(sk);
 
+       lock_sock(sk);
        if (po->rx_ring.pg_vec) {
                memset(&req_u, 0, sizeof(req_u));
                packet_set_ring(sk, &req_u, 1, 0);
@@ -3017,6 +3025,7 @@ static int packet_release(struct socket *sock)
                memset(&req_u, 0, sizeof(req_u));
                packet_set_ring(sk, &req_u, 1, 1);
        }
+       release_sock(sk);
 
        f = fanout_release(sk);
 
@@ -3250,7 +3259,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
 
        if (proto) {
                po->prot_hook.type = proto;
-               register_prot_hook(sk);
+               __register_prot_hook(sk);
        }
 
        mutex_lock(&net->packet.sklist_lock);
@@ -3643,6 +3652,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                union tpacket_req_u req_u;
                int len;
 
+               lock_sock(sk);
                switch (po->tp_version) {
                case TPACKET_V1:
                case TPACKET_V2:
@@ -3653,12 +3663,17 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                        len = sizeof(req_u.req3);
                        break;
                }
-               if (optlen < len)
-                       return -EINVAL;
-               if (copy_from_user(&req_u.req, optval, len))
-                       return -EFAULT;
-               return packet_set_ring(sk, &req_u, 0,
-                       optname == PACKET_TX_RING);
+               if (optlen < len) {
+                       ret = -EINVAL;
+               } else {
+                       if (copy_from_user(&req_u.req, optval, len))
+                               ret = -EFAULT;
+                       else
+                               ret = packet_set_ring(sk, &req_u, 0,
+                                                   optname == PACKET_TX_RING);
+               }
+               release_sock(sk);
+               return ret;
        }
        case PACKET_COPY_THRESH:
        {
@@ -3724,12 +3739,18 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
                if (optlen != sizeof(val))
                        return -EINVAL;
-               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-                       return -EBUSY;
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
-               po->tp_loss = !!val;
-               return 0;
+
+               lock_sock(sk);
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+                       ret = -EBUSY;
+               } else {
+                       po->tp_loss = !!val;
+                       ret = 0;
+               }
+               release_sock(sk);
+               return ret;
        }
        case PACKET_AUXDATA:
        {
@@ -3740,7 +3761,9 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
 
+               lock_sock(sk);
                po->auxdata = !!val;
+               release_sock(sk);
                return 0;
        }
        case PACKET_ORIGDEV:
@@ -3752,7 +3775,9 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
 
+               lock_sock(sk);
                po->origdev = !!val;
+               release_sock(sk);
                return 0;
        }
        case PACKET_VNET_HDR:
@@ -3761,15 +3786,20 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
                if (sock->type != SOCK_RAW)
                        return -EINVAL;
-               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-                       return -EBUSY;
                if (optlen < sizeof(val))
                        return -EINVAL;
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
 
-               po->has_vnet_hdr = !!val;
-               return 0;
+               lock_sock(sk);
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+                       ret = -EBUSY;
+               } else {
+                       po->has_vnet_hdr = !!val;
+                       ret = 0;
+               }
+               release_sock(sk);
+               return ret;
        }
        case PACKET_TIMESTAMP:
        {
@@ -3807,11 +3837,17 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
                if (optlen != sizeof(val))
                        return -EINVAL;
-               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-                       return -EBUSY;
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
-               po->tp_tx_has_off = !!val;
+
+               lock_sock(sk);
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+                       ret = -EBUSY;
+               } else {
+                       po->tp_tx_has_off = !!val;
+                       ret = 0;
+               }
+               release_sock(sk);
                return 0;
        }
        case PACKET_QDISC_BYPASS:
@@ -4208,8 +4244,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
        /* Added to avoid minimal code churn */
        struct tpacket_req *req = &req_u->req;
 
-       lock_sock(sk);
-
        rb = tx_ring ? &po->tx_ring : &po->rx_ring;
        rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
 
@@ -4347,7 +4381,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
        if (pg_vec)
                free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
-       release_sock(sk);
        return err;
 }
 
index a1d2b2319ae990d55bb3c469cc1ba404cadcbdb9..3bb7c5fb3bff2fd5d91c3d973d006d0cdde29a0b 100644 (file)
@@ -112,10 +112,12 @@ struct packet_sock {
        int                     copy_thresh;
        spinlock_t              bind_lock;
        struct mutex            pg_vec_lock;
-       unsigned int            running:1,      /* prot_hook is attached*/
-                               auxdata:1,
+       unsigned int            running;        /* bind_lock must be held */
+       unsigned int            auxdata:1,      /* writer must hold sock lock */
                                origdev:1,
-                               has_vnet_hdr:1;
+                               has_vnet_hdr:1,
+                               tp_loss:1,
+                               tp_tx_has_off:1;
        int                     pressure;
        int                     ifindex;        /* bound device         */
        __be16                  num;
@@ -125,8 +127,6 @@ struct packet_sock {
        enum tpacket_versions   tp_version;
        unsigned int            tp_hdrlen;
        unsigned int            tp_reserve;
-       unsigned int            tp_loss:1;
-       unsigned int            tp_tx_has_off:1;
        unsigned int            tp_tstamp;
        struct net_device __rcu *cached_dev;
        int                     (*xmit)(struct sk_buff *skb);
index b33e5aeb4c06d30b9c576ed2c2adb9a1915c9492..2aa07b547b1685a6aa96155c559dbefd21150281 100644 (file)
@@ -1135,3 +1135,4 @@ module_exit(qrtr_proto_fini);
 
 MODULE_DESCRIPTION("Qualcomm IPC-router driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_NETPROTO(PF_QIPCRTR);
index a5994cf0512bd731f55a1dfa798d85ff658e18ef..8527cfdc446d9bb82e8fa9fe1364dc13249b1e03 100644 (file)
@@ -652,7 +652,7 @@ static int find_decode_metaid(struct sk_buff *skb, struct tcf_ife_info *ife,
                }
        }
 
-       return 0;
+       return -ENOENT;
 }
 
 static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
@@ -682,7 +682,12 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
                u16 mtype;
                u16 dlen;
 
-               curr_data = ife_tlv_meta_decode(tlv_data, &mtype, &dlen, NULL);
+               curr_data = ife_tlv_meta_decode(tlv_data, ifehdr_end, &mtype,
+                                               &dlen, NULL);
+               if (!curr_data) {
+                       qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats));
+                       return TC_ACT_SHOT;
+               }
 
                if (find_decode_metaid(skb, ife, mtype, dlen, curr_data)) {
                        /* abuse overlimits to count when we receive metadata
index 31083b5035ecf6412abced7a939d8b1b8f53a302..2e3f7b75a8ece789fbbc722754200ad8505b5d64 100644 (file)
@@ -556,46 +556,49 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
        addr->v6.sin6_scope_id = 0;
 }
 
-/* Compare addresses exactly.
- * v4-mapped-v6 is also in consideration.
- */
-static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
-                           const union sctp_addr *addr2)
+static int __sctp_v6_cmp_addr(const union sctp_addr *addr1,
+                             const union sctp_addr *addr2)
 {
        if (addr1->sa.sa_family != addr2->sa.sa_family) {
                if (addr1->sa.sa_family == AF_INET &&
                    addr2->sa.sa_family == AF_INET6 &&
-                   ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) {
-                       if (addr2->v6.sin6_port == addr1->v4.sin_port &&
-                           addr2->v6.sin6_addr.s6_addr32[3] ==
-                           addr1->v4.sin_addr.s_addr)
-                               return 1;
-               }
+                   ipv6_addr_v4mapped(&addr2->v6.sin6_addr) &&
+                   addr2->v6.sin6_addr.s6_addr32[3] ==
+                   addr1->v4.sin_addr.s_addr)
+                       return 1;
+
                if (addr2->sa.sa_family == AF_INET &&
                    addr1->sa.sa_family == AF_INET6 &&
-                   ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) {
-                       if (addr1->v6.sin6_port == addr2->v4.sin_port &&
-                           addr1->v6.sin6_addr.s6_addr32[3] ==
-                           addr2->v4.sin_addr.s_addr)
-                               return 1;
-               }
+                   ipv6_addr_v4mapped(&addr1->v6.sin6_addr) &&
+                   addr1->v6.sin6_addr.s6_addr32[3] ==
+                   addr2->v4.sin_addr.s_addr)
+                       return 1;
+
                return 0;
        }
-       if (addr1->v6.sin6_port != addr2->v6.sin6_port)
-               return 0;
+
        if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
                return 0;
+
        /* If this is a linklocal address, compare the scope_id. */
-       if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-               if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
-                   (addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) {
-                       return 0;
-               }
-       }
+       if ((ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
+           addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
+           addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)
+               return 0;
 
        return 1;
 }
 
+/* Compare addresses exactly.
+ * v4-mapped-v6 is also in consideration.
+ */
+static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
+                           const union sctp_addr *addr2)
+{
+       return __sctp_v6_cmp_addr(addr1, addr2) &&
+              addr1->v6.sin6_port == addr2->v6.sin6_port;
+}
+
 /* Initialize addr struct to INADDR_ANY. */
 static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port)
 {
@@ -875,8 +878,8 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
                               const union sctp_addr *addr2,
                               struct sctp_sock *opt)
 {
-       struct sctp_af *af1, *af2;
        struct sock *sk = sctp_opt2sk(opt);
+       struct sctp_af *af1, *af2;
 
        af1 = sctp_get_af_specific(addr1->sa.sa_family);
        af2 = sctp_get_af_specific(addr2->sa.sa_family);
@@ -892,10 +895,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
        if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
                return 1;
 
-       if (addr1->sa.sa_family != addr2->sa.sa_family)
-               return 0;
-
-       return af1->cmp_addr(addr1, addr2);
+       return __sctp_v6_cmp_addr(addr1, addr2);
 }
 
 /* Verify that the provided sockaddr looks bindable.   Common verification,
index 5f8046c62d90ba435d851d6736c81c91f1679212..f5d4b69dbabc888e85245ae5edbefcbd4cd9dc81 100644 (file)
@@ -1259,14 +1259,12 @@ static int smc_shutdown(struct socket *sock, int how)
                rc = smc_close_shutdown_write(smc);
                break;
        case SHUT_RD:
-               if (sk->sk_state == SMC_LISTEN)
-                       rc = smc_close_active(smc);
-               else
-                       rc = 0;
-                       /* nothing more to do because peer is not involved */
+               rc = 0;
+               /* nothing more to do because peer is not involved */
                break;
        }
-       rc1 = kernel_sock_shutdown(smc->clcsock, how);
+       if (smc->clcsock)
+               rc1 = kernel_sock_shutdown(smc->clcsock, how);
        /* map sock_shutdown_cmd constants to sk_shutdown value range */
        sk->sk_shutdown |= how + 1;
 
index b9283ce5cd85b5df0062b5137720b7b8afe6c3de..092bebc7004835fc4ad56a5474e16c6876c910ac 100644 (file)
@@ -67,7 +67,7 @@ static void strp_abort_strp(struct strparser *strp, int err)
 
 static void strp_start_timer(struct strparser *strp, long timeo)
 {
-       if (timeo)
+       if (timeo && timeo != LONG_MAX)
                mod_delayed_work(strp_wq, &strp->msg_timer_work, timeo);
 }
 
@@ -296,9 +296,9 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
                                        strp_start_timer(strp, timeo);
                                }
 
+                               stm->accum_len += cand_len;
                                strp->need_bytes = stm->strp.full_len -
                                                       stm->accum_len;
-                               stm->accum_len += cand_len;
                                stm->early_eaten = cand_len;
                                STRP_STATS_ADD(strp->stats.bytes, cand_len);
                                desc->count = 0; /* Stop reading socket */
@@ -321,6 +321,7 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
                /* Hurray, we have a new message! */
                cancel_delayed_work(&strp->msg_timer_work);
                strp->skb_head = NULL;
+               strp->need_bytes = 0;
                STRP_STATS_INCR(strp->stats.msgs);
 
                /* Give skb to upper layer */
@@ -410,9 +411,7 @@ void strp_data_ready(struct strparser *strp)
                return;
 
        if (strp->need_bytes) {
-               if (strp_peek_len(strp) >= strp->need_bytes)
-                       strp->need_bytes = 0;
-               else
+               if (strp_peek_len(strp) < strp->need_bytes)
                        return;
        }
 
index 0f08934b2cea01d95a57c710cb0e5f964d2d629d..c81ef5e6c9813be0d79f075e5b3d0eef54ac51f0 100644 (file)
@@ -1375,6 +1375,7 @@ rpc_gssd_dummy_depopulate(struct dentry *pipe_dentry)
        struct dentry *clnt_dir = pipe_dentry->d_parent;
        struct dentry *gssd_dir = clnt_dir->d_parent;
 
+       dget(pipe_dentry);
        __rpc_rmpipe(d_inode(clnt_dir), pipe_dentry);
        __rpc_depopulate(clnt_dir, gssd_dummy_info_file, 0, 1);
        __rpc_depopulate(gssd_dir, gssd_dummy_clnt_dir, 0, 1);
index 32dc33a94bc714f762a066389a4907e558244cd7..5453e564da8276fc2e1b7510c2dee8589f1b1f89 100644 (file)
@@ -777,7 +777,7 @@ int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg,
 
        ret = tipc_bearer_get_name(net, bearer_name, bearer_id);
        if (ret || !mon)
-               return -EINVAL;
+               return 0;
 
        hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
                          NLM_F_MULTI, TIPC_NL_MON_GET);
index b1fe20972aa91af997a60951fd34152354a22315..dd1c4fa2eb78aef7357f7e76a0be55832944e4b8 100644 (file)
@@ -241,7 +241,8 @@ err:
 static struct publication *tipc_service_remove_publ(struct net *net,
                                                    struct tipc_service *sc,
                                                    u32 lower, u32 upper,
-                                                   u32 node, u32 key)
+                                                   u32 node, u32 key,
+                                                   struct service_range **rng)
 {
        struct tipc_subscription *sub, *tmp;
        struct service_range *sr;
@@ -275,19 +276,15 @@ static struct publication *tipc_service_remove_publ(struct net *net,
 
        list_del(&p->all_publ);
        list_del(&p->local_publ);
-
-       /* Remove service range item if this was its last publication */
-       if (list_empty(&sr->all_publ)) {
+       if (list_empty(&sr->all_publ))
                last = true;
-               rb_erase(&sr->tree_node, &sc->ranges);
-               kfree(sr);
-       }
 
        /* Notify any waiting subscriptions */
        list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) {
                tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN,
                                        p->port, p->node, p->scope, last);
        }
+       *rng = sr;
        return p;
 }
 
@@ -379,13 +376,20 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
                                             u32 node, u32 key)
 {
        struct tipc_service *sc = tipc_service_find(net, type);
+       struct service_range *sr = NULL;
        struct publication *p = NULL;
 
        if (!sc)
                return NULL;
 
        spin_lock_bh(&sc->lock);
-       p = tipc_service_remove_publ(net, sc, lower, upper, node, key);
+       p = tipc_service_remove_publ(net, sc, lower, upper, node, key, &sr);
+
+       /* Remove service range item if this was its last publication */
+       if (sr && list_empty(&sr->all_publ)) {
+               rb_erase(&sr->tree_node, &sc->ranges);
+               kfree(sr);
+       }
 
        /* Delete service item if this no more publications and subscriptions */
        if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) {
@@ -665,13 +669,14 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower,
 /**
  * tipc_nametbl_subscribe - add a subscription object to the name table
  */
-void tipc_nametbl_subscribe(struct tipc_subscription *sub)
+bool tipc_nametbl_subscribe(struct tipc_subscription *sub)
 {
        struct name_table *nt = tipc_name_table(sub->net);
        struct tipc_net *tn = tipc_net(sub->net);
        struct tipc_subscr *s = &sub->evt.s;
        u32 type = tipc_sub_read(s, seq.type);
        struct tipc_service *sc;
+       bool res = true;
 
        spin_lock_bh(&tn->nametbl_lock);
        sc = tipc_service_find(sub->net, type);
@@ -685,8 +690,10 @@ void tipc_nametbl_subscribe(struct tipc_subscription *sub)
                pr_warn("Failed to subscribe for {%u,%u,%u}\n", type,
                        tipc_sub_read(s, seq.lower),
                        tipc_sub_read(s, seq.upper));
+               res = false;
        }
        spin_unlock_bh(&tn->nametbl_lock);
+       return res;
 }
 
 /**
@@ -744,16 +751,17 @@ int tipc_nametbl_init(struct net *net)
 static void tipc_service_delete(struct net *net, struct tipc_service *sc)
 {
        struct service_range *sr, *tmpr;
-       struct publication *p, *tmpb;
+       struct publication *p, *tmp;
 
        spin_lock_bh(&sc->lock);
        rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) {
-               list_for_each_entry_safe(p, tmpb,
-                                        &sr->all_publ, all_publ) {
+               list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) {
                        tipc_service_remove_publ(net, sc, p->lower, p->upper,
-                                                p->node, p->key);
+                                                p->node, p->key, &sr);
                        kfree_rcu(p, rcu);
                }
+               rb_erase(&sr->tree_node, &sc->ranges);
+               kfree(sr);
        }
        hlist_del_init_rcu(&sc->service_list);
        spin_unlock_bh(&sc->lock);
index 4b14fc28d9e24d08653454ff5a8f13b6cdd40db1..0febba41da86ed64df54f447e7eb9b63cbea30cf 100644 (file)
@@ -126,7 +126,7 @@ struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
 struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
                                             u32 lower, u32 upper,
                                             u32 node, u32 key);
-void tipc_nametbl_subscribe(struct tipc_subscription *s);
+bool tipc_nametbl_subscribe(struct tipc_subscription *s);
 void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
 int tipc_nametbl_init(struct net *net);
 void tipc_nametbl_stop(struct net *net);
index 856f9e97ea293210bea1d2003d2092482732ace9..4fbaa0464405370601cb2fd1dd3b03733836d342 100644 (file)
@@ -252,6 +252,8 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
                u64 *w0 = (u64 *)&node_id[0];
                u64 *w1 = (u64 *)&node_id[8];
 
+               if (!attrs[TIPC_NLA_NET_NODEID_W1])
+                       return -EINVAL;
                *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]);
                *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]);
                tipc_net_init(net, node_id, 0);
index b76f13f6fea10a53d00ed14a38cdf5cdf7afa44c..6ff2254088f647d4f7410c3335ccdae2e68ec522 100644 (file)
@@ -79,7 +79,10 @@ const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
 
 const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
        [TIPC_NLA_NET_UNSPEC]           = { .type = NLA_UNSPEC },
-       [TIPC_NLA_NET_ID]               = { .type = NLA_U32 }
+       [TIPC_NLA_NET_ID]               = { .type = NLA_U32 },
+       [TIPC_NLA_NET_ADDR]             = { .type = NLA_U32 },
+       [TIPC_NLA_NET_NODEID]           = { .type = NLA_U64 },
+       [TIPC_NLA_NET_NODEID_W1]        = { .type = NLA_U64 },
 };
 
 const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
index c77dd2f3c5898e5c9d05f3a9e5fa72e2dc729bd0..6f98b56dd48ece2cbedb19d6e44fd9c55488e7a9 100644 (file)
@@ -2232,8 +2232,8 @@ int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb)
        struct net *net = sock_net(skb->sk);
        u32 prev_bearer = cb->args[0];
        struct tipc_nl_msg msg;
+       int bearer_id;
        int err;
-       int i;
 
        if (prev_bearer == MAX_BEARERS)
                return 0;
@@ -2243,16 +2243,13 @@ int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb)
        msg.seq = cb->nlh->nlmsg_seq;
 
        rtnl_lock();
-       for (i = prev_bearer; i < MAX_BEARERS; i++) {
-               prev_bearer = i;
+       for (bearer_id = prev_bearer; bearer_id < MAX_BEARERS; bearer_id++) {
                err = __tipc_nl_add_monitor(net, &msg, prev_bearer);
                if (err)
-                       goto out;
+                       break;
        }
-
-out:
        rtnl_unlock();
-       cb->args[0] = prev_bearer;
+       cb->args[0] = bearer_id;
 
        return skb->len;
 }
index 1fd1c8b5ce0346cff07fa0a2218701000ced77f0..252a52ae0893261fc6f146ad81111c59f375fdce 100644 (file)
@@ -1278,7 +1278,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
        struct tipc_msg *hdr = &tsk->phdr;
        struct tipc_name_seq *seq;
        struct sk_buff_head pkts;
-       u32 dnode, dport;
+       u32 dport, dnode = 0;
        u32 type, inst;
        int mtu, rc;
 
@@ -1348,6 +1348,8 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
                msg_set_destnode(hdr, dnode);
                msg_set_destport(hdr, dest->addr.id.ref);
                msg_set_hdr_sz(hdr, BASIC_H_SIZE);
+       } else {
+               return -EINVAL;
        }
 
        /* Block or return if destination link is congested */
index b7d80bc5f4abcb6dad2df7f6a5489b6b048f27dc..f340e53da62582a879dfe2b4d8080d846378f26b 100644 (file)
@@ -153,7 +153,10 @@ struct tipc_subscription *tipc_sub_subscribe(struct net *net,
        memcpy(&sub->evt.s, s, sizeof(*s));
        spin_lock_init(&sub->lock);
        kref_init(&sub->kref);
-       tipc_nametbl_subscribe(sub);
+       if (!tipc_nametbl_subscribe(sub)) {
+               kfree(sub);
+               return NULL;
+       }
        timer_setup(&sub->timer, tipc_sub_timeout, 0);
        timeout = tipc_sub_read(&sub->evt.s, timeout);
        if (timeout != TIPC_WAIT_FOREVER)
index 4dc766b03f0056ae87f36422fe592078424210a3..71e79597f940a20b7eb49d35e5bcccf5d2c60963 100644 (file)
@@ -41,6 +41,8 @@
 #include <net/strparser.h>
 #include <net/tls.h>
 
+#define MAX_IV_SIZE    TLS_CIPHER_AES_GCM_128_IV_SIZE
+
 static int tls_do_decryption(struct sock *sk,
                             struct scatterlist *sgin,
                             struct scatterlist *sgout,
@@ -673,7 +675,7 @@ static int decrypt_skb(struct sock *sk, struct sk_buff *skb,
 {
        struct tls_context *tls_ctx = tls_get_ctx(sk);
        struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
-       char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + tls_ctx->rx.iv_size];
+       char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + MAX_IV_SIZE];
        struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
        struct scatterlist *sgin = &sgin_arr[0];
        struct strp_msg *rxm = strp_msg(skb);
@@ -1094,6 +1096,12 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
                goto free_priv;
        }
 
+       /* Sanity-check the IV size for stack allocations. */
+       if (iv_size > MAX_IV_SIZE) {
+               rc = -EINVAL;
+               goto free_priv;
+       }
+
        cctx->prepend_size = TLS_HEADER_SIZE + nonce_size;
        cctx->tag_size = tag_size;
        cctx->overhead_size = cctx->prepend_size + cctx->tag_size;
index aac9b8f6552e670c2fef8d7c77c90618c65a7fc8..c1076c19b8580688ff041f71aee0d05ce0906030 100644 (file)
@@ -2018,7 +2018,13 @@ const struct vsock_transport *vsock_core_get_transport(void)
 }
 EXPORT_SYMBOL_GPL(vsock_core_get_transport);
 
+static void __exit vsock_exit(void)
+{
+       /* Do nothing.  This function makes this module removable. */
+}
+
 module_init(vsock_init_tables);
+module_exit(vsock_exit);
 
 MODULE_AUTHOR("VMware, Inc.");
 MODULE_DESCRIPTION("VMware Virtual Socket Family");
index 830c55514f9f555055705eceeb50daf7daca20d5..49b13553eaaecf136e14d29f2f9cc9518471e49b 100644 (file)
@@ -56,6 +56,21 @@ struct dummy {
        unsigned long jiffies_expire;
 };
 
+/*
+ * The constructor makes more sense together with klp_shadow_get_or_alloc().
+ * In this example, it would be safe to assign the pointer also to the shadow
+ * variable returned by klp_shadow_alloc().  But we wanted to show the more
+ * complicated use of the API.
+ */
+static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
+{
+       void **shadow_leak = shadow_data;
+       void *leak = ctor_data;
+
+       *shadow_leak = leak;
+       return 0;
+}
+
 struct dummy *livepatch_fix1_dummy_alloc(void)
 {
        struct dummy *d;
@@ -74,7 +89,8 @@ struct dummy *livepatch_fix1_dummy_alloc(void)
         * pointer to handle resource release.
         */
        leak = kzalloc(sizeof(int), GFP_KERNEL);
-       klp_shadow_alloc(d, SV_LEAK, &leak, sizeof(leak), GFP_KERNEL);
+       klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
+                        shadow_leak_ctor, leak);
 
        pr_info("%s: dummy @ %p, expires @ %lx\n",
                __func__, d, d->jiffies_expire);
@@ -82,9 +98,19 @@ struct dummy *livepatch_fix1_dummy_alloc(void)
        return d;
 }
 
+static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
+{
+       void *d = obj;
+       void **shadow_leak = shadow_data;
+
+       kfree(*shadow_leak);
+       pr_info("%s: dummy @ %p, prevented leak @ %p\n",
+                        __func__, d, *shadow_leak);
+}
+
 void livepatch_fix1_dummy_free(struct dummy *d)
 {
-       void **shadow_leak, *leak;
+       void **shadow_leak;
 
        /*
         * Patch: fetch the saved SV_LEAK shadow variable, detach and
@@ -93,15 +119,10 @@ void livepatch_fix1_dummy_free(struct dummy *d)
         * was loaded.)
         */
        shadow_leak = klp_shadow_get(d, SV_LEAK);
-       if (shadow_leak) {
-               leak = *shadow_leak;
-               klp_shadow_free(d, SV_LEAK);
-               kfree(leak);
-               pr_info("%s: dummy @ %p, prevented leak @ %p\n",
-                        __func__, d, leak);
-       } else {
+       if (shadow_leak)
+               klp_shadow_free(d, SV_LEAK, livepatch_fix1_dummy_leak_dtor);
+       else
                pr_info("%s: dummy @ %p leaked!\n", __func__, d);
-       }
 
        kfree(d);
 }
@@ -147,7 +168,7 @@ static int livepatch_shadow_fix1_init(void)
 static void livepatch_shadow_fix1_exit(void)
 {
        /* Cleanup any existing SV_LEAK shadow variables */
-       klp_shadow_free_all(SV_LEAK);
+       klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
 
        WARN_ON(klp_unregister_patch(&patch));
 }
index ff9948f0ec007b77ff54a60cd6d88203d399cbc3..b34c7bf8335666e9218a61563d82da4940191df6 100644 (file)
@@ -53,39 +53,42 @@ struct dummy {
 bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies)
 {
        int *shadow_count;
-       int count;
 
        /*
         * Patch: handle in-flight dummy structures, if they do not
         * already have a SV_COUNTER shadow variable, then attach a
         * new one.
         */
-       count = 0;
        shadow_count = klp_shadow_get_or_alloc(d, SV_COUNTER,
-                                              &count, sizeof(count),
-                                              GFP_NOWAIT);
+                               sizeof(*shadow_count), GFP_NOWAIT,
+                               NULL, NULL);
        if (shadow_count)
                *shadow_count += 1;
 
        return time_after(jiffies, d->jiffies_expire);
 }
 
+static void livepatch_fix2_dummy_leak_dtor(void *obj, void *shadow_data)
+{
+       void *d = obj;
+       void **shadow_leak = shadow_data;
+
+       kfree(*shadow_leak);
+       pr_info("%s: dummy @ %p, prevented leak @ %p\n",
+                        __func__, d, *shadow_leak);
+}
+
 void livepatch_fix2_dummy_free(struct dummy *d)
 {
-       void **shadow_leak, *leak;
+       void **shadow_leak;
        int *shadow_count;
 
        /* Patch: copy the memory leak patch from the fix1 module. */
        shadow_leak = klp_shadow_get(d, SV_LEAK);
-       if (shadow_leak) {
-               leak = *shadow_leak;
-               klp_shadow_free(d, SV_LEAK);
-               kfree(leak);
-               pr_info("%s: dummy @ %p, prevented leak @ %p\n",
-                        __func__, d, leak);
-       } else {
+       if (shadow_leak)
+               klp_shadow_free(d, SV_LEAK, livepatch_fix2_dummy_leak_dtor);
+       else
                pr_info("%s: dummy @ %p leaked!\n", __func__, d);
-       }
 
        /*
         * Patch: fetch the SV_COUNTER shadow variable and display
@@ -95,7 +98,7 @@ void livepatch_fix2_dummy_free(struct dummy *d)
        if (shadow_count) {
                pr_info("%s: dummy @ %p, check counter = %d\n",
                        __func__, d, *shadow_count);
-               klp_shadow_free(d, SV_COUNTER);
+               klp_shadow_free(d, SV_COUNTER, NULL);
        }
 
        kfree(d);
@@ -142,7 +145,7 @@ static int livepatch_shadow_fix2_init(void)
 static void livepatch_shadow_fix2_exit(void)
 {
        /* Cleanup any existing SV_COUNTER shadow variables */
-       klp_shadow_free_all(SV_COUNTER);
+       klp_shadow_free_all(SV_COUNTER, NULL);
 
        WARN_ON(klp_unregister_patch(&patch));
 }
index 48620c93d6976eca3a9b1cc3c34cfe21a69c7a39..1ce701fcb3f3b5e2165eea48329d1f10718da4e7 100644 (file)
@@ -449,6 +449,8 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer,
                                magic |= VFS_CAP_FLAGS_EFFECTIVE;
                        memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
                        cap->magic_etc = cpu_to_le32(magic);
+               } else {
+                       size = -ENOMEM;
                }
        }
        kfree(tmpbuf);
index 69734b0eafd0d6941cc1a232d219e5d9705a0c42..9aa15bfc79369aebf6eaa0ef8dd32acecd7a1ec5 100644 (file)
@@ -1492,7 +1492,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
                              int op_flag)
 {
        struct snd_ctl_tlv header;
-       unsigned int *container;
+       unsigned int __user *container;
        unsigned int container_size;
        struct snd_kcontrol *kctl;
        struct snd_ctl_elem_id id;
index b719d0bd833ecb6d7560380db5eb3b78a9b040c4..06d7c40af570c05fc20e0d13e1ded5c5ff36823b 100644 (file)
@@ -27,10 +27,11 @@ static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
                                      s32 __user *src)
 {
        snd_pcm_sframes_t delay;
+       int err;
 
-       delay = snd_pcm_delay(substream);
-       if (delay < 0)
-               return delay;
+       err = snd_pcm_delay(substream, &delay);
+       if (err)
+               return err;
        if (put_user(delay, src))
                return -EFAULT;
        return 0;
index 35ffccea94c3eb6cfe7755b6c1da7547d018a9a0..0e875d5a9e8621ee378014176596207d201a2363 100644 (file)
@@ -2692,7 +2692,8 @@ static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
        return err;
 }
                
-static snd_pcm_sframes_t snd_pcm_delay(struct snd_pcm_substream *substream)
+static int snd_pcm_delay(struct snd_pcm_substream *substream,
+                        snd_pcm_sframes_t *delay)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err;
@@ -2708,7 +2709,9 @@ static snd_pcm_sframes_t snd_pcm_delay(struct snd_pcm_substream *substream)
                n += runtime->delay;
        }
        snd_pcm_stream_unlock_irq(substream);
-       return err < 0 ? err : n;
+       if (!err)
+               *delay = n;
+       return err;
 }
                
 static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
@@ -2751,6 +2754,7 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
        sync_ptr.s.status.hw_ptr = status->hw_ptr;
        sync_ptr.s.status.tstamp = status->tstamp;
        sync_ptr.s.status.suspended_state = status->suspended_state;
+       sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
        snd_pcm_stream_unlock_irq(substream);
        if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
                return -EFAULT;
@@ -2916,11 +2920,13 @@ static int snd_pcm_common_ioctl(struct file *file,
                return snd_pcm_hwsync(substream);
        case SNDRV_PCM_IOCTL_DELAY:
        {
-               snd_pcm_sframes_t delay = snd_pcm_delay(substream);
+               snd_pcm_sframes_t delay;
                snd_pcm_sframes_t __user *res = arg;
+               int err;
 
-               if (delay < 0)
-                       return delay;
+               err = snd_pcm_delay(substream, &delay);
+               if (err)
+                       return err;
                if (put_user(delay, res))
                        return -EFAULT;
                return 0;
@@ -3008,13 +3014,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
        case SNDRV_PCM_IOCTL_DROP:
                return snd_pcm_drop(substream);
        case SNDRV_PCM_IOCTL_DELAY:
-       {
-               result = snd_pcm_delay(substream);
-               if (result < 0)
-                       return result;
-               *frames = result;
-               return 0;
-       }
+               return snd_pcm_delay(substream, frames);
        default:
                return -EINVAL;
        }
@@ -3234,7 +3234,7 @@ static __poll_t snd_pcm_capture_poll(struct file *file, poll_table * wait)
 /*
  * mmap status record
  */
-static int snd_pcm_mmap_status_fault(struct vm_fault *vmf)
+static vm_fault_t snd_pcm_mmap_status_fault(struct vm_fault *vmf)
 {
        struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
        struct snd_pcm_runtime *runtime;
@@ -3270,7 +3270,7 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
 /*
  * mmap control record
  */
-static int snd_pcm_mmap_control_fault(struct vm_fault *vmf)
+static vm_fault_t snd_pcm_mmap_control_fault(struct vm_fault *vmf)
 {
        struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
        struct snd_pcm_runtime *runtime;
@@ -3359,7 +3359,7 @@ snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
 /*
  * fault callback for mmapping a RAM page
  */
-static int snd_pcm_mmap_data_fault(struct vm_fault *vmf)
+static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf)
 {
        struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
        struct snd_pcm_runtime *runtime;
index f69764d7cdd7025d3935143883c162372e3c0c7c..e30e30ba6e3984804ec325457d76d8195d69245d 100644 (file)
@@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
        struct snd_rawmidi_params params;
        unsigned int val;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(params.stream, &src->stream) ||
            get_user(params.buffer_size, &src->buffer_size) ||
            get_user(params.avail_min, &src->avail_min) ||
@@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
        params.no_active_sensing = val;
        switch (params.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                return snd_rawmidi_output_params(rfile->output, &params);
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                return snd_rawmidi_input_params(rfile->input, &params);
        }
        return -EINVAL;
@@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
        int err;
        struct snd_rawmidi_status status;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(status.stream, &src->stream))
                return -EFAULT;
 
        switch (status.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                err = snd_rawmidi_output_status(rfile->output, &status);
                break;
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                err = snd_rawmidi_input_status(rfile->input, &status);
                break;
        default:
@@ -112,16 +116,18 @@ static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
        int err;
        struct snd_rawmidi_status status;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(status.stream, &src->stream))
                return -EFAULT;
 
        switch (status.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                err = snd_rawmidi_output_status(rfile->output, &status);
                break;
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                err = snd_rawmidi_input_status(rfile->input, &status);
                break;
        default:
index c3908862bc8b63932aaa8724a50d7a5ae19a8cf3..86ca584c27b28081663e8493e7b54b5d0009784d 100644 (file)
@@ -26,6 +26,7 @@
 #include <sound/seq_oss_legacy.h>
 #include "seq_oss_readq.h"
 #include "seq_oss_writeq.h"
+#include <linux/nospec.h>
 
 
 /*
@@ -287,10 +288,10 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
 {
        struct seq_oss_synthinfo *info;
 
-       if (!snd_seq_oss_synth_is_valid(dp, dev))
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -298,6 +299,7 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
                        return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
                }
 
+               ch = array_index_nospec(ch, info->nr_voices);
                if (note == 255 && info->ch[ch].note >= 0) {
                        /* volume control */
                        int type;
@@ -347,10 +349,10 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
 {
        struct seq_oss_synthinfo *info;
 
-       if (!snd_seq_oss_synth_is_valid(dp, dev))
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -358,6 +360,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
                        return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
                }
 
+               ch = array_index_nospec(ch, info->nr_voices);
                if (info->ch[ch].note >= 0) {
                        note = info->ch[ch].note;
                        info->ch[ch].vel = 0;
@@ -381,7 +384,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
 static int
 set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       if (!snd_seq_oss_synth_info(dp, dev))
                return -ENXIO;
        
        ev->type = type;
@@ -399,7 +402,7 @@ set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note,
 static int
 set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       if (!snd_seq_oss_synth_info(dp, dev))
                return -ENXIO;
        
        ev->type = type;
index b30b2139e3f033fd71e59fbe10cfa1e25340adc6..9debd1b8fd2880fde1e0fe349a4745bdb443b477 100644 (file)
@@ -29,6 +29,7 @@
 #include "../seq_lock.h"
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/nospec.h>
 
 
 /*
@@ -315,6 +316,7 @@ get_mididev(struct seq_oss_devinfo *dp, int dev)
 {
        if (dev < 0 || dev >= dp->max_mididev)
                return NULL;
+       dev = array_index_nospec(dev, dp->max_mididev);
        return get_mdev(dev);
 }
 
index cd0e0ebbfdb1a1931b50f0fc9d70cdd08c17f740..278ebb9931225998dd07f0606eeabe289d71aff5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/nospec.h>
 
 /*
  * constants
@@ -339,17 +340,13 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
        dp->max_synthdev = 0;
 }
 
-/*
- * check if the specified device is MIDI mapped device
- */
-static int
-is_midi_dev(struct seq_oss_devinfo *dp, int dev)
+static struct seq_oss_synthinfo *
+get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev)
 {
        if (dev < 0 || dev >= dp->max_synthdev)
-               return 0;
-       if (dp->synths[dev].is_midi)
-               return 1;
-       return 0;
+               return NULL;
+       dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS);
+       return &dp->synths[dev];
 }
 
 /*
@@ -359,14 +356,20 @@ static struct seq_oss_synth *
 get_synthdev(struct seq_oss_devinfo *dp, int dev)
 {
        struct seq_oss_synth *rec;
-       if (dev < 0 || dev >= dp->max_synthdev)
-               return NULL;
-       if (! dp->synths[dev].opened)
+       struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);
+
+       if (!info)
                return NULL;
-       if (dp->synths[dev].is_midi)
-               return &midi_synth_dev;
-       if ((rec = get_sdev(dev)) == NULL)
+       if (!info->opened)
                return NULL;
+       if (info->is_midi) {
+               rec = &midi_synth_dev;
+               snd_use_lock_use(&rec->use_lock);
+       } else {
+               rec = get_sdev(dev);
+               if (!rec)
+                       return NULL;
+       }
        if (! rec->opened) {
                snd_use_lock_free(&rec->use_lock);
                return NULL;
@@ -402,10 +405,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
        struct seq_oss_synth *rec;
        struct seq_oss_synthinfo *info;
 
-       if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
-               return;
-       info = &dp->synths[dev];
-       if (! info->opened)
+       info = get_synthinfo_nospec(dp, dev);
+       if (!info || !info->opened)
                return;
        if (info->sysex)
                info->sysex->len = 0; /* reset sysex */
@@ -454,12 +455,14 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
                            const char __user *buf, int p, int c)
 {
        struct seq_oss_synth *rec;
+       struct seq_oss_synthinfo *info;
        int rc;
 
-       if (dev < 0 || dev >= dp->max_synthdev)
+       info = get_synthinfo_nospec(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       if (is_midi_dev(dp, dev))
+       if (info->is_midi)
                return 0;
        if ((rec = get_synthdev(dp, dev)) == NULL)
                return -ENXIO;
@@ -467,24 +470,25 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
        if (rec->oper.load_patch == NULL)
                rc = -ENXIO;
        else
-               rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c);
+               rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c);
        snd_use_lock_free(&rec->use_lock);
        return rc;
 }
 
 /*
- * check if the device is valid synth device
+ * check if the device is valid synth device and return the synth info
  */
-int
-snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
+struct seq_oss_synthinfo *
+snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev)
 {
        struct seq_oss_synth *rec;
+
        rec = get_synthdev(dp, dev);
        if (rec) {
                snd_use_lock_free(&rec->use_lock);
-               return 1;
+               return get_synthinfo_nospec(dp, dev);
        }
-       return 0;
+       return NULL;
 }
 
 
@@ -499,16 +503,18 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
        int i, send;
        unsigned char *dest;
        struct seq_oss_synth_sysex *sysex;
+       struct seq_oss_synthinfo *info;
 
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       sysex = dp->synths[dev].sysex;
+       sysex = info->sysex;
        if (sysex == NULL) {
                sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
                if (sysex == NULL)
                        return -ENOMEM;
-               dp->synths[dev].sysex = sysex;
+               info->sysex = sysex;
        }
 
        send = 0;
@@ -553,10 +559,12 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
 int
 snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev);
+
+       if (!info)
                return -EINVAL;
-       snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client,
-                             dp->synths[dev].arg.addr.port);
+       snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client,
+                             info->arg.addr.port);
        return 0;
 }
 
@@ -568,16 +576,18 @@ int
 snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
 {
        struct seq_oss_synth *rec;
+       struct seq_oss_synthinfo *info;
        int rc;
 
-       if (is_midi_dev(dp, dev))
+       info = get_synthinfo_nospec(dp, dev);
+       if (!info || info->is_midi)
                return -ENXIO;
        if ((rec = get_synthdev(dp, dev)) == NULL)
                return -ENXIO;
        if (rec->oper.ioctl == NULL)
                rc = -ENXIO;
        else
-               rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr);
+               rc = rec->oper.ioctl(&info->arg, cmd, addr);
        snd_use_lock_free(&rec->use_lock);
        return rc;
 }
@@ -589,7 +599,10 @@ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, u
 int
 snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
+       struct seq_oss_synthinfo *info;
+
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info || info->is_midi)
                return -ENXIO;
        ev->type = SNDRV_SEQ_EVENT_OSS;
        memcpy(ev->data.raw8.d, data, 8);
index 74ac55f166b6517751d197c14a5aaf4b6805ca01..a63f9e22974dfb33ff0f309f0ab309625e0265ea 100644 (file)
@@ -37,7 +37,8 @@ void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp);
 void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
 int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
                                 const char __user *buf, int p, int c);
-int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev);
+struct seq_oss_synthinfo *snd_seq_oss_synth_info(struct seq_oss_devinfo *dp,
+                                                int dev);
 int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
                            struct snd_seq_event *ev);
 int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
index ddcc1a325a618124b9206a9f0c0c9a23774938ed..42920a2433282befccd62aaa43bbec949fe22e6c 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/nospec.h>
 #include <sound/opl3.h>
 #include <sound/asound_fm.h>
 
@@ -448,7 +449,7 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
 {
        unsigned short reg_side;
        unsigned char op_offset;
-       unsigned char voice_offset;
+       unsigned char voice_offset, voice_op;
 
        unsigned short opl3_reg;
        unsigned char reg_val;
@@ -473,7 +474,9 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
                voice_offset = voice->voice - MAX_OPL2_VOICES;
        }
        /* Get register offset of operator */
-       op_offset = snd_opl3_regmap[voice_offset][voice->op];
+       voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES);
+       voice_op = array_index_nospec(voice->op, 4);
+       op_offset = snd_opl3_regmap[voice_offset][voice_op];
 
        reg_val = 0x00;
        /* Set amplitude modulation (tremolo) effect */
index 8573289c381ed7314c6e1a08d4b39191756941f9..928a255bfc351406058b1c2bd8a43d785f63ef97 100644 (file)
@@ -435,7 +435,7 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
                err = init_stream(dice, AMDTP_IN_STREAM, i);
                if (err < 0) {
                        for (; i >= 0; i--)
-                               destroy_stream(dice, AMDTP_OUT_STREAM, i);
+                               destroy_stream(dice, AMDTP_IN_STREAM, i);
                        goto end;
                }
        }
index 4ddb4cdd054b860142da4356dc6abeef44b4c698..96bb01b6b7512df8aea3871e61275773d4d8543d 100644 (file)
@@ -14,7 +14,7 @@ MODULE_LICENSE("GPL v2");
 #define OUI_WEISS              0x001c6a
 #define OUI_LOUD               0x000ff2
 #define OUI_FOCUSRITE          0x00130e
-#define OUI_TCELECTRONIC       0x001486
+#define OUI_TCELECTRONIC       0x000166
 
 #define DICE_CATEGORY_ID       0x04
 #define WEISS_CATEGORY_ID      0x00
index 7eb617175fdec656f0ae6a8ad8387c416f535b39..a31a70dccecff024f92ee8bbcc9ead5ef1cd4bed 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "hpi_internal.h"
 #include "hpimsginit.h"
+#include <linux/nospec.h>
 
 /* The actual message size for each object type */
 static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
@@ -39,10 +40,12 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
 {
        u16 size;
 
-       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
+       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
+               object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
                size = msg_size[object];
-       else
+       } else {
                size = sizeof(*phm);
+       }
 
        memset(phm, 0, size);
        phm->size = size;
@@ -66,10 +69,12 @@ void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
 {
        u16 size;
 
-       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
+       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
+               object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
                size = res_size[object];
-       else
+       } else {
                size = sizeof(*phr);
+       }
 
        memset(phr, 0, sizeof(*phr));
        phr->size = size;
index 5badd08e1d69cc12657410359255ab691eff62f0..b1a2a7ea4172331c07b50340c5d26ebe2f9e6bf0 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/stringify.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/nospec.h>
 
 #ifdef MODULE_FIRMWARE
 MODULE_FIRMWARE("asihpi/dsp5000.bin");
@@ -186,7 +187,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                struct hpi_adapter *pa = NULL;
 
                if (hm->h.adapter_index < ARRAY_SIZE(adapters))
-                       pa = &adapters[hm->h.adapter_index];
+                       pa = &adapters[array_index_nospec(hm->h.adapter_index,
+                                                         ARRAY_SIZE(adapters))];
 
                if (!pa || !pa->adapter || !pa->adapter->type) {
                        hpi_init_response(&hr->r0, hm->h.object,
index 57df06e76968ac4abd0f00b3005c416af256cb7b..cc009a4a3d1d206a8480a506894a59c0226c2e9a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/compat.h>
+#include <linux/nospec.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
@@ -51,7 +52,16 @@ static int get_wcap_ioctl(struct hda_codec *codec,
        
        if (get_user(verb, &arg->verb))
                return -EFAULT;
-       res = get_wcaps(codec, verb >> 24);
+       /* open-code get_wcaps(verb>>24) with nospec */
+       verb >>= 24;
+       if (verb < codec->core.start_nid ||
+           verb >= codec->core.start_nid + codec->core.num_nodes) {
+               res = 0;
+       } else {
+               verb -= codec->core.start_nid;
+               verb = array_index_nospec(verb, codec->core.num_nodes);
+               res = codec->wcaps[verb];
+       }
        if (put_user(res, &arg->res))
                return -EFAULT;
        return 0;
index 7a111a1b58360d34062abf83d06503482929fa32..b0c8c79848a94fd9aae962207ed1c673e0d815ed 100644 (file)
@@ -1647,7 +1647,8 @@ static void azx_check_snoop_available(struct azx *chip)
                 */
                u8 val;
                pci_read_config_byte(chip->pci, 0x42, &val);
-               if (!(val & 0x80) && chip->pci->revision == 0x30)
+               if (!(val & 0x80) && (chip->pci->revision == 0x30 ||
+                                     chip->pci->revision == 0x20))
                        snoop = false;
        }
 
index b4f1b6e88305496f91d028ceb82fe9b8a6a60ccb..7d7eb1354eeec4dc48a734251e6cb9f5d12cd850 100644 (file)
@@ -1383,6 +1383,8 @@ static void hdmi_pcm_setup_pin(struct hdmi_spec *spec,
                pcm = get_pcm_rec(spec, per_pin->pcm_idx);
        else
                return;
+       if (!pcm->pcm)
+               return;
        if (!test_bit(per_pin->pcm_idx, &spec->pcm_in_use))
                return;
 
@@ -2151,8 +2153,13 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
        int dev, err;
        int pin_idx, pcm_idx;
 
-
        for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
+               if (!get_pcm_rec(spec, pcm_idx)->pcm) {
+                       /* no PCM: mark this for skipping permanently */
+                       set_bit(pcm_idx, &spec->pcm_bitmap);
+                       continue;
+               }
+
                err = generic_hdmi_build_jack(codec, pcm_idx);
                if (err < 0)
                        return err;
index aef1f52db7d9e5264fdcdb382dac477edc098514..8c238e51bb5abad3a874bffc4d7e718feb3cb6cd 100644 (file)
@@ -331,6 +331,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
                /* fallthrough */
        case 0x10ec0215:
        case 0x10ec0233:
+       case 0x10ec0235:
        case 0x10ec0236:
        case 0x10ec0255:
        case 0x10ec0256:
@@ -6370,6 +6371,8 @@ static const struct hda_fixup alc269_fixups[] = {
                        { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
                        { }
                },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MIC
        },
 };
 
@@ -6573,6 +6576,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
+       SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
+       SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
@@ -7157,8 +7162,11 @@ static int patch_alc269(struct hda_codec *codec)
        case 0x10ec0298:
                spec->codec_variant = ALC269_TYPE_ALC298;
                break;
+       case 0x10ec0235:
        case 0x10ec0255:
                spec->codec_variant = ALC269_TYPE_ALC255;
+               spec->shutup = alc256_shutup;
+               spec->init_hook = alc256_init;
                break;
        case 0x10ec0236:
        case 0x10ec0256:
index 4c59983158e0ed8d37bcad8ae3735129a1bd1ef8..11b5b5e0e0580fd3a3d33cf99dd71728db1bdd3a 100644 (file)
 #include <linux/pci.h>
 #include <linux/math64.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -5698,40 +5699,43 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
                struct snd_pcm_channel_info *info)
 {
        struct hdspm *hdspm = snd_pcm_substream_chip(substream);
+       unsigned int channel = info->channel;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
+               if (snd_BUG_ON(channel >= hdspm->max_channels_out)) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: output channel out of range (%d)\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               if (hdspm->channel_map_out[info->channel] < 0) {
+               channel = array_index_nospec(channel, hdspm->max_channels_out);
+               if (hdspm->channel_map_out[channel] < 0) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: output channel %d mapped out\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               info->offset = hdspm->channel_map_out[info->channel] *
+               info->offset = hdspm->channel_map_out[channel] *
                        HDSPM_CHANNEL_BUFFER_BYTES;
        } else {
-               if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
+               if (snd_BUG_ON(channel >= hdspm->max_channels_in)) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: input channel out of range (%d)\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               if (hdspm->channel_map_in[info->channel] < 0) {
+               channel = array_index_nospec(channel, hdspm->max_channels_in);
+               if (hdspm->channel_map_in[channel] < 0) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: input channel %d mapped out\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               info->offset = hdspm->channel_map_in[info->channel] *
+               info->offset = hdspm->channel_map_in[channel] *
                        HDSPM_CHANNEL_BUFFER_BYTES;
        }
 
index df648b1d92177c30c2380b96de4e9ebd24fb07aa..edd765e2237707ea468455723d542eb74e97bf0f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -2071,9 +2072,10 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
        if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
                return -EINVAL;
 
-       if ((chn = rme9652->channel_map[info->channel]) < 0) {
+       chn = rme9652->channel_map[array_index_nospec(info->channel,
+                                                     RME9652_NCHANNELS)];
+       if (chn < 0)
                return -EINVAL;
-       }
 
        info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
        info->first = 0;
index b205c782e494133d05fd27cb76509e7e690d5f85..f41560ecbcd18024f2f1354cd741115fcbd69739 100644 (file)
@@ -43,7 +43,7 @@
 #define DUAL_CHANNEL           2
 
 static struct snd_soc_jack cz_jack;
-struct clk *da7219_dai_clk;
+static struct clk *da7219_dai_clk;
 
 static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
 {
index 80c2a06285bbe1f5df619542836bef3a15941c96..12bf24c26818a3ff046a426f56d0cebb356be9a2 100644 (file)
@@ -502,7 +502,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (adau->sigmadsp) {
-               ret = adau17x1_setup_firmware(adau, params_rate(params));
+               ret = adau17x1_setup_firmware(component, params_rate(params));
                if (ret < 0)
                        return ret;
        }
@@ -835,26 +835,40 @@ bool adau17x1_volatile_register(struct device *dev, unsigned int reg)
 }
 EXPORT_SYMBOL_GPL(adau17x1_volatile_register);
 
-int adau17x1_setup_firmware(struct adau *adau, unsigned int rate)
+int adau17x1_setup_firmware(struct snd_soc_component *component,
+       unsigned int rate)
 {
        int ret;
-       int dspsr;
+       int dspsr, dsp_run;
+       struct adau *adau = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+       snd_soc_dapm_mutex_lock(dapm);
 
        ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);
        if (ret)
-               return ret;
+               goto err;
+
+       ret = regmap_read(adau->regmap, ADAU17X1_DSP_RUN, &dsp_run);
+       if (ret)
+               goto err;
 
        regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1);
        regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf);
+       regmap_write(adau->regmap, ADAU17X1_DSP_RUN, 0);
 
        ret = sigmadsp_setup(adau->sigmadsp, rate);
        if (ret) {
                regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0);
-               return ret;
+               goto err;
        }
        regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr);
+       regmap_write(adau->regmap, ADAU17X1_DSP_RUN, dsp_run);
 
-       return 0;
+err:
+       snd_soc_dapm_mutex_unlock(dapm);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
 
index a7b1cb770814624f51465664e2dd3e592a91f1df..e6fe87beec07701810be444eee2abd3280c51674 100644 (file)
@@ -68,7 +68,8 @@ int adau17x1_resume(struct snd_soc_component *component);
 
 extern const struct snd_soc_dai_ops adau17x1_dai_ops;
 
-int adau17x1_setup_firmware(struct adau *adau, unsigned int rate);
+int adau17x1_setup_firmware(struct snd_soc_component *component,
+       unsigned int rate);
 bool adau17x1_has_dsp(struct adau *adau);
 
 #define ADAU17X1_CLOCK_CONTROL                 0x4000
index 12ee83d52405d06a72c8cd5a67485c69bf2ddeb1..b7cf7cce95fecd526bd4d8699e6dee9f4119d4db 100644 (file)
@@ -1187,7 +1187,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
                return irq;
        }
 
-       ret = devm_request_irq(dev, irq, pm8916_mbhc_switch_irq_handler,
+       ret = devm_request_threaded_irq(dev, irq, NULL,
+                              pm8916_mbhc_switch_irq_handler,
                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
                               IRQF_ONESHOT,
                               "mbhc switch irq", priv);
@@ -1201,7 +1202,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
                        return irq;
                }
 
-               ret = devm_request_irq(dev, irq, mbhc_btn_press_irq_handler,
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                                      mbhc_btn_press_irq_handler,
                                       IRQF_TRIGGER_RISING |
                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                       "mbhc btn press irq", priv);
@@ -1214,7 +1216,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
                        return irq;
                }
 
-               ret = devm_request_irq(dev, irq, mbhc_btn_release_irq_handler,
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                                      mbhc_btn_release_irq_handler,
                                       IRQF_TRIGGER_RISING |
                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                       "mbhc btn release irq", priv);
index e8a66b03faabf405ec43f7170e0205fd4650eb29..1570b91bf018f9421c91a4c66631d819a800876c 100644 (file)
@@ -89,6 +89,7 @@ static const struct reg_default rt5514_reg[] = {
        {RT5514_PLL3_CALIB_CTRL5,       0x40220012},
        {RT5514_DELAY_BUF_CTRL1,        0x7fff006a},
        {RT5514_DELAY_BUF_CTRL3,        0x00000000},
+       {RT5514_ASRC_IN_CTRL1,          0x00000003},
        {RT5514_DOWNFILTER0_CTRL1,      0x00020c2f},
        {RT5514_DOWNFILTER0_CTRL2,      0x00020c2f},
        {RT5514_DOWNFILTER0_CTRL3,      0x10000362},
@@ -181,6 +182,7 @@ static bool rt5514_readable_register(struct device *dev, unsigned int reg)
        case RT5514_PLL3_CALIB_CTRL5:
        case RT5514_DELAY_BUF_CTRL1:
        case RT5514_DELAY_BUF_CTRL3:
+       case RT5514_ASRC_IN_CTRL1:
        case RT5514_DOWNFILTER0_CTRL1:
        case RT5514_DOWNFILTER0_CTRL2:
        case RT5514_DOWNFILTER0_CTRL3:
@@ -238,6 +240,7 @@ static bool rt5514_i2c_readable_register(struct device *dev,
        case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL5:
        case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL1:
        case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL3:
+       case RT5514_DSP_MAPPING | RT5514_ASRC_IN_CTRL1:
        case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL1:
        case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL2:
        case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL3:
index 40a700493f4c8f0d3dec67956ee8afb8b20c37f3..da8fd98c7f51c2a1ee3116a00d17d8820bb3582d 100644 (file)
@@ -144,6 +144,13 @@ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
 
        psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
 
+       /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
+       if (ratio <= 256) {
+               pm = ratio;
+               fp = 1;
+               goto out;
+       }
+
        /* Set the max fluctuation -- 0.1% of the max devisor */
        savesub = (psr ? 1 : 8)  * 256 * maxfp / 1000;
 
index 0823b08923b5ef5d0860c14807af75f899eed0ed..89df2d9f63d7d45d219d7172bcb85e9926e8e549 100644 (file)
@@ -217,6 +217,7 @@ struct fsl_ssi_soc_data {
  * @dai_fmt: DAI configuration this device is currently used with
  * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
  * @i2s_net: I2S and Network mode configurations of SCR register
+ *           (this is the initial settings based on the DAI format)
  * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
  * @use_dma: DMA is used or FIQ with stream filter
  * @use_dual_fifo: DMA with support for dual FIFO mode
@@ -829,16 +830,23 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (!fsl_ssi_is_ac97(ssi)) {
+               /*
+                * Keep the ssi->i2s_net intact while having a local variable
+                * to override settings for special use cases. Otherwise, the
+                * ssi->i2s_net will lose the settings for regular use cases.
+                */
+               u8 i2s_net = ssi->i2s_net;
+
                /* Normal + Network mode to send 16-bit data in 32-bit frames */
                if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
-                       ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
+                       i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
 
                /* Use Normal mode to send mono data at 1st slot of 2 slots */
                if (channels == 1)
-                       ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL;
+                       i2s_net = SSI_SCR_I2S_MODE_NORMAL;
 
                regmap_update_bits(regs, REG_SSI_SCR,
-                                  SSI_SCR_I2S_NET_MASK, ssi->i2s_net);
+                                  SSI_SCR_I2S_NET_MASK, i2s_net);
        }
 
        /* In synchronous mode, the SSI uses STCCR for capture */
index ceb105cbd461582196bff4e59c225cf6083952bd..addac2a8e52a573d40e5a7a0ede942c2fa85f6ab 100644 (file)
@@ -72,24 +72,28 @@ config SND_SOC_INTEL_BAYTRAIL
          for Baytrail Chromebooks but this option is now deprecated and is
          not recommended, use SND_SST_ATOM_HIFI2_PLATFORM instead.
 
+config SND_SST_ATOM_HIFI2_PLATFORM
+       tristate
+       select SND_SOC_COMPRESS
+
 config SND_SST_ATOM_HIFI2_PLATFORM_PCI
-       tristate "PCI HiFi2 (Medfield, Merrifield) Platforms"
+       tristate "PCI HiFi2 (Merrifield) Platforms"
        depends on X86 && PCI
        select SND_SST_IPC_PCI
-       select SND_SOC_COMPRESS
+       select SND_SST_ATOM_HIFI2_PLATFORM
        help
-         If you have a Intel Medfield or Merrifield/Edison platform, then
+         If you have a Intel Merrifield/Edison platform, then
          enable this option by saying Y or m. Distros will typically not
-         enable this option: Medfield devices are not available to
-         developers and while Merrifield/Edison can run a mainline kernel with
-         limited functionality it will require a firmware file which
-         is not in the standard firmware tree
+         enable this option: while Merrifield/Edison can run a mainline
+         kernel with limited functionality it will require a firmware file
+         which is not in the standard firmware tree
 
-config SND_SST_ATOM_HIFI2_PLATFORM
+config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
        tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
+       default ACPI
        depends on X86 && ACPI
        select SND_SST_IPC_ACPI
-       select SND_SOC_COMPRESS
+       select SND_SST_ATOM_HIFI2_PLATFORM
        select SND_SOC_ACPI_INTEL_MATCH
        select IOSF_MBI
        help
index 09db2aec12a3010525b872ec817626cb5365b311..b2f5d2fa354d1d888dddf829847883bc84bdcdd1 100644 (file)
@@ -281,7 +281,7 @@ static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
 static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
                                 unsigned int freq)
 {
-       struct clk *parent_clk;
+       struct clk *parent_clk, *mux;
        char *parent_clk_name;
        int ret = 0;
 
@@ -329,14 +329,21 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
                return -ENODEV;
        }
 
+       mux = clk_get_parent(dmic->fclk);
+       if (IS_ERR(mux)) {
+               dev_err(dmic->dev, "can't get fck mux parent\n");
+               clk_put(parent_clk);
+               return -ENODEV;
+       }
+
        mutex_lock(&dmic->mutex);
        if (dmic->active) {
                /* disable clock while reparenting */
                pm_runtime_put_sync(dmic->dev);
-               ret = clk_set_parent(dmic->fclk, parent_clk);
+               ret = clk_set_parent(mux, parent_clk);
                pm_runtime_get_sync(dmic->dev);
        } else {
-               ret = clk_set_parent(dmic->fclk, parent_clk);
+               ret = clk_set_parent(mux, parent_clk);
        }
        mutex_unlock(&dmic->mutex);
 
@@ -349,6 +356,7 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
        dmic->fclk_freq = freq;
 
 err_busy:
+       clk_put(mux);
        clk_put(parent_clk);
 
        return ret;
index 6a76688a8ba953d5b8f373e6a382c8437ec7bfa6..94f081b93258f8948035cee1b816feef3ea79a68 100644 (file)
@@ -1536,7 +1536,7 @@ static int rsnd_remove(struct platform_device *pdev)
        return ret;
 }
 
-static int rsnd_suspend(struct device *dev)
+static int __maybe_unused rsnd_suspend(struct device *dev)
 {
        struct rsnd_priv *priv = dev_get_drvdata(dev);
 
@@ -1545,7 +1545,7 @@ static int rsnd_suspend(struct device *dev)
        return 0;
 }
 
-static int rsnd_resume(struct device *dev)
+static int __maybe_unused rsnd_resume(struct device *dev)
 {
        struct rsnd_priv *priv = dev_get_drvdata(dev);
 
index fa27d0fca6dce10ed8befc8df9cdf7406dbcac75..986b8b2f90fba577cce10462e75ad9966258b49f 100644 (file)
@@ -513,7 +513,7 @@ static void remove_widget(struct snd_soc_component *comp,
         */
        if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) {
                /* enumerated widget mixer */
-               for (i = 0; i < w->num_kcontrols; i++) {
+               for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
                        struct snd_kcontrol *kcontrol = w->kcontrols[i];
                        struct soc_enum *se =
                                (struct soc_enum *)kcontrol->private_value;
@@ -530,7 +530,7 @@ static void remove_widget(struct snd_soc_component *comp,
                }
        } else {
                /* volume mixer or bytes controls */
-               for (i = 0; i < w->num_kcontrols; i++) {
+               for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
                        struct snd_kcontrol *kcontrol = w->kcontrols[i];
 
                        if (dobj->widget.kcontrol_type
@@ -1325,8 +1325,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
                        ec->hdr.name);
 
                kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
-               if (kc[i].name == NULL)
+               if (kc[i].name == NULL) {
+                       kfree(se);
                        goto err_se;
+               }
                kc[i].private_value = (long)se;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = ec->hdr.access;
@@ -1442,8 +1444,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
                        be->hdr.name, be->hdr.access);
 
                kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
-               if (kc[i].name == NULL)
+               if (kc[i].name == NULL) {
+                       kfree(sbe);
                        goto err;
+               }
                kc[i].private_value = (long)sbe;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = be->hdr.access;
@@ -2576,7 +2580,7 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index)
 
                        /* match index */
                        if (dobj->index != index &&
-                               dobj->index != SND_SOC_TPLG_INDEX_ALL)
+                               index != SND_SOC_TPLG_INDEX_ALL)
                                continue;
 
                        switch (dobj->type) {
index 6d7cde56a355ea57266bbd85c94de9b4a7cefea5..e2cf55c53ea8bce34d13e6773bf599e8ec630859 100644 (file)
@@ -125,7 +125,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
        }
 
        usb_fill_int_urb(urb, line6->usbdev,
-                        usb_sndbulkpipe(line6->usbdev,
+                        usb_sndintpipe(line6->usbdev,
                                         line6->properties->ep_ctrl_w),
                         transfer_buffer, length, midi_sent, line6,
                         line6->interval);
index 301ad61ed4267f28476af340325ae5173a12d2ad..344d7b069d5994ff242a9f0a3f9bf19f4201ffaa 100644 (file)
@@ -1776,7 +1776,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
                                build_feature_ctl(state, _ftr, ch_bits, control,
                                                  &iterm, unitid, ch_read_only);
                        if (uac_v2v3_control_is_readable(master_bits, control))
-                               build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
+                               build_feature_ctl(state, _ftr, 0, control,
+                                                 &iterm, unitid,
                                                  !uac_v2v3_control_is_writeable(master_bits,
                                                                                 control));
                }
@@ -1859,7 +1860,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
        check_input_term(state, d->bTerminalID, &iterm);
        if (state->mixer->protocol == UAC_VERSION_2) {
                /* Check for jack detection. */
-               if (uac_v2v3_control_is_readable(d->bmControls,
+               if (uac_v2v3_control_is_readable(le16_to_cpu(d->bmControls),
                                                 UAC2_TE_CONNECTOR)) {
                        build_connector_control(state, &iterm, true);
                }
@@ -2561,7 +2562,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
                        if (err < 0 && err != -EINVAL)
                                return err;
 
-                       if (uac_v2v3_control_is_readable(desc->bmControls,
+                       if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
                                                         UAC2_TE_CONNECTOR)) {
                                build_connector_control(&state, &state.oterm,
                                                        false);
index 9038b2e7df732d453993a180071a98ea3b2ff79f..eaa03acd4686bdd20e19b69502c23ca465977ade 100644 (file)
@@ -353,8 +353,11 @@ static struct usbmix_name_map bose_companion5_map[] = {
 /*
  * Dell usb dock with ALC4020 codec had a firmware problem where it got
  * screwed up when zero volume is passed; just skip it as a workaround
+ *
+ * Also the extension unit gives an access error, so skip it as well.
  */
 static const struct usbmix_name_map dell_alc4020_map[] = {
+       { 4, NULL },    /* extension unit */
        { 16, NULL },
        { 19, NULL },
        { 0 }
index 6a8f5843334e98558d09174e157c308644c736a5..956be9f7c72a44e9326bd15c3df328540747124d 100644 (file)
@@ -349,7 +349,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
                         * TODO: this conversion is not complete, update it
                         * after adding UAC3 values to asound.h
                         */
-                       switch (is->bChPurpose) {
+                       switch (is->bChRelationship) {
                        case UAC3_CH_MONO:
                                map = SNDRV_CHMAP_MONO;
                                break;
index ebcab5c5465d28dfff6b0fbebc5185b3e8f30001..8082f7b077f187453a38db038345eaa41d4c9a1e 100644 (file)
@@ -139,7 +139,7 @@ static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
        snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
 }
 
-static int usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
+static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
 {
        unsigned long offset;
        struct page *page;
index d8bd7c99b48c91ab5a64914af75a434755922256..c1dd9a7b48df6749d8c566fc6fbac2a7fb1d630b 100644 (file)
@@ -31,7 +31,7 @@
 #include "usbusx2y.h"
 #include "usX2Yhwdep.h"
 
-static int snd_us428ctls_vm_fault(struct vm_fault *vmf)
+static vm_fault_t snd_us428ctls_vm_fault(struct vm_fault *vmf)
 {
        unsigned long offset;
        struct page * page;
index 0d050528a4e154dd856e3120fa464ffddb179ca4..4fd9276b8e501a198443ac0db59439365fd10c89 100644 (file)
@@ -652,7 +652,7 @@ static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
 }
 
 
-static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
+static vm_fault_t snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
 {
        unsigned long offset;
        void *vaddr;
index 6edd177bb1c7c66e0ec32caf7ec8d2c3680ed2f3..2ba95d6fe852d7bed7460b022f1ed5b8409caacd 100644 (file)
@@ -135,6 +135,15 @@ struct kvm_arch_memory_slot {
 #define KVM_REG_ARM_CRM_SHIFT          7
 #define KVM_REG_ARM_32_CRN_MASK                0x0000000000007800
 #define KVM_REG_ARM_32_CRN_SHIFT       11
+/*
+ * For KVM currently all guest registers are nonsecure, but we reserve a bit
+ * in the encoding to distinguish secure from nonsecure for AArch32 system
+ * registers that are banked by security. This is 1 for the secure banked
+ * register, and 0 for the nonsecure banked register or if the register is
+ * not banked by security.
+ */
+#define KVM_REG_ARM_SECURE_MASK        0x0000000010000000
+#define KVM_REG_ARM_SECURE_SHIFT       28
 
 #define ARM_CP15_REG_SHIFT_MASK(x,n) \
        (((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK)
index fb3a6de7440bce69c794449ecf5740e8df924f87..6847d85400a8b738ca2adf00ea95fdf8f349fafc 100644 (file)
 # define NEED_MOVBE    0
 #endif
 
-#ifdef CONFIG_X86_5LEVEL
-# define NEED_LA57     (1<<(X86_FEATURE_LA57 & 31))
-#else
-# define NEED_LA57     0
-#endif
-
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_PARAVIRT
 /* Paravirtualized systems may not have PSE or PGE available */
 #define REQUIRED_MASK13        0
 #define REQUIRED_MASK14        0
 #define REQUIRED_MASK15        0
-#define REQUIRED_MASK16        (NEED_LA57)
+#define REQUIRED_MASK16        0
 #define REQUIRED_MASK17        0
 #define REQUIRED_MASK18        0
 #define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
index f3a960488eae0fcf308ba8467c8de26a3061a840..c535c2fdea136a5e58725e72a2d867f545d393eb 100644 (file)
@@ -354,8 +354,25 @@ struct kvm_xcrs {
        __u64 padding[16];
 };
 
-/* definition of registers in kvm_run */
+#define KVM_SYNC_X86_REGS      (1UL << 0)
+#define KVM_SYNC_X86_SREGS     (1UL << 1)
+#define KVM_SYNC_X86_EVENTS    (1UL << 2)
+
+#define KVM_SYNC_X86_VALID_FIELDS \
+       (KVM_SYNC_X86_REGS| \
+        KVM_SYNC_X86_SREGS| \
+        KVM_SYNC_X86_EVENTS)
+
+/* kvm_sync_regs struct included by kvm_run struct */
 struct kvm_sync_regs {
+       /* Members of this structure are potentially malicious.
+        * Care must be taken by code reading, esp. interpreting,
+        * data fields from them inside KVM to prevent TOCTOU and
+        * double-fetch types of vulnerabilities.
+        */
+       struct kvm_regs regs;
+       struct kvm_sregs sregs;
+       struct kvm_vcpu_events events;
 };
 
 #define KVM_X86_QUIRK_LINT0_REENABLED  (1 << 0)
index 04e32f965ad7f038beb2d8db9dc2119e07628744..1827c2f973f93c533ca9a3e12ced636d13319556 100644 (file)
@@ -151,11 +151,21 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  * required ordering.
  */
 
-#define READ_ONCE(x) \
-       ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
-
-#define WRITE_ONCE(x, val) \
-       ({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
+#define READ_ONCE(x)                                   \
+({                                                     \
+       union { typeof(x) __val; char __c[1]; } __u =   \
+               { .__c = { 0 } };                       \
+       __read_once_size(&(x), __u.__c, sizeof(x));     \
+       __u.__val;                                      \
+})
+
+#define WRITE_ONCE(x, val)                             \
+({                                                     \
+       union { typeof(x) __val; char __c[1]; } __u =   \
+               { .__val = (val) };                     \
+       __write_once_size(&(x), __u.__c, sizeof(x));    \
+       __u.__val;                                      \
+})
 
 
 #ifndef __fallthrough
index edfeaba954295a76c1c842253004404365436208..a1a959ba24ffada75e13de61aa570490a988c8d4 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef _LINUX_CORESIGHT_PMU_H
index f8b134f5608f3cbeb0d5afcbbf7963599f4f9e4b..e7ee32861d51d4b2e47b9182a48c05fe837b8d21 100644 (file)
@@ -27,6 +27,9 @@
 # define MAP_UNINITIALIZED 0x0         /* Don't support this flag */
 #endif
 
+/* 0x0100 - 0x80000 flags are defined in asm-generic/mman.h */
+#define MAP_FIXED_NOREPLACE    0x100000        /* MAP_FIXED which doesn't unmap underlying mapping */
+
 /*
  * Flags for mlock
  */
index 9d07465023a263ba6d1e357d43a97b8ef550941b..c5ec89732a8d92a7db596795602192a83615122f 100644 (file)
@@ -864,6 +864,7 @@ enum bpf_func_id {
 /* BPF_FUNC_skb_set_tunnel_key flags. */
 #define BPF_F_ZERO_CSUM_TX             (1ULL << 1)
 #define BPF_F_DONT_FRAGMENT            (1ULL << 2)
+#define BPF_F_SEQ_NUMBER               (1ULL << 3)
 
 /* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
  * BPF_FUNC_perf_event_read_value flags.
index 6d9447700e18c983804e1fecc4a6854e138d10f6..68699f654118592527096dc26336f57da6a01cdc 100644 (file)
@@ -941,4 +941,43 @@ enum {
        IFLA_EVENT_BONDING_OPTIONS,     /* change in bonding options */
 };
 
+/* tun section */
+
+enum {
+       IFLA_TUN_UNSPEC,
+       IFLA_TUN_OWNER,
+       IFLA_TUN_GROUP,
+       IFLA_TUN_TYPE,
+       IFLA_TUN_PI,
+       IFLA_TUN_VNET_HDR,
+       IFLA_TUN_PERSIST,
+       IFLA_TUN_MULTI_QUEUE,
+       IFLA_TUN_NUM_QUEUES,
+       IFLA_TUN_NUM_DISABLED_QUEUES,
+       __IFLA_TUN_MAX,
+};
+
+#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1)
+
+/* rmnet section */
+
+#define RMNET_FLAGS_INGRESS_DEAGGREGATION         (1U << 0)
+#define RMNET_FLAGS_INGRESS_MAP_COMMANDS          (1U << 1)
+#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4           (1U << 2)
+#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4            (1U << 3)
+
+enum {
+       IFLA_RMNET_UNSPEC,
+       IFLA_RMNET_MUX_ID,
+       IFLA_RMNET_FLAGS,
+       __IFLA_RMNET_MAX,
+};
+
+#define IFLA_RMNET_MAX (__IFLA_RMNET_MAX - 1)
+
+struct ifla_rmnet_flags {
+       __u32   flags;
+       __u32   mask;
+};
+
 #endif /* _UAPI_LINUX_IF_LINK_H */
index 6b89f87db200333922c0947ce481e4638f2e953d..1065006c9bf5890abdf99f9a4c444552af5542d1 100644 (file)
@@ -396,6 +396,10 @@ struct kvm_run {
                char padding[256];
        };
 
+       /* 2048 is the size of the char array used to bound/pad the size
+        * of the union that holds sync regs.
+        */
+       #define SYNC_REGS_SIZE_BYTES 2048
        /*
         * shared registers between kvm and userspace.
         * kvm_valid_regs specifies the register classes set by the host
@@ -407,7 +411,7 @@ struct kvm_run {
        __u64 kvm_dirty_regs;
        union {
                struct kvm_sync_regs regs;
-               char padding[2048];
+               char padding[SYNC_REGS_SIZE_BYTES];
        } s;
 };
 
@@ -936,6 +940,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
 #define KVM_CAP_S390_BPB 152
 #define KVM_CAP_GET_MSR_FEATURES 153
+#define KVM_CAP_HYPERV_EVENTFD 154
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1375,6 +1380,10 @@ struct kvm_enc_region {
 #define KVM_MEMORY_ENCRYPT_REG_REGION    _IOR(KVMIO, 0xbb, struct kvm_enc_region)
 #define KVM_MEMORY_ENCRYPT_UNREG_REGION  _IOR(KVMIO, 0xbc, struct kvm_enc_region)
 
+/* Available with KVM_CAP_HYPERV_EVENTFD */
+#define KVM_HYPERV_EVENTFD        _IOW(KVMIO,  0xbd, struct kvm_hyperv_eventfd)
+
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
        /* Guest initialization commands */
@@ -1515,4 +1524,14 @@ struct kvm_assigned_msix_entry {
 #define KVM_ARM_DEV_EL1_PTIMER         (1 << 1)
 #define KVM_ARM_DEV_PMU                        (1 << 2)
 
+struct kvm_hyperv_eventfd {
+       __u32 conn_id;
+       __s32 fd;
+       __u32 flags;
+       __u32 padding[3];
+};
+
+#define KVM_HYPERV_CONN_ID_MASK                0x00ffffff
+#define KVM_HYPERV_EVENTFD_DEASSIGN    (1 << 0)
+
 #endif /* __LINUX_KVM_H */
index 912b85b52344b31aa405b546b5d1160a61a52df1..b8e288a1f7409012d50e464e7993b96d4c404610 100644 (file)
@@ -650,11 +650,23 @@ struct perf_event_mmap_page {
 #define PERF_RECORD_MISC_COMM_EXEC             (1 << 13)
 #define PERF_RECORD_MISC_SWITCH_OUT            (1 << 13)
 /*
- * Indicates that the content of PERF_SAMPLE_IP points to
- * the actual instruction that triggered the event. See also
- * perf_event_attr::precise_ip.
+ * These PERF_RECORD_MISC_* flags below are safely reused
+ * for the following events:
+ *
+ *   PERF_RECORD_MISC_EXACT_IP           - PERF_RECORD_SAMPLE of precise events
+ *   PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events
+ *
+ *
+ * PERF_RECORD_MISC_EXACT_IP:
+ *   Indicates that the content of PERF_SAMPLE_IP points to
+ *   the actual instruction that triggered the event. See also
+ *   perf_event_attr::precise_ip.
+ *
+ * PERF_RECORD_MISC_SWITCH_OUT_PREEMPT:
+ *   Indicates that thread was preempted in TASK_RUNNING state.
  */
 #define PERF_RECORD_MISC_EXACT_IP              (1 << 14)
+#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT    (1 << 14)
 /*
  * Reserve the last bit to indicate some extended misc field
  */
index 07d61583fd02bd08b9748d974bca8b86a0706a3a..ed0a120d4f084fa0cfc10b5257ea9bce0c3d3a24 100644 (file)
@@ -242,6 +242,7 @@ typedef int __bitwise snd_pcm_format_t;
 #define        SNDRV_PCM_FORMAT_DSD_U16_BE     ((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */
 #define        SNDRV_PCM_FORMAT_DSD_U32_BE     ((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */
 #define        SNDRV_PCM_FORMAT_LAST           SNDRV_PCM_FORMAT_DSD_U32_BE
+#define        SNDRV_PCM_FORMAT_FIRST          SNDRV_PCM_FORMAT_S8
 
 #ifdef SNDRV_LITTLE_ENDIAN
 #define        SNDRV_PCM_FORMAT_S16            SNDRV_PCM_FORMAT_S16_LE
index f6a1babcbac416d0893b72004ce1261d6373d989..cb7154eccbdc1e6a825060b137155ce4560df2a4 100644 (file)
@@ -433,7 +433,7 @@ match:
 
        if (ambiguous_option) {
                 fprintf(stderr,
-                        " Error: Ambiguous option: %s (could be --%s%s or --%s%s)",
+                        " Error: Ambiguous option: %s (could be --%s%s or --%s%s)\n",
                         arg,
                         (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
                         ambiguous_option->long_name,
@@ -458,7 +458,7 @@ static void check_typos(const char *arg, const struct option *options)
                return;
 
        if (strstarts(arg, "no-")) {
-               fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
+               fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg);
                exit(129);
        }
 
@@ -466,7 +466,7 @@ static void check_typos(const char *arg, const struct option *options)
                if (!options->long_name)
                        continue;
                if (strstarts(options->long_name, arg)) {
-                       fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
+                       fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg);
                        exit(129);
                }
        }
index 8ae824dbfca3fea24889064aca1fd46d60f0cbf2..f76d9914686a238a976b7230b4c21b9a20092fbe 100644 (file)
@@ -31,8 +31,8 @@ INCLUDES := -I$(srctree)/tools/include \
            -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
            -I$(srctree)/tools/objtool/arch/$(ARCH)/include
 WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
-CFLAGS   += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
-LDFLAGS  += -lelf $(LIBSUBCMD)
+CFLAGS   += -Werror $(WARNINGS) $(HOSTCFLAGS) -g $(INCLUDES)
+LDFLAGS  += -lelf $(LIBSUBCMD) $(HOSTLDFLAGS)
 
 # Allow old libelf to be used:
 elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr)
index 5b4fff3adc4be4ca66a30a9e8b85b55e1a472f4a..32f4a898e3f2f323fcd66021728192d8961b89f9 100644 (file)
@@ -334,6 +334,11 @@ annotate.*::
 
                99.93 â”‚      mov    %eax,%eax
 
+       annotate.offset_level::
+               Default is '1', meaning just jump targets will have offsets show right beside
+               the instruction. When set to '2' 'call' instructions will also have its offsets
+               shown, 3 or higher will show offsets for all instructions.
+
 hist.*::
        hist.percentage::
                This option control the way to calculate overhead of filtered entries -
index b0211410969b39473dcc43158e195a005de16075..f8d2167cf3e7a2221b8688aff0f0fa55968db369 100644 (file)
@@ -28,29 +28,46 @@ OPTIONS
 <command>...::
        Any command you can specify in a shell.
 
+-i::
+--input=<file>::
+       Input file name.
+
 -f::
 --force::
        Don't do ownership validation
 
 -t::
---type=::
+--type=<type>::
        Select the memory operation type: load or store (default: load,store)
 
 -D::
---dump-raw-samples=::
+--dump-raw-samples::
        Dump the raw decoded samples on the screen in a format that is easy to parse with
        one sample per line.
 
 -x::
---field-separator::
+--field-separator=<separator>::
        Specify the field separator used when dump raw samples (-D option). By default,
        The separator is the space character.
 
 -C::
---cpu-list::
-       Restrict dump of raw samples to those provided via this option. Note that the same
-       option can be passed in record mode. It will be interpreted the same way as perf
-       record.
+--cpu=<cpu>::
+       Monitor only on the list of CPUs provided. Multiple CPUs can be provided as a
+        comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. Default
+        is to monitor all CPUS.
+-U::
+--hide-unresolved::
+       Only display entries resolved to a symbol.
+
+-p::
+--phys-data::
+       Record/Report sample physical addresses
+
+RECORD OPTIONS
+--------------
+-e::
+--event <event>::
+       Event selector. Use 'perf mem record -e list' to list available events.
 
 -K::
 --all-kernel::
@@ -60,12 +77,15 @@ OPTIONS
 --all-user::
        Configure all used events to run in user space.
 
---ldload::
+-v::
+--verbose::
+       Be more verbose (show counter open errors, etc)
+
+--ldlat <n>::
        Specify desired latency for loads event.
 
--p::
---phys-data::
-       Record/Report sample physical addresses
+In addition, for report all perf report options are valid, and for record
+all perf record options.
 
 SEE ALSO
 --------
index bb33601a823b4e26f13f3fa218ebef2548af2a67..63f938b887dd135d31cc0e8928f650e23bbd3c0b 100644 (file)
@@ -104,8 +104,8 @@ OPTIONS for 'perf sched timehist'
     kallsyms pathname
 
 -g::
---no-call-graph::
-       Do not display call chains if present.
+--call-graph::
+       Display call chains if present (default on).
 
 --max-stack::
        Maximum number of functions to display in backtrace, default 5.
index 36ec0257f8d3ce1007de2fed447d72565c70c25d..afdafe2110a17adea848871e033a85f85972b4a1 100644 (file)
@@ -228,14 +228,15 @@ OPTIONS
        For sample events it's possible to display misc field with -F +misc option,
        following letters are displayed for each bit:
 
-         PERF_RECORD_MISC_KERNEL        K
-         PERF_RECORD_MISC_USER          U
-         PERF_RECORD_MISC_HYPERVISOR    H
-         PERF_RECORD_MISC_GUEST_KERNEL  G
-         PERF_RECORD_MISC_GUEST_USER    g
-         PERF_RECORD_MISC_MMAP_DATA*    M
-         PERF_RECORD_MISC_COMM_EXEC     E
-         PERF_RECORD_MISC_SWITCH_OUT    S
+         PERF_RECORD_MISC_KERNEL               K
+         PERF_RECORD_MISC_USER                 U
+         PERF_RECORD_MISC_HYPERVISOR           H
+         PERF_RECORD_MISC_GUEST_KERNEL         G
+         PERF_RECORD_MISC_GUEST_USER           g
+         PERF_RECORD_MISC_MMAP_DATA*           M
+         PERF_RECORD_MISC_COMM_EXEC            E
+         PERF_RECORD_MISC_SWITCH_OUT           S
+         PERF_RECORD_MISC_SWITCH_OUT_PREEMPT   Sp
 
          $ perf script -F +misc ...
           sched-messaging  1414 K     28690.636582:       4590 cycles ...
index f15b306be1834e33da6a58c1b5dd4e8201dc82cd..e6c3b4e555c257f033fd7bf2ef2635173664dac5 100644 (file)
@@ -153,7 +153,7 @@ perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- m
 
 -I msecs::
 --interval-print msecs::
-Print count deltas every N milliseconds (minimum: 10ms)
+Print count deltas every N milliseconds (minimum: 1ms)
 The overhead percentage could be high in some cases, for instance with small, sub 100ms intervals.  Use with caution.
        example: 'perf stat -I 1000 -e cycles -a sleep 5'
 
index c7abd83a8e19d7adf42cc825443b69583edbf5b5..ae7dc46e8f8a3f4e74b53dcf1040a4e0b69a96b9 100644 (file)
@@ -68,7 +68,7 @@ ifeq ($(NO_PERF_REGS),0)
 endif
 
 ifneq ($(NO_SYSCALL_TABLE),1)
-  CFLAGS += -DHAVE_SYSCALL_TABLE
+  CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
 endif
 
 # So far there's only x86 and arm libdw unwind support merged in perf.
@@ -847,7 +847,7 @@ ifndef NO_JVMTI
   ifeq ($(feature-jvmti), 1)
     $(call detected_var,JDIR)
   else
-    $(warning No openjdk development package found, please install JDK package)
+    $(warning No openjdk development package found, please install JDK package, e.g. openjdk-8-jdk, java-1.8.0-openjdk-devel)
     NO_JVMTI := 1
   endif
 endif
diff --git a/tools/perf/arch/arm/include/arch-tests.h b/tools/perf/arch/arm/include/arch-tests.h
new file mode 100644 (file)
index 0000000..90ec4c8
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARCH_TESTS_H
+#define ARCH_TESTS_H
+
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+struct thread;
+struct perf_sample;
+#endif
+
+extern struct test arch_tests[];
+
+#endif
index b30eff9bcc83fd14026100f8626e913fd8f954e9..883c57ff0c084fb00a5b4dffa6275840f97dc814 100644 (file)
@@ -1,2 +1,4 @@
 libperf-y += regs_load.o
 libperf-y += dwarf-unwind.o
+
+libperf-y += arch-tests.o
diff --git a/tools/perf/arch/arm/tests/arch-tests.c b/tools/perf/arch/arm/tests/arch-tests.c
new file mode 100644 (file)
index 0000000..5b1543c
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include "tests/tests.h"
+#include "arch-tests.h"
+
+struct test arch_tests[] = {
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+       {
+               .desc = "DWARF unwind",
+               .func = test__dwarf_unwind,
+       },
+#endif
+       {
+               .func = NULL,
+       },
+};
index fa639e3e52acb37b13dd63920eb963f509c9431b..1ce6bdbda561588fdc1ff4a6c8e99cf6ce7ebeeb 100644 (file)
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <stdbool.h>
index 5c655ad4621e7a8befc7e35aba12720062e3f561..2f595cd73da662be982a71f130f045f734c29fce 100644 (file)
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <api/fs/fs.h>
index 5256741be5496f2e6f42c1026b94ec93653f33c7..1a12e64f51279293dd1f515b84444116d794afbc 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef INCLUDE__PERF_CS_ETM_H__
index ac4dffc807b89f81d29bb70517471ff827755984..e047571e60800e34aeb4fc8f141289132ef22387 100644 (file)
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <string.h>
index 6cb48e4cffd9a1602525510a5ea4129acd69958a..3afe8256eff275ef94c277dfae9a8c865615d681 100644 (file)
@@ -87,6 +87,7 @@ struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
        struct perf_evsel *pos;
        int diagnose = 0;
 
+       *err = 0;
        if (evlist->nr_entries == 0)
                return NULL;
 
index a4c30f1c70bec19d2175a35477e3ee3ab7bc77d3..163b92f339980e4d75208bf682607d6104c4f072 100644 (file)
@@ -146,21 +146,3 @@ char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
                zfree(&buf);
        return buf;
 }
-
-/*
- * Compare the cpuid string returned by get_cpuid() function
- * with the name generated by the jevents file read from
- * pmu-events/arch/s390/mapfile.csv.
- *
- * Parameter mapcpuid is the cpuid as stored in the
- * pmu-events/arch/s390/mapfile.csv. This is just the type number.
- * Parameter cpuid is the cpuid returned by function get_cpuid().
- */
-int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
-{
-       char *cp = strchr(cpuid, ',');
-
-       if (cp == NULL)
-               return -1;
-       return strncmp(cp + 1, mapcpuid, strlen(mapcpuid));
-}
index d74eaa7aa927d5a3abf5b5cdfe054e0381572f1b..1a38e78117ce6f410cc0521e09fedeaa31cf8519 100644 (file)
@@ -21,7 +21,7 @@ _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
 $(header): $(sys)/syscall_64.tbl $(systbl)
        @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \
         (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \
-        || echo "Warning: Kernel ABI header at 'tools/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true
+        || echo "Warning: Kernel ABI header at 'tools/perf/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true
        $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
 
 clean::
index 5bd1ba8c02829e8f571e7d6453b6ea76165d8445..44f5aba78210e9892bedb25590a8983c1e5ae2d0 100644 (file)
@@ -1,21 +1,43 @@
 // SPDX-License-Identifier: GPL-2.0
 static struct ins x86__instructions[] = {
+       { .name = "adc",        .ops = &mov_ops,  },
+       { .name = "adcb",       .ops = &mov_ops,  },
+       { .name = "adcl",       .ops = &mov_ops,  },
        { .name = "add",        .ops = &mov_ops,  },
        { .name = "addl",       .ops = &mov_ops,  },
        { .name = "addq",       .ops = &mov_ops,  },
+       { .name = "addsd",      .ops = &mov_ops,  },
        { .name = "addw",       .ops = &mov_ops,  },
        { .name = "and",        .ops = &mov_ops,  },
+       { .name = "andb",       .ops = &mov_ops,  },
+       { .name = "andl",       .ops = &mov_ops,  },
+       { .name = "andpd",      .ops = &mov_ops,  },
+       { .name = "andps",      .ops = &mov_ops,  },
+       { .name = "andq",       .ops = &mov_ops,  },
+       { .name = "andw",       .ops = &mov_ops,  },
+       { .name = "bsr",        .ops = &mov_ops,  },
+       { .name = "bt",         .ops = &mov_ops,  },
+       { .name = "btr",        .ops = &mov_ops,  },
        { .name = "bts",        .ops = &mov_ops,  },
+       { .name = "btsq",       .ops = &mov_ops,  },
        { .name = "call",       .ops = &call_ops, },
        { .name = "callq",      .ops = &call_ops, },
+       { .name = "cmovbe",     .ops = &mov_ops,  },
+       { .name = "cmove",      .ops = &mov_ops,  },
+       { .name = "cmovae",     .ops = &mov_ops,  },
        { .name = "cmp",        .ops = &mov_ops,  },
        { .name = "cmpb",       .ops = &mov_ops,  },
        { .name = "cmpl",       .ops = &mov_ops,  },
        { .name = "cmpq",       .ops = &mov_ops,  },
        { .name = "cmpw",       .ops = &mov_ops,  },
        { .name = "cmpxch",     .ops = &mov_ops,  },
+       { .name = "cmpxchg",    .ops = &mov_ops,  },
+       { .name = "cs",         .ops = &mov_ops,  },
        { .name = "dec",        .ops = &dec_ops,  },
        { .name = "decl",       .ops = &dec_ops,  },
+       { .name = "divsd",      .ops = &mov_ops,  },
+       { .name = "divss",      .ops = &mov_ops,  },
+       { .name = "gs",         .ops = &mov_ops,  },
        { .name = "imul",       .ops = &mov_ops,  },
        { .name = "inc",        .ops = &dec_ops,  },
        { .name = "incl",       .ops = &dec_ops,  },
@@ -57,25 +79,68 @@ static struct ins x86__instructions[] = {
        { .name = "lea",        .ops = &mov_ops,  },
        { .name = "lock",       .ops = &lock_ops, },
        { .name = "mov",        .ops = &mov_ops,  },
+       { .name = "movapd",     .ops = &mov_ops,  },
+       { .name = "movaps",     .ops = &mov_ops,  },
        { .name = "movb",       .ops = &mov_ops,  },
        { .name = "movdqa",     .ops = &mov_ops,  },
+       { .name = "movdqu",     .ops = &mov_ops,  },
        { .name = "movl",       .ops = &mov_ops,  },
        { .name = "movq",       .ops = &mov_ops,  },
+       { .name = "movsd",      .ops = &mov_ops,  },
        { .name = "movslq",     .ops = &mov_ops,  },
+       { .name = "movss",      .ops = &mov_ops,  },
+       { .name = "movupd",     .ops = &mov_ops,  },
+       { .name = "movups",     .ops = &mov_ops,  },
+       { .name = "movw",       .ops = &mov_ops,  },
        { .name = "movzbl",     .ops = &mov_ops,  },
        { .name = "movzwl",     .ops = &mov_ops,  },
+       { .name = "mulsd",      .ops = &mov_ops,  },
+       { .name = "mulss",      .ops = &mov_ops,  },
        { .name = "nop",        .ops = &nop_ops,  },
        { .name = "nopl",       .ops = &nop_ops,  },
        { .name = "nopw",       .ops = &nop_ops,  },
        { .name = "or",         .ops = &mov_ops,  },
+       { .name = "orb",        .ops = &mov_ops,  },
        { .name = "orl",        .ops = &mov_ops,  },
+       { .name = "orps",       .ops = &mov_ops,  },
+       { .name = "orq",        .ops = &mov_ops,  },
+       { .name = "pand",       .ops = &mov_ops,  },
+       { .name = "paddq",      .ops = &mov_ops,  },
+       { .name = "pcmpeqb",    .ops = &mov_ops,  },
+       { .name = "por",        .ops = &mov_ops,  },
+       { .name = "rclb",       .ops = &mov_ops,  },
+       { .name = "rcll",       .ops = &mov_ops,  },
+       { .name = "retq",       .ops = &ret_ops,  },
+       { .name = "sbb",        .ops = &mov_ops,  },
+       { .name = "sbbl",       .ops = &mov_ops,  },
+       { .name = "sete",       .ops = &mov_ops,  },
+       { .name = "sub",        .ops = &mov_ops,  },
+       { .name = "subl",       .ops = &mov_ops,  },
+       { .name = "subq",       .ops = &mov_ops,  },
+       { .name = "subsd",      .ops = &mov_ops,  },
+       { .name = "subw",       .ops = &mov_ops,  },
        { .name = "test",       .ops = &mov_ops,  },
        { .name = "testb",      .ops = &mov_ops,  },
        { .name = "testl",      .ops = &mov_ops,  },
+       { .name = "ucomisd",    .ops = &mov_ops,  },
+       { .name = "ucomiss",    .ops = &mov_ops,  },
+       { .name = "vaddsd",     .ops = &mov_ops,  },
+       { .name = "vandpd",     .ops = &mov_ops,  },
+       { .name = "vmovdqa",    .ops = &mov_ops,  },
+       { .name = "vmovq",      .ops = &mov_ops,  },
+       { .name = "vmovsd",     .ops = &mov_ops,  },
+       { .name = "vmulsd",     .ops = &mov_ops,  },
+       { .name = "vorpd",      .ops = &mov_ops,  },
+       { .name = "vsubsd",     .ops = &mov_ops,  },
+       { .name = "vucomisd",   .ops = &mov_ops,  },
        { .name = "xadd",       .ops = &mov_ops,  },
        { .name = "xbeginl",    .ops = &jump_ops, },
        { .name = "xbeginq",    .ops = &jump_ops, },
-       { .name = "retq",       .ops = &ret_ops,  },
+       { .name = "xchg",       .ops = &mov_ops,  },
+       { .name = "xor",        .ops = &mov_ops, },
+       { .name = "xorb",       .ops = &mov_ops, },
+       { .name = "xorpd",      .ops = &mov_ops, },
+       { .name = "xorps",      .ops = &mov_ops, },
 };
 
 static bool x86__ins_is_fused(struct arch *arch, const char *ins1,
index 5aef183e2f85c5f6c45e44d4e9a68c9ea62c0d74..4dfe42666d0ce6e20214e70f0c2a6a3884106290 100644 (file)
 # The format is:
 # <number> <abi> <name> <entry point>
 #
+# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
+#
 # The abi is "common", "64" or "x32" for this file.
 #
-0      common  read                    sys_read
-1      common  write                   sys_write
-2      common  open                    sys_open
-3      common  close                   sys_close
-4      common  stat                    sys_newstat
-5      common  fstat                   sys_newfstat
-6      common  lstat                   sys_newlstat
-7      common  poll                    sys_poll
-8      common  lseek                   sys_lseek
-9      common  mmap                    sys_mmap
-10     common  mprotect                sys_mprotect
-11     common  munmap                  sys_munmap
-12     common  brk                     sys_brk
-13     64      rt_sigaction            sys_rt_sigaction
-14     common  rt_sigprocmask          sys_rt_sigprocmask
-15     64      rt_sigreturn            sys_rt_sigreturn/ptregs
-16     64      ioctl                   sys_ioctl
-17     common  pread64                 sys_pread64
-18     common  pwrite64                sys_pwrite64
-19     64      readv                   sys_readv
-20     64      writev                  sys_writev
-21     common  access                  sys_access
-22     common  pipe                    sys_pipe
-23     common  select                  sys_select
-24     common  sched_yield             sys_sched_yield
-25     common  mremap                  sys_mremap
-26     common  msync                   sys_msync
-27     common  mincore                 sys_mincore
-28     common  madvise                 sys_madvise
-29     common  shmget                  sys_shmget
-30     common  shmat                   sys_shmat
-31     common  shmctl                  sys_shmctl
-32     common  dup                     sys_dup
-33     common  dup2                    sys_dup2
-34     common  pause                   sys_pause
-35     common  nanosleep               sys_nanosleep
-36     common  getitimer               sys_getitimer
-37     common  alarm                   sys_alarm
-38     common  setitimer               sys_setitimer
-39     common  getpid                  sys_getpid
-40     common  sendfile                sys_sendfile64
-41     common  socket                  sys_socket
-42     common  connect                 sys_connect
-43     common  accept                  sys_accept
-44     common  sendto                  sys_sendto
-45     64      recvfrom                sys_recvfrom
-46     64      sendmsg                 sys_sendmsg
-47     64      recvmsg                 sys_recvmsg
-48     common  shutdown                sys_shutdown
-49     common  bind                    sys_bind
-50     common  listen                  sys_listen
-51     common  getsockname             sys_getsockname
-52     common  getpeername             sys_getpeername
-53     common  socketpair              sys_socketpair
-54     64      setsockopt              sys_setsockopt
-55     64      getsockopt              sys_getsockopt
-56     common  clone                   sys_clone/ptregs
-57     common  fork                    sys_fork/ptregs
-58     common  vfork                   sys_vfork/ptregs
-59     64      execve                  sys_execve/ptregs
-60     common  exit                    sys_exit
-61     common  wait4                   sys_wait4
-62     common  kill                    sys_kill
-63     common  uname                   sys_newuname
-64     common  semget                  sys_semget
-65     common  semop                   sys_semop
-66     common  semctl                  sys_semctl
-67     common  shmdt                   sys_shmdt
-68     common  msgget                  sys_msgget
-69     common  msgsnd                  sys_msgsnd
-70     common  msgrcv                  sys_msgrcv
-71     common  msgctl                  sys_msgctl
-72     common  fcntl                   sys_fcntl
-73     common  flock                   sys_flock
-74     common  fsync                   sys_fsync
-75     common  fdatasync               sys_fdatasync
-76     common  truncate                sys_truncate
-77     common  ftruncate               sys_ftruncate
-78     common  getdents                sys_getdents
-79     common  getcwd                  sys_getcwd
-80     common  chdir                   sys_chdir
-81     common  fchdir                  sys_fchdir
-82     common  rename                  sys_rename
-83     common  mkdir                   sys_mkdir
-84     common  rmdir                   sys_rmdir
-85     common  creat                   sys_creat
-86     common  link                    sys_link
-87     common  unlink                  sys_unlink
-88     common  symlink                 sys_symlink
-89     common  readlink                sys_readlink
-90     common  chmod                   sys_chmod
-91     common  fchmod                  sys_fchmod
-92     common  chown                   sys_chown
-93     common  fchown                  sys_fchown
-94     common  lchown                  sys_lchown
-95     common  umask                   sys_umask
-96     common  gettimeofday            sys_gettimeofday
-97     common  getrlimit               sys_getrlimit
-98     common  getrusage               sys_getrusage
-99     common  sysinfo                 sys_sysinfo
-100    common  times                   sys_times
-101    64      ptrace                  sys_ptrace
-102    common  getuid                  sys_getuid
-103    common  syslog                  sys_syslog
-104    common  getgid                  sys_getgid
-105    common  setuid                  sys_setuid
-106    common  setgid                  sys_setgid
-107    common  geteuid                 sys_geteuid
-108    common  getegid                 sys_getegid
-109    common  setpgid                 sys_setpgid
-110    common  getppid                 sys_getppid
-111    common  getpgrp                 sys_getpgrp
-112    common  setsid                  sys_setsid
-113    common  setreuid                sys_setreuid
-114    common  setregid                sys_setregid
-115    common  getgroups               sys_getgroups
-116    common  setgroups               sys_setgroups
-117    common  setresuid               sys_setresuid
-118    common  getresuid               sys_getresuid
-119    common  setresgid               sys_setresgid
-120    common  getresgid               sys_getresgid
-121    common  getpgid                 sys_getpgid
-122    common  setfsuid                sys_setfsuid
-123    common  setfsgid                sys_setfsgid
-124    common  getsid                  sys_getsid
-125    common  capget                  sys_capget
-126    common  capset                  sys_capset
-127    64      rt_sigpending           sys_rt_sigpending
-128    64      rt_sigtimedwait         sys_rt_sigtimedwait
-129    64      rt_sigqueueinfo         sys_rt_sigqueueinfo
-130    common  rt_sigsuspend           sys_rt_sigsuspend
-131    64      sigaltstack             sys_sigaltstack
-132    common  utime                   sys_utime
-133    common  mknod                   sys_mknod
+0      common  read                    __x64_sys_read
+1      common  write                   __x64_sys_write
+2      common  open                    __x64_sys_open
+3      common  close                   __x64_sys_close
+4      common  stat                    __x64_sys_newstat
+5      common  fstat                   __x64_sys_newfstat
+6      common  lstat                   __x64_sys_newlstat
+7      common  poll                    __x64_sys_poll
+8      common  lseek                   __x64_sys_lseek
+9      common  mmap                    __x64_sys_mmap
+10     common  mprotect                __x64_sys_mprotect
+11     common  munmap                  __x64_sys_munmap
+12     common  brk                     __x64_sys_brk
+13     64      rt_sigaction            __x64_sys_rt_sigaction
+14     common  rt_sigprocmask          __x64_sys_rt_sigprocmask
+15     64      rt_sigreturn            __x64_sys_rt_sigreturn/ptregs
+16     64      ioctl                   __x64_sys_ioctl
+17     common  pread64                 __x64_sys_pread64
+18     common  pwrite64                __x64_sys_pwrite64
+19     64      readv                   __x64_sys_readv
+20     64      writev                  __x64_sys_writev
+21     common  access                  __x64_sys_access
+22     common  pipe                    __x64_sys_pipe
+23     common  select                  __x64_sys_select
+24     common  sched_yield             __x64_sys_sched_yield
+25     common  mremap                  __x64_sys_mremap
+26     common  msync                   __x64_sys_msync
+27     common  mincore                 __x64_sys_mincore
+28     common  madvise                 __x64_sys_madvise
+29     common  shmget                  __x64_sys_shmget
+30     common  shmat                   __x64_sys_shmat
+31     common  shmctl                  __x64_sys_shmctl
+32     common  dup                     __x64_sys_dup
+33     common  dup2                    __x64_sys_dup2
+34     common  pause                   __x64_sys_pause
+35     common  nanosleep               __x64_sys_nanosleep
+36     common  getitimer               __x64_sys_getitimer
+37     common  alarm                   __x64_sys_alarm
+38     common  setitimer               __x64_sys_setitimer
+39     common  getpid                  __x64_sys_getpid
+40     common  sendfile                __x64_sys_sendfile64
+41     common  socket                  __x64_sys_socket
+42     common  connect                 __x64_sys_connect
+43     common  accept                  __x64_sys_accept
+44     common  sendto                  __x64_sys_sendto
+45     64      recvfrom                __x64_sys_recvfrom
+46     64      sendmsg                 __x64_sys_sendmsg
+47     64      recvmsg                 __x64_sys_recvmsg
+48     common  shutdown                __x64_sys_shutdown
+49     common  bind                    __x64_sys_bind
+50     common  listen                  __x64_sys_listen
+51     common  getsockname             __x64_sys_getsockname
+52     common  getpeername             __x64_sys_getpeername
+53     common  socketpair              __x64_sys_socketpair
+54     64      setsockopt              __x64_sys_setsockopt
+55     64      getsockopt              __x64_sys_getsockopt
+56     common  clone                   __x64_sys_clone/ptregs
+57     common  fork                    __x64_sys_fork/ptregs
+58     common  vfork                   __x64_sys_vfork/ptregs
+59     64      execve                  __x64_sys_execve/ptregs
+60     common  exit                    __x64_sys_exit
+61     common  wait4                   __x64_sys_wait4
+62     common  kill                    __x64_sys_kill
+63     common  uname                   __x64_sys_newuname
+64     common  semget                  __x64_sys_semget
+65     common  semop                   __x64_sys_semop
+66     common  semctl                  __x64_sys_semctl
+67     common  shmdt                   __x64_sys_shmdt
+68     common  msgget                  __x64_sys_msgget
+69     common  msgsnd                  __x64_sys_msgsnd
+70     common  msgrcv                  __x64_sys_msgrcv
+71     common  msgctl                  __x64_sys_msgctl
+72     common  fcntl                   __x64_sys_fcntl
+73     common  flock                   __x64_sys_flock
+74     common  fsync                   __x64_sys_fsync
+75     common  fdatasync               __x64_sys_fdatasync
+76     common  truncate                __x64_sys_truncate
+77     common  ftruncate               __x64_sys_ftruncate
+78     common  getdents                __x64_sys_getdents
+79     common  getcwd                  __x64_sys_getcwd
+80     common  chdir                   __x64_sys_chdir
+81     common  fchdir                  __x64_sys_fchdir
+82     common  rename                  __x64_sys_rename
+83     common  mkdir                   __x64_sys_mkdir
+84     common  rmdir                   __x64_sys_rmdir
+85     common  creat                   __x64_sys_creat
+86     common  link                    __x64_sys_link
+87     common  unlink                  __x64_sys_unlink
+88     common  symlink                 __x64_sys_symlink
+89     common  readlink                __x64_sys_readlink
+90     common  chmod                   __x64_sys_chmod
+91     common  fchmod                  __x64_sys_fchmod
+92     common  chown                   __x64_sys_chown
+93     common  fchown                  __x64_sys_fchown
+94     common  lchown                  __x64_sys_lchown
+95     common  umask                   __x64_sys_umask
+96     common  gettimeofday            __x64_sys_gettimeofday
+97     common  getrlimit               __x64_sys_getrlimit
+98     common  getrusage               __x64_sys_getrusage
+99     common  sysinfo                 __x64_sys_sysinfo
+100    common  times                   __x64_sys_times
+101    64      ptrace                  __x64_sys_ptrace
+102    common  getuid                  __x64_sys_getuid
+103    common  syslog                  __x64_sys_syslog
+104    common  getgid                  __x64_sys_getgid
+105    common  setuid                  __x64_sys_setuid
+106    common  setgid                  __x64_sys_setgid
+107    common  geteuid                 __x64_sys_geteuid
+108    common  getegid                 __x64_sys_getegid
+109    common  setpgid                 __x64_sys_setpgid
+110    common  getppid                 __x64_sys_getppid
+111    common  getpgrp                 __x64_sys_getpgrp
+112    common  setsid                  __x64_sys_setsid
+113    common  setreuid                __x64_sys_setreuid
+114    common  setregid                __x64_sys_setregid
+115    common  getgroups               __x64_sys_getgroups
+116    common  setgroups               __x64_sys_setgroups
+117    common  setresuid               __x64_sys_setresuid
+118    common  getresuid               __x64_sys_getresuid
+119    common  setresgid               __x64_sys_setresgid
+120    common  getresgid               __x64_sys_getresgid
+121    common  getpgid                 __x64_sys_getpgid
+122    common  setfsuid                __x64_sys_setfsuid
+123    common  setfsgid                __x64_sys_setfsgid
+124    common  getsid                  __x64_sys_getsid
+125    common  capget                  __x64_sys_capget
+126    common  capset                  __x64_sys_capset
+127    64      rt_sigpending           __x64_sys_rt_sigpending
+128    64      rt_sigtimedwait         __x64_sys_rt_sigtimedwait
+129    64      rt_sigqueueinfo         __x64_sys_rt_sigqueueinfo
+130    common  rt_sigsuspend           __x64_sys_rt_sigsuspend
+131    64      sigaltstack             __x64_sys_sigaltstack
+132    common  utime                   __x64_sys_utime
+133    common  mknod                   __x64_sys_mknod
 134    64      uselib
-135    common  personality             sys_personality
-136    common  ustat                   sys_ustat
-137    common  statfs                  sys_statfs
-138    common  fstatfs                 sys_fstatfs
-139    common  sysfs                   sys_sysfs
-140    common  getpriority             sys_getpriority
-141    common  setpriority             sys_setpriority
-142    common  sched_setparam          sys_sched_setparam
-143    common  sched_getparam          sys_sched_getparam
-144    common  sched_setscheduler      sys_sched_setscheduler
-145    common  sched_getscheduler      sys_sched_getscheduler
-146    common  sched_get_priority_max  sys_sched_get_priority_max
-147    common  sched_get_priority_min  sys_sched_get_priority_min
-148    common  sched_rr_get_interval   sys_sched_rr_get_interval
-149    common  mlock                   sys_mlock
-150    common  munlock                 sys_munlock
-151    common  mlockall                sys_mlockall
-152    common  munlockall              sys_munlockall
-153    common  vhangup                 sys_vhangup
-154    common  modify_ldt              sys_modify_ldt
-155    common  pivot_root              sys_pivot_root
-156    64      _sysctl                 sys_sysctl
-157    common  prctl                   sys_prctl
-158    common  arch_prctl              sys_arch_prctl
-159    common  adjtimex                sys_adjtimex
-160    common  setrlimit               sys_setrlimit
-161    common  chroot                  sys_chroot
-162    common  sync                    sys_sync
-163    common  acct                    sys_acct
-164    common  settimeofday            sys_settimeofday
-165    common  mount                   sys_mount
-166    common  umount2                 sys_umount
-167    common  swapon                  sys_swapon
-168    common  swapoff                 sys_swapoff
-169    common  reboot                  sys_reboot
-170    common  sethostname             sys_sethostname
-171    common  setdomainname           sys_setdomainname
-172    common  iopl                    sys_iopl/ptregs
-173    common  ioperm                  sys_ioperm
+135    common  personality             __x64_sys_personality
+136    common  ustat                   __x64_sys_ustat
+137    common  statfs                  __x64_sys_statfs
+138    common  fstatfs                 __x64_sys_fstatfs
+139    common  sysfs                   __x64_sys_sysfs
+140    common  getpriority             __x64_sys_getpriority
+141    common  setpriority             __x64_sys_setpriority
+142    common  sched_setparam          __x64_sys_sched_setparam
+143    common  sched_getparam          __x64_sys_sched_getparam
+144    common  sched_setscheduler      __x64_sys_sched_setscheduler
+145    common  sched_getscheduler      __x64_sys_sched_getscheduler
+146    common  sched_get_priority_max  __x64_sys_sched_get_priority_max
+147    common  sched_get_priority_min  __x64_sys_sched_get_priority_min
+148    common  sched_rr_get_interval   __x64_sys_sched_rr_get_interval
+149    common  mlock                   __x64_sys_mlock
+150    common  munlock                 __x64_sys_munlock
+151    common  mlockall                __x64_sys_mlockall
+152    common  munlockall              __x64_sys_munlockall
+153    common  vhangup                 __x64_sys_vhangup
+154    common  modify_ldt              __x64_sys_modify_ldt
+155    common  pivot_root              __x64_sys_pivot_root
+156    64      _sysctl                 __x64_sys_sysctl
+157    common  prctl                   __x64_sys_prctl
+158    common  arch_prctl              __x64_sys_arch_prctl
+159    common  adjtimex                __x64_sys_adjtimex
+160    common  setrlimit               __x64_sys_setrlimit
+161    common  chroot                  __x64_sys_chroot
+162    common  sync                    __x64_sys_sync
+163    common  acct                    __x64_sys_acct
+164    common  settimeofday            __x64_sys_settimeofday
+165    common  mount                   __x64_sys_mount
+166    common  umount2                 __x64_sys_umount
+167    common  swapon                  __x64_sys_swapon
+168    common  swapoff                 __x64_sys_swapoff
+169    common  reboot                  __x64_sys_reboot
+170    common  sethostname             __x64_sys_sethostname
+171    common  setdomainname           __x64_sys_setdomainname
+172    common  iopl                    __x64_sys_iopl/ptregs
+173    common  ioperm                  __x64_sys_ioperm
 174    64      create_module
-175    common  init_module             sys_init_module
-176    common  delete_module           sys_delete_module
+175    common  init_module             __x64_sys_init_module
+176    common  delete_module           __x64_sys_delete_module
 177    64      get_kernel_syms
 178    64      query_module
-179    common  quotactl                sys_quotactl
+179    common  quotactl                __x64_sys_quotactl
 180    64      nfsservctl
 181    common  getpmsg
 182    common  putpmsg
 183    common  afs_syscall
 184    common  tuxcall
 185    common  security
-186    common  gettid                  sys_gettid
-187    common  readahead               sys_readahead
-188    common  setxattr                sys_setxattr
-189    common  lsetxattr               sys_lsetxattr
-190    common  fsetxattr               sys_fsetxattr
-191    common  getxattr                sys_getxattr
-192    common  lgetxattr               sys_lgetxattr
-193    common  fgetxattr               sys_fgetxattr
-194    common  listxattr               sys_listxattr
-195    common  llistxattr              sys_llistxattr
-196    common  flistxattr              sys_flistxattr
-197    common  removexattr             sys_removexattr
-198    common  lremovexattr            sys_lremovexattr
-199    common  fremovexattr            sys_fremovexattr
-200    common  tkill                   sys_tkill
-201    common  time                    sys_time
-202    common  futex                   sys_futex
-203    common  sched_setaffinity       sys_sched_setaffinity
-204    common  sched_getaffinity       sys_sched_getaffinity
+186    common  gettid                  __x64_sys_gettid
+187    common  readahead               __x64_sys_readahead
+188    common  setxattr                __x64_sys_setxattr
+189    common  lsetxattr               __x64_sys_lsetxattr
+190    common  fsetxattr               __x64_sys_fsetxattr
+191    common  getxattr                __x64_sys_getxattr
+192    common  lgetxattr               __x64_sys_lgetxattr
+193    common  fgetxattr               __x64_sys_fgetxattr
+194    common  listxattr               __x64_sys_listxattr
+195    common  llistxattr              __x64_sys_llistxattr
+196    common  flistxattr              __x64_sys_flistxattr
+197    common  removexattr             __x64_sys_removexattr
+198    common  lremovexattr            __x64_sys_lremovexattr
+199    common  fremovexattr            __x64_sys_fremovexattr
+200    common  tkill                   __x64_sys_tkill
+201    common  time                    __x64_sys_time
+202    common  futex                   __x64_sys_futex
+203    common  sched_setaffinity       __x64_sys_sched_setaffinity
+204    common  sched_getaffinity       __x64_sys_sched_getaffinity
 205    64      set_thread_area
-206    64      io_setup                sys_io_setup
-207    common  io_destroy              sys_io_destroy
-208    common  io_getevents            sys_io_getevents
-209    64      io_submit               sys_io_submit
-210    common  io_cancel               sys_io_cancel
+206    64      io_setup                __x64_sys_io_setup
+207    common  io_destroy              __x64_sys_io_destroy
+208    common  io_getevents            __x64_sys_io_getevents
+209    64      io_submit               __x64_sys_io_submit
+210    common  io_cancel               __x64_sys_io_cancel
 211    64      get_thread_area
-212    common  lookup_dcookie          sys_lookup_dcookie
-213    common  epoll_create            sys_epoll_create
+212    common  lookup_dcookie          __x64_sys_lookup_dcookie
+213    common  epoll_create            __x64_sys_epoll_create
 214    64      epoll_ctl_old
 215    64      epoll_wait_old
-216    common  remap_file_pages        sys_remap_file_pages
-217    common  getdents64              sys_getdents64
-218    common  set_tid_address         sys_set_tid_address
-219    common  restart_syscall         sys_restart_syscall
-220    common  semtimedop              sys_semtimedop
-221    common  fadvise64               sys_fadvise64
-222    64      timer_create            sys_timer_create
-223    common  timer_settime           sys_timer_settime
-224    common  timer_gettime           sys_timer_gettime
-225    common  timer_getoverrun        sys_timer_getoverrun
-226    common  timer_delete            sys_timer_delete
-227    common  clock_settime           sys_clock_settime
-228    common  clock_gettime           sys_clock_gettime
-229    common  clock_getres            sys_clock_getres
-230    common  clock_nanosleep         sys_clock_nanosleep
-231    common  exit_group              sys_exit_group
-232    common  epoll_wait              sys_epoll_wait
-233    common  epoll_ctl               sys_epoll_ctl
-234    common  tgkill                  sys_tgkill
-235    common  utimes                  sys_utimes
+216    common  remap_file_pages        __x64_sys_remap_file_pages
+217    common  getdents64              __x64_sys_getdents64
+218    common  set_tid_address         __x64_sys_set_tid_address
+219    common  restart_syscall         __x64_sys_restart_syscall
+220    common  semtimedop              __x64_sys_semtimedop
+221    common  fadvise64               __x64_sys_fadvise64
+222    64      timer_create            __x64_sys_timer_create
+223    common  timer_settime           __x64_sys_timer_settime
+224    common  timer_gettime           __x64_sys_timer_gettime
+225    common  timer_getoverrun        __x64_sys_timer_getoverrun
+226    common  timer_delete            __x64_sys_timer_delete
+227    common  clock_settime           __x64_sys_clock_settime
+228    common  clock_gettime           __x64_sys_clock_gettime
+229    common  clock_getres            __x64_sys_clock_getres
+230    common  clock_nanosleep         __x64_sys_clock_nanosleep
+231    common  exit_group              __x64_sys_exit_group
+232    common  epoll_wait              __x64_sys_epoll_wait
+233    common  epoll_ctl               __x64_sys_epoll_ctl
+234    common  tgkill                  __x64_sys_tgkill
+235    common  utimes                  __x64_sys_utimes
 236    64      vserver
-237    common  mbind                   sys_mbind
-238    common  set_mempolicy           sys_set_mempolicy
-239    common  get_mempolicy           sys_get_mempolicy
-240    common  mq_open                 sys_mq_open
-241    common  mq_unlink               sys_mq_unlink
-242    common  mq_timedsend            sys_mq_timedsend
-243    common  mq_timedreceive         sys_mq_timedreceive
-244    64      mq_notify               sys_mq_notify
-245    common  mq_getsetattr           sys_mq_getsetattr
-246    64      kexec_load              sys_kexec_load
-247    64      waitid                  sys_waitid
-248    common  add_key                 sys_add_key
-249    common  request_key             sys_request_key
-250    common  keyctl                  sys_keyctl
-251    common  ioprio_set              sys_ioprio_set
-252    common  ioprio_get              sys_ioprio_get
-253    common  inotify_init            sys_inotify_init
-254    common  inotify_add_watch       sys_inotify_add_watch
-255    common  inotify_rm_watch        sys_inotify_rm_watch
-256    common  migrate_pages           sys_migrate_pages
-257    common  openat                  sys_openat
-258    common  mkdirat                 sys_mkdirat
-259    common  mknodat                 sys_mknodat
-260    common  fchownat                sys_fchownat
-261    common  futimesat               sys_futimesat
-262    common  newfstatat              sys_newfstatat
-263    common  unlinkat                sys_unlinkat
-264    common  renameat                sys_renameat
-265    common  linkat                  sys_linkat
-266    common  symlinkat               sys_symlinkat
-267    common  readlinkat              sys_readlinkat
-268    common  fchmodat                sys_fchmodat
-269    common  faccessat               sys_faccessat
-270    common  pselect6                sys_pselect6
-271    common  ppoll                   sys_ppoll
-272    common  unshare                 sys_unshare
-273    64      set_robust_list         sys_set_robust_list
-274    64      get_robust_list         sys_get_robust_list
-275    common  splice                  sys_splice
-276    common  tee                     sys_tee
-277    common  sync_file_range         sys_sync_file_range
-278    64      vmsplice                sys_vmsplice
-279    64      move_pages              sys_move_pages
-280    common  utimensat               sys_utimensat
-281    common  epoll_pwait             sys_epoll_pwait
-282    common  signalfd                sys_signalfd
-283    common  timerfd_create          sys_timerfd_create
-284    common  eventfd                 sys_eventfd
-285    common  fallocate               sys_fallocate
-286    common  timerfd_settime         sys_timerfd_settime
-287    common  timerfd_gettime         sys_timerfd_gettime
-288    common  accept4                 sys_accept4
-289    common  signalfd4               sys_signalfd4
-290    common  eventfd2                sys_eventfd2
-291    common  epoll_create1           sys_epoll_create1
-292    common  dup3                    sys_dup3
-293    common  pipe2                   sys_pipe2
-294    common  inotify_init1           sys_inotify_init1
-295    64      preadv                  sys_preadv
-296    64      pwritev                 sys_pwritev
-297    64      rt_tgsigqueueinfo       sys_rt_tgsigqueueinfo
-298    common  perf_event_open         sys_perf_event_open
-299    64      recvmmsg                sys_recvmmsg
-300    common  fanotify_init           sys_fanotify_init
-301    common  fanotify_mark           sys_fanotify_mark
-302    common  prlimit64               sys_prlimit64
-303    common  name_to_handle_at       sys_name_to_handle_at
-304    common  open_by_handle_at       sys_open_by_handle_at
-305    common  clock_adjtime           sys_clock_adjtime
-306    common  syncfs                  sys_syncfs
-307    64      sendmmsg                sys_sendmmsg
-308    common  setns                   sys_setns
-309    common  getcpu                  sys_getcpu
-310    64      process_vm_readv        sys_process_vm_readv
-311    64      process_vm_writev       sys_process_vm_writev
-312    common  kcmp                    sys_kcmp
-313    common  finit_module            sys_finit_module
-314    common  sched_setattr           sys_sched_setattr
-315    common  sched_getattr           sys_sched_getattr
-316    common  renameat2               sys_renameat2
-317    common  seccomp                 sys_seccomp
-318    common  getrandom               sys_getrandom
-319    common  memfd_create            sys_memfd_create
-320    common  kexec_file_load         sys_kexec_file_load
-321    common  bpf                     sys_bpf
-322    64      execveat                sys_execveat/ptregs
-323    common  userfaultfd             sys_userfaultfd
-324    common  membarrier              sys_membarrier
-325    common  mlock2                  sys_mlock2
-326    common  copy_file_range         sys_copy_file_range
-327    64      preadv2                 sys_preadv2
-328    64      pwritev2                sys_pwritev2
-329    common  pkey_mprotect           sys_pkey_mprotect
-330    common  pkey_alloc              sys_pkey_alloc
-331    common  pkey_free               sys_pkey_free
-332    common  statx                   sys_statx
+237    common  mbind                   __x64_sys_mbind
+238    common  set_mempolicy           __x64_sys_set_mempolicy
+239    common  get_mempolicy           __x64_sys_get_mempolicy
+240    common  mq_open                 __x64_sys_mq_open
+241    common  mq_unlink               __x64_sys_mq_unlink
+242    common  mq_timedsend            __x64_sys_mq_timedsend
+243    common  mq_timedreceive         __x64_sys_mq_timedreceive
+244    64      mq_notify               __x64_sys_mq_notify
+245    common  mq_getsetattr           __x64_sys_mq_getsetattr
+246    64      kexec_load              __x64_sys_kexec_load
+247    64      waitid                  __x64_sys_waitid
+248    common  add_key                 __x64_sys_add_key
+249    common  request_key             __x64_sys_request_key
+250    common  keyctl                  __x64_sys_keyctl
+251    common  ioprio_set              __x64_sys_ioprio_set
+252    common  ioprio_get              __x64_sys_ioprio_get
+253    common  inotify_init            __x64_sys_inotify_init
+254    common  inotify_add_watch       __x64_sys_inotify_add_watch
+255    common  inotify_rm_watch        __x64_sys_inotify_rm_watch
+256    common  migrate_pages           __x64_sys_migrate_pages
+257    common  openat                  __x64_sys_openat
+258    common  mkdirat                 __x64_sys_mkdirat
+259    common  mknodat                 __x64_sys_mknodat
+260    common  fchownat                __x64_sys_fchownat
+261    common  futimesat               __x64_sys_futimesat
+262    common  newfstatat              __x64_sys_newfstatat
+263    common  unlinkat                __x64_sys_unlinkat
+264    common  renameat                __x64_sys_renameat
+265    common  linkat                  __x64_sys_linkat
+266    common  symlinkat               __x64_sys_symlinkat
+267    common  readlinkat              __x64_sys_readlinkat
+268    common  fchmodat                __x64_sys_fchmodat
+269    common  faccessat               __x64_sys_faccessat
+270    common  pselect6                __x64_sys_pselect6
+271    common  ppoll                   __x64_sys_ppoll
+272    common  unshare                 __x64_sys_unshare
+273    64      set_robust_list         __x64_sys_set_robust_list
+274    64      get_robust_list         __x64_sys_get_robust_list
+275    common  splice                  __x64_sys_splice
+276    common  tee                     __x64_sys_tee
+277    common  sync_file_range         __x64_sys_sync_file_range
+278    64      vmsplice                __x64_sys_vmsplice
+279    64      move_pages              __x64_sys_move_pages
+280    common  utimensat               __x64_sys_utimensat
+281    common  epoll_pwait             __x64_sys_epoll_pwait
+282    common  signalfd                __x64_sys_signalfd
+283    common  timerfd_create          __x64_sys_timerfd_create
+284    common  eventfd                 __x64_sys_eventfd
+285    common  fallocate               __x64_sys_fallocate
+286    common  timerfd_settime         __x64_sys_timerfd_settime
+287    common  timerfd_gettime         __x64_sys_timerfd_gettime
+288    common  accept4                 __x64_sys_accept4
+289    common  signalfd4               __x64_sys_signalfd4
+290    common  eventfd2                __x64_sys_eventfd2
+291    common  epoll_create1           __x64_sys_epoll_create1
+292    common  dup3                    __x64_sys_dup3
+293    common  pipe2                   __x64_sys_pipe2
+294    common  inotify_init1           __x64_sys_inotify_init1
+295    64      preadv                  __x64_sys_preadv
+296    64      pwritev                 __x64_sys_pwritev
+297    64      rt_tgsigqueueinfo       __x64_sys_rt_tgsigqueueinfo
+298    common  perf_event_open         __x64_sys_perf_event_open
+299    64      recvmmsg                __x64_sys_recvmmsg
+300    common  fanotify_init           __x64_sys_fanotify_init
+301    common  fanotify_mark           __x64_sys_fanotify_mark
+302    common  prlimit64               __x64_sys_prlimit64
+303    common  name_to_handle_at       __x64_sys_name_to_handle_at
+304    common  open_by_handle_at       __x64_sys_open_by_handle_at
+305    common  clock_adjtime           __x64_sys_clock_adjtime
+306    common  syncfs                  __x64_sys_syncfs
+307    64      sendmmsg                __x64_sys_sendmmsg
+308    common  setns                   __x64_sys_setns
+309    common  getcpu                  __x64_sys_getcpu
+310    64      process_vm_readv        __x64_sys_process_vm_readv
+311    64      process_vm_writev       __x64_sys_process_vm_writev
+312    common  kcmp                    __x64_sys_kcmp
+313    common  finit_module            __x64_sys_finit_module
+314    common  sched_setattr           __x64_sys_sched_setattr
+315    common  sched_getattr           __x64_sys_sched_getattr
+316    common  renameat2               __x64_sys_renameat2
+317    common  seccomp                 __x64_sys_seccomp
+318    common  getrandom               __x64_sys_getrandom
+319    common  memfd_create            __x64_sys_memfd_create
+320    common  kexec_file_load         __x64_sys_kexec_file_load
+321    common  bpf                     __x64_sys_bpf
+322    64      execveat                __x64_sys_execveat/ptregs
+323    common  userfaultfd             __x64_sys_userfaultfd
+324    common  membarrier              __x64_sys_membarrier
+325    common  mlock2                  __x64_sys_mlock2
+326    common  copy_file_range         __x64_sys_copy_file_range
+327    64      preadv2                 __x64_sys_preadv2
+328    64      pwritev2                __x64_sys_pwritev2
+329    common  pkey_mprotect           __x64_sys_pkey_mprotect
+330    common  pkey_alloc              __x64_sys_pkey_alloc
+331    common  pkey_free               __x64_sys_pkey_free
+332    common  statx                   __x64_sys_statx
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
-# for native 64-bit operation.
+# for native 64-bit operation. The __x32_compat_sys stubs are created
+# on-the-fly for compat_sys_*() compatibility system calls if X86_X32
+# is defined.
 #
-512    x32     rt_sigaction            compat_sys_rt_sigaction
+512    x32     rt_sigaction            __x32_compat_sys_rt_sigaction
 513    x32     rt_sigreturn            sys32_x32_rt_sigreturn
-514    x32     ioctl                   compat_sys_ioctl
-515    x32     readv                   compat_sys_readv
-516    x32     writev                  compat_sys_writev
-517    x32     recvfrom                compat_sys_recvfrom
-518    x32     sendmsg                 compat_sys_sendmsg
-519    x32     recvmsg                 compat_sys_recvmsg
-520    x32     execve                  compat_sys_execve/ptregs
-521    x32     ptrace                  compat_sys_ptrace
-522    x32     rt_sigpending           compat_sys_rt_sigpending
-523    x32     rt_sigtimedwait         compat_sys_rt_sigtimedwait
-524    x32     rt_sigqueueinfo         compat_sys_rt_sigqueueinfo
-525    x32     sigaltstack             compat_sys_sigaltstack
-526    x32     timer_create            compat_sys_timer_create
-527    x32     mq_notify               compat_sys_mq_notify
-528    x32     kexec_load              compat_sys_kexec_load
-529    x32     waitid                  compat_sys_waitid
-530    x32     set_robust_list         compat_sys_set_robust_list
-531    x32     get_robust_list         compat_sys_get_robust_list
-532    x32     vmsplice                compat_sys_vmsplice
-533    x32     move_pages              compat_sys_move_pages
-534    x32     preadv                  compat_sys_preadv64
-535    x32     pwritev                 compat_sys_pwritev64
-536    x32     rt_tgsigqueueinfo       compat_sys_rt_tgsigqueueinfo
-537    x32     recvmmsg                compat_sys_recvmmsg
-538    x32     sendmmsg                compat_sys_sendmmsg
-539    x32     process_vm_readv        compat_sys_process_vm_readv
-540    x32     process_vm_writev       compat_sys_process_vm_writev
-541    x32     setsockopt              compat_sys_setsockopt
-542    x32     getsockopt              compat_sys_getsockopt
-543    x32     io_setup                compat_sys_io_setup
-544    x32     io_submit               compat_sys_io_submit
-545    x32     execveat                compat_sys_execveat/ptregs
-546    x32     preadv2                 compat_sys_preadv64v2
-547    x32     pwritev2                compat_sys_pwritev64v2
+514    x32     ioctl                   __x32_compat_sys_ioctl
+515    x32     readv                   __x32_compat_sys_readv
+516    x32     writev                  __x32_compat_sys_writev
+517    x32     recvfrom                __x32_compat_sys_recvfrom
+518    x32     sendmsg                 __x32_compat_sys_sendmsg
+519    x32     recvmsg                 __x32_compat_sys_recvmsg
+520    x32     execve                  __x32_compat_sys_execve/ptregs
+521    x32     ptrace                  __x32_compat_sys_ptrace
+522    x32     rt_sigpending           __x32_compat_sys_rt_sigpending
+523    x32     rt_sigtimedwait         __x32_compat_sys_rt_sigtimedwait
+524    x32     rt_sigqueueinfo         __x32_compat_sys_rt_sigqueueinfo
+525    x32     sigaltstack             __x32_compat_sys_sigaltstack
+526    x32     timer_create            __x32_compat_sys_timer_create
+527    x32     mq_notify               __x32_compat_sys_mq_notify
+528    x32     kexec_load              __x32_compat_sys_kexec_load
+529    x32     waitid                  __x32_compat_sys_waitid
+530    x32     set_robust_list         __x32_compat_sys_set_robust_list
+531    x32     get_robust_list         __x32_compat_sys_get_robust_list
+532    x32     vmsplice                __x32_compat_sys_vmsplice
+533    x32     move_pages              __x32_compat_sys_move_pages
+534    x32     preadv                  __x32_compat_sys_preadv64
+535    x32     pwritev                 __x32_compat_sys_pwritev64
+536    x32     rt_tgsigqueueinfo       __x32_compat_sys_rt_tgsigqueueinfo
+537    x32     recvmmsg                __x32_compat_sys_recvmmsg
+538    x32     sendmmsg                __x32_compat_sys_sendmmsg
+539    x32     process_vm_readv        __x32_compat_sys_process_vm_readv
+540    x32     process_vm_writev       __x32_compat_sys_process_vm_writev
+541    x32     setsockopt              __x32_compat_sys_setsockopt
+542    x32     getsockopt              __x32_compat_sys_getsockopt
+543    x32     io_setup                __x32_compat_sys_io_setup
+544    x32     io_submit               __x32_compat_sys_io_submit
+545    x32     execveat                __x32_compat_sys_execveat/ptregs
+546    x32     preadv2                 __x32_compat_sys_preadv64v2
+547    x32     pwritev2                __x32_compat_sys_pwritev64v2
index 4aca13f23b9d2f4005846d89c68833705576d8d1..1c41b4eaf73cd407ebe0e86e673d7c82dfb9d501 100644 (file)
@@ -439,7 +439,7 @@ int cmd_help(int argc, const char **argv)
 #ifdef HAVE_LIBELF_SUPPORT
                "probe",
 #endif
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
+#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
                "trace",
 #endif
        NULL };
index 506564651cda983c4dd996f0acba0f8c1e66f9a1..57393e94d1561f8e9a7611f787f30147f25ca6c8 100644 (file)
@@ -83,7 +83,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
        };
 
        argc = parse_options(argc, argv, options, record_mem_usage,
-                            PARSE_OPT_STOP_AT_NON_OPTION);
+                            PARSE_OPT_KEEP_UNKNOWN);
 
        rec_argc = argc + 9; /* max number of arguments */
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
@@ -436,7 +436,7 @@ int cmd_mem(int argc, const char **argv)
        }
 
        argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands,
-                                       mem_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+                                       mem_usage, PARSE_OPT_KEEP_UNKNOWN);
 
        if (!argc || !(strncmp(argv[0], "rec", 3) || mem.operation))
                usage_with_options(mem_usage, mem_options);
index 313c424233938cc118f59e6e55950a5e0de22faa..e0a9845b6cbc57db5e13426d536a18b771202717 100644 (file)
@@ -657,8 +657,11 @@ static int perf_sample__fprintf_start(struct perf_sample *sample,
                        break;
                case PERF_RECORD_SWITCH:
                case PERF_RECORD_SWITCH_CPU_WIDE:
-                       if (has(SWITCH_OUT))
+                       if (has(SWITCH_OUT)) {
                                ret += fprintf(fp, "S");
+                               if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
+                                       ret += fprintf(fp, "p");
+                       }
                default:
                        break;
                }
@@ -2801,11 +2804,11 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
        for_each_lang(scripts_path, scripts_dir, lang_dirent) {
                scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
                          lang_dirent->d_name);
-#ifdef NO_LIBPERL
+#ifndef HAVE_LIBPERL_SUPPORT
                if (strstr(lang_path, "perl"))
                        continue;
 #endif
-#ifdef NO_LIBPYTHON
+#ifndef HAVE_LIBPYTHON_SUPPORT
                if (strstr(lang_path, "python"))
                        continue;
 #endif
index f5c45485590886442c85b349ee448c9189fe5889..f17dc601b0f39aaff4f5c92a27b93b0075df5741 100644 (file)
@@ -172,6 +172,7 @@ static bool                 interval_count;
 static const char              *output_name;
 static int                     output_fd;
 static int                     print_free_counters_hint;
+static int                     print_mixed_hw_group_error;
 
 struct perf_stat {
        bool                     record;
@@ -1126,6 +1127,30 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
                fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
 }
 
+static bool is_mixed_hw_group(struct perf_evsel *counter)
+{
+       struct perf_evlist *evlist = counter->evlist;
+       u32 pmu_type = counter->attr.type;
+       struct perf_evsel *pos;
+
+       if (counter->nr_members < 2)
+               return false;
+
+       evlist__for_each_entry(evlist, pos) {
+               /* software events can be part of any hardware group */
+               if (pos->attr.type == PERF_TYPE_SOFTWARE)
+                       continue;
+               if (pmu_type == PERF_TYPE_SOFTWARE) {
+                       pmu_type = pos->attr.type;
+                       continue;
+               }
+               if (pmu_type != pos->attr.type)
+                       return true;
+       }
+
+       return false;
+}
+
 static void printout(int id, int nr, struct perf_evsel *counter, double uval,
                     char *prefix, u64 run, u64 ena, double noise,
                     struct runtime_stat *st)
@@ -1178,8 +1203,11 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
                        counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
                        csv_sep);
 
-               if (counter->supported)
+               if (counter->supported) {
                        print_free_counters_hint = 1;
+                       if (is_mixed_hw_group(counter))
+                               print_mixed_hw_group_error = 1;
+               }
 
                fprintf(stat_config.output, "%-*s%s",
                        csv_output ? 0 : unit_width,
@@ -1256,7 +1284,8 @@ static void uniquify_event_name(struct perf_evsel *counter)
        char *new_name;
        char *config;
 
-       if (!counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
+       if (counter->uniquified_name ||
+           !counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
                                           strlen(counter->pmu_name)))
                return;
 
@@ -1274,6 +1303,8 @@ static void uniquify_event_name(struct perf_evsel *counter)
                        counter->name = new_name;
                }
        }
+
+       counter->uniquified_name = true;
 }
 
 static void collect_all_aliases(struct perf_evsel *counter,
@@ -1757,6 +1788,11 @@ static void print_footer(void)
 "      echo 0 > /proc/sys/kernel/nmi_watchdog\n"
 "      perf stat ...\n"
 "      echo 1 > /proc/sys/kernel/nmi_watchdog\n");
+
+       if (print_mixed_hw_group_error)
+               fprintf(output,
+                       "The events in group usually have to be from "
+                       "the same PMU. Try reorganizing the group.\n");
 }
 
 static void print_counters(struct timespec *ts, int argc, const char **argv)
@@ -1943,7 +1979,8 @@ static const struct option stat_options[] = {
        OPT_STRING(0, "post", &post_cmd, "command",
                        "command to run after to the measured command"),
        OPT_UINTEGER('I', "interval-print", &stat_config.interval,
-                   "print counts at regular interval in ms (>= 10)"),
+                   "print counts at regular interval in ms "
+                   "(overhead is possible for values <= 100ms)"),
        OPT_INTEGER(0, "interval-count", &stat_config.times,
                    "print counts for fixed number of times"),
        OPT_UINTEGER(0, "timeout", &stat_config.timeout,
@@ -2923,17 +2960,6 @@ int cmd_stat(int argc, const char **argv)
                }
        }
 
-       if (interval && interval < 100) {
-               if (interval < 10) {
-                       pr_err("print interval must be >= 10ms\n");
-                       parse_options_usage(stat_usage, stat_options, "I", 1);
-                       goto out;
-               } else
-                       pr_warning("print interval < 100ms. "
-                                  "The overhead percentage could be high in some cases. "
-                                  "Please proceed with caution.\n");
-       }
-
        if (stat_config.times && interval)
                interval_count = true;
        else if (stat_config.times && !interval) {
index 2abe3910d6b6413e99246a49a1cfd41a5cc30703..50df168be326d84cba4e5cfbc26ea8a119d392cf 100644 (file)
@@ -60,7 +60,10 @@ static void library_status(void)
        STATUS(HAVE_DWARF_GETLOCATIONS_SUPPORT, dwarf_getlocations);
        STATUS(HAVE_GLIBC_SUPPORT, glibc);
        STATUS(HAVE_GTK2_SUPPORT, gtk2);
+#ifndef HAVE_SYSCALL_TABLE_SUPPORT
        STATUS(HAVE_LIBAUDIT_SUPPORT, libaudit);
+#endif
+       STATUS(HAVE_SYSCALL_TABLE_SUPPORT, syscall_table);
        STATUS(HAVE_LIBBFD_SUPPORT, libbfd);
        STATUS(HAVE_LIBELF_SUPPORT, libelf);
        STATUS(HAVE_LIBNUMA_SUPPORT, libnuma);
index 1659029d03fccc03db57b0e94ec342571675b8e3..20a08cb323329be20348fbf513091d40780ac12a 100644 (file)
@@ -73,7 +73,7 @@ static struct cmd_struct commands[] = {
        { "lock",       cmd_lock,       0 },
        { "kvm",        cmd_kvm,        0 },
        { "test",       cmd_test,       0 },
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
+#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
        { "trace",      cmd_trace,      0 },
 #endif
        { "inject",     cmd_inject,     0 },
@@ -491,7 +491,7 @@ int main(int argc, const char **argv)
                argv[0] = cmd;
        }
        if (strstarts(cmd, "trace")) {
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
+#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
                setup_path();
                argv[0] = "trace";
                return cmd_trace(argc, argv);
index ca7682748a4b8d34d0dd2b87eaea1e980264291d..78bcf7f8e2066e470e5868c976aaa2a1b305d207 100644 (file)
@@ -1,6 +1,6 @@
 Family-model,Version,Filename,EventType
-209[78],1,cf_z10,core
-281[78],1,cf_z196,core
-282[78],1,cf_zec12,core
-296[45],1,cf_z13,core
-3906,3,cf_z14,core
+^IBM.209[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z10,core
+^IBM.281[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z196,core
+^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core
+^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core
+^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core
index f906b793196fc7594a96f795617bdbb73ae42639..8a33ca4f9e1f7feed87159d755ba3b4797a987b6 100644 (file)
@@ -35,3 +35,6 @@ inherit=0
 # sampling disabled
 sample_freq=0
 sample_period=0
+freq=0
+write_backward=0
+sample_id_all=0
index e4123c1b0e8839054188c08d2df3c45052c85b49..1ca5106df5f15a58a20500294c038db954304c3a 100644 (file)
@@ -31,7 +31,7 @@ struct bpf_map_def SEC("maps") flip_table = {
        .max_entries = 1,
 };
 
-SEC("func=SyS_epoll_pwait")
+SEC("func=do_epoll_wait")
 int bpf_func__SyS_epoll_pwait(void *ctx)
 {
        int ind =0;
index 3626924740d8092107a196eb944e18651727c9e3..ff3ec8337f0a2eeb8062ccf6064f677fdd4078a3 100644 (file)
@@ -9,7 +9,6 @@
 #define SEC(NAME) __attribute__((section(NAME), used))
 
 #include <uapi/linux/fs.h>
-#include <uapi/asm/ptrace.h>
 
 SEC("func=vfs_llseek")
 int bpf_func__vfs_llseek(void *ctx)
index 625f5a6772af7c8790d5e60265225688dd642a13..cac8f8889bc3b540355963ee793fb0e4aadbfd12 100644 (file)
@@ -118,6 +118,7 @@ static struct test generic_tests[] = {
        {
                .desc = "Breakpoint accounting",
                .func = test__bp_accounting,
+               .is_supported = test__bp_signal_is_supported,
        },
        {
                .desc = "Number of exit events of a simple workload",
index bb8e6bcb0d967a22291df3896fc90a43bd81bc78..0919b0793e5b681d876630ac5dc7834bed9269c6 100644 (file)
@@ -75,7 +75,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
                snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
                evsels[i] = perf_evsel__newtp("syscalls", name);
                if (IS_ERR(evsels[i])) {
-                       pr_debug("perf_evsel__new\n");
+                       pr_debug("perf_evsel__new(%s)\n", name);
                        goto out_delete_evlist;
                }
 
index 1ecc1f0ff84a19e771a7027419b91df728f693f5..016882dbbc16bddda77e180f421d0bcff2ad1760 100755 (executable)
@@ -19,12 +19,10 @@ trace_libc_inet_pton_backtrace() {
        expected[1]=".*inet_pton[[:space:]]\($libc\)$"
        case "$(uname -m)" in
        s390x)
-               eventattr='call-graph=dwarf'
+               eventattr='call-graph=dwarf,max-stack=4'
                expected[2]="gaih_inet.*[[:space:]]\($libc|inlined\)$"
-               expected[3]="__GI_getaddrinfo[[:space:]]\($libc|inlined\)$"
+               expected[3]="(__GI_)?getaddrinfo[[:space:]]\($libc|inlined\)$"
                expected[4]="main[[:space:]]\(.*/bin/ping.*\)$"
-               expected[5]="__libc_start_main[[:space:]]\($libc\)$"
-               expected[6]="_start[[:space:]]\(.*/bin/ping.*\)$"
                ;;
        *)
                eventattr='max-stack=3'
index 417e3ecfe9d730fc1c02e2c2e24fe36e23fbf83a..9f68077b241b9c59475cb5d8403e0002f06769a3 100644 (file)
@@ -54,6 +54,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
        P_MMAP_FLAG(EXECUTABLE);
        P_MMAP_FLAG(FILE);
        P_MMAP_FLAG(FIXED);
+#ifdef MAP_FIXED_NOREPLACE
+       P_MMAP_FLAG(FIXED_NOREPLACE);
+#endif
        P_MMAP_FLAG(GROWSDOWN);
        P_MMAP_FLAG(HUGETLB);
        P_MMAP_FLAG(LOCKED);
index 12c099a87f8baefa1036f7cebc0a8496a89f3fd7..3781d74088a744042ff6dc2d8588154a01110e62 100644 (file)
@@ -692,6 +692,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
                "J             Toggle showing number of jump sources on targets\n"
                "n             Search next string\n"
                "o             Toggle disassembler output/simplified view\n"
+               "O             Bump offset level (jump targets -> +call -> all -> cycle thru)\n"
                "s             Toggle source code view\n"
                "t             Circulate percent, total period, samples view\n"
                "/             Search string\n"
@@ -719,6 +720,10 @@ static int annotate_browser__run(struct annotate_browser *browser,
                        notes->options->use_offset = !notes->options->use_offset;
                        annotation__update_column_widths(notes);
                        continue;
+               case 'O':
+                       if (++notes->options->offset_level > ANNOTATION__MAX_OFFSET_LEVEL)
+                               notes->options->offset_level = ANNOTATION__MIN_OFFSET_LEVEL;
+                       continue;
                case 'j':
                        notes->options->jump_arrows = !notes->options->jump_arrows;
                        continue;
index 0eec06c105c6f4a721a4d29897e73c50d217bab4..e5f247247daa870fdca3497991a886b993938a17 100644 (file)
@@ -2714,7 +2714,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
        "h/?/F1        Show this window\n"                              \
        "UP/DOWN/PGUP\n"                                                \
        "PGDN/SPACE    Navigate\n"                                      \
-       "q/ESC/CTRL+C  Exit browser\n\n"                                \
+       "q/ESC/CTRL+C  Exit browser or go back to previous screen\n\n"  \
        "For multiple event sessions:\n\n"                              \
        "TAB/UNTAB     Switch events\n\n"                               \
        "For symbolic views (--sort has sym):\n\n"                      \
index fbad8dfbb186f52818c0237d490f71c78ab749fe..536ee148bff82576d7ab21949b1c20d749929539 100644 (file)
@@ -46,6 +46,7 @@
 struct annotation_options annotation__default_options = {
        .use_offset     = true,
        .jump_arrows    = true,
+       .offset_level   = ANNOTATION__OFFSET_JUMP_TARGETS,
 };
 
 const char     *disassembler_style;
@@ -2512,7 +2513,8 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
                if (!notes->options->use_offset) {
                        printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
                } else {
-                       if (al->jump_sources) {
+                       if (al->jump_sources &&
+                           notes->options->offset_level >= ANNOTATION__OFFSET_JUMP_TARGETS) {
                                if (notes->options->show_nr_jumps) {
                                        int prev;
                                        printed = scnprintf(bf, sizeof(bf), "%*d ",
@@ -2523,9 +2525,14 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
                                        obj__printf(obj, bf);
                                        obj__set_color(obj, prev);
                                }
-
+print_addr:
                                printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ",
                                                    notes->widths.target, addr);
+                       } else if (ins__is_call(&disasm_line(al)->ins) &&
+                                  notes->options->offset_level >= ANNOTATION__OFFSET_CALL) {
+                               goto print_addr;
+                       } else if (notes->options->offset_level == ANNOTATION__MAX_OFFSET_LEVEL) {
+                               goto print_addr;
                        } else {
                                printed = scnprintf(bf, sizeof(bf), "%-*s  ",
                                                    notes->widths.addr, " ");
@@ -2642,10 +2649,11 @@ int __annotation__scnprintf_samples_period(struct annotation *notes,
  */
 static struct annotation_config {
        const char *name;
-       bool *value;
+       void *value;
 } annotation__configs[] = {
        ANNOTATION__CFG(hide_src_code),
        ANNOTATION__CFG(jump_arrows),
+       ANNOTATION__CFG(offset_level),
        ANNOTATION__CFG(show_linenr),
        ANNOTATION__CFG(show_nr_jumps),
        ANNOTATION__CFG(show_nr_samples),
@@ -2677,8 +2685,16 @@ static int annotation__config(const char *var, const char *value,
 
        if (cfg == NULL)
                pr_debug("%s variable unknown, ignoring...", var);
-       else
-               *cfg->value = perf_config_bool(name, value);
+       else if (strcmp(var, "annotate.offset_level") == 0) {
+               perf_config_int(cfg->value, name, value);
+
+               if (*(int *)cfg->value > ANNOTATION__MAX_OFFSET_LEVEL)
+                       *(int *)cfg->value = ANNOTATION__MAX_OFFSET_LEVEL;
+               else if (*(int *)cfg->value < ANNOTATION__MIN_OFFSET_LEVEL)
+                       *(int *)cfg->value = ANNOTATION__MIN_OFFSET_LEVEL;
+       } else {
+               *(bool *)cfg->value = perf_config_bool(name, value);
+       }
        return 0;
 }
 
index db8d09bea07eb5e28a6820e192ce976e29734c1b..f28a9e43421d9c364519db7dd9267a23ea89d8e9 100644 (file)
@@ -70,8 +70,17 @@ struct annotation_options {
             show_nr_jumps,
             show_nr_samples,
             show_total_period;
+       u8   offset_level;
 };
 
+enum {
+       ANNOTATION__OFFSET_JUMP_TARGETS = 1,
+       ANNOTATION__OFFSET_CALL,
+       ANNOTATION__MAX_OFFSET_LEVEL,
+};
+
+#define ANNOTATION__MIN_OFFSET_LEVEL ANNOTATION__OFFSET_JUMP_TARGETS
+
 extern struct annotation_options annotation__default_options;
 
 struct annotation;
index 640af88331b4ecd7a4509d1120b5bef5b6990ff3..c8b98fa2299736a2f76decf2d3f5458d41974131 100644 (file)
@@ -1,6 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * SPDX-License-Identifier: GPL-2.0
- *
  * Copyright(C) 2015-2018 Linaro Limited.
  *
  * Author: Tor Jeremiassen <tor@ti.com>
index 1b0d422373be5e8dce853cd15a312b22355147ce..40020b1ca54f4ecbd05bc3524538634f435dc6be 100644 (file)
@@ -1,6 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * SPDX-License-Identifier: GPL-2.0
- *
  * Copyright(C) 2015-2018 Linaro Limited.
  *
  * Author: Tor Jeremiassen <tor@ti.com>
index 5864d5dca616e9df9d3b256e0928033c7d835c3e..37f8d48179caef841128d0d7f7a8c635bb395769 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef INCLUDE__UTIL_PERF_CS_ETM_H__
index f0a6cbd033cc7196afa30bb161bc545e95742bb2..98ff3a6a3d507f9ba41079b19423dbf49aa013b3 100644 (file)
@@ -1421,7 +1421,9 @@ size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp)
 {
        bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
-       const char *in_out = out ? "OUT" : "IN ";
+       const char *in_out = !out ? "IN         " :
+               !(event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT) ?
+                                   "OUT        " : "OUT preempt";
 
        if (event->header.type == PERF_RECORD_SWITCH)
                return fprintf(fp, " %s\n", in_out);
index 1ac8d9236efddaadb0de61a78bc6fbe4cc869a2c..4cd2cf93f7263e97307b69ec65d0e5c752be51fa 100644 (file)
@@ -930,8 +930,11 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
         * than leader in case leader 'leads' the sampling.
         */
        if ((leader != evsel) && leader->sample_read) {
-               attr->sample_freq   = 0;
-               attr->sample_period = 0;
+               attr->freq           = 0;
+               attr->sample_freq    = 0;
+               attr->sample_period  = 0;
+               attr->write_backward = 0;
+               attr->sample_id_all  = 0;
        }
 
        if (opts->no_samples)
@@ -1922,7 +1925,8 @@ try_fallback:
                goto fallback_missing_features;
        } else if (!perf_missing_features.group_read &&
                    evsel->attr.inherit &&
-                  (evsel->attr.read_format & PERF_FORMAT_GROUP)) {
+                  (evsel->attr.read_format & PERF_FORMAT_GROUP) &&
+                  perf_evsel__is_group_leader(evsel)) {
                perf_missing_features.group_read = true;
                pr_debug2("switching off group read\n");
                goto fallback_missing_features;
@@ -2754,8 +2758,14 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
                   (paranoid = perf_event_paranoid()) > 1) {
                const char *name = perf_evsel__name(evsel);
                char *new_name;
+               const char *sep = ":";
 
-               if (asprintf(&new_name, "%s%su", name, strchr(name, ':') ? "" : ":") < 0)
+               /* Is there already the separator in the name. */
+               if (strchr(name, '/') ||
+                   strchr(name, ':'))
+                       sep = "";
+
+               if (asprintf(&new_name, "%s%su", name, sep) < 0)
                        return false;
 
                if (evsel->name)
@@ -2870,8 +2880,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
 #if defined(__i386__) || defined(__x86_64__)
                if (evsel->attr.type == PERF_TYPE_HARDWARE)
                        return scnprintf(msg, size, "%s",
-       "No hardware sampling interrupt available.\n"
-       "No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.");
+       "No hardware sampling interrupt available.\n");
 #endif
                break;
        case EBUSY:
@@ -2894,8 +2903,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
 
        return scnprintf(msg, size,
        "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n"
-       "/bin/dmesg may provide additional information.\n"
-       "No CONFIG_PERF_EVENTS=y kernel support configured?",
+       "/bin/dmesg | grep -i perf may provide additional information.\n",
                         err, str_error_r(err, sbuf, sizeof(sbuf)),
                         perf_evsel__name(evsel));
 }
index d3ee3af618ef5226ec199d0c7c2df80f7726a485..92ec009a292d3efd4cf4738d51533e7e4048e22d 100644 (file)
@@ -115,6 +115,7 @@ struct perf_evsel {
        unsigned int            sample_size;
        int                     id_pos;
        int                     is_pos;
+       bool                    uniquified_name;
        bool                    snapshot;
        bool                    supported;
        bool                    needs_swap;
index ff17920a5ebc62a04fcaeca722da2e1951b82afa..c3cef36d417683581ed7405ac842854057f8ff7b 100755 (executable)
@@ -38,7 +38,7 @@ do
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
 
-echo "#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)"
+echo "#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)"
 sed -n -e 's/^perf-\([^        ]*\)[   ].* audit*/\1/p' command-list.txt |
 sort |
 while read cmd
index 121df1683c36ac770aa91febb346477742eef444..a8bff2178fbc0cbe5c8c56e6548f7027c09ca56f 100644 (file)
@@ -1320,7 +1320,8 @@ static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp)
 
        dir = opendir(path);
        if (!dir) {
-               pr_warning("failed: can't open node sysfs data\n");
+               pr_debug2("%s: could't read %s, does this arch have topology information?\n",
+                         __func__, path);
                return -1;
        }
 
index 2eca8478e24f0d8b5bf60658f4190bb6213579d0..32d50492505d4b5018dc3fe3794e284e519f8346 100644 (file)
@@ -1019,13 +1019,6 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type)
        return ret;
 }
 
-static void map_groups__fixup_end(struct map_groups *mg)
-{
-       int i;
-       for (i = 0; i < MAP__NR_TYPES; ++i)
-               __map_groups__fixup_end(mg, i);
-}
-
 static char *get_kernel_version(const char *root_dir)
 {
        char version[PATH_MAX];
@@ -1233,6 +1226,7 @@ int machine__create_kernel_maps(struct machine *machine)
 {
        struct dso *kernel = machine__get_kernel(machine);
        const char *name = NULL;
+       struct map *map;
        u64 addr = 0;
        int ret;
 
@@ -1259,13 +1253,25 @@ int machine__create_kernel_maps(struct machine *machine)
                        machine__destroy_kernel_maps(machine);
                        return -1;
                }
-               machine__set_kernel_mmap(machine, addr, 0);
+
+               /* we have a real start address now, so re-order the kmaps */
+               map = machine__kernel_map(machine);
+
+               map__get(map);
+               map_groups__remove(&machine->kmaps, map);
+
+               /* assume it's the last in the kmaps */
+               machine__set_kernel_mmap(machine, addr, ~0ULL);
+
+               map_groups__insert(&machine->kmaps, map);
+               map__put(map);
        }
 
-       /*
-        * Now that we have all the maps created, just set the ->end of them:
-        */
-       map_groups__fixup_end(&machine->kmaps);
+       /* update end address of the kernel map using adjacent module address */
+       map = map__next(machine__kernel_map(machine));
+       if (map)
+               machine__set_kernel_mmap(machine, addr, map->start);
+
        return 0;
 }
 
index 7afeb80cc39eed61632940ea163165a6f7a11da7..d14464c42714b84d738e151eb9a71d4269cc37ab 100644 (file)
@@ -224,15 +224,15 @@ event_def: event_pmu |
           event_bpf_file
 
 event_pmu:
-PE_NAME opt_event_config
+PE_NAME '/' event_config '/'
 {
        struct list_head *list, *orig_terms, *terms;
 
-       if (parse_events_copy_term_list($2, &orig_terms))
+       if (parse_events_copy_term_list($3, &orig_terms))
                YYABORT;
 
        ALLOC_LIST(list);
-       if (parse_events_add_pmu(_parse_state, list, $1, $2, false)) {
+       if (parse_events_add_pmu(_parse_state, list, $1, $3, false)) {
                struct perf_pmu *pmu = NULL;
                int ok = 0;
                char *pattern;
@@ -262,7 +262,7 @@ PE_NAME opt_event_config
                if (!ok)
                        YYABORT;
        }
-       parse_events_terms__delete($2);
+       parse_events_terms__delete($3);
        parse_events_terms__delete(orig_terms);
        $$ = list;
 }
index 064bdcb7bd78dcce2303bd24563bddcf42dc86d2..d2fb597c9a8c78d8e8fd8a9890e67f8b8f4432d7 100644 (file)
@@ -539,9 +539,10 @@ static bool pmu_is_uncore(const char *name)
 
 /*
  *  PMU CORE devices have different name other than cpu in sysfs on some
- *  platforms. looking for possible sysfs files to identify as core device.
+ *  platforms.
+ *  Looking for possible sysfs files to identify the arm core device.
  */
-static int is_pmu_core(const char *name)
+static int is_arm_pmu_core(const char *name)
 {
        struct stat st;
        char path[PATH_MAX];
@@ -550,18 +551,18 @@ static int is_pmu_core(const char *name)
        if (!sysfs)
                return 0;
 
-       /* Look for cpu sysfs (x86 and others) */
-       scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu", sysfs);
-       if ((stat(path, &st) == 0) &&
-                       (strncmp(name, "cpu", strlen("cpu")) == 0))
-               return 1;
-
        /* Look for cpu sysfs (specific to arm) */
        scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
                                sysfs, name);
        if (stat(path, &st) == 0)
                return 1;
 
+       /* Look for cpu sysfs (specific to s390) */
+       scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s",
+                 sysfs, name);
+       if (stat(path, &st) == 0 && !strncmp(name, "cpum_", 5))
+               return 1;
+
        return 0;
 }
 
@@ -580,7 +581,7 @@ char * __weak get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
  * cpuid string generated on this platform.
  * Otherwise return non-zero.
  */
-int __weak strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
+int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
 {
        regex_t re;
        regmatch_t pmatch[1];
@@ -662,6 +663,7 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
        struct pmu_events_map *map;
        struct pmu_event *pe;
        const char *name = pmu->name;
+       const char *pname;
 
        map = perf_pmu__find_map(pmu);
        if (!map)
@@ -680,11 +682,9 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
                        break;
                }
 
-               if (!is_pmu_core(name)) {
-                       /* check for uncore devices */
-                       if (pe->pmu == NULL)
-                               continue;
-                       if (strncmp(pe->pmu, name, strlen(pe->pmu)))
+               if (!is_arm_pmu_core(name)) {
+                       pname = pe->pmu ? pe->pmu : "cpu";
+                       if (strncmp(pname, name, strlen(pname)))
                                continue;
                }
 
index 62b2dd2253eb5d8b694ac53b76fb4738ca7c7766..1466814ebada5d30d3eb2dad96a6345c10eee6af 100644 (file)
@@ -2091,16 +2091,14 @@ static bool symbol__read_kptr_restrict(void)
 
 int symbol__annotation_init(void)
 {
+       if (symbol_conf.init_annotation)
+               return 0;
+
        if (symbol_conf.initialized) {
                pr_err("Annotation needs to be init before symbol__init()\n");
                return -1;
        }
 
-       if (symbol_conf.init_annotation) {
-               pr_warning("Annotation being initialized multiple times\n");
-               return 0;
-       }
-
        symbol_conf.priv_size += sizeof(struct annotation);
        symbol_conf.init_annotation = true;
        return 0;
index 895122d638dd84394eadc603221b241707488221..0ee7f568d60cced8ab428c3f73cae9d1e7b67620 100644 (file)
@@ -17,7 +17,7 @@
 #include <stdlib.h>
 #include <linux/compiler.h>
 
-#ifdef HAVE_SYSCALL_TABLE
+#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 #include <string.h>
 #include "string2.h"
 #include "util.h"
@@ -139,7 +139,7 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
        return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
 
-#else /* HAVE_SYSCALL_TABLE */
+#else /* HAVE_SYSCALL_TABLE_SUPPORT */
 
 #include <libaudit.h>
 
@@ -176,4 +176,4 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
 {
        return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
-#endif /* HAVE_SYSCALL_TABLE */
+#endif /* HAVE_SYSCALL_TABLE_SUPPORT */
index 0ac9077f62a2ce2e9a9c4e398583623633af82e7..b1e5c3a2b8e36cada0370ec30db338cb0fc45081 100644 (file)
@@ -98,7 +98,7 @@ static void register_python_scripting(struct scripting_ops *scripting_ops)
        }
 }
 
-#ifdef NO_LIBPYTHON
+#ifndef HAVE_LIBPYTHON_SUPPORT
 void setup_python_scripting(void)
 {
        register_python_scripting(&python_scripting_unsupported_ops);
@@ -161,7 +161,7 @@ static void register_perl_scripting(struct scripting_ops *scripting_ops)
        }
 }
 
-#ifdef NO_LIBPERL
+#ifndef HAVE_LIBPERL_SUPPORT
 void setup_perl_scripting(void)
 {
        register_perl_scripting(&perl_scripting_unsupported_ops);
index cb166be4918d7713f801e95204559c0abd9e8d62..4ea385be528fc80080bb4b24ed9639896ba7d0c4 100644 (file)
@@ -138,6 +138,7 @@ static u32 handle[] = {
 };
 
 static unsigned long dimm_fail_cmd_flags[NUM_DCR];
+static int dimm_fail_cmd_code[NUM_DCR];
 
 struct nfit_test_fw {
        enum intel_fw_update_state state;
@@ -892,8 +893,11 @@ static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
        if (i >= ARRAY_SIZE(handle))
                return -ENXIO;
 
-       if ((1 << func) & dimm_fail_cmd_flags[i])
+       if ((1 << func) & dimm_fail_cmd_flags[i]) {
+               if (dimm_fail_cmd_code[i])
+                       return dimm_fail_cmd_code[i];
                return -EIO;
+       }
 
        return i;
 }
@@ -1162,12 +1166,12 @@ static int ars_state_init(struct device *dev, struct ars_state *ars_state)
 
 static void put_dimms(void *data)
 {
-       struct device **dimm_dev = data;
+       struct nfit_test *t = data;
        int i;
 
-       for (i = 0; i < NUM_DCR; i++)
-               if (dimm_dev[i])
-                       device_unregister(dimm_dev[i]);
+       for (i = 0; i < t->num_dcr; i++)
+               if (t->dimm_dev[i])
+                       device_unregister(t->dimm_dev[i]);
 }
 
 static struct class *nfit_test_dimm;
@@ -1176,13 +1180,11 @@ static int dimm_name_to_id(struct device *dev)
 {
        int dimm;
 
-       if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1
-                       || dimm >= NUM_DCR || dimm < 0)
+       if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1)
                return -ENXIO;
        return dimm;
 }
 
-
 static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
                char *buf)
 {
@@ -1191,7 +1193,7 @@ static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
        if (dimm < 0)
                return dimm;
 
-       return sprintf(buf, "%#x", handle[dimm]);
+       return sprintf(buf, "%#x\n", handle[dimm]);
 }
 DEVICE_ATTR_RO(handle);
 
@@ -1225,8 +1227,39 @@ static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RW(fail_cmd);
 
+static ssize_t fail_cmd_code_show(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       int dimm = dimm_name_to_id(dev);
+
+       if (dimm < 0)
+               return dimm;
+
+       return sprintf(buf, "%d\n", dimm_fail_cmd_code[dimm]);
+}
+
+static ssize_t fail_cmd_code_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t size)
+{
+       int dimm = dimm_name_to_id(dev);
+       unsigned long val;
+       ssize_t rc;
+
+       if (dimm < 0)
+               return dimm;
+
+       rc = kstrtol(buf, 0, &val);
+       if (rc)
+               return rc;
+
+       dimm_fail_cmd_code[dimm] = val;
+       return size;
+}
+static DEVICE_ATTR_RW(fail_cmd_code);
+
 static struct attribute *nfit_test_dimm_attributes[] = {
        &dev_attr_fail_cmd.attr,
+       &dev_attr_fail_cmd_code.attr,
        &dev_attr_handle.attr,
        NULL,
 };
@@ -1240,6 +1273,23 @@ static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
        NULL,
 };
 
+static int nfit_test_dimm_init(struct nfit_test *t)
+{
+       int i;
+
+       if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t))
+               return -ENOMEM;
+       for (i = 0; i < t->num_dcr; i++) {
+               t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
+                               &t->pdev.dev, 0, NULL,
+                               nfit_test_dimm_attribute_groups,
+                               "test_dimm%d", i + t->dcr_idx);
+               if (!t->dimm_dev[i])
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
 static void smart_init(struct nfit_test *t)
 {
        int i;
@@ -1335,17 +1385,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
        if (!t->_fit)
                return -ENOMEM;
 
-       if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev))
+       if (nfit_test_dimm_init(t))
                return -ENOMEM;
-       for (i = 0; i < NUM_DCR; i++) {
-               t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
-                               &t->pdev.dev, 0, NULL,
-                               nfit_test_dimm_attribute_groups,
-                               "test_dimm%d", i);
-               if (!t->dimm_dev[i])
-                       return -ENOMEM;
-       }
-
        smart_init(t);
        return ars_state_init(&t->pdev.dev, &t->ars_state);
 }
@@ -1377,6 +1418,8 @@ static int nfit_test1_alloc(struct nfit_test *t)
        if (!t->spa_set[1])
                return -ENOMEM;
 
+       if (nfit_test_dimm_init(t))
+               return -ENOMEM;
        smart_init(t);
        return ars_state_init(&t->pdev.dev, &t->ars_state);
 }
@@ -2222,6 +2265,9 @@ static void nfit_test1_setup(struct nfit_test *t)
        set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
        set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
        set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en);
+       set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
+       set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
+       set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
 }
 
 static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
index 9cf83f895d98873ec81044ce4c4c0ecb89ac5ec3..5e1ab2f0eb794a16598cee7082e5d8194162430b 100644 (file)
@@ -12,3 +12,6 @@ test_tcpbpf_user
 test_verifier_log
 feature
 test_libbpf_open
+test_sock
+test_sock_addr
+urandom_read
index 73bb20cfb9b7b07c5c604812e0bbdd3245b7bc34..f4d99fabc56de89ea0a093b59763f98669573f86 100644 (file)
@@ -13,6 +13,7 @@
 #include <bpf/bpf.h>
 
 #include "cgroup_helpers.h"
+#include "bpf_rlimit.h"
 
 #ifndef ARRAY_SIZE
 # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
index d488f20926e8962f1b8d59ecf5b85c6ee4767c7a..2950f80ba7fb9f8770cb92bde50003d3c6186e78 100644 (file)
@@ -15,6 +15,7 @@
 #include <bpf/libbpf.h>
 
 #include "cgroup_helpers.h"
+#include "bpf_rlimit.h"
 
 #define CG_PATH        "/foo"
 #define CONNECT4_PROG_PATH     "./connect4_prog.o"
index c6e1dcf992c44a104abedb2592fbbef1c47f233b..9832a875a828979be26b8756cbd589d5cf5e44f1 100755 (executable)
@@ -4,7 +4,7 @@ set -eu
 
 ping_once()
 {
-       ping -q -c 1 -W 1 ${1%%/*} >/dev/null 2>&1
+       ping -${1} -q -c 1 -W 1 ${2%%/*} >/dev/null 2>&1
 }
 
 wait_for_ip()
@@ -13,7 +13,7 @@ wait_for_ip()
        echo -n "Wait for testing IPv4/IPv6 to become available "
        for _i in $(seq ${MAX_PING_TRIES}); do
                echo -n "."
-               if ping_once ${TEST_IPv4} && ping_once ${TEST_IPv6}; then
+               if ping_once 4 ${TEST_IPv4} && ping_once 6 ${TEST_IPv6}; then
                        echo " OK"
                        return
                fi
index 4e6d09fb166f1076bdbd6a03227559792270071e..5c7d7001ad37c34d1ccaf5ef34e05864cbeaa8ed 100644 (file)
@@ -1,8 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
-TEST_PROGS := dnotify_test devpts_pts
-all: $(TEST_PROGS)
 
-include ../lib.mk
+TEST_GEN_PROGS := devpts_pts
+TEST_GEN_PROGS_EXTENDED := dnotify_test
 
-clean:
-       rm -fr $(TEST_PROGS)
+include ../lib.mk
index 826f38d5dd19f1a0455cdc1074bdd83b6dce02c5..261c81f086064e922da966f8a1497e1b724e2d85 100644 (file)
@@ -4,6 +4,7 @@
 all:
 
 TEST_PROGS := fw_run_tests.sh
+TEST_FILES := fw_fallback.sh fw_filesystem.sh fw_lib.sh
 
 include ../lib.mk
 
index 9ea31b57d71a60008430b56a1b1498ed0184ec86..962d7f4ac6276c598bedf42755e5f711a9c51925 100755 (executable)
@@ -154,11 +154,13 @@ test_finish()
        if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
                echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
        fi
-       if [ "$OLD_FWPATH" = "" ]; then
-               OLD_FWPATH=" "
-       fi
        if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
-               echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
+               if [ "$OLD_FWPATH" = "" ]; then
+                       # A zero-length write won't work; write a null byte
+                       printf '\000' >/sys/module/firmware_class/parameters/path
+               else
+                       echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
+               fi
        fi
        if [ -f $FW ]; then
                rm -f "$FW"
index 06d638e9dc62748bf33bfbf7dbcb37f9494fdc00..cffdd4eb0a57ccc76b6da44b6f557cec1798f72d 100755 (executable)
@@ -66,5 +66,5 @@ if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
        run_test_config_0003
 else
        echo "Running basic kernel configuration, working with your config"
-       run_test
+       run_tests
 fi
index dc44de904797c6be6fce4c376b7ec86b5333a7c9..2ddcc96ae4561acd3d773db814dffbb4c0acdb51 100644 (file)
@@ -4,17 +4,18 @@ top_srcdir = ../../../../
 UNAME_M := $(shell uname -m)
 
 LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c
-LIBKVM_x86_64 = lib/x86.c
+LIBKVM_x86_64 = lib/x86.c lib/vmx.c
 
 TEST_GEN_PROGS_x86_64 = set_sregs_test
 TEST_GEN_PROGS_x86_64 += sync_regs_test
+TEST_GEN_PROGS_x86_64 += vmx_tsc_adjust_test
 
 TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M))
 LIBKVM += $(LIBKVM_$(UNAME_M))
 
 INSTALL_HDR_PATH = $(top_srcdir)/usr
 LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
-CFLAGS += -O2 -g -I$(LINUX_HDR_PATH) -Iinclude -I$(<D)
+CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D)
 
 # After inclusion, $(OUTPUT) is defined and
 # $(TEST_GEN_PROGS) starts with $(OUTPUT)/
index 57974ad46373b2686cefcb28b27692cf8cf5c992..637b7017b6ee5360db21e12f54dc118769c1633b 100644 (file)
@@ -112,24 +112,27 @@ void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
 vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm,
        vm_paddr_t paddr_min, uint32_t memslot);
 
-void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid);
+struct kvm_cpuid2 *kvm_get_supported_cpuid(void);
 void vcpu_set_cpuid(
        struct kvm_vm *vm, uint32_t vcpuid, struct kvm_cpuid2 *cpuid);
 
-struct kvm_cpuid2 *allocate_kvm_cpuid2(void);
 struct kvm_cpuid_entry2 *
-find_cpuid_index_entry(struct kvm_cpuid2 *cpuid, uint32_t function,
-                      uint32_t index);
+kvm_get_supported_cpuid_index(uint32_t function, uint32_t index);
 
 static inline struct kvm_cpuid_entry2 *
-find_cpuid_entry(struct kvm_cpuid2 *cpuid, uint32_t function)
+kvm_get_supported_cpuid_entry(uint32_t function)
 {
-       return find_cpuid_index_entry(cpuid, function, 0);
+       return kvm_get_supported_cpuid_index(function, 0);
 }
 
 struct kvm_vm *vm_create_default(uint32_t vcpuid, void *guest_code);
 void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code);
 
+typedef void (*vmx_guest_code_t)(vm_vaddr_t vmxon_vaddr,
+                                vm_paddr_t vmxon_paddr,
+                                vm_vaddr_t vmcs_vaddr,
+                                vm_paddr_t vmcs_paddr);
+
 struct kvm_userspace_memory_region *
 kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start,
                                 uint64_t end);
diff --git a/tools/testing/selftests/kvm/include/vmx.h b/tools/testing/selftests/kvm/include/vmx.h
new file mode 100644 (file)
index 0000000..6ed8499
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * tools/testing/selftests/kvm/include/vmx.h
+ *
+ * Copyright (C) 2018, Google LLC.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ */
+
+#ifndef SELFTEST_KVM_VMX_H
+#define SELFTEST_KVM_VMX_H
+
+#include <stdint.h>
+#include "x86.h"
+
+#define CPUID_VMX_BIT                          5
+
+#define CPUID_VMX                              (1 << 5)
+
+/*
+ * Definitions of Primary Processor-Based VM-Execution Controls.
+ */
+#define CPU_BASED_VIRTUAL_INTR_PENDING         0x00000004
+#define CPU_BASED_USE_TSC_OFFSETING            0x00000008
+#define CPU_BASED_HLT_EXITING                  0x00000080
+#define CPU_BASED_INVLPG_EXITING               0x00000200
+#define CPU_BASED_MWAIT_EXITING                        0x00000400
+#define CPU_BASED_RDPMC_EXITING                        0x00000800
+#define CPU_BASED_RDTSC_EXITING                        0x00001000
+#define CPU_BASED_CR3_LOAD_EXITING             0x00008000
+#define CPU_BASED_CR3_STORE_EXITING            0x00010000
+#define CPU_BASED_CR8_LOAD_EXITING             0x00080000
+#define CPU_BASED_CR8_STORE_EXITING            0x00100000
+#define CPU_BASED_TPR_SHADOW                   0x00200000
+#define CPU_BASED_VIRTUAL_NMI_PENDING          0x00400000
+#define CPU_BASED_MOV_DR_EXITING               0x00800000
+#define CPU_BASED_UNCOND_IO_EXITING            0x01000000
+#define CPU_BASED_USE_IO_BITMAPS               0x02000000
+#define CPU_BASED_MONITOR_TRAP                 0x08000000
+#define CPU_BASED_USE_MSR_BITMAPS              0x10000000
+#define CPU_BASED_MONITOR_EXITING              0x20000000
+#define CPU_BASED_PAUSE_EXITING                        0x40000000
+#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS  0x80000000
+
+#define CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR    0x0401e172
+
+/*
+ * Definitions of Secondary Processor-Based VM-Execution Controls.
+ */
+#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
+#define SECONDARY_EXEC_ENABLE_EPT              0x00000002
+#define SECONDARY_EXEC_DESC                    0x00000004
+#define SECONDARY_EXEC_RDTSCP                  0x00000008
+#define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE  0x00000010
+#define SECONDARY_EXEC_ENABLE_VPID             0x00000020
+#define SECONDARY_EXEC_WBINVD_EXITING          0x00000040
+#define SECONDARY_EXEC_UNRESTRICTED_GUEST      0x00000080
+#define SECONDARY_EXEC_APIC_REGISTER_VIRT      0x00000100
+#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY   0x00000200
+#define SECONDARY_EXEC_PAUSE_LOOP_EXITING      0x00000400
+#define SECONDARY_EXEC_RDRAND_EXITING          0x00000800
+#define SECONDARY_EXEC_ENABLE_INVPCID          0x00001000
+#define SECONDARY_EXEC_ENABLE_VMFUNC           0x00002000
+#define SECONDARY_EXEC_SHADOW_VMCS             0x00004000
+#define SECONDARY_EXEC_RDSEED_EXITING          0x00010000
+#define SECONDARY_EXEC_ENABLE_PML              0x00020000
+#define SECONDARY_EPT_VE                       0x00040000
+#define SECONDARY_ENABLE_XSAV_RESTORE          0x00100000
+#define SECONDARY_EXEC_TSC_SCALING             0x02000000
+
+#define PIN_BASED_EXT_INTR_MASK                        0x00000001
+#define PIN_BASED_NMI_EXITING                  0x00000008
+#define PIN_BASED_VIRTUAL_NMIS                 0x00000020
+#define PIN_BASED_VMX_PREEMPTION_TIMER         0x00000040
+#define PIN_BASED_POSTED_INTR                  0x00000080
+
+#define PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR    0x00000016
+
+#define VM_EXIT_SAVE_DEBUG_CONTROLS            0x00000004
+#define VM_EXIT_HOST_ADDR_SPACE_SIZE           0x00000200
+#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL     0x00001000
+#define VM_EXIT_ACK_INTR_ON_EXIT               0x00008000
+#define VM_EXIT_SAVE_IA32_PAT                  0x00040000
+#define VM_EXIT_LOAD_IA32_PAT                  0x00080000
+#define VM_EXIT_SAVE_IA32_EFER                 0x00100000
+#define VM_EXIT_LOAD_IA32_EFER                 0x00200000
+#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER      0x00400000
+
+#define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR      0x00036dff
+
+#define VM_ENTRY_LOAD_DEBUG_CONTROLS           0x00000004
+#define VM_ENTRY_IA32E_MODE                    0x00000200
+#define VM_ENTRY_SMM                           0x00000400
+#define VM_ENTRY_DEACT_DUAL_MONITOR            0x00000800
+#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL    0x00002000
+#define VM_ENTRY_LOAD_IA32_PAT                 0x00004000
+#define VM_ENTRY_LOAD_IA32_EFER                        0x00008000
+
+#define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR     0x000011ff
+
+#define VMX_MISC_PREEMPTION_TIMER_RATE_MASK    0x0000001f
+#define VMX_MISC_SAVE_EFER_LMA                 0x00000020
+
+#define EXIT_REASON_FAILED_VMENTRY     0x80000000
+#define EXIT_REASON_EXCEPTION_NMI      0
+#define EXIT_REASON_EXTERNAL_INTERRUPT 1
+#define EXIT_REASON_TRIPLE_FAULT       2
+#define EXIT_REASON_PENDING_INTERRUPT  7
+#define EXIT_REASON_NMI_WINDOW         8
+#define EXIT_REASON_TASK_SWITCH                9
+#define EXIT_REASON_CPUID              10
+#define EXIT_REASON_HLT                        12
+#define EXIT_REASON_INVD               13
+#define EXIT_REASON_INVLPG             14
+#define EXIT_REASON_RDPMC              15
+#define EXIT_REASON_RDTSC              16
+#define EXIT_REASON_VMCALL             18
+#define EXIT_REASON_VMCLEAR            19
+#define EXIT_REASON_VMLAUNCH           20
+#define EXIT_REASON_VMPTRLD            21
+#define EXIT_REASON_VMPTRST            22
+#define EXIT_REASON_VMREAD             23
+#define EXIT_REASON_VMRESUME           24
+#define EXIT_REASON_VMWRITE            25
+#define EXIT_REASON_VMOFF              26
+#define EXIT_REASON_VMON               27
+#define EXIT_REASON_CR_ACCESS          28
+#define EXIT_REASON_DR_ACCESS          29
+#define EXIT_REASON_IO_INSTRUCTION     30
+#define EXIT_REASON_MSR_READ           31
+#define EXIT_REASON_MSR_WRITE          32
+#define EXIT_REASON_INVALID_STATE      33
+#define EXIT_REASON_MWAIT_INSTRUCTION  36
+#define EXIT_REASON_MONITOR_INSTRUCTION 39
+#define EXIT_REASON_PAUSE_INSTRUCTION  40
+#define EXIT_REASON_MCE_DURING_VMENTRY 41
+#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
+#define EXIT_REASON_APIC_ACCESS                44
+#define EXIT_REASON_EOI_INDUCED                45
+#define EXIT_REASON_EPT_VIOLATION      48
+#define EXIT_REASON_EPT_MISCONFIG      49
+#define EXIT_REASON_INVEPT             50
+#define EXIT_REASON_RDTSCP             51
+#define EXIT_REASON_PREEMPTION_TIMER   52
+#define EXIT_REASON_INVVPID            53
+#define EXIT_REASON_WBINVD             54
+#define EXIT_REASON_XSETBV             55
+#define EXIT_REASON_APIC_WRITE         56
+#define EXIT_REASON_INVPCID            58
+#define EXIT_REASON_PML_FULL           62
+#define EXIT_REASON_XSAVES             63
+#define EXIT_REASON_XRSTORS            64
+#define LAST_EXIT_REASON               64
+
+enum vmcs_field {
+       VIRTUAL_PROCESSOR_ID            = 0x00000000,
+       POSTED_INTR_NV                  = 0x00000002,
+       GUEST_ES_SELECTOR               = 0x00000800,
+       GUEST_CS_SELECTOR               = 0x00000802,
+       GUEST_SS_SELECTOR               = 0x00000804,
+       GUEST_DS_SELECTOR               = 0x00000806,
+       GUEST_FS_SELECTOR               = 0x00000808,
+       GUEST_GS_SELECTOR               = 0x0000080a,
+       GUEST_LDTR_SELECTOR             = 0x0000080c,
+       GUEST_TR_SELECTOR               = 0x0000080e,
+       GUEST_INTR_STATUS               = 0x00000810,
+       GUEST_PML_INDEX                 = 0x00000812,
+       HOST_ES_SELECTOR                = 0x00000c00,
+       HOST_CS_SELECTOR                = 0x00000c02,
+       HOST_SS_SELECTOR                = 0x00000c04,
+       HOST_DS_SELECTOR                = 0x00000c06,
+       HOST_FS_SELECTOR                = 0x00000c08,
+       HOST_GS_SELECTOR                = 0x00000c0a,
+       HOST_TR_SELECTOR                = 0x00000c0c,
+       IO_BITMAP_A                     = 0x00002000,
+       IO_BITMAP_A_HIGH                = 0x00002001,
+       IO_BITMAP_B                     = 0x00002002,
+       IO_BITMAP_B_HIGH                = 0x00002003,
+       MSR_BITMAP                      = 0x00002004,
+       MSR_BITMAP_HIGH                 = 0x00002005,
+       VM_EXIT_MSR_STORE_ADDR          = 0x00002006,
+       VM_EXIT_MSR_STORE_ADDR_HIGH     = 0x00002007,
+       VM_EXIT_MSR_LOAD_ADDR           = 0x00002008,
+       VM_EXIT_MSR_LOAD_ADDR_HIGH      = 0x00002009,
+       VM_ENTRY_MSR_LOAD_ADDR          = 0x0000200a,
+       VM_ENTRY_MSR_LOAD_ADDR_HIGH     = 0x0000200b,
+       PML_ADDRESS                     = 0x0000200e,
+       PML_ADDRESS_HIGH                = 0x0000200f,
+       TSC_OFFSET                      = 0x00002010,
+       TSC_OFFSET_HIGH                 = 0x00002011,
+       VIRTUAL_APIC_PAGE_ADDR          = 0x00002012,
+       VIRTUAL_APIC_PAGE_ADDR_HIGH     = 0x00002013,
+       APIC_ACCESS_ADDR                = 0x00002014,
+       APIC_ACCESS_ADDR_HIGH           = 0x00002015,
+       POSTED_INTR_DESC_ADDR           = 0x00002016,
+       POSTED_INTR_DESC_ADDR_HIGH      = 0x00002017,
+       EPT_POINTER                     = 0x0000201a,
+       EPT_POINTER_HIGH                = 0x0000201b,
+       EOI_EXIT_BITMAP0                = 0x0000201c,
+       EOI_EXIT_BITMAP0_HIGH           = 0x0000201d,
+       EOI_EXIT_BITMAP1                = 0x0000201e,
+       EOI_EXIT_BITMAP1_HIGH           = 0x0000201f,
+       EOI_EXIT_BITMAP2                = 0x00002020,
+       EOI_EXIT_BITMAP2_HIGH           = 0x00002021,
+       EOI_EXIT_BITMAP3                = 0x00002022,
+       EOI_EXIT_BITMAP3_HIGH           = 0x00002023,
+       VMREAD_BITMAP                   = 0x00002026,
+       VMREAD_BITMAP_HIGH              = 0x00002027,
+       VMWRITE_BITMAP                  = 0x00002028,
+       VMWRITE_BITMAP_HIGH             = 0x00002029,
+       XSS_EXIT_BITMAP                 = 0x0000202C,
+       XSS_EXIT_BITMAP_HIGH            = 0x0000202D,
+       TSC_MULTIPLIER                  = 0x00002032,
+       TSC_MULTIPLIER_HIGH             = 0x00002033,
+       GUEST_PHYSICAL_ADDRESS          = 0x00002400,
+       GUEST_PHYSICAL_ADDRESS_HIGH     = 0x00002401,
+       VMCS_LINK_POINTER               = 0x00002800,
+       VMCS_LINK_POINTER_HIGH          = 0x00002801,
+       GUEST_IA32_DEBUGCTL             = 0x00002802,
+       GUEST_IA32_DEBUGCTL_HIGH        = 0x00002803,
+       GUEST_IA32_PAT                  = 0x00002804,
+       GUEST_IA32_PAT_HIGH             = 0x00002805,
+       GUEST_IA32_EFER                 = 0x00002806,
+       GUEST_IA32_EFER_HIGH            = 0x00002807,
+       GUEST_IA32_PERF_GLOBAL_CTRL     = 0x00002808,
+       GUEST_IA32_PERF_GLOBAL_CTRL_HIGH= 0x00002809,
+       GUEST_PDPTR0                    = 0x0000280a,
+       GUEST_PDPTR0_HIGH               = 0x0000280b,
+       GUEST_PDPTR1                    = 0x0000280c,
+       GUEST_PDPTR1_HIGH               = 0x0000280d,
+       GUEST_PDPTR2                    = 0x0000280e,
+       GUEST_PDPTR2_HIGH               = 0x0000280f,
+       GUEST_PDPTR3                    = 0x00002810,
+       GUEST_PDPTR3_HIGH               = 0x00002811,
+       GUEST_BNDCFGS                   = 0x00002812,
+       GUEST_BNDCFGS_HIGH              = 0x00002813,
+       HOST_IA32_PAT                   = 0x00002c00,
+       HOST_IA32_PAT_HIGH              = 0x00002c01,
+       HOST_IA32_EFER                  = 0x00002c02,
+       HOST_IA32_EFER_HIGH             = 0x00002c03,
+       HOST_IA32_PERF_GLOBAL_CTRL      = 0x00002c04,
+       HOST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,
+       PIN_BASED_VM_EXEC_CONTROL       = 0x00004000,
+       CPU_BASED_VM_EXEC_CONTROL       = 0x00004002,
+       EXCEPTION_BITMAP                = 0x00004004,
+       PAGE_FAULT_ERROR_CODE_MASK      = 0x00004006,
+       PAGE_FAULT_ERROR_CODE_MATCH     = 0x00004008,
+       CR3_TARGET_COUNT                = 0x0000400a,
+       VM_EXIT_CONTROLS                = 0x0000400c,
+       VM_EXIT_MSR_STORE_COUNT         = 0x0000400e,
+       VM_EXIT_MSR_LOAD_COUNT          = 0x00004010,
+       VM_ENTRY_CONTROLS               = 0x00004012,
+       VM_ENTRY_MSR_LOAD_COUNT         = 0x00004014,
+       VM_ENTRY_INTR_INFO_FIELD        = 0x00004016,
+       VM_ENTRY_EXCEPTION_ERROR_CODE   = 0x00004018,
+       VM_ENTRY_INSTRUCTION_LEN        = 0x0000401a,
+       TPR_THRESHOLD                   = 0x0000401c,
+       SECONDARY_VM_EXEC_CONTROL       = 0x0000401e,
+       PLE_GAP                         = 0x00004020,
+       PLE_WINDOW                      = 0x00004022,
+       VM_INSTRUCTION_ERROR            = 0x00004400,
+       VM_EXIT_REASON                  = 0x00004402,
+       VM_EXIT_INTR_INFO               = 0x00004404,
+       VM_EXIT_INTR_ERROR_CODE         = 0x00004406,
+       IDT_VECTORING_INFO_FIELD        = 0x00004408,
+       IDT_VECTORING_ERROR_CODE        = 0x0000440a,
+       VM_EXIT_INSTRUCTION_LEN         = 0x0000440c,
+       VMX_INSTRUCTION_INFO            = 0x0000440e,
+       GUEST_ES_LIMIT                  = 0x00004800,
+       GUEST_CS_LIMIT                  = 0x00004802,
+       GUEST_SS_LIMIT                  = 0x00004804,
+       GUEST_DS_LIMIT                  = 0x00004806,
+       GUEST_FS_LIMIT                  = 0x00004808,
+       GUEST_GS_LIMIT                  = 0x0000480a,
+       GUEST_LDTR_LIMIT                = 0x0000480c,
+       GUEST_TR_LIMIT                  = 0x0000480e,
+       GUEST_GDTR_LIMIT                = 0x00004810,
+       GUEST_IDTR_LIMIT                = 0x00004812,
+       GUEST_ES_AR_BYTES               = 0x00004814,
+       GUEST_CS_AR_BYTES               = 0x00004816,
+       GUEST_SS_AR_BYTES               = 0x00004818,
+       GUEST_DS_AR_BYTES               = 0x0000481a,
+       GUEST_FS_AR_BYTES               = 0x0000481c,
+       GUEST_GS_AR_BYTES               = 0x0000481e,
+       GUEST_LDTR_AR_BYTES             = 0x00004820,
+       GUEST_TR_AR_BYTES               = 0x00004822,
+       GUEST_INTERRUPTIBILITY_INFO     = 0x00004824,
+       GUEST_ACTIVITY_STATE            = 0X00004826,
+       GUEST_SYSENTER_CS               = 0x0000482A,
+       VMX_PREEMPTION_TIMER_VALUE      = 0x0000482E,
+       HOST_IA32_SYSENTER_CS           = 0x00004c00,
+       CR0_GUEST_HOST_MASK             = 0x00006000,
+       CR4_GUEST_HOST_MASK             = 0x00006002,
+       CR0_READ_SHADOW                 = 0x00006004,
+       CR4_READ_SHADOW                 = 0x00006006,
+       CR3_TARGET_VALUE0               = 0x00006008,
+       CR3_TARGET_VALUE1               = 0x0000600a,
+       CR3_TARGET_VALUE2               = 0x0000600c,
+       CR3_TARGET_VALUE3               = 0x0000600e,
+       EXIT_QUALIFICATION              = 0x00006400,
+       GUEST_LINEAR_ADDRESS            = 0x0000640a,
+       GUEST_CR0                       = 0x00006800,
+       GUEST_CR3                       = 0x00006802,
+       GUEST_CR4                       = 0x00006804,
+       GUEST_ES_BASE                   = 0x00006806,
+       GUEST_CS_BASE                   = 0x00006808,
+       GUEST_SS_BASE                   = 0x0000680a,
+       GUEST_DS_BASE                   = 0x0000680c,
+       GUEST_FS_BASE                   = 0x0000680e,
+       GUEST_GS_BASE                   = 0x00006810,
+       GUEST_LDTR_BASE                 = 0x00006812,
+       GUEST_TR_BASE                   = 0x00006814,
+       GUEST_GDTR_BASE                 = 0x00006816,
+       GUEST_IDTR_BASE                 = 0x00006818,
+       GUEST_DR7                       = 0x0000681a,
+       GUEST_RSP                       = 0x0000681c,
+       GUEST_RIP                       = 0x0000681e,
+       GUEST_RFLAGS                    = 0x00006820,
+       GUEST_PENDING_DBG_EXCEPTIONS    = 0x00006822,
+       GUEST_SYSENTER_ESP              = 0x00006824,
+       GUEST_SYSENTER_EIP              = 0x00006826,
+       HOST_CR0                        = 0x00006c00,
+       HOST_CR3                        = 0x00006c02,
+       HOST_CR4                        = 0x00006c04,
+       HOST_FS_BASE                    = 0x00006c06,
+       HOST_GS_BASE                    = 0x00006c08,
+       HOST_TR_BASE                    = 0x00006c0a,
+       HOST_GDTR_BASE                  = 0x00006c0c,
+       HOST_IDTR_BASE                  = 0x00006c0e,
+       HOST_IA32_SYSENTER_ESP          = 0x00006c10,
+       HOST_IA32_SYSENTER_EIP          = 0x00006c12,
+       HOST_RSP                        = 0x00006c14,
+       HOST_RIP                        = 0x00006c16,
+};
+
+struct vmx_msr_entry {
+       uint32_t index;
+       uint32_t reserved;
+       uint64_t value;
+} __attribute__ ((aligned(16)));
+
+static inline int vmxon(uint64_t phys)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmxon %[pa]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [pa]"m"(phys)
+               : "cc", "memory");
+
+       return ret;
+}
+
+static inline void vmxoff(void)
+{
+       __asm__ __volatile__("vmxoff");
+}
+
+static inline int vmclear(uint64_t vmcs_pa)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmclear %[pa]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [pa]"m"(vmcs_pa)
+               : "cc", "memory");
+
+       return ret;
+}
+
+static inline int vmptrld(uint64_t vmcs_pa)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmptrld %[pa]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [pa]"m"(vmcs_pa)
+               : "cc", "memory");
+
+       return ret;
+}
+
+/*
+ * No guest state (e.g. GPRs) is established by this vmlaunch.
+ */
+static inline int vmlaunch(void)
+{
+       int ret;
+
+       __asm__ __volatile__("push %%rbp;"
+                            "push %%rcx;"
+                            "push %%rdx;"
+                            "push %%rsi;"
+                            "push %%rdi;"
+                            "push $0;"
+                            "vmwrite %%rsp, %[host_rsp];"
+                            "lea 1f(%%rip), %%rax;"
+                            "vmwrite %%rax, %[host_rip];"
+                            "vmlaunch;"
+                            "incq (%%rsp);"
+                            "1: pop %%rax;"
+                            "pop %%rdi;"
+                            "pop %%rsi;"
+                            "pop %%rdx;"
+                            "pop %%rcx;"
+                            "pop %%rbp;"
+                            : [ret]"=&a"(ret)
+                            : [host_rsp]"r"((uint64_t)HOST_RSP),
+                              [host_rip]"r"((uint64_t)HOST_RIP)
+                            : "memory", "cc", "rbx", "r8", "r9", "r10",
+                              "r11", "r12", "r13", "r14", "r15");
+       return ret;
+}
+
+/*
+ * No guest state (e.g. GPRs) is established by this vmresume.
+ */
+static inline int vmresume(void)
+{
+       int ret;
+
+       __asm__ __volatile__("push %%rbp;"
+                            "push %%rcx;"
+                            "push %%rdx;"
+                            "push %%rsi;"
+                            "push %%rdi;"
+                            "push $0;"
+                            "vmwrite %%rsp, %[host_rsp];"
+                            "lea 1f(%%rip), %%rax;"
+                            "vmwrite %%rax, %[host_rip];"
+                            "vmresume;"
+                            "incq (%%rsp);"
+                            "1: pop %%rax;"
+                            "pop %%rdi;"
+                            "pop %%rsi;"
+                            "pop %%rdx;"
+                            "pop %%rcx;"
+                            "pop %%rbp;"
+                            : [ret]"=&a"(ret)
+                            : [host_rsp]"r"((uint64_t)HOST_RSP),
+                              [host_rip]"r"((uint64_t)HOST_RIP)
+                            : "memory", "cc", "rbx", "r8", "r9", "r10",
+                              "r11", "r12", "r13", "r14", "r15");
+       return ret;
+}
+
+static inline int vmread(uint64_t encoding, uint64_t *value)
+{
+       uint64_t tmp;
+       uint8_t ret;
+
+       __asm__ __volatile__("vmread %[encoding], %[value]; setna %[ret]"
+               : [value]"=rm"(tmp), [ret]"=rm"(ret)
+               : [encoding]"r"(encoding)
+               : "cc", "memory");
+
+       *value = tmp;
+       return ret;
+}
+
+/*
+ * A wrapper around vmread that ignores errors and returns zero if the
+ * vmread instruction fails.
+ */
+static inline uint64_t vmreadz(uint64_t encoding)
+{
+       uint64_t value = 0;
+       vmread(encoding, &value);
+       return value;
+}
+
+static inline int vmwrite(uint64_t encoding, uint64_t value)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmwrite %[value], %[encoding]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [value]"rm"(value), [encoding]"r"(encoding)
+               : "cc", "memory");
+
+       return ret;
+}
+
+static inline uint32_t vmcs_revision(void)
+{
+       return rdmsr(MSR_IA32_VMX_BASIC);
+}
+
+void prepare_for_vmx_operation(void);
+void prepare_vmcs(void *guest_rip, void *guest_rsp);
+struct kvm_vm *vm_create_default_vmx(uint32_t vcpuid,
+                                    vmx_guest_code_t guest_code);
+
+#endif /* !SELFTEST_KVM_VMX_H */
index 7ca1bb40c498ac229b3cafc9f1069f03541cef98..2cedfda181d4560dbc02ca0d2c5e44ab54326c61 100644 (file)
@@ -378,7 +378,7 @@ int kvm_memcmp_hva_gva(void *hva,
  * complicated. This function uses a reasonable default length for
  * the array and performs the appropriate allocation.
  */
-struct kvm_cpuid2 *allocate_kvm_cpuid2(void)
+static struct kvm_cpuid2 *allocate_kvm_cpuid2(void)
 {
        struct kvm_cpuid2 *cpuid;
        int nent = 100;
@@ -402,17 +402,21 @@ struct kvm_cpuid2 *allocate_kvm_cpuid2(void)
  * Input Args: None
  *
  * Output Args:
- *   cpuid - The supported KVM CPUID
  *
- * Return: void
+ * Return: The supported KVM CPUID
  *
  * Get the guest CPUID supported by KVM.
  */
-void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid)
+struct kvm_cpuid2 *kvm_get_supported_cpuid(void)
 {
+       static struct kvm_cpuid2 *cpuid;
        int ret;
        int kvm_fd;
 
+       if (cpuid)
+               return cpuid;
+
+       cpuid = allocate_kvm_cpuid2();
        kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
        TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i",
                KVM_DEV_PATH, kvm_fd, errno);
@@ -422,6 +426,7 @@ void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid)
                    ret, errno);
 
        close(kvm_fd);
+       return cpuid;
 }
 
 /* Locate a cpuid entry.
@@ -435,12 +440,13 @@ void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid)
  * Return: A pointer to the cpuid entry. Never returns NULL.
  */
 struct kvm_cpuid_entry2 *
-find_cpuid_index_entry(struct kvm_cpuid2 *cpuid, uint32_t function,
-                      uint32_t index)
+kvm_get_supported_cpuid_index(uint32_t function, uint32_t index)
 {
+       struct kvm_cpuid2 *cpuid;
        struct kvm_cpuid_entry2 *entry = NULL;
        int i;
 
+       cpuid = kvm_get_supported_cpuid();
        for (i = 0; i < cpuid->nent; i++) {
                if (cpuid->entries[i].function == function &&
                    cpuid->entries[i].index == index) {
@@ -1435,7 +1441,7 @@ vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm,
        sparsebit_idx_t pg;
 
        TEST_ASSERT((paddr_min % vm->page_size) == 0, "Min physical address "
-               "not divisable by page size.\n"
+               "not divisible by page size.\n"
                "  paddr_min: 0x%lx page_size: 0x%x",
                paddr_min, vm->page_size);
 
index 0c5cf3e0cb6fba7d38a7b31180f305d9257d05d9..b132bc95d18339a62ac2572acf56e533d0a8a18f 100644 (file)
  *     avoided by moving the setting of the nodes mask bits into
  *     the previous nodes num_after setting.
  *
- *   + Node starting index is evenly divisable by the number of bits
+ *   + Node starting index is evenly divisible by the number of bits
  *     within a nodes mask member.
  *
  *   + Nodes never represent a range of bits that wrap around the
@@ -1741,7 +1741,7 @@ void sparsebit_validate_internal(struct sparsebit *s)
 
                /* Validate node index is divisible by the mask size */
                if (nodep->idx % MASK_BITS) {
-                       fprintf(stderr, "Node index not divisable by "
+                       fprintf(stderr, "Node index not divisible by "
                                "mask size,\n"
                                "  nodep: %p nodep->idx: 0x%lx "
                                "MASK_BITS: %lu\n",
diff --git a/tools/testing/selftests/kvm/lib/vmx.c b/tools/testing/selftests/kvm/lib/vmx.c
new file mode 100644 (file)
index 0000000..0231bc0
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * tools/testing/selftests/kvm/lib/x86.c
+ *
+ * Copyright (C) 2018, Google LLC.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_name */
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "x86.h"
+#include "vmx.h"
+
+/* Create a default VM for VMX tests.
+ *
+ * Input Args:
+ *   vcpuid - The id of the single VCPU to add to the VM.
+ *   guest_code - The vCPU's entry point
+ *
+ * Output Args: None
+ *
+ * Return:
+ *   Pointer to opaque structure that describes the created VM.
+ */
+struct kvm_vm *
+vm_create_default_vmx(uint32_t vcpuid, vmx_guest_code_t guest_code)
+{
+       struct kvm_cpuid2 *cpuid;
+       struct kvm_vm *vm;
+       vm_vaddr_t vmxon_vaddr;
+       vm_paddr_t vmxon_paddr;
+       vm_vaddr_t vmcs_vaddr;
+       vm_paddr_t vmcs_paddr;
+
+       vm = vm_create_default(vcpuid, (void *) guest_code);
+
+       /* Enable nesting in CPUID */
+       vcpu_set_cpuid(vm, vcpuid, kvm_get_supported_cpuid());
+
+       /* Setup of a region of guest memory for the vmxon region. */
+       vmxon_vaddr = vm_vaddr_alloc(vm, getpagesize(), 0, 0, 0);
+       vmxon_paddr = addr_gva2gpa(vm, vmxon_vaddr);
+
+       /* Setup of a region of guest memory for a vmcs. */
+       vmcs_vaddr = vm_vaddr_alloc(vm, getpagesize(), 0, 0, 0);
+       vmcs_paddr = addr_gva2gpa(vm, vmcs_vaddr);
+
+       vcpu_args_set(vm, vcpuid, 4, vmxon_vaddr, vmxon_paddr, vmcs_vaddr,
+                     vmcs_paddr);
+
+       return vm;
+}
+
+void prepare_for_vmx_operation(void)
+{
+       uint64_t feature_control;
+       uint64_t required;
+       unsigned long cr0;
+       unsigned long cr4;
+
+       /*
+        * Ensure bits in CR0 and CR4 are valid in VMX operation:
+        * - Bit X is 1 in _FIXED0: bit X is fixed to 1 in CRx.
+        * - Bit X is 0 in _FIXED1: bit X is fixed to 0 in CRx.
+        */
+       __asm__ __volatile__("mov %%cr0, %0" : "=r"(cr0) : : "memory");
+       cr0 &= rdmsr(MSR_IA32_VMX_CR0_FIXED1);
+       cr0 |= rdmsr(MSR_IA32_VMX_CR0_FIXED0);
+       __asm__ __volatile__("mov %0, %%cr0" : : "r"(cr0) : "memory");
+
+       __asm__ __volatile__("mov %%cr4, %0" : "=r"(cr4) : : "memory");
+       cr4 &= rdmsr(MSR_IA32_VMX_CR4_FIXED1);
+       cr4 |= rdmsr(MSR_IA32_VMX_CR4_FIXED0);
+       /* Enable VMX operation */
+       cr4 |= X86_CR4_VMXE;
+       __asm__ __volatile__("mov %0, %%cr4" : : "r"(cr4) : "memory");
+
+       /*
+        * Configure IA32_FEATURE_CONTROL MSR to allow VMXON:
+        *  Bit 0: Lock bit. If clear, VMXON causes a #GP.
+        *  Bit 2: Enables VMXON outside of SMX operation. If clear, VMXON
+        *    outside of SMX causes a #GP.
+        */
+       required = FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
+       required |= FEATURE_CONTROL_LOCKED;
+       feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL);
+       if ((feature_control & required) != required)
+               wrmsr(MSR_IA32_FEATURE_CONTROL, feature_control | required);
+}
+
+/*
+ * Initialize the control fields to the most basic settings possible.
+ */
+static inline void init_vmcs_control_fields(void)
+{
+       vmwrite(VIRTUAL_PROCESSOR_ID, 0);
+       vmwrite(POSTED_INTR_NV, 0);
+
+       vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_PINBASED_CTLS));
+       vmwrite(CPU_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_PROCBASED_CTLS));
+       vmwrite(EXCEPTION_BITMAP, 0);
+       vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
+       vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, -1); /* Never match */
+       vmwrite(CR3_TARGET_COUNT, 0);
+       vmwrite(VM_EXIT_CONTROLS, rdmsr(MSR_IA32_VMX_EXIT_CTLS) |
+               VM_EXIT_HOST_ADDR_SPACE_SIZE);    /* 64-bit host */
+       vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
+       vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
+       vmwrite(VM_ENTRY_CONTROLS, rdmsr(MSR_IA32_VMX_ENTRY_CTLS) |
+               VM_ENTRY_IA32E_MODE);             /* 64-bit guest */
+       vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
+       vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
+       vmwrite(TPR_THRESHOLD, 0);
+       vmwrite(SECONDARY_VM_EXEC_CONTROL, 0);
+
+       vmwrite(CR0_GUEST_HOST_MASK, 0);
+       vmwrite(CR4_GUEST_HOST_MASK, 0);
+       vmwrite(CR0_READ_SHADOW, get_cr0());
+       vmwrite(CR4_READ_SHADOW, get_cr4());
+}
+
+/*
+ * Initialize the host state fields based on the current host state, with
+ * the exception of HOST_RSP and HOST_RIP, which should be set by vmlaunch
+ * or vmresume.
+ */
+static inline void init_vmcs_host_state(void)
+{
+       uint32_t exit_controls = vmreadz(VM_EXIT_CONTROLS);
+
+       vmwrite(HOST_ES_SELECTOR, get_es());
+       vmwrite(HOST_CS_SELECTOR, get_cs());
+       vmwrite(HOST_SS_SELECTOR, get_ss());
+       vmwrite(HOST_DS_SELECTOR, get_ds());
+       vmwrite(HOST_FS_SELECTOR, get_fs());
+       vmwrite(HOST_GS_SELECTOR, get_gs());
+       vmwrite(HOST_TR_SELECTOR, get_tr());
+
+       if (exit_controls & VM_EXIT_LOAD_IA32_PAT)
+               vmwrite(HOST_IA32_PAT, rdmsr(MSR_IA32_CR_PAT));
+       if (exit_controls & VM_EXIT_LOAD_IA32_EFER)
+               vmwrite(HOST_IA32_EFER, rdmsr(MSR_EFER));
+       if (exit_controls & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
+               vmwrite(HOST_IA32_PERF_GLOBAL_CTRL,
+                       rdmsr(MSR_CORE_PERF_GLOBAL_CTRL));
+
+       vmwrite(HOST_IA32_SYSENTER_CS, rdmsr(MSR_IA32_SYSENTER_CS));
+
+       vmwrite(HOST_CR0, get_cr0());
+       vmwrite(HOST_CR3, get_cr3());
+       vmwrite(HOST_CR4, get_cr4());
+       vmwrite(HOST_FS_BASE, rdmsr(MSR_FS_BASE));
+       vmwrite(HOST_GS_BASE, rdmsr(MSR_GS_BASE));
+       vmwrite(HOST_TR_BASE,
+               get_desc64_base((struct desc64 *)(get_gdt_base() + get_tr())));
+       vmwrite(HOST_GDTR_BASE, get_gdt_base());
+       vmwrite(HOST_IDTR_BASE, get_idt_base());
+       vmwrite(HOST_IA32_SYSENTER_ESP, rdmsr(MSR_IA32_SYSENTER_ESP));
+       vmwrite(HOST_IA32_SYSENTER_EIP, rdmsr(MSR_IA32_SYSENTER_EIP));
+}
+
+/*
+ * Initialize the guest state fields essentially as a clone of
+ * the host state fields. Some host state fields have fixed
+ * values, and we set the corresponding guest state fields accordingly.
+ */
+static inline void init_vmcs_guest_state(void *rip, void *rsp)
+{
+       vmwrite(GUEST_ES_SELECTOR, vmreadz(HOST_ES_SELECTOR));
+       vmwrite(GUEST_CS_SELECTOR, vmreadz(HOST_CS_SELECTOR));
+       vmwrite(GUEST_SS_SELECTOR, vmreadz(HOST_SS_SELECTOR));
+       vmwrite(GUEST_DS_SELECTOR, vmreadz(HOST_DS_SELECTOR));
+       vmwrite(GUEST_FS_SELECTOR, vmreadz(HOST_FS_SELECTOR));
+       vmwrite(GUEST_GS_SELECTOR, vmreadz(HOST_GS_SELECTOR));
+       vmwrite(GUEST_LDTR_SELECTOR, 0);
+       vmwrite(GUEST_TR_SELECTOR, vmreadz(HOST_TR_SELECTOR));
+       vmwrite(GUEST_INTR_STATUS, 0);
+       vmwrite(GUEST_PML_INDEX, 0);
+
+       vmwrite(VMCS_LINK_POINTER, -1ll);
+       vmwrite(GUEST_IA32_DEBUGCTL, 0);
+       vmwrite(GUEST_IA32_PAT, vmreadz(HOST_IA32_PAT));
+       vmwrite(GUEST_IA32_EFER, vmreadz(HOST_IA32_EFER));
+       vmwrite(GUEST_IA32_PERF_GLOBAL_CTRL,
+               vmreadz(HOST_IA32_PERF_GLOBAL_CTRL));
+
+       vmwrite(GUEST_ES_LIMIT, -1);
+       vmwrite(GUEST_CS_LIMIT, -1);
+       vmwrite(GUEST_SS_LIMIT, -1);
+       vmwrite(GUEST_DS_LIMIT, -1);
+       vmwrite(GUEST_FS_LIMIT, -1);
+       vmwrite(GUEST_GS_LIMIT, -1);
+       vmwrite(GUEST_LDTR_LIMIT, -1);
+       vmwrite(GUEST_TR_LIMIT, 0x67);
+       vmwrite(GUEST_GDTR_LIMIT, 0xffff);
+       vmwrite(GUEST_IDTR_LIMIT, 0xffff);
+       vmwrite(GUEST_ES_AR_BYTES,
+               vmreadz(GUEST_ES_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_CS_AR_BYTES, 0xa09b);
+       vmwrite(GUEST_SS_AR_BYTES, 0xc093);
+       vmwrite(GUEST_DS_AR_BYTES,
+               vmreadz(GUEST_DS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_FS_AR_BYTES,
+               vmreadz(GUEST_FS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_GS_AR_BYTES,
+               vmreadz(GUEST_GS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_LDTR_AR_BYTES, 0x10000);
+       vmwrite(GUEST_TR_AR_BYTES, 0x8b);
+       vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
+       vmwrite(GUEST_ACTIVITY_STATE, 0);
+       vmwrite(GUEST_SYSENTER_CS, vmreadz(HOST_IA32_SYSENTER_CS));
+       vmwrite(VMX_PREEMPTION_TIMER_VALUE, 0);
+
+       vmwrite(GUEST_CR0, vmreadz(HOST_CR0));
+       vmwrite(GUEST_CR3, vmreadz(HOST_CR3));
+       vmwrite(GUEST_CR4, vmreadz(HOST_CR4));
+       vmwrite(GUEST_ES_BASE, 0);
+       vmwrite(GUEST_CS_BASE, 0);
+       vmwrite(GUEST_SS_BASE, 0);
+       vmwrite(GUEST_DS_BASE, 0);
+       vmwrite(GUEST_FS_BASE, vmreadz(HOST_FS_BASE));
+       vmwrite(GUEST_GS_BASE, vmreadz(HOST_GS_BASE));
+       vmwrite(GUEST_LDTR_BASE, 0);
+       vmwrite(GUEST_TR_BASE, vmreadz(HOST_TR_BASE));
+       vmwrite(GUEST_GDTR_BASE, vmreadz(HOST_GDTR_BASE));
+       vmwrite(GUEST_IDTR_BASE, vmreadz(HOST_IDTR_BASE));
+       vmwrite(GUEST_DR7, 0x400);
+       vmwrite(GUEST_RSP, (uint64_t)rsp);
+       vmwrite(GUEST_RIP, (uint64_t)rip);
+       vmwrite(GUEST_RFLAGS, 2);
+       vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, 0);
+       vmwrite(GUEST_SYSENTER_ESP, vmreadz(HOST_IA32_SYSENTER_ESP));
+       vmwrite(GUEST_SYSENTER_EIP, vmreadz(HOST_IA32_SYSENTER_EIP));
+}
+
+void prepare_vmcs(void *guest_rip, void *guest_rsp)
+{
+       init_vmcs_control_fields();
+       init_vmcs_host_state();
+       init_vmcs_guest_state(guest_rip, guest_rsp);
+}
diff --git a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
new file mode 100644 (file)
index 0000000..8f7f620
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * gtests/tests/vmx_tsc_adjust_test.c
+ *
+ * Copyright (C) 2018, Google LLC.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ *
+ * IA32_TSC_ADJUST test
+ *
+ * According to the SDM, "if an execution of WRMSR to the
+ * IA32_TIME_STAMP_COUNTER MSR adds (or subtracts) value X from the TSC,
+ * the logical processor also adds (or subtracts) value X from the
+ * IA32_TSC_ADJUST MSR.
+ *
+ * Note that when L1 doesn't intercept writes to IA32_TSC, a
+ * WRMSR(IA32_TSC) from L2 sets L1's TSC value, not L2's perceived TSC
+ * value.
+ *
+ * This test verifies that this unusual case is handled correctly.
+ */
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "x86.h"
+#include "vmx.h"
+
+#include <string.h>
+#include <sys/ioctl.h>
+
+#ifndef MSR_IA32_TSC_ADJUST
+#define MSR_IA32_TSC_ADJUST 0x3b
+#endif
+
+#define PAGE_SIZE      4096
+#define VCPU_ID                5
+
+#define TSC_ADJUST_VALUE (1ll << 32)
+#define TSC_OFFSET_VALUE -(1ll << 48)
+
+enum {
+       PORT_ABORT = 0x1000,
+       PORT_REPORT,
+       PORT_DONE,
+};
+
+struct vmx_page {
+       vm_vaddr_t virt;
+       vm_paddr_t phys;
+};
+
+enum {
+       VMXON_PAGE = 0,
+       VMCS_PAGE,
+       MSR_BITMAP_PAGE,
+
+       NUM_VMX_PAGES,
+};
+
+struct kvm_single_msr {
+       struct kvm_msrs header;
+       struct kvm_msr_entry entry;
+} __attribute__((packed));
+
+/* The virtual machine object. */
+static struct kvm_vm *vm;
+
+/* Array of vmx_page descriptors that is shared with the guest. */
+struct vmx_page *vmx_pages;
+
+#define exit_to_l0(_port, _arg) do_exit_to_l0(_port, (unsigned long) (_arg))
+static void do_exit_to_l0(uint16_t port, unsigned long arg)
+{
+       __asm__ __volatile__("in %[port], %%al"
+               :
+               : [port]"d"(port), "D"(arg)
+               : "rax");
+}
+
+
+#define GUEST_ASSERT(_condition) do {                                       \
+       if (!(_condition))                                                   \
+               exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition); \
+} while (0)
+
+static void check_ia32_tsc_adjust(int64_t max)
+{
+       int64_t adjust;
+
+       adjust = rdmsr(MSR_IA32_TSC_ADJUST);
+       exit_to_l0(PORT_REPORT, adjust);
+       GUEST_ASSERT(adjust <= max);
+}
+
+static void l2_guest_code(void)
+{
+       uint64_t l1_tsc = rdtsc() - TSC_OFFSET_VALUE;
+
+       wrmsr(MSR_IA32_TSC, l1_tsc - TSC_ADJUST_VALUE);
+       check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE);
+
+       /* Exit to L1 */
+       __asm__ __volatile__("vmcall");
+}
+
+static void l1_guest_code(struct vmx_page *vmx_pages)
+{
+#define L2_GUEST_STACK_SIZE 64
+       unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
+       uint32_t control;
+       uintptr_t save_cr3;
+
+       GUEST_ASSERT(rdtsc() < TSC_ADJUST_VALUE);
+       wrmsr(MSR_IA32_TSC, rdtsc() - TSC_ADJUST_VALUE);
+       check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE);
+
+       prepare_for_vmx_operation();
+
+       /* Enter VMX root operation. */
+       *(uint32_t *)vmx_pages[VMXON_PAGE].virt = vmcs_revision();
+       GUEST_ASSERT(!vmxon(vmx_pages[VMXON_PAGE].phys));
+
+       /* Load a VMCS. */
+       *(uint32_t *)vmx_pages[VMCS_PAGE].virt = vmcs_revision();
+       GUEST_ASSERT(!vmclear(vmx_pages[VMCS_PAGE].phys));
+       GUEST_ASSERT(!vmptrld(vmx_pages[VMCS_PAGE].phys));
+
+       /* Prepare the VMCS for L2 execution. */
+       prepare_vmcs(l2_guest_code, &l2_guest_stack[L2_GUEST_STACK_SIZE]);
+       control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
+       control |= CPU_BASED_USE_MSR_BITMAPS | CPU_BASED_USE_TSC_OFFSETING;
+       vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
+       vmwrite(MSR_BITMAP, vmx_pages[MSR_BITMAP_PAGE].phys);
+       vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE);
+
+       /* Jump into L2.  First, test failure to load guest CR3.  */
+       save_cr3 = vmreadz(GUEST_CR3);
+       vmwrite(GUEST_CR3, -1ull);
+       GUEST_ASSERT(!vmlaunch());
+       GUEST_ASSERT(vmreadz(VM_EXIT_REASON) ==
+                    (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_INVALID_STATE));
+       check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE);
+       vmwrite(GUEST_CR3, save_cr3);
+
+       GUEST_ASSERT(!vmlaunch());
+       GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+
+       check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE);
+
+       exit_to_l0(PORT_DONE, 0);
+}
+
+static void allocate_vmx_page(struct vmx_page *page)
+{
+       vm_vaddr_t virt;
+
+       virt = vm_vaddr_alloc(vm, PAGE_SIZE, 0, 0, 0);
+       memset(addr_gva2hva(vm, virt), 0, PAGE_SIZE);
+
+       page->virt = virt;
+       page->phys = addr_gva2gpa(vm, virt);
+}
+
+static vm_vaddr_t allocate_vmx_pages(void)
+{
+       vm_vaddr_t vmx_pages_vaddr;
+       int i;
+
+       vmx_pages_vaddr = vm_vaddr_alloc(
+               vm, sizeof(struct vmx_page) * NUM_VMX_PAGES, 0, 0, 0);
+
+       vmx_pages = (void *) addr_gva2hva(vm, vmx_pages_vaddr);
+
+       for (i = 0; i < NUM_VMX_PAGES; i++)
+               allocate_vmx_page(&vmx_pages[i]);
+
+       return vmx_pages_vaddr;
+}
+
+void report(int64_t val)
+{
+       printf("IA32_TSC_ADJUST is %ld (%lld * TSC_ADJUST_VALUE + %lld).\n",
+              val, val / TSC_ADJUST_VALUE, val % TSC_ADJUST_VALUE);
+}
+
+int main(int argc, char *argv[])
+{
+       vm_vaddr_t vmx_pages_vaddr;
+       struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1);
+
+       if (!(entry->ecx & CPUID_VMX)) {
+               printf("nested VMX not enabled, skipping test");
+               return 0;
+       }
+
+       vm = vm_create_default_vmx(VCPU_ID, (void *) l1_guest_code);
+
+       /* Allocate VMX pages and shared descriptors (vmx_pages). */
+       vmx_pages_vaddr = allocate_vmx_pages();
+       vcpu_args_set(vm, VCPU_ID, 1, vmx_pages_vaddr);
+
+       for (;;) {
+               volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);
+               struct kvm_regs regs;
+
+               vcpu_run(vm, VCPU_ID);
+               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
+                           "Got exit_reason other than KVM_EXIT_IO: %u (%s),\n",
+                           run->exit_reason,
+                           exit_reason_str(run->exit_reason));
+
+               vcpu_regs_get(vm, VCPU_ID, &regs);
+
+               switch (run->io.port) {
+               case PORT_ABORT:
+                       TEST_ASSERT(false, "%s", (const char *) regs.rdi);
+                       /* NOT REACHED */
+               case PORT_REPORT:
+                       report(regs.rdi);
+                       break;
+               case PORT_DONE:
+                       goto done;
+               default:
+                       TEST_ASSERT(false, "Unknown port 0x%x.", run->io.port);
+               }
+       }
+
+       kvm_vm_free(vm);
+done:
+       return 0;
+}
index 785fc18a16b4701f3ef875b60648726750b0cd26..8f1e13d2e547c746a4d13e57802b92e27b4fd1a3 100644 (file)
@@ -5,7 +5,7 @@ CFLAGS =  -Wall -Wl,--no-as-needed -O2 -g
 CFLAGS += -I../../../../usr/include/
 
 TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh
-TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh
+TEST_PROGS += fib_tests.sh fib-onlink-tests.sh in_netns.sh pmtu.sh
 TEST_GEN_FILES =  socket
 TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy
 TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
index 40370354d4c11e48f9404eccfbda1b5bf03cd682..c9c3281077bca413b9164547c9a3da9a2a061103 100644 (file)
@@ -100,12 +100,19 @@ asm (
        "       shl     $32, %r8\n"
        "       orq     $0x7f7f7f7f, %r8\n"
        "       movq    %r8, %r9\n"
-       "       movq    %r8, %r10\n"
-       "       movq    %r8, %r11\n"
-       "       movq    %r8, %r12\n"
-       "       movq    %r8, %r13\n"
-       "       movq    %r8, %r14\n"
-       "       movq    %r8, %r15\n"
+       "       incq    %r9\n"
+       "       movq    %r9, %r10\n"
+       "       incq    %r10\n"
+       "       movq    %r10, %r11\n"
+       "       incq    %r11\n"
+       "       movq    %r11, %r12\n"
+       "       incq    %r12\n"
+       "       movq    %r12, %r13\n"
+       "       incq    %r13\n"
+       "       movq    %r13, %r14\n"
+       "       incq    %r14\n"
+       "       movq    %r14, %r15\n"
+       "       incq    %r15\n"
        "       ret\n"
        "       .code32\n"
        "       .popsection\n"
@@ -128,12 +135,13 @@ int check_regs64(void)
        int err = 0;
        int num = 8;
        uint64_t *r64 = &regs64.r8;
+       uint64_t expected = 0x7f7f7f7f7f7f7f7fULL;
 
        if (!kernel_is_64bit)
                return 0;
 
        do {
-               if (*r64 == 0x7f7f7f7f7f7f7f7fULL)
+               if (*r64 == expected++)
                        continue; /* register did not change */
                if (syscall_addr != (long)&int80) {
                        /*
@@ -147,18 +155,17 @@ int check_regs64(void)
                                continue;
                        }
                } else {
-                       /* INT80 syscall entrypoint can be used by
+                       /*
+                        * INT80 syscall entrypoint can be used by
                         * 64-bit programs too, unlike SYSCALL/SYSENTER.
                         * Therefore it must preserve R12+
                         * (they are callee-saved registers in 64-bit C ABI).
                         *
-                        * This was probably historically not intended,
-                        * but R8..11 are clobbered (cleared to 0).
-                        * IOW: they are the only registers which aren't
-                        * preserved across INT80 syscall.
+                        * Starting in Linux 4.17 (and any kernel that
+                        * backports the change), R8..11 are preserved.
+                        * Historically (and probably unintentionally), they
+                        * were clobbered or zeroed.
                         */
-                       if (*r64 == 0 && num <= 11)
-                               continue;
                }
                printf("[FAIL]\tR%d has changed:%016llx\n", num, *r64);
                err++;
index dba629c5f8acd17eb7ef1743bf7fa0641094ed44..a4c1b76240df2d8a818fbef3ea73aac68f713fb2 100644 (file)
@@ -63,7 +63,7 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
 static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
 static u32 kvm_next_vmid;
 static unsigned int kvm_vmid_bits __read_mostly;
-static DEFINE_SPINLOCK(kvm_vmid_lock);
+static DEFINE_RWLOCK(kvm_vmid_lock);
 
 static bool vgic_present;
 
@@ -473,11 +473,16 @@ static void update_vttbr(struct kvm *kvm)
 {
        phys_addr_t pgd_phys;
        u64 vmid;
+       bool new_gen;
 
-       if (!need_new_vmid_gen(kvm))
+       read_lock(&kvm_vmid_lock);
+       new_gen = need_new_vmid_gen(kvm);
+       read_unlock(&kvm_vmid_lock);
+
+       if (!new_gen)
                return;
 
-       spin_lock(&kvm_vmid_lock);
+       write_lock(&kvm_vmid_lock);
 
        /*
         * We need to re-check the vmid_gen here to ensure that if another vcpu
@@ -485,7 +490,7 @@ static void update_vttbr(struct kvm *kvm)
         * use the same vmid.
         */
        if (!need_new_vmid_gen(kvm)) {
-               spin_unlock(&kvm_vmid_lock);
+               write_unlock(&kvm_vmid_lock);
                return;
        }
 
@@ -519,7 +524,7 @@ static void update_vttbr(struct kvm *kvm)
        vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits);
        kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid;
 
-       spin_unlock(&kvm_vmid_lock);
+       write_unlock(&kvm_vmid_lock);
 }
 
 static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
index 6919352cbf15e8d50b3742e32acfd152be4b18a8..c4762bef13c6d389ff0c1e4f656322d66bb167b0 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/preempt.h>
 #include <linux/kvm_host.h>
+#include <linux/uaccess.h>
 #include <linux/wait.h>
 
 #include <asm/cputype.h>
@@ -427,3 +428,62 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
        smccc_set_retval(vcpu, val, 0, 0, 0);
        return 1;
 }
+
+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
+{
+       return 1;               /* PSCI version */
+}
+
+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+       if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices))
+               return -EFAULT;
+
+       return 0;
+}
+
+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+       if (reg->id == KVM_REG_ARM_PSCI_VERSION) {
+               void __user *uaddr = (void __user *)(long)reg->addr;
+               u64 val;
+
+               val = kvm_psci_version(vcpu, vcpu->kvm);
+               if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)))
+                       return -EFAULT;
+
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+       if (reg->id == KVM_REG_ARM_PSCI_VERSION) {
+               void __user *uaddr = (void __user *)(long)reg->addr;
+               bool wants_02;
+               u64 val;
+
+               if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
+                       return -EFAULT;
+
+               wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features);
+
+               switch (val) {
+               case KVM_ARM_PSCI_0_1:
+                       if (wants_02)
+                               return -EINVAL;
+                       vcpu->kvm->arch.psci_version = val;
+                       return 0;
+               case KVM_ARM_PSCI_0_2:
+               case KVM_ARM_PSCI_1_0:
+                       if (!wants_02)
+                               return -EINVAL;
+                       vcpu->kvm->arch.psci_version = val;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
index e21e2f49b005256543fa912b8b33df8c134ff726..ffc587bf4742676d14930d21f07005275576a79e 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/irqchip/arm-gic.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
+#include <linux/nospec.h>
+
 #include <kvm/iodev.h>
 #include <kvm/arm_vgic.h>
 
@@ -324,6 +326,9 @@ static unsigned long vgic_mmio_read_apr(struct kvm_vcpu *vcpu,
 
                if (n > vgic_v3_max_apr_idx(vcpu))
                        return 0;
+
+               n = array_index_nospec(n, 4);
+
                /* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */
                return vgicv3->vgic_ap1r[n];
        }
index e74baec7636130c6e379c93c7312a0be70f97a59..702936cbe173013086a2a60349ed34a041152877 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 #include <linux/list_sort.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
+#include <linux/nospec.h>
+
 #include <asm/kvm_hyp.h>
 
 #include "vgic.h"
@@ -101,12 +103,16 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu,
                              u32 intid)
 {
        /* SGIs and PPIs */
-       if (intid <= VGIC_MAX_PRIVATE)
+       if (intid <= VGIC_MAX_PRIVATE) {
+               intid = array_index_nospec(intid, VGIC_MAX_PRIVATE);
                return &vcpu->arch.vgic_cpu.private_irqs[intid];
+       }
 
        /* SPIs */
-       if (intid <= VGIC_MAX_SPI)
+       if (intid <= VGIC_MAX_SPI) {
+               intid = array_index_nospec(intid, VGIC_MAX_SPI);
                return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS];
+       }
 
        /* LPIs */
        if (intid >= VGIC_MIN_LPI)
@@ -594,6 +600,7 @@ retry:
 
        list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
                struct kvm_vcpu *target_vcpu, *vcpuA, *vcpuB;
+               bool target_vcpu_needs_kick = false;
 
                spin_lock(&irq->irq_lock);
 
@@ -664,11 +671,18 @@ retry:
                        list_del(&irq->ap_list);
                        irq->vcpu = target_vcpu;
                        list_add_tail(&irq->ap_list, &new_cpu->ap_list_head);
+                       target_vcpu_needs_kick = true;
                }
 
                spin_unlock(&irq->irq_lock);
                spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
                spin_unlock_irqrestore(&vcpuA->arch.vgic_cpu.ap_list_lock, flags);
+
+               if (target_vcpu_needs_kick) {
+                       kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
+                       kvm_vcpu_kick(target_vcpu);
+               }
+
                goto retry;
        }