Merge tag 'usb-5.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 12 Oct 2019 22:37:12 +0000 (15:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 12 Oct 2019 22:37:12 +0000 (15:37 -0700)
Pull USB fixes from Greg KH:
 "Here are a lot of small USB driver fixes for 5.4-rc3.

  syzbot has stepped up its testing of the USB driver stack, now able to
  trigger fun race conditions between disconnect and probe functions.
  Because of that we have a lot of fixes in here from Johan and others
  fixing these reported issues that have been around since almost all
  time.

  We also are just deleting the rio500 driver, making all of the syzbot
  bugs found in it moot as it turns out no one has been using it for
  years as there is a userspace version that is being used instead.

  There are also a number of other small fixes in here, all resolving
  reported issues or regressions.

  All have been in linux-next without any reported issues"

* tag 'usb-5.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (65 commits)
  USB: yurex: fix NULL-derefs on disconnect
  USB: iowarrior: use pr_err()
  USB: iowarrior: drop redundant iowarrior mutex
  USB: iowarrior: drop redundant disconnect mutex
  USB: iowarrior: fix use-after-free after driver unbind
  USB: iowarrior: fix use-after-free on release
  USB: iowarrior: fix use-after-free on disconnect
  USB: chaoskey: fix use-after-free on release
  USB: adutux: fix use-after-free on release
  USB: ldusb: fix NULL-derefs on driver unbind
  USB: legousbtower: fix use-after-free on release
  usb: cdns3: Fix for incorrect DMA mask.
  usb: cdns3: fix cdns3_core_init_role()
  usb: cdns3: gadget: Fix full-speed mode
  USB: usb-skeleton: drop redundant in-urb check
  USB: usb-skeleton: fix use-after-free after driver unbind
  USB: usb-skeleton: fix NULL-deref on disconnect
  usb:cdns3: Fix for CV CH9 running with g_zero driver.
  usb: dwc3: Remove dev_err() on platform_get_irq() failure
  usb: dwc3: Switch to platform_get_irq_byname_optional()
  ...

522 files changed:
CREDITS
Documentation/admin-guide/cgroup-v2.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/arm64/memory.rst
Documentation/core-api/index.rst
Documentation/core-api/memory-allocation.rst
Documentation/core-api/symbol-namespaces.rst [new file with mode: 0644]
Documentation/dev-tools/kselftest.rst
Documentation/devicetree/bindings/dsp/fsl,dsp.yaml
Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml
Documentation/devicetree/bindings/media/rc.yaml
Documentation/devicetree/bindings/phy/lantiq,vrx200-pcie-phy.yaml
Documentation/kbuild/makefiles.rst
Documentation/kbuild/modules.rst
Documentation/kbuild/namespaces.rst [deleted file]
Documentation/kbuild/reproducible-builds.rst
Documentation/networking/device_drivers/index.rst
Documentation/networking/j1939.rst
Documentation/process/coding-style.rst
Documentation/process/deprecated.rst
MAINTAINERS
Makefile
arch/arm/boot/dts/am335x-icev2.dts
arch/arm/boot/dts/am33xx-l4.dtsi
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/dra7-l4.dtsi
arch/arm/boot/dts/omap3-gta04.dtsi
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/configs/davinci_all_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/crypto/Kconfig
arch/arm/crypto/aes-ce-core.S
arch/arm/include/asm/xen/xen-ops.h [deleted file]
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/pm.c
arch/arm/xen/Makefile
arch/arm/xen/efi.c [deleted file]
arch/arm/xen/enlighten.c
arch/arm/xen/mm.c
arch/arm64/Kconfig
arch/arm64/Makefile
arch/arm64/configs/defconfig
arch/arm64/include/asm/atomic_lse.h
arch/arm64/include/asm/kvm_hyp.h
arch/arm64/include/asm/vdso/compat_barrier.h
arch/arm64/include/asm/vdso_datapage.h [deleted file]
arch/arm64/include/asm/xen/xen-ops.h [deleted file]
arch/arm64/kernel/armv8_deprecated.c
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/ftrace.c
arch/arm64/kernel/process.c
arch/arm64/kernel/vdso/gettimeofday.S [deleted file]
arch/arm64/kernel/vdso32/Makefile
arch/arm64/kvm/hyp/switch.c
arch/arm64/kvm/hyp/tlb.c
arch/arm64/mm/fault.c
arch/arm64/xen/Makefile
arch/mips/boot/dts/qca/ar9331.dtsi
arch/mips/fw/arc/memory.c
arch/mips/fw/sni/sniprom.c
arch/mips/include/asm/cmpxchg.h
arch/mips/include/asm/octeon/cvmx-ipd.h
arch/mips/include/asm/unistd.h
arch/mips/include/uapi/asm/hwcap.h
arch/mips/kernel/cpu-bugs64.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/setup.c
arch/mips/kernel/syscall.c
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_n64.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl
arch/mips/loongson64/Platform
arch/mips/loongson64/common/mem.c
arch/mips/loongson64/common/serial.c
arch/mips/loongson64/loongson-3/numa.c
arch/mips/pmcs-msp71xx/msp_prom.c
arch/mips/vdso/Makefile
arch/mips/vdso/gettimeofday.c [deleted file]
arch/powerpc/boot/Makefile
arch/powerpc/include/asm/book3s/64/tlbflush-radix.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/pseries/lpar.c
arch/riscv/include/asm/asm.h
arch/riscv/kernel/entry.S
arch/riscv/kernel/traps.c
arch/riscv/mm/init.c
arch/s390/configs/debug_defconfig
arch/s390/configs/defconfig
arch/s390/configs/zfcpdump_defconfig
arch/s390/include/asm/atomic_ops.h
arch/s390/include/asm/bitops.h
arch/s390/include/asm/cpacf.h
arch/s390/include/asm/cpu_mf.h
arch/s390/include/asm/hugetlb.h
arch/s390/include/asm/jump_label.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/qdio.h
arch/s390/include/asm/uaccess.h
arch/s390/kernel/perf_cpum_cf_diag.c
arch/s390/kernel/perf_cpum_sf.c
arch/s390/kvm/kvm-s390.c
arch/s390/pci/pci_clp.c
arch/x86/events/amd/core.c
arch/x86/events/intel/core.c
arch/x86/events/intel/cstate.c
arch/x86/events/msr.c
arch/x86/include/asm/cpu_entry_area.h
arch/x86/include/asm/intel-family.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/mwait.h
arch/x86/include/asm/pti.h
arch/x86/include/asm/uaccess.h
arch/x86/kernel/cpu/vmware.c
arch/x86/kernel/process.h
arch/x86/kvm/cpuid.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/pmu_intel.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/delay.c
arch/x86/platform/efi/efi.c
arch/x86/xen/efi.c
arch/x86/xen/enlighten.c
block/blk-mq.c
block/blk-rq-qos.c
block/blk-rq-qos.h
block/blk-wbt.c
block/sed-opal.c
drivers/ata/libata-scsi.c
drivers/block/loop.c
drivers/block/nbd.c
drivers/block/null_blk_zoned.c
drivers/char/random.c
drivers/clk/ti/clk-7xx.c
drivers/clocksource/timer-of.c
drivers/firmware/efi/cper.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/rci2-table.c
drivers/firmware/efi/tpm.c
drivers/gpio/gpio-eic-sprd.c
drivers/gpio/gpio-max77620.c
drivers/gpio/gpiolib-of.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/Makefile
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/nv.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/dcn21/Makefile
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
drivers/gpu/drm/arm/malidp_mw.c
drivers/gpu/drm/bridge/tc358767.c
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_writeback.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display.h
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dp.h
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_sprite.c
drivers/gpu/drm/i915/gem/i915_gem_mman.c
drivers/gpu/drm/i915/gem/i915_gem_pm.c
drivers/gpu/drm/i915/gt/intel_engine.h
drivers/gpu/drm/i915/gt/intel_engine_cs.c
drivers/gpu/drm/i915/gt/intel_lrc.c
drivers/gpu/drm/i915/gt/intel_reset.c
drivers/gpu/drm/i915/gt/intel_reset.h
drivers/gpu/drm/i915/gt/intel_ringbuffer.c
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.h
drivers/gpu/drm/i915/i915_request.c
drivers/gpu/drm/i915/i915_request.h
drivers/gpu/drm/i915/intel_pch.c
drivers/gpu/drm/i915/intel_pch.h
drivers/gpu/drm/i915/selftests/i915_gem.c
drivers/gpu/drm/omapdrm/dss/dss.c
drivers/gpu/drm/panel/panel-lg-lb035q02.c
drivers/gpu/drm/panel/panel-nec-nl8048hl11.c
drivers/gpu/drm/panel/panel-sony-acx565akm.c
drivers/gpu/drm/panel/panel-tpo-td028ttec1.c
drivers/gpu/drm/panel/panel-tpo-td043mtea1.c
drivers/gpu/drm/rcar-du/rcar_du_writeback.c
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
drivers/gpu/drm/vc4/vc4_txp.c
drivers/gpu/drm/xen/xen_drm_front.c
drivers/hid/hid-hyperv.c
drivers/hv/vmbus_drv.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/device.c
drivers/infiniband/core/nldev.c
drivers/infiniband/core/security.c
drivers/infiniband/core/umem_odp.c
drivers/infiniband/hw/cxgb4/device.c
drivers/infiniband/hw/cxgb4/mem.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/hfi1/sdma.c
drivers/infiniband/hw/i40iw/i40iw_verbs.c
drivers/infiniband/hw/mlx5/devx.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/mlx5/odp.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
drivers/infiniband/sw/siw/siw_qp.c
drivers/net/dsa/qca8k.c
drivers/net/dsa/rtl8366.c
drivers/net/dsa/rtl8366rb.c
drivers/net/dsa/sja1105/sja1105_main.c
drivers/net/dsa/sja1105/sja1105_spi.c
drivers/net/ethernet/atheros/ag71xx.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
drivers/net/ethernet/hisilicon/hns_mdio.c
drivers/net/ethernet/mellanox/mlx5/core/mr.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c
drivers/net/ethernet/mscc/ocelot_board.c
drivers/net/ethernet/pensando/Kconfig
drivers/net/ethernet/qlogic/qla3xxx.c
drivers/net/ethernet/socionext/netsec.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
drivers/net/ieee802154/atusb.c
drivers/net/ieee802154/ca8210.c
drivers/net/ieee802154/mcr20a.c
drivers/net/phy/at803x.c
drivers/net/phy/mdio_device.c
drivers/net/phy/phy-core.c
drivers/net/phy/phy.c
drivers/net/phy/phy_device.c
drivers/net/ppp/pptp.c
drivers/net/tun.c
drivers/net/usb/hso.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/virtio_net.c
drivers/net/vrf.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/xen-netfront.c
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/nvme/host/rdma.c
drivers/nvme/host/tcp.c
drivers/nvme/target/io-cmd-bdev.c
drivers/nvme/target/tcp.c
drivers/ptp/ptp_qoriq.c
drivers/s390/block/dasd_eckd.c
drivers/s390/cio/cio.h
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/qdio_setup.c
drivers/s390/net/qeth_core_main.c
drivers/scsi/bnx2fc/bnx2fc_io.c
drivers/scsi/hisi_sas/hisi_sas_main.c
drivers/scsi/megaraid.c
drivers/scsi/qedf/qedf_main.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/storvsc_drv.c
drivers/scsi/ufs/ufshcd.c
drivers/staging/octeon/ethernet-tx.c
drivers/video/logo/Makefile
drivers/xen/balloon.c
drivers/xen/efi.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
drivers/xen/xenbus/xenbus_dev_frontend.c
fs/binfmt_elf.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ref-verify.c
fs/btrfs/send.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/netmisc.c
fs/cifs/smb2pdu.c
fs/cifs/smb2proto.h
fs/erofs/data.c
fs/erofs/super.c
fs/erofs/zdata.c
fs/fs-writeback.c
fs/io_uring.c
fs/libfs.c
fs/nfs/direct.c
fs/nfs/nfs4proc.c
fs/nfs/write.c
fs/ocfs2/aops.c
fs/ocfs2/ioctl.c
fs/ocfs2/xattr.c
fs/readdir.c
fs/statfs.c
fs/super.c
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_bmap.h
fs/xfs/libxfs/xfs_dir2_block.c
fs/xfs/scrub/refcount.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_log.c
fs/xfs/xfs_log_recover.c
include/linux/bitops.h
include/linux/compiler_attributes.h
include/linux/dsa/sja1105.h
include/linux/export.h
include/linux/kvm_host.h
include/linux/leds.h
include/linux/memcontrol.h
include/linux/mii.h
include/linux/phy.h
include/linux/skbuff.h
include/linux/slab.h
include/linux/string.h
include/linux/sunrpc/xprtsock.h
include/linux/tpm_eventlog.h
include/linux/uaccess.h
include/trace/events/rxrpc.h
include/uapi/drm/amdgpu_drm.h
include/uapi/linux/nvme_ioctl.h
include/uapi/linux/pg.h
include/uapi/linux/sched.h
include/xen/xen-ops.h
kernel/dma/remap.c
kernel/events/core.c
kernel/fork.c
kernel/freezer.c
kernel/gen_kheaders.sh
kernel/panic.c
kernel/sched/core.c
kernel/sched/cputime.c
kernel/sched/fair.c
kernel/sched/membarrier.c
kernel/time/tick-broadcast-hrtimer.c
lib/string.c
lib/strnlen_user.c
lib/test_user_copy.c
lib/textsearch.c
lib/usercopy.c
lib/vdso/Kconfig
mm/backing-dev.c
mm/memcontrol.c
mm/memremap.c
mm/page_alloc.c
mm/shmem.c
mm/shuffle.c
mm/slab_common.c
mm/slob.c
mm/slub.c
mm/sparse.c
mm/vmpressure.c
mm/vmscan.c
mm/z3fold.c
net/batman-adv/soft-interface.c
net/core/devlink.c
net/core/skbuff.c
net/core/sock.c
net/dccp/ipv4.c
net/dsa/tag_sja1105.c
net/ipv4/ip_gre.c
net/ipv4/ip_input.c
net/ipv4/ipmr.c
net/ipv4/netfilter/nf_dup_ipv4.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/ip6_input.c
net/ipv6/netfilter/nf_dup_ipv6.c
net/ipv6/raw.c
net/ipv6/udp.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_eth.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/mac80211/debugfs_netdev.c
net/mac80211/util.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nft_connlimit.c
net/nfc/llcp_sock.c
net/openvswitch/vport-internal_dev.c
net/packet/af_packet.c
net/rds/ib.c
net/sched/sch_cbq.c
net/sched/sch_cbs.c
net/sched/sch_dsmark.c
net/sched/sch_taprio.c
net/sctp/input.c
net/sctp/sm_make_chunk.c
net/sunrpc/xprtsock.c
net/tipc/link.c
net/tipc/msg.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/hyperv_transport.c
net/vmw_vsock/virtio_transport_common.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/scan.c
net/wireless/wext-compat.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_interface.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c
scripts/Kbuild.include
scripts/Makefile.build
scripts/Makefile.lib
scripts/coccinelle/misc/add_namespace.cocci
scripts/mod/modpost.c
scripts/namespace.pl
scripts/nsdeps
scripts/setlocalversion
security/integrity/Makefile
security/selinux/ss/services.c
tools/arch/arm/include/uapi/asm/kvm.h
tools/arch/arm64/include/uapi/asm/kvm.h
tools/arch/s390/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/vmx.h
tools/include/uapi/asm-generic/mman-common.h
tools/include/uapi/drm/i915_drm.h
tools/include/uapi/linux/fs.h
tools/include/uapi/linux/fscrypt.h [new file with mode: 0644]
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/usbdevice_fs.h
tools/lib/subcmd/Makefile
tools/perf/Documentation/asciidoc.conf
tools/perf/Documentation/jitdump-specification.txt
tools/perf/arch/arm/annotate/instructions.c
tools/perf/arch/arm64/annotate/instructions.c
tools/perf/arch/powerpc/util/header.c
tools/perf/arch/s390/annotate/instructions.c
tools/perf/arch/s390/util/header.c
tools/perf/arch/x86/annotate/instructions.c
tools/perf/arch/x86/util/header.c
tools/perf/builtin-kvm.c
tools/perf/builtin-script.c
tools/perf/check-headers.sh
tools/perf/pmu-events/arch/s390/cf_m8561/basic.json [deleted file]
tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json [deleted file]
tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json [deleted file]
tools/perf/pmu-events/arch/s390/cf_m8561/extended.json [deleted file]
tools/perf/pmu-events/arch/s390/cf_z15/basic.json [new file with mode: 0644]
tools/perf/pmu-events/arch/s390/cf_z15/crypto.json [new file with mode: 0644]
tools/perf/pmu-events/arch/s390/cf_z15/crypto6.json [new file with mode: 0644]
tools/perf/pmu-events/arch/s390/cf_z15/extended.json [new file with mode: 0644]
tools/perf/pmu-events/arch/s390/cf_z15/transaction.json [new file with mode: 0644]
tools/perf/pmu-events/arch/s390/mapfile.csv
tools/perf/pmu-events/jevents.c
tools/perf/tests/perf-hooks.c
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/evsel.c
tools/perf/util/jitdump.c
tools/perf/util/llvm-utils.c
tools/perf/util/map.c
tools/perf/util/python.c
tools/testing/selftests/Makefile
tools/testing/selftests/kselftest/runner.sh
tools/testing/selftests/kselftest_install.sh
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/include/x86_64/processor.h
tools/testing/selftests/kvm/include/x86_64/vmx.h
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/kvm_util_internal.h
tools/testing/selftests/kvm/lib/x86_64/processor.c
tools/testing/selftests/kvm/lib/x86_64/vmx.c
tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c [new file with mode: 0644]
tools/testing/selftests/net/.gitignore
tools/testing/selftests/net/udpgso.c
tools/testing/selftests/pidfd/Makefile
tools/testing/selftests/powerpc/mm/tlbie_test.c
tools/testing/selftests/rtc/settings [new file with mode: 0644]
tools/testing/selftests/watchdog/watchdog-test.c
usr/include/Makefile
virt/kvm/arm/vgic/trace.h
virt/kvm/kvm_main.c

diff --git a/CREDITS b/CREDITS
index 8b67a85..031605d 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1637,6 +1637,10 @@ S: Panoramastrasse 18
 S: D-69126 Heidelberg
 S: Germany
 
+N: Simon Horman
+M: horms@verge.net.au
+D: Renesas ARM/ARM64 SoC maintainer
+
 N: Christopher Horn
 E: chorn@warwick.net
 D: Miscellaneous sysctl hacks
index 0fa8c0e..5361ebe 100644 (file)
@@ -615,8 +615,8 @@ on an IO device and is an example of this type.
 Protections
 -----------
 
-A cgroup is protected to be allocated upto the configured amount of
-the resource if the usages of all its ancestors are under their
+A cgroup is protected upto the configured amount of the resource
+as long as the usages of all its ancestors are under their
 protected levels.  Protections can be hard guarantees or best effort
 soft boundaries.  Protections can also be over-committed in which case
 only upto the amount available to the parent is protected among
@@ -1096,7 +1096,10 @@ PAGE_SIZE multiple when read back.
        is within its effective min boundary, the cgroup's memory
        won't be reclaimed under any conditions. If there is no
        unprotected reclaimable memory available, OOM killer
-       is invoked.
+       is invoked. Above the effective min boundary (or
+       effective low boundary if it is higher), pages are reclaimed
+       proportionally to the overage, reducing reclaim pressure for
+       smaller overages.
 
        Effective min boundary is limited by memory.min values of
        all ancestor cgroups. If there is memory.min overcommitment
@@ -1118,7 +1121,10 @@ PAGE_SIZE multiple when read back.
        Best-effort memory protection.  If the memory usage of a
        cgroup is within its effective low boundary, the cgroup's
        memory won't be reclaimed unless memory can be reclaimed
-       from unprotected cgroups.
+       from unprotected cgroups.  Above the effective low boundary (or
+       effective min boundary if it is higher), pages are reclaimed
+       proportionally to the overage, reducing reclaim pressure for
+       smaller overages.
 
        Effective low boundary is limited by memory.low values of
        all ancestor cgroups. If there is memory.low overcommitment
@@ -2482,8 +2488,10 @@ system performance due to overreclaim, to the point where the feature
 becomes self-defeating.
 
 The memory.low boundary on the other hand is a top-down allocated
-reserve.  A cgroup enjoys reclaim protection when it's within its low,
-which makes delegation of subtrees possible.
+reserve.  A cgroup enjoys reclaim protection when it's within its
+effective low, which makes delegation of subtrees possible. It also
+enjoys having reclaim pressure proportional to its overage when
+above its effective low.
 
 The original high boundary, the hard limit, is defined as a strict
 limit that can not budge, even if the OOM killer has to be called.
index c7ac2f3..a84a83f 100644 (file)
                                the unplug protocol
                        never -- do not unplug even if version check succeeds
 
+       xen_legacy_crash        [X86,XEN]
+                       Crash from Xen panic notifier, without executing late
+                       panic() code such as dumping handler.
+
        xen_nopvspin    [X86,XEN]
                        Disables the ticketlock slowpath using Xen PV
                        optimizations.
index b040909..02e0217 100644 (file)
@@ -154,11 +154,18 @@ return virtual addresses to userspace from a 48-bit range.
 
 Software can "opt-in" to receiving VAs from a 52-bit space by
 specifying an mmap hint parameter that is larger than 48-bit.
+
 For example:
-    maybe_high_address = mmap(~0UL, size, prot, flags,...);
+
+.. code-block:: c
+
+   maybe_high_address = mmap(~0UL, size, prot, flags,...);
 
 It is also possible to build a debug kernel that returns addresses
 from a 52-bit space by enabling the following kernel config options:
+
+.. code-block:: sh
+
    CONFIG_EXPERT=y && CONFIG_ARM64_FORCE_52BIT=y
 
 Note that this option is only intended for debugging applications
index fa16a05..ab0eae1 100644 (file)
@@ -38,6 +38,7 @@ Core utilities
    protection-keys
    ../RCU/index
    gcc-plugins
+   symbol-namespaces
 
 
 Interfaces for kernel debugging
index 7744aa3..939e3df 100644 (file)
@@ -98,6 +98,10 @@ limited. The actual limit depends on the hardware and the kernel
 configuration, but it is a good practice to use `kmalloc` for objects
 smaller than page size.
 
+The address of a chunk allocated with `kmalloc` is aligned to at least
+ARCH_KMALLOC_MINALIGN bytes.  For sizes which are a power of two, the
+alignment is also guaranteed to be at least the respective size.
+
 For large allocations you can use :c:func:`vmalloc` and
 :c:func:`vzalloc`, or directly request pages from the page
 allocator. The memory allocated by `vmalloc` and related functions is
diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst
new file mode 100644 (file)
index 0000000..982ed7b
--- /dev/null
@@ -0,0 +1,154 @@
+=================
+Symbol Namespaces
+=================
+
+The following document describes how to use Symbol Namespaces to structure the
+export surface of in-kernel symbols exported through the family of
+EXPORT_SYMBOL() macros.
+
+.. Table of Contents
+
+       === 1 Introduction
+       === 2 How to define Symbol Namespaces
+          --- 2.1 Using the EXPORT_SYMBOL macros
+          --- 2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
+       === 3 How to use Symbols exported in Namespaces
+       === 4 Loading Modules that use namespaced Symbols
+       === 5 Automatically creating MODULE_IMPORT_NS statements
+
+1. Introduction
+===============
+
+Symbol Namespaces have been introduced as a means to structure the export
+surface of the in-kernel API. It allows subsystem maintainers to partition
+their exported symbols into separate namespaces. That is useful for
+documentation purposes (think of the SUBSYSTEM_DEBUG namespace) as well as for
+limiting the availability of a set of symbols for use in other parts of the
+kernel. As of today, modules that make use of symbols exported into namespaces,
+are required to import the namespace. Otherwise the kernel will, depending on
+its configuration, reject loading the module or warn about a missing import.
+
+2. How to define Symbol Namespaces
+==================================
+
+Symbols can be exported into namespace using different methods. All of them are
+changing the way EXPORT_SYMBOL and friends are instrumented to create ksymtab
+entries.
+
+2.1 Using the EXPORT_SYMBOL macros
+==================================
+
+In addition to the macros EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(), that allow
+exporting of kernel symbols to the kernel symbol table, variants of these are
+available to export symbols into a certain namespace: EXPORT_SYMBOL_NS() and
+EXPORT_SYMBOL_NS_GPL(). They take one additional argument: the namespace.
+Please note that due to macro expansion that argument needs to be a
+preprocessor symbol. E.g. to export the symbol `usb_stor_suspend` into the
+namespace `USB_STORAGE`, use::
+
+       EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE);
+
+The corresponding ksymtab entry struct `kernel_symbol` will have the member
+`namespace` set accordingly. A symbol that is exported without a namespace will
+refer to `NULL`. There is no default namespace if none is defined. `modpost`
+and kernel/module.c make use the namespace at build time or module load time,
+respectively.
+
+2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
+=============================================
+
+Defining namespaces for all symbols of a subsystem can be very verbose and may
+become hard to maintain. Therefore a default define (DEFAULT_SYMBOL_NAMESPACE)
+is been provided, that, if set, will become the default for all EXPORT_SYMBOL()
+and EXPORT_SYMBOL_GPL() macro expansions that do not specify a namespace.
+
+There are multiple ways of specifying this define and it depends on the
+subsystem and the maintainer's preference, which one to use. The first option
+is to define the default namespace in the `Makefile` of the subsystem. E.g. to
+export all symbols defined in usb-common into the namespace USB_COMMON, add a
+line like this to drivers/usb/common/Makefile::
+
+       ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON
+
+That will affect all EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() statements. A
+symbol exported with EXPORT_SYMBOL_NS() while this definition is present, will
+still be exported into the namespace that is passed as the namespace argument
+as this argument has preference over a default symbol namespace.
+
+A second option to define the default namespace is directly in the compilation
+unit as preprocessor statement. The above example would then read::
+
+       #undef  DEFAULT_SYMBOL_NAMESPACE
+       #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON
+
+within the corresponding compilation unit before any EXPORT_SYMBOL macro is
+used.
+
+3. How to use Symbols exported in Namespaces
+============================================
+
+In order to use symbols that are exported into namespaces, kernel modules need
+to explicitly import these namespaces. Otherwise the kernel might reject to
+load the module. The module code is required to use the macro MODULE_IMPORT_NS
+for the namespaces it uses symbols from. E.g. a module using the
+usb_stor_suspend symbol from above, needs to import the namespace USB_STORAGE
+using a statement like::
+
+       MODULE_IMPORT_NS(USB_STORAGE);
+
+This will create a `modinfo` tag in the module for each imported namespace.
+This has the side effect, that the imported namespaces of a module can be
+inspected with modinfo::
+
+       $ modinfo drivers/usb/storage/ums-karma.ko
+       [...]
+       import_ns:      USB_STORAGE
+       [...]
+
+
+It is advisable to add the MODULE_IMPORT_NS() statement close to other module
+metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE(). Refer to section
+5. for a way to create missing import statements automatically.
+
+4. Loading Modules that use namespaced Symbols
+==============================================
+
+At module loading time (e.g. `insmod`), the kernel will check each symbol
+referenced from the module for its availability and whether the namespace it
+might be exported to has been imported by the module. The default behaviour of
+the kernel is to reject loading modules that don't specify sufficient imports.
+An error will be logged and loading will be failed with EINVAL. In order to
+allow loading of modules that don't satisfy this precondition, a configuration
+option is available: Setting MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y will
+enable loading regardless, but will emit a warning.
+
+5. Automatically creating MODULE_IMPORT_NS statements
+=====================================================
+
+Missing namespaces imports can easily be detected at build time. In fact,
+modpost will emit a warning if a module uses a symbol from a namespace
+without importing it.
+MODULE_IMPORT_NS() statements will usually be added at a definite location
+(along with other module meta data). To make the life of module authors (and
+subsystem maintainers) easier, a script and make target is available to fixup
+missing imports. Fixing missing imports can be done with::
+
+       $ make nsdeps
+
+A typical scenario for module authors would be::
+
+       - write code that depends on a symbol from a not imported namespace
+       - `make`
+       - notice the warning of modpost telling about a missing import
+       - run `make nsdeps` to add the import to the correct code location
+
+For subsystem maintainers introducing a namespace, the steps are very similar.
+Again, `make nsdeps` will eventually add the missing namespace imports for
+in-tree modules::
+
+       - move or add symbols to a namespace (e.g. with EXPORT_SYMBOL_NS())
+       - `make` (preferably with an allmodconfig to cover all in-kernel
+         modules)
+       - notice the warning of modpost telling about a missing import
+       - run `make nsdeps` to add the import to the correct code location
+
index 2560490..ecdfdc9 100644 (file)
@@ -89,6 +89,22 @@ To build, save output files in a separate directory with KBUILD_OUTPUT ::
 
   $ export KBUILD_OUTPUT=/tmp/kselftest; make TARGETS="size timers" kselftest
 
+Additionally you can use the "SKIP_TARGETS" variable on the make command
+line to specify one or more targets to exclude from the TARGETS list.
+
+To run all tests but a single subsystem::
+
+  $ make -C tools/testing/selftests SKIP_TARGETS=ptrace run_tests
+
+You can specify multiple tests to skip::
+
+  $  make SKIP_TARGETS="size timers" kselftest
+
+You can also specify a restricted list of tests to run together with a
+dedicated skiplist::
+
+  $  make TARGETS="bpf breakpoints size timers" SKIP_TARGETS=bpf kselftest
+
 See the top-level tools/testing/selftests/Makefile for the list of all
 possible targets.
 
index 3248595..f04870d 100644 (file)
@@ -85,4 +85,5 @@ examples:
                         <&pd IMX_SC_R_DSP_RAM>;
         mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
         mboxes = <&lsio_mu13 2 0>, <&lsio_mu13 2 1>, <&lsio_mu13 3 0>, <&lsio_mu13 3 1>;
+        memory-region = <&dsp_reserved>;
     };
index 676ec42..567a33a 100644 (file)
@@ -43,13 +43,9 @@ properties:
 
   dvdd-supply:
     description: DVdd voltage supply
-    items:
-      - const: dvdd
 
   avdd-supply:
     description: AVdd voltage supply
-    items:
-      - const: avdd
 
   adi,rejection-60-Hz-enable:
     description: |
@@ -99,6 +95,9 @@ required:
 examples:
   - |
     spi0 {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
       adc@0 {
         compatible = "adi,ad7192";
         reg = <0>;
index 3d5c154..9054555 100644 (file)
@@ -73,7 +73,6 @@ properties:
           - rc-genius-tvgo-a11mce
           - rc-gotview7135
           - rc-hauppauge
-          - rc-hauppauge
           - rc-hisi-poplar
           - rc-hisi-tv-demo
           - rc-imon-mce
index 8a56a85..a974821 100644 (file)
@@ -37,7 +37,7 @@ properties:
       - description: exclusive PHY reset line
       - description: shared reset line between the PCIe PHY and PCIe controller
 
-  resets-names:
+  reset-names:
     items:
       - const: phy
       - const: pcie
index 6ba9d53..b89c881 100644 (file)
@@ -954,11 +954,6 @@ When kbuild executes, the following steps are followed (roughly):
 
        From commandline LDFLAGS_MODULE shall be used (see kbuild.txt).
 
-    KBUILD_ARFLAGS   Options for $(AR) when creating archives
-
-       $(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic
-       mode) if this option is supported by $(AR).
-
     KBUILD_LDS
 
        The linker script with full path. Assigned by the top-level Makefile.
index d2ae799..774a998 100644 (file)
@@ -498,10 +498,11 @@ build.
        will be written containing all exported symbols that were not
        defined in the kernel.
 
---- 6.3 Symbols From Another External Module
+6.3 Symbols From Another External Module
+----------------------------------------
 
        Sometimes, an external module uses exported symbols from
-       another external module. kbuild needs to have full knowledge of
+       another external module. Kbuild needs to have full knowledge of
        all symbols to avoid spitting out warnings about undefined
        symbols. Three solutions exist for this situation.
 
@@ -521,7 +522,7 @@ build.
                The top-level kbuild file would then look like::
 
                        #./Kbuild (or ./Makefile):
-                               obj-y := foo/ bar/
+                               obj-m := foo/ bar/
 
                And executing::
 
diff --git a/Documentation/kbuild/namespaces.rst b/Documentation/kbuild/namespaces.rst
deleted file mode 100644 (file)
index 982ed7b..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-=================
-Symbol Namespaces
-=================
-
-The following document describes how to use Symbol Namespaces to structure the
-export surface of in-kernel symbols exported through the family of
-EXPORT_SYMBOL() macros.
-
-.. Table of Contents
-
-       === 1 Introduction
-       === 2 How to define Symbol Namespaces
-          --- 2.1 Using the EXPORT_SYMBOL macros
-          --- 2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
-       === 3 How to use Symbols exported in Namespaces
-       === 4 Loading Modules that use namespaced Symbols
-       === 5 Automatically creating MODULE_IMPORT_NS statements
-
-1. Introduction
-===============
-
-Symbol Namespaces have been introduced as a means to structure the export
-surface of the in-kernel API. It allows subsystem maintainers to partition
-their exported symbols into separate namespaces. That is useful for
-documentation purposes (think of the SUBSYSTEM_DEBUG namespace) as well as for
-limiting the availability of a set of symbols for use in other parts of the
-kernel. As of today, modules that make use of symbols exported into namespaces,
-are required to import the namespace. Otherwise the kernel will, depending on
-its configuration, reject loading the module or warn about a missing import.
-
-2. How to define Symbol Namespaces
-==================================
-
-Symbols can be exported into namespace using different methods. All of them are
-changing the way EXPORT_SYMBOL and friends are instrumented to create ksymtab
-entries.
-
-2.1 Using the EXPORT_SYMBOL macros
-==================================
-
-In addition to the macros EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(), that allow
-exporting of kernel symbols to the kernel symbol table, variants of these are
-available to export symbols into a certain namespace: EXPORT_SYMBOL_NS() and
-EXPORT_SYMBOL_NS_GPL(). They take one additional argument: the namespace.
-Please note that due to macro expansion that argument needs to be a
-preprocessor symbol. E.g. to export the symbol `usb_stor_suspend` into the
-namespace `USB_STORAGE`, use::
-
-       EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE);
-
-The corresponding ksymtab entry struct `kernel_symbol` will have the member
-`namespace` set accordingly. A symbol that is exported without a namespace will
-refer to `NULL`. There is no default namespace if none is defined. `modpost`
-and kernel/module.c make use the namespace at build time or module load time,
-respectively.
-
-2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
-=============================================
-
-Defining namespaces for all symbols of a subsystem can be very verbose and may
-become hard to maintain. Therefore a default define (DEFAULT_SYMBOL_NAMESPACE)
-is been provided, that, if set, will become the default for all EXPORT_SYMBOL()
-and EXPORT_SYMBOL_GPL() macro expansions that do not specify a namespace.
-
-There are multiple ways of specifying this define and it depends on the
-subsystem and the maintainer's preference, which one to use. The first option
-is to define the default namespace in the `Makefile` of the subsystem. E.g. to
-export all symbols defined in usb-common into the namespace USB_COMMON, add a
-line like this to drivers/usb/common/Makefile::
-
-       ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON
-
-That will affect all EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() statements. A
-symbol exported with EXPORT_SYMBOL_NS() while this definition is present, will
-still be exported into the namespace that is passed as the namespace argument
-as this argument has preference over a default symbol namespace.
-
-A second option to define the default namespace is directly in the compilation
-unit as preprocessor statement. The above example would then read::
-
-       #undef  DEFAULT_SYMBOL_NAMESPACE
-       #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON
-
-within the corresponding compilation unit before any EXPORT_SYMBOL macro is
-used.
-
-3. How to use Symbols exported in Namespaces
-============================================
-
-In order to use symbols that are exported into namespaces, kernel modules need
-to explicitly import these namespaces. Otherwise the kernel might reject to
-load the module. The module code is required to use the macro MODULE_IMPORT_NS
-for the namespaces it uses symbols from. E.g. a module using the
-usb_stor_suspend symbol from above, needs to import the namespace USB_STORAGE
-using a statement like::
-
-       MODULE_IMPORT_NS(USB_STORAGE);
-
-This will create a `modinfo` tag in the module for each imported namespace.
-This has the side effect, that the imported namespaces of a module can be
-inspected with modinfo::
-
-       $ modinfo drivers/usb/storage/ums-karma.ko
-       [...]
-       import_ns:      USB_STORAGE
-       [...]
-
-
-It is advisable to add the MODULE_IMPORT_NS() statement close to other module
-metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE(). Refer to section
-5. for a way to create missing import statements automatically.
-
-4. Loading Modules that use namespaced Symbols
-==============================================
-
-At module loading time (e.g. `insmod`), the kernel will check each symbol
-referenced from the module for its availability and whether the namespace it
-might be exported to has been imported by the module. The default behaviour of
-the kernel is to reject loading modules that don't specify sufficient imports.
-An error will be logged and loading will be failed with EINVAL. In order to
-allow loading of modules that don't satisfy this precondition, a configuration
-option is available: Setting MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y will
-enable loading regardless, but will emit a warning.
-
-5. Automatically creating MODULE_IMPORT_NS statements
-=====================================================
-
-Missing namespaces imports can easily be detected at build time. In fact,
-modpost will emit a warning if a module uses a symbol from a namespace
-without importing it.
-MODULE_IMPORT_NS() statements will usually be added at a definite location
-(along with other module meta data). To make the life of module authors (and
-subsystem maintainers) easier, a script and make target is available to fixup
-missing imports. Fixing missing imports can be done with::
-
-       $ make nsdeps
-
-A typical scenario for module authors would be::
-
-       - write code that depends on a symbol from a not imported namespace
-       - `make`
-       - notice the warning of modpost telling about a missing import
-       - run `make nsdeps` to add the import to the correct code location
-
-For subsystem maintainers introducing a namespace, the steps are very similar.
-Again, `make nsdeps` will eventually add the missing namespace imports for
-in-tree modules::
-
-       - move or add symbols to a namespace (e.g. with EXPORT_SYMBOL_NS())
-       - `make` (preferably with an allmodconfig to cover all in-kernel
-         modules)
-       - notice the warning of modpost telling about a missing import
-       - run `make nsdeps` to add the import to the correct code location
-
index ab92e98..5033938 100644 (file)
@@ -16,16 +16,21 @@ the kernel may be unreproducible, and how to avoid them.
 Timestamps
 ----------
 
-The kernel embeds a timestamp in two places:
+The kernel embeds timestamps in three places:
 
 * The version string exposed by ``uname()`` and included in
   ``/proc/version``
 
 * File timestamps in the embedded initramfs
 
-By default the timestamp is the current time.  This must be overridden
-using the `KBUILD_BUILD_TIMESTAMP`_ variable.  If you are building
-from a git commit, you could use its commit date.
+* If enabled via ``CONFIG_IKHEADERS``, file timestamps of kernel
+  headers embedded in the kernel or respective module,
+  exposed via ``/sys/kernel/kheaders.tar.xz``
+
+By default the timestamp is the current time and in the case of
+``kheaders`` the various files' modification times. This must
+be overridden using the `KBUILD_BUILD_TIMESTAMP`_ variable.
+If you are building from a git commit, you could use its commit date.
 
 The kernel does *not* use the ``__DATE__`` and ``__TIME__`` macros,
 and enables warnings if they are used.  If you incorporate external
index f51f925..c1f7f75 100644 (file)
@@ -23,6 +23,7 @@ Contents:
    intel/ice
    google/gve
    mellanox/mlx5
+   netronome/nfp
    pensando/ionic
 
 .. only::  subproject and html
index ce7e7a0..dc60b13 100644 (file)
@@ -272,7 +272,7 @@ supported flags are:
 * MSG_DONTWAIT, i.e. non-blocking operation.
 
 recvmsg(2)
-^^^^^^^^^
+^^^^^^^^^^
 
 In most cases recvmsg(2) is needed if you want to extract more information than
 recvfrom(2) can provide. For example package priority and timestamp. The
index f4a2198..ada573b 100644 (file)
@@ -56,7 +56,7 @@ instead of ``double-indenting`` the ``case`` labels.  E.g.:
        case 'K':
        case 'k':
                mem <<= 10;
-               /* fall through */
+               fallthrough;
        default:
                break;
        }
index 053b24a..179f2a5 100644 (file)
@@ -122,14 +122,27 @@ memory adjacent to the stack (when built without `CONFIG_VMAP_STACK=y`)
 
 Implicit switch case fall-through
 ---------------------------------
-The C language allows switch cases to "fall through" when
-a "break" statement is missing at the end of a case. This,
-however, introduces ambiguity in the code, as it's not always
-clear if the missing break is intentional or a bug. As there
-have been a long list of flaws `due to missing "break" statements
+The C language allows switch cases to "fall-through" when a "break" statement
+is missing at the end of a case. This, however, introduces ambiguity in the
+code, as it's not always clear if the missing break is intentional or a bug.
+
+As there have been a long list of flaws `due to missing "break" statements
 <https://cwe.mitre.org/data/definitions/484.html>`_, we no longer allow
-"implicit fall-through". In order to identify an intentional fall-through
-case, we have adopted the marking used by static analyzers: a comment
-saying `/* Fall through */`. Once the C++17 `__attribute__((fallthrough))`
-is more widely handled by C compilers, static analyzers, and IDEs, we can
-switch to using that instead.
+"implicit fall-through".
+
+In order to identify intentional fall-through cases, we have adopted a
+pseudo-keyword macro 'fallthrough' which expands to gcc's extension
+__attribute__((__fallthrough__)).  `Statement Attributes
+<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_
+
+When the C17/C18  [[fallthrough]] syntax is more commonly supported by
+C compilers, static analyzers, and IDEs, we can switch to using that syntax
+for the macro pseudo-keyword.
+
+All switch/case blocks must end in one of:
+
+       break;
+       fallthrough;
+       continue;
+       goto <label>;
+       return [expression];
index 3bcf493..a69e6db 100644 (file)
@@ -2165,12 +2165,10 @@ F:      arch/arm64/boot/dts/realtek/
 F:     Documentation/devicetree/bindings/arm/realtek.yaml
 
 ARM/RENESAS ARM64 ARCHITECTURE
-M:     Simon Horman <horms@verge.net.au>
 M:     Geert Uytterhoeven <geert+renesas@glider.be>
 M:     Magnus Damm <magnus.damm@gmail.com>
 L:     linux-renesas-soc@vger.kernel.org
 Q:     http://patchwork.kernel.org/project/linux-renesas-soc/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next
 S:     Supported
 F:     arch/arm64/boot/dts/renesas/
@@ -2282,12 +2280,10 @@ S:      Maintained
 F:     drivers/media/platform/s5p-mfc/
 
 ARM/SHMOBILE ARM ARCHITECTURE
-M:     Simon Horman <horms@verge.net.au>
 M:     Geert Uytterhoeven <geert+renesas@glider.be>
 M:     Magnus Damm <magnus.damm@gmail.com>
 L:     linux-renesas-soc@vger.kernel.org
 Q:     http://patchwork.kernel.org/project/linux-renesas-soc/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next
 S:     Supported
 F:     arch/arm/boot/dts/emev2*
@@ -6112,7 +6108,10 @@ M:       Gao Xiang <gaoxiang25@huawei.com>
 M:     Chao Yu <yuchao0@huawei.com>
 L:     linux-erofs@lists.ozlabs.org
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
+F:     Documentation/filesystems/erofs.txt
 F:     fs/erofs/
+F:     include/trace/events/erofs.h
 
 ERRSEQ ERROR TRACKING INFRASTRUCTURE
 M:     Jeff Layton <jlayton@kernel.org>
@@ -9075,6 +9074,7 @@ F:        security/keys/
 KGDB / KDB /debug_core
 M:     Jason Wessel <jason.wessel@windriver.com>
 M:     Daniel Thompson <daniel.thompson@linaro.org>
+R:     Douglas Anderson <dianders@chromium.org>
 W:     http://kgdb.wiki.kernel.org/
 L:     kgdb-bugreport@lists.sourceforge.net
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb.git
@@ -9183,6 +9183,7 @@ M:        Pavel Machek <pavel@ucw.cz>
 R:     Dan Murphy <dmurphy@ti.com>
 L:     linux-leds@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git
 S:     Maintained
 F:     Documentation/devicetree/bindings/leds/
 F:     drivers/leds/
@@ -11543,6 +11544,7 @@ NSDEPS
 M:     Matthias Maennich <maennich@google.com>
 S:     Maintained
 F:     scripts/nsdeps
+F:     Documentation/core-api/symbol-namespaces.rst
 
 NTB AMD DRIVER
 M:     Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
index 6f54f2f..f87a5d6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@
 VERSION = 5
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
-NAME = Bobtail Squid
+EXTRAVERSION = -rc2
+NAME = Nesting Opossum
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -206,24 +206,8 @@ ifndef KBUILD_CHECKSRC
   KBUILD_CHECKSRC = 0
 endif
 
-# Use make M=dir to specify directory of external module to build
-# Old syntax make ... SUBDIRS=$PWD is still supported
-# Setting the environment variable KBUILD_EXTMOD take precedence
-ifdef SUBDIRS
-  $(warning ================= WARNING ================)
-  $(warning 'SUBDIRS' will be removed after Linux 5.3)
-  $(warning )
-  $(warning If you are building an individual subdirectory)
-  $(warning in the kernel tree, you can do like this:)
-  $(warning $$ make path/to/dir/you/want/to/build/)
-  $(warning (Do not forget the trailing slash))
-  $(warning )
-  $(warning If you are building an external module,)
-  $(warning Please use 'M=' or 'KBUILD_EXTMOD' instead)
-  $(warning ==========================================)
-  KBUILD_EXTMOD ?= $(SUBDIRS)
-endif
-
+# Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the
+# directory of external module to build. Setting M= takes precedence.
 ifeq ("$(origin M)", "command line")
   KBUILD_EXTMOD := $(M)
 endif
@@ -498,7 +482,6 @@ export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
 export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
-export KBUILD_ARFLAGS
 
 # Files to ignore in find ... statements
 
@@ -616,7 +599,7 @@ endif
 # in addition to whatever we do anyway.
 # Just "make" or "make all" shall build modules as well
 
-ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
+ifneq ($(filter all _all modules nsdeps,$(MAKECMDGOALS)),)
   KBUILD_MODULES := 1
 endif
 
@@ -914,9 +897,6 @@ ifdef CONFIG_RETPOLINE
 KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
 endif
 
-# use the deterministic mode of AR if available
-KBUILD_ARFLAGS := $(call ar-option,D)
-
 include scripts/Makefile.kasan
 include scripts/Makefile.extrawarn
 include scripts/Makefile.ubsan
@@ -1237,9 +1217,8 @@ PHONY += kselftest
 kselftest:
        $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests run_tests
 
-PHONY += kselftest-clean
-kselftest-clean:
-       $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests clean
+kselftest-%: FORCE
+       $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests $*
 
 PHONY += kselftest-merge
 kselftest-merge:
index 18f70b3..204bccf 100644 (file)
        pinctrl-0 = <&mmc0_pins_default>;
 };
 
-&gpio0 {
+&gpio0_target {
        /* Do not idle the GPIO used for holding the VTT regulator */
        ti,no-reset-on-init;
        ti,no-idle-on-init;
index 9915c89..7a9eb2b 100644 (file)
                        ranges = <0x0 0x5000 0x1000>;
                };
 
-               target-module@7000 {                    /* 0x44e07000, ap 14 20.0 */
+               gpio0_target: target-module@7000 {      /* 0x44e07000, ap 14 20.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
                        ti,hwmods = "gpio1";
                        reg = <0x7000 0x4>,
                        reg = <0xe000 0x4>,
                              <0xe054 0x4>;
                        reg-names = "rev", "sysc";
-                       ti,sysc-midle ;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
                        ti,sysc-sidle = <SYSC_IDLE_FORCE>,
                                        <SYSC_IDLE_NO>,
                                        <SYSC_IDLE_SMART>;
index 848e2a8..14bbc43 100644 (file)
                                ti,hwmods = "dss_dispc";
                                clocks = <&disp_clk>;
                                clock-names = "fck";
+
+                               max-memory-bandwidth = <230000000>;
                        };
 
                        rfbi: rfbi@4832a800 {
index ea0e7c1..5cac2dd 100644 (file)
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 129 1>, <&edma_xbar 128 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&ipu_clkctrl DRA7_IPU_MCASP1_CLKCTRL 22>,
+                               clocks = <&ipu_clkctrl DRA7_IPU_MCASP1_CLKCTRL 0>,
                                         <&ipu_clkctrl DRA7_IPU_MCASP1_CLKCTRL 24>,
                                         <&ipu_clkctrl DRA7_IPU_MCASP1_CLKCTRL 28>;
                                clock-names = "fck", "ahclkx", "ahclkr";
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 131 1>, <&edma_xbar 130 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP2_CLKCTRL 22>,
-                                        <&l4per2_clkctrl DRA7_L4PER2_MCASP2_CLKCTRL 24>,
+                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP2_CLKCTRL 0>,
+                                        <&ipu_clkctrl DRA7_IPU_MCASP1_CLKCTRL 24>,
                                         <&l4per2_clkctrl DRA7_L4PER2_MCASP2_CLKCTRL 28>;
                                clock-names = "fck", "ahclkx", "ahclkr";
                                status = "disabled";
                                        <SYSC_IDLE_SMART>;
                        /* Domains (P, C): l4per_pwrdm, l4per2_clkdm */
                        clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 0>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 24>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 28>;
-                       clock-names = "fck", "ahclkx", "ahclkr";
+                                <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 24>;
+                       clock-names = "fck", "ahclkx";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x68000 0x2000>,
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 133 1>, <&edma_xbar 132 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 22>,
+                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 0>,
                                         <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 24>;
                                clock-names = "fck", "ahclkx";
                                status = "disabled";
                                        <SYSC_IDLE_SMART>;
                        /* Domains (P, C): l4per_pwrdm, l4per2_clkdm */
                        clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP4_CLKCTRL 0>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP4_CLKCTRL 24>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP4_CLKCTRL 28>;
-                       clock-names = "fck", "ahclkx", "ahclkr";
+                                <&l4per2_clkctrl DRA7_L4PER2_MCASP4_CLKCTRL 24>;
+                       clock-names = "fck", "ahclkx";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x6c000 0x2000>,
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 135 1>, <&edma_xbar 134 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP4_CLKCTRL 22>,
+                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP4_CLKCTRL 0>,
                                         <&l4per2_clkctrl DRA7_L4PER2_MCASP4_CLKCTRL 24>;
                                clock-names = "fck", "ahclkx";
                                status = "disabled";
                                        <SYSC_IDLE_SMART>;
                        /* Domains (P, C): l4per_pwrdm, l4per2_clkdm */
                        clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP5_CLKCTRL 0>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP5_CLKCTRL 24>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP5_CLKCTRL 28>;
-                       clock-names = "fck", "ahclkx", "ahclkr";
+                                <&l4per2_clkctrl DRA7_L4PER2_MCASP5_CLKCTRL 24>;
+                       clock-names = "fck", "ahclkx";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x70000 0x2000>,
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 137 1>, <&edma_xbar 136 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP5_CLKCTRL 22>,
+                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP5_CLKCTRL 0>,
                                         <&l4per2_clkctrl DRA7_L4PER2_MCASP5_CLKCTRL 24>;
                                clock-names = "fck", "ahclkx";
                                status = "disabled";
                                        <SYSC_IDLE_SMART>;
                        /* Domains (P, C): l4per_pwrdm, l4per2_clkdm */
                        clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP6_CLKCTRL 0>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP6_CLKCTRL 24>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP6_CLKCTRL 28>;
-                       clock-names = "fck", "ahclkx", "ahclkr";
+                                <&l4per2_clkctrl DRA7_L4PER2_MCASP6_CLKCTRL 24>;
+                       clock-names = "fck", "ahclkx";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x74000 0x2000>,
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 139 1>, <&edma_xbar 138 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP6_CLKCTRL 22>,
+                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP6_CLKCTRL 0>,
                                         <&l4per2_clkctrl DRA7_L4PER2_MCASP6_CLKCTRL 24>;
                                clock-names = "fck", "ahclkx";
                                status = "disabled";
                                        <SYSC_IDLE_SMART>;
                        /* Domains (P, C): l4per_pwrdm, l4per2_clkdm */
                        clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP7_CLKCTRL 0>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP7_CLKCTRL 24>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP7_CLKCTRL 28>;
-                       clock-names = "fck", "ahclkx", "ahclkr";
+                                <&l4per2_clkctrl DRA7_L4PER2_MCASP7_CLKCTRL 24>;
+                       clock-names = "fck", "ahclkx";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x78000 0x2000>,
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 141 1>, <&edma_xbar 140 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP7_CLKCTRL 22>,
+                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP7_CLKCTRL 0>,
                                         <&l4per2_clkctrl DRA7_L4PER2_MCASP7_CLKCTRL 24>;
                                clock-names = "fck", "ahclkx";
                                status = "disabled";
                                        <SYSC_IDLE_SMART>;
                        /* Domains (P, C): l4per_pwrdm, l4per2_clkdm */
                        clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP8_CLKCTRL 0>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP8_CLKCTRL 24>,
-                                <&l4per2_clkctrl DRA7_L4PER2_MCASP8_CLKCTRL 28>;
-                       clock-names = "fck", "ahclkx", "ahclkr";
+                                <&l4per2_clkctrl DRA7_L4PER2_MCASP8_CLKCTRL 24>;
+                       clock-names = "fck", "ahclkx";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x7c000 0x2000>,
                                interrupt-names = "tx", "rx";
                                dmas = <&edma_xbar 143 1>, <&edma_xbar 142 1>;
                                dma-names = "tx", "rx";
-                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP8_CLKCTRL 22>,
+                               clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP8_CLKCTRL 0>,
                                         <&l4per2_clkctrl DRA7_L4PER2_MCASP8_CLKCTRL 24>;
                                clock-names = "fck", "ahclkx";
                                status = "disabled";
index d01fc87..b6ef1a7 100644 (file)
                        spi-max-frequency = <100000>;
                        spi-cpol;
                        spi-cpha;
+                       spi-cs-high;
 
                        backlight= <&backlight>;
                        label = "lcd";
index a53657b..bda454d 100644 (file)
@@ -8,6 +8,7 @@
 #include <dt-bindings/mfd/dbx500-prcmu.h>
 #include <dt-bindings/arm/ux500_pm_domains.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        #address-cells = <1>;
                 * cooling.
                 */
                cpu_thermal: cpu-thermal {
-                       polling-delay-passive = <0>;
-                       polling-delay = <1000>;
+                       polling-delay-passive = <250>;
+                       /*
+                        * This sensor fires interrupts to update the thermal
+                        * zone, so no polling is needed.
+                        */
+                       polling-delay = <0>;
 
                        thermal-sensors = <&thermal>;
 
@@ -79,7 +84,7 @@
 
                        cooling-maps {
                                trip = <&cpu_alert>;
-                               cooling-device = <&CPU0 0 2>;
+                               cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
                                contribution = <100>;
                        };
                };
index b34970c..01e3c0f 100644 (file)
@@ -228,7 +228,7 @@ CONFIG_RTC_DRV_OMAP=m
 CONFIG_DMADEVICES=y
 CONFIG_TI_EDMA=y
 CONFIG_COMMON_CLK_PWM=m
-CONFIG_REMOTEPROC=m
+CONFIG_REMOTEPROC=y
 CONFIG_DA8XX_REMOTEPROC=m
 CONFIG_MEMORY=y
 CONFIG_TI_AEMIF=m
index 13ba532..e4c8def 100644 (file)
@@ -415,7 +415,7 @@ CONFIG_SPI_SH_MSIOF=m
 CONFIG_SPI_SH_HSPI=y
 CONFIG_SPI_SIRF=y
 CONFIG_SPI_STM32=m
-CONFIG_SPI_STM32_QSPI=m
+CONFIG_SPI_STM32_QSPI=y
 CONFIG_SPI_SUN4I=y
 CONFIG_SPI_SUN6I=y
 CONFIG_SPI_TEGRA114=y
@@ -933,7 +933,7 @@ CONFIG_BCM2835_MBOX=y
 CONFIG_ROCKCHIP_IOMMU=y
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
-CONFIG_REMOTEPROC=m
+CONFIG_REMOTEPROC=y
 CONFIG_ST_REMOTEPROC=m
 CONFIG_RPMSG_VIRTIO=m
 CONFIG_ASPEED_LPC_CTRL=m
index 64eb896..d3f5097 100644 (file)
@@ -364,6 +364,7 @@ CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1=m
 CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11=m
 CONFIG_DRM_TILCDC=m
 CONFIG_DRM_PANEL_SIMPLE=m
+CONFIG_DRM_TI_TFP410=m
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_MODE_HELPERS=y
@@ -423,6 +424,7 @@ CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_SIMPLE=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
 CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OPTION=m
 CONFIG_USB_TEST=m
 CONFIG_NOP_USB_XCEIV=m
 CONFIG_AM335X_PHY_USB=m
@@ -460,6 +462,7 @@ CONFIG_MMC_SDHCI_OMAP=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=m
 CONFIG_LEDS_CPCAP=m
+CONFIG_LEDS_LM3532=m
 CONFIG_LEDS_GPIO=m
 CONFIG_LEDS_PCA963X=m
 CONFIG_LEDS_PWM=m
@@ -481,7 +484,7 @@ CONFIG_RTC_DRV_OMAP=m
 CONFIG_RTC_DRV_CPCAP=m
 CONFIG_DMADEVICES=y
 CONFIG_OMAP_IOMMU=y
-CONFIG_REMOTEPROC=m
+CONFIG_REMOTEPROC=y
 CONFIG_OMAP_REMOTEPROC=m
 CONFIG_WKUP_M3_RPROC=m
 CONFIG_SOC_TI=y
index b24df84..043b0b1 100644 (file)
@@ -98,6 +98,7 @@ config CRYPTO_AES_ARM_CE
        tristate "Accelerated AES using ARMv8 Crypto Extensions"
        depends on KERNEL_MODE_NEON
        select CRYPTO_BLKCIPHER
+       select CRYPTO_LIB_AES
        select CRYPTO_SIMD
        help
          Use an implementation of AES in CBC, CTR and XTS modes that uses
index b978cdf..4d17073 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/assembler.h>
 
        .text
+       .arch           armv8-a
        .fpu            crypto-neon-fp-armv8
        .align          3
 
diff --git a/arch/arm/include/asm/xen/xen-ops.h b/arch/arm/include/asm/xen/xen-ops.h
deleted file mode 100644 (file)
index ec154e7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_XEN_OPS_H
-#define _ASM_XEN_OPS_H
-
-void xen_efi_runtime_setup(void);
-
-#endif /* _ASM_XEN_OPS_H */
index dd939e1..29fd136 100644 (file)
@@ -763,7 +763,8 @@ static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = {
        .rev_offs       = 0x0000,
        .sysc_offs      = 0x0010,
        .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+       .sysc_flags     = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+                         SYSC_HAS_RESET_STATUS,
        .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
                          SIDLE_SMART_WKUP),
        .sysc_fields    = &omap_hwmod_sysc_type2,
index 2bcb634..5452477 100644 (file)
@@ -231,8 +231,9 @@ static struct omap_hwmod am33xx_control_hwmod = {
 static struct omap_hwmod_class_sysconfig lcdc_sysc = {
        .rev_offs       = 0x0,
        .sysc_offs      = 0x54,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+       .sysc_flags     = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE,
+       .idlemodes      = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                         MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART,
        .sysc_fields    = &omap_hwmod_sysc_type2,
 };
 
index 1fde1bf..7ac9af5 100644 (file)
@@ -74,83 +74,6 @@ int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
        return 0;
 }
 
-/*
- * This API is to be called during init to set the various voltage
- * domains to the voltage as per the opp table. Typically we boot up
- * at the nominal voltage. So this function finds out the rate of
- * the clock associated with the voltage domain, finds out the correct
- * opp entry and sets the voltage domain to the voltage specified
- * in the opp entry
- */
-static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
-                                        const char *oh_name)
-{
-       struct voltagedomain *voltdm;
-       struct clk *clk;
-       struct dev_pm_opp *opp;
-       unsigned long freq, bootup_volt;
-       struct device *dev;
-
-       if (!vdd_name || !clk_name || !oh_name) {
-               pr_err("%s: invalid parameters\n", __func__);
-               goto exit;
-       }
-
-       if (!strncmp(oh_name, "mpu", 3))
-               /* 
-                * All current OMAPs share voltage rail and clock
-                * source, so CPU0 is used to represent the MPU-SS.
-                */
-               dev = get_cpu_device(0);
-       else
-               dev = omap_device_get_by_hwmod_name(oh_name);
-
-       if (IS_ERR(dev)) {
-               pr_err("%s: Unable to get dev pointer for hwmod %s\n",
-                       __func__, oh_name);
-               goto exit;
-       }
-
-       voltdm = voltdm_lookup(vdd_name);
-       if (!voltdm) {
-               pr_err("%s: unable to get vdd pointer for vdd_%s\n",
-                       __func__, vdd_name);
-               goto exit;
-       }
-
-       clk =  clk_get(NULL, clk_name);
-       if (IS_ERR(clk)) {
-               pr_err("%s: unable to get clk %s\n", __func__, clk_name);
-               goto exit;
-       }
-
-       freq = clk_get_rate(clk);
-       clk_put(clk);
-
-       opp = dev_pm_opp_find_freq_ceil(dev, &freq);
-       if (IS_ERR(opp)) {
-               pr_err("%s: unable to find boot up OPP for vdd_%s\n",
-                       __func__, vdd_name);
-               goto exit;
-       }
-
-       bootup_volt = dev_pm_opp_get_voltage(opp);
-       dev_pm_opp_put(opp);
-
-       if (!bootup_volt) {
-               pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n",
-                      __func__, vdd_name);
-               goto exit;
-       }
-
-       voltdm_scale(voltdm, bootup_volt);
-       return 0;
-
-exit:
-       pr_err("%s: unable to set vdd_%s\n", __func__, vdd_name);
-       return -EINVAL;
-}
-
 #ifdef CONFIG_SUSPEND
 static int omap_pm_enter(suspend_state_t suspend_state)
 {
@@ -208,25 +131,6 @@ void omap_common_suspend_init(void *pm_suspend)
 }
 #endif /* CONFIG_SUSPEND */
 
-static void __init omap3_init_voltages(void)
-{
-       if (!soc_is_omap34xx())
-               return;
-
-       omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu");
-       omap2_set_init_voltage("core", "l3_ick", "l3_main");
-}
-
-static void __init omap4_init_voltages(void)
-{
-       if (!soc_is_omap44xx())
-               return;
-
-       omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu");
-       omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1");
-       omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
-}
-
 int __maybe_unused omap_pm_nop_init(void)
 {
        return 0;
@@ -246,10 +150,6 @@ int __init omap2_common_pm_late_init(void)
        omap4_twl_init();
        omap_voltage_late_init();
 
-       /* Initialize the voltages */
-       omap3_init_voltages();
-       omap4_init_voltages();
-
        /* Smartreflex device init */
        omap_devinit_smartreflex();
 
index 7ed2898..c32d047 100644 (file)
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y          := enlighten.o hypercall.o grant-table.o p2m.o mm.o
-obj-$(CONFIG_XEN_EFI) += efi.o
diff --git a/arch/arm/xen/efi.c b/arch/arm/xen/efi.c
deleted file mode 100644 (file)
index d687a73..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) 2015, Linaro Limited, Shannon Zhao
- */
-
-#include <linux/efi.h>
-#include <xen/xen-ops.h>
-#include <asm/xen/xen-ops.h>
-
-/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
- * e.g. efi.systab, will be set like normal EFI.
- */
-void __init xen_efi_runtime_setup(void)
-{
-       efi.get_time                 = xen_efi_get_time;
-       efi.set_time                 = xen_efi_set_time;
-       efi.get_wakeup_time          = xen_efi_get_wakeup_time;
-       efi.set_wakeup_time          = xen_efi_set_wakeup_time;
-       efi.get_variable             = xen_efi_get_variable;
-       efi.get_next_variable        = xen_efi_get_next_variable;
-       efi.set_variable             = xen_efi_set_variable;
-       efi.query_variable_info      = xen_efi_query_variable_info;
-       efi.update_capsule           = xen_efi_update_capsule;
-       efi.query_capsule_caps       = xen_efi_query_capsule_caps;
-       efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
-       efi.reset_system             = xen_efi_reset_system;
-}
-EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
index 1e57692..dd6804a 100644 (file)
@@ -15,7 +15,6 @@
 #include <xen/xen-ops.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
-#include <asm/xen/xen-ops.h>
 #include <asm/system_misc.h>
 #include <asm/efi.h>
 #include <linux/interrupt.h>
@@ -437,7 +436,7 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
 EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
 EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
 EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
-EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op_raw);
 EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
 EXPORT_SYMBOL_GPL(HYPERVISOR_vm_assist);
 EXPORT_SYMBOL_GPL(HYPERVISOR_dm_op);
index 2b2c208..38fa917 100644 (file)
@@ -28,7 +28,10 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
 
        for_each_memblock(memory, reg) {
                if (reg->base < (phys_addr_t)0xffffffff) {
-                       flags |= __GFP_DMA;
+                       if (IS_ENABLED(CONFIG_ZONE_DMA32))
+                               flags |= __GFP_DMA32;
+                       else
+                               flags |= __GFP_DMA;
                        break;
                }
        }
index 41a9b42..950a56b 100644 (file)
@@ -110,7 +110,6 @@ config ARM64
        select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select GENERIC_GETTIMEOFDAY
-       select GENERIC_COMPAT_VDSO if (!CPU_BIG_ENDIAN && COMPAT)
        select HANDLE_DOMAIN_IRQ
        select HARDIRQS_SW_RESEND
        select HAVE_PCI
@@ -1159,7 +1158,7 @@ menuconfig COMPAT
 if COMPAT
 
 config KUSER_HELPERS
-       bool "Enable kuser helpers page for 32 bit applications"
+       bool "Enable kuser helpers page for 32-bit applications"
        default y
        help
          Warning: disabling this option may break 32-bit user programs.
@@ -1185,6 +1184,18 @@ config KUSER_HELPERS
          Say N here only if you are absolutely certain that you do not
          need these helpers; otherwise, the safe option is to say Y.
 
+config COMPAT_VDSO
+       bool "Enable vDSO for 32-bit applications"
+       depends on !CPU_BIG_ENDIAN && "$(CROSS_COMPILE_COMPAT)" != ""
+       select GENERIC_COMPAT_VDSO
+       default y
+       help
+         Place in the process address space of 32-bit applications an
+         ELF shared object providing fast implementations of gettimeofday
+         and clock_gettime.
+
+         You must have a 32-bit build of glibc 2.22 or later for programs
+         to seamlessly take advantage of this.
 
 menuconfig ARMV8_DEPRECATED
        bool "Emulate deprecated/obsolete ARMv8 instructions"
index 84a3d50..2c0238c 100644 (file)
@@ -53,22 +53,6 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
   endif
 endif
 
-ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
-  CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
-
-  ifeq ($(CONFIG_CC_IS_CLANG), y)
-    $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
-  else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),)
-    $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
-  else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
-    $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
-  else
-    export CROSS_COMPILE_COMPAT
-    export CONFIG_COMPAT_VDSO := y
-    compat_vdso := -DCONFIG_COMPAT_VDSO=1
-  endif
-endif
-
 KBUILD_CFLAGS  += -mgeneral-regs-only $(lseinstr) $(brokengasinst)     \
                   $(compat_vdso) $(cc_has_k_constraint)
 KBUILD_CFLAGS  += -fno-asynchronous-unwind-tables
index 8e05c39..c9a867a 100644 (file)
@@ -723,7 +723,7 @@ CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_ARM_SMMU=y
 CONFIG_ARM_SMMU_V3=y
 CONFIG_QCOM_IOMMU=y
-CONFIG_REMOTEPROC=m
+CONFIG_REMOTEPROC=y
 CONFIG_QCOM_Q6V5_MSS=m
 CONFIG_QCOM_Q6V5_PAS=m
 CONFIG_QCOM_SYSMON=m
index c6bd87d..574808b 100644 (file)
@@ -321,7 +321,8 @@ static inline s64 __lse_atomic64_dec_if_positive(atomic64_t *v)
 }
 
 #define __CMPXCHG_CASE(w, sfx, name, sz, mb, cl...)                    \
-static inline u##sz __lse__cmpxchg_case_##name##sz(volatile void *ptr, \
+static __always_inline u##sz                                           \
+__lse__cmpxchg_case_##name##sz(volatile void *ptr,                     \
                                              u##sz old,                \
                                              u##sz new)                \
 {                                                                      \
@@ -362,7 +363,8 @@ __CMPXCHG_CASE(x,  ,  mb_, 64, al, "memory")
 #undef __CMPXCHG_CASE
 
 #define __CMPXCHG_DBL(name, mb, cl...)                                 \
-static inline long __lse__cmpxchg_double##name(unsigned long old1,     \
+static __always_inline long                                            \
+__lse__cmpxchg_double##name(unsigned long old1,                                \
                                         unsigned long old2,            \
                                         unsigned long new1,            \
                                         unsigned long new2,            \
index 86825aa..97f21cc 100644 (file)
 #define read_sysreg_el2(r)     read_sysreg_elx(r, _EL2, _EL1)
 #define write_sysreg_el2(v,r)  write_sysreg_elx(v, r, _EL2, _EL1)
 
-/**
- * hyp_alternate_select - Generates patchable code sequences that are
- * used to switch between two implementations of a function, depending
- * on the availability of a feature.
- *
- * @fname: a symbol name that will be defined as a function returning a
- * function pointer whose type will match @orig and @alt
- * @orig: A pointer to the default function, as returned by @fname when
- * @cond doesn't hold
- * @alt: A pointer to the alternate function, as returned by @fname
- * when @cond holds
- * @cond: a CPU feature (as described in asm/cpufeature.h)
- */
-#define hyp_alternate_select(fname, orig, alt, cond)                   \
-typeof(orig) * __hyp_text fname(void)                                  \
-{                                                                      \
-       typeof(alt) *val = orig;                                        \
-       asm volatile(ALTERNATIVE("nop           \n",                    \
-                                "mov   %0, %1  \n",                    \
-                                cond)                                  \
-                    : "+r" (val) : "r" (alt));                         \
-       return val;                                                     \
-}
-
 int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
 
 void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
index fb60a88..3fd8fd6 100644 (file)
@@ -20,7 +20,7 @@
 
 #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
 
-#if __LINUX_ARM_ARCH__ >= 8
+#if __LINUX_ARM_ARCH__ >= 8 && defined(CONFIG_AS_DMB_ISHLD)
 #define aarch32_smp_mb()       dmb(ish)
 #define aarch32_smp_rmb()      dmb(ishld)
 #define aarch32_smp_wmb()      dmb(ishst)
diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h
deleted file mode 100644 (file)
index 1f38bf3..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012 ARM Limited
- */
-#ifndef __ASM_VDSO_DATAPAGE_H
-#define __ASM_VDSO_DATAPAGE_H
-
-#ifndef __ASSEMBLY__
-
-struct vdso_data {
-       __u64 cs_cycle_last;    /* Timebase at clocksource init */
-       __u64 raw_time_sec;     /* Raw time */
-       __u64 raw_time_nsec;
-       __u64 xtime_clock_sec;  /* Kernel time */
-       __u64 xtime_clock_nsec;
-       __u64 xtime_coarse_sec; /* Coarse time */
-       __u64 xtime_coarse_nsec;
-       __u64 wtm_clock_sec;    /* Wall to monotonic time */
-       __u64 wtm_clock_nsec;
-       __u32 tb_seq_count;     /* Timebase sequence counter */
-       /* cs_* members must be adjacent and in this order (ldp accesses) */
-       __u32 cs_mono_mult;     /* NTP-adjusted clocksource multiplier */
-       __u32 cs_shift;         /* Clocksource shift (mono = raw) */
-       __u32 cs_raw_mult;      /* Raw clocksource multiplier */
-       __u32 tz_minuteswest;   /* Whacky timezone stuff */
-       __u32 tz_dsttime;
-       __u32 use_syscall;
-       __u32 hrtimer_res;
-};
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm64/include/asm/xen/xen-ops.h b/arch/arm64/include/asm/xen/xen-ops.h
deleted file mode 100644 (file)
index e6e7840..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_XEN_OPS_H
-#define _ASM_XEN_OPS_H
-
-void xen_efi_runtime_setup(void);
-
-#endif /* _ASM_XEN_OPS_H */
index 2ec09de..ca158be 100644 (file)
@@ -174,6 +174,9 @@ static void __init register_insn_emulation(struct insn_emulation_ops *ops)
        struct insn_emulation *insn;
 
        insn = kzalloc(sizeof(*insn), GFP_KERNEL);
+       if (!insn)
+               return;
+
        insn->ops = ops;
        insn->min = INSN_UNDEF;
 
@@ -233,6 +236,8 @@ static void __init register_insn_emulation_sysctl(void)
 
        insns_sysctl = kcalloc(nr_insn_emulated + 1, sizeof(*sysctl),
                               GFP_KERNEL);
+       if (!insns_sysctl)
+               return;
 
        raw_spin_lock_irqsave(&insn_emulation_lock, flags);
        list_for_each_entry(insn, &insn_emulation, node) {
index 1e43ba5..f593f4c 100644 (file)
@@ -128,8 +128,8 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn,
        int cpu, slot = -1;
 
        /*
-        * enable_smccc_arch_workaround_1() passes NULL for the hyp_vecs
-        * start/end if we're a guest. Skip the hyp-vectors work.
+        * detect_harden_bp_fw() passes NULL for the hyp_vecs start/end if
+        * we're a guest. Skip the hyp-vectors work.
         */
        if (!hyp_vecs_start) {
                __this_cpu_write(bp_hardening_data.fn, fn);
index 9323bcc..cabebf1 100644 (file)
@@ -136,6 +136,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
 
 static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_SB_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_FRINTTS_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
                       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_GPI_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
index 84a8227..e304fe0 100644 (file)
@@ -775,6 +775,7 @@ el0_sync_compat:
        b.ge    el0_dbg
        b       el0_inv
 el0_svc_compat:
+       gic_prio_kentry_setup tmp=x1
        mov     x0, sp
        bl      el0_svc_compat_handler
        b       ret_to_user
index 1717732..06e56b4 100644 (file)
@@ -121,10 +121,16 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 
                        /*
                         * Ensure updated trampoline is visible to instruction
-                        * fetch before we patch in the branch.
+                        * fetch before we patch in the branch. Although the
+                        * architecture doesn't require an IPI in this case,
+                        * Neoverse-N1 erratum #1542419 does require one
+                        * if the TLB maintenance in module_enable_ro() is
+                        * skipped due to rodata_enabled. It doesn't seem worth
+                        * it to make it conditional given that this is
+                        * certainly not a fast-path.
                         */
-                       __flush_icache_range((unsigned long)&dst[0],
-                                            (unsigned long)&dst[1]);
+                       flush_icache_range((unsigned long)&dst[0],
+                                          (unsigned long)&dst[1]);
                }
                addr = (unsigned long)dst;
 #else /* CONFIG_ARM64_MODULE_PLTS */
index a47462d..1fb2819 100644 (file)
@@ -332,22 +332,27 @@ void arch_release_task_struct(struct task_struct *tsk)
        fpsimd_release_task(tsk);
 }
 
-/*
- * src and dst may temporarily have aliased sve_state after task_struct
- * is copied.  We cannot fix this properly here, because src may have
- * live SVE state and dst's thread_info may not exist yet, so tweaking
- * either src's or dst's TIF_SVE is not safe.
- *
- * The unaliasing is done in copy_thread() instead.  This works because
- * dst is not schedulable or traceable until both of these functions
- * have been called.
- */
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
        if (current->mm)
                fpsimd_preserve_current_state();
        *dst = *src;
 
+       /* We rely on the above assignment to initialize dst's thread_flags: */
+       BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK));
+
+       /*
+        * Detach src's sve_state (if any) from dst so that it does not
+        * get erroneously used or freed prematurely.  dst's sve_state
+        * will be allocated on demand later on if dst uses SVE.
+        * For consistency, also clear TIF_SVE here: this could be done
+        * later in copy_process(), but to avoid tripping up future
+        * maintainers it is best not to leave TIF_SVE and sve_state in
+        * an inconsistent state, even temporarily.
+        */
+       dst->thread.sve_state = NULL;
+       clear_tsk_thread_flag(dst, TIF_SVE);
+
        return 0;
 }
 
@@ -360,13 +365,6 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 
        memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
 
-       /*
-        * Unalias p->thread.sve_state (if any) from the parent task
-        * and disable discard SVE state for p:
-        */
-       clear_tsk_thread_flag(p, TIF_SVE);
-       p->thread.sve_state = NULL;
-
        /*
         * In case p was allocated the same task_struct pointer as some
         * other recently-exited task, make sure p is disassociated from
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
deleted file mode 100644 (file)
index e69de29..0000000
index 1fba077..76b327f 100644 (file)
@@ -8,15 +8,21 @@
 ARCH_REL_TYPE_ABS := R_ARM_JUMP_SLOT|R_ARM_GLOB_DAT|R_ARM_ABS32
 include $(srctree)/lib/vdso/Makefile
 
-COMPATCC := $(CROSS_COMPILE_COMPAT)gcc
+# Same as cc-*option, but using CC_COMPAT instead of CC
+ifeq ($(CONFIG_CC_IS_CLANG), y)
+CC_COMPAT ?= $(CC)
+else
+CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc
+endif
 
-# Same as cc-*option, but using COMPATCC instead of CC
 cc32-option = $(call try-run,\
-        $(COMPATCC) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
+        $(CC_COMPAT) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
 cc32-disable-warning = $(call try-run,\
-       $(COMPATCC) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+       $(CC_COMPAT) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
 cc32-ldoption = $(call try-run,\
-        $(COMPATCC) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
+        $(CC_COMPAT) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
+cc32-as-instr = $(call try-run,\
+       printf "%b\n" "$(1)" | $(CC_COMPAT) $(VDSO_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
 
 # We cannot use the global flags to compile the vDSO files, the main reason
 # being that the 32-bit compiler may be older than the main (64-bit) compiler
@@ -25,22 +31,21 @@ cc32-ldoption = $(call try-run,\
 # arm64 one.
 # As a result we set our own flags here.
 
-# From top-level Makefile
-# NOSTDINC_FLAGS
-VDSO_CPPFLAGS := -nostdinc -isystem $(shell $(COMPATCC) -print-file-name=include)
+# KBUILD_CPPFLAGS and NOSTDINC_FLAGS from top-level Makefile
+VDSO_CPPFLAGS := -D__KERNEL__ -nostdinc -isystem $(shell $(CC_COMPAT) -print-file-name=include)
 VDSO_CPPFLAGS += $(LINUXINCLUDE)
-VDSO_CPPFLAGS += $(KBUILD_CPPFLAGS)
 
 # Common C and assembly flags
 # From top-level Makefile
 VDSO_CAFLAGS := $(VDSO_CPPFLAGS)
+ifneq ($(shell $(CC_COMPAT) --version 2>&1 | head -n 1 | grep clang),)
+VDSO_CAFLAGS += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
+endif
+
 VDSO_CAFLAGS += $(call cc32-option,-fno-PIE)
 ifdef CONFIG_DEBUG_INFO
 VDSO_CAFLAGS += -g
 endif
-ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(COMPATCC)), y)
-VDSO_CAFLAGS += -DCC_HAVE_ASM_GOTO
-endif
 
 # From arm Makefile
 VDSO_CAFLAGS += $(call cc32-option,-fno-dwarf2-cfi-asm)
@@ -55,6 +60,7 @@ endif
 VDSO_CAFLAGS += -fPIC -fno-builtin -fno-stack-protector
 VDSO_CAFLAGS += -DDISABLE_BRANCH_PROFILING
 
+
 # Try to compile for ARMv8. If the compiler is too old and doesn't support it,
 # fall back to v7. There is no easy way to check for what architecture the code
 # is being compiled, so define a macro specifying that (see arch/arm/Makefile).
@@ -91,6 +97,12 @@ VDSO_CFLAGS += -Wno-int-to-pointer-cast
 VDSO_AFLAGS := $(VDSO_CAFLAGS)
 VDSO_AFLAGS += -D__ASSEMBLY__
 
+# Check for binutils support for dmb ishld
+dmbinstr := $(call cc32-as-instr,dmb ishld,-DCONFIG_AS_DMB_ISHLD=1)
+
+VDSO_CFLAGS += $(dmbinstr)
+VDSO_AFLAGS += $(dmbinstr)
+
 VDSO_LDFLAGS := $(VDSO_CPPFLAGS)
 # From arm vDSO Makefile
 VDSO_LDFLAGS += -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1
@@ -159,14 +171,14 @@ quiet_cmd_vdsold_and_vdso_check = LD32    $@
       cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check)
 
 quiet_cmd_vdsold = LD32    $@
-      cmd_vdsold = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_LDFLAGS) \
+      cmd_vdsold = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_LDFLAGS) \
                    -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
 quiet_cmd_vdsocc = CC32    $@
-      cmd_vdsocc = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $<
+      cmd_vdsocc = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $<
 quiet_cmd_vdsocc_gettimeofday = CC32    $@
-      cmd_vdsocc_gettimeofday = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) $(VDSO_CFLAGS_gettimeofday_o) -c -o $@ $<
+      cmd_vdsocc_gettimeofday = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) $(VDSO_CFLAGS_gettimeofday_o) -c -o $@ $<
 quiet_cmd_vdsoas = AS32    $@
-      cmd_vdsoas = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_AFLAGS) -c -o $@ $<
+      cmd_vdsoas = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_AFLAGS) -c -o $@ $<
 
 quiet_cmd_vdsomunge = MUNGE   $@
       cmd_vdsomunge = $(obj)/$(munge) $< $@
index bd978ad..3d38150 100644 (file)
@@ -229,20 +229,6 @@ static void __hyp_text __hyp_vgic_restore_state(struct kvm_vcpu *vcpu)
        }
 }
 
-static bool __hyp_text __true_value(void)
-{
-       return true;
-}
-
-static bool __hyp_text __false_value(void)
-{
-       return false;
-}
-
-static hyp_alternate_select(__check_arm_834220,
-                           __false_value, __true_value,
-                           ARM64_WORKAROUND_834220);
-
 static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
 {
        u64 par, tmp;
@@ -298,7 +284,8 @@ static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
         * resolve the IPA using the AT instruction.
         */
        if (!(esr & ESR_ELx_S1PTW) &&
-           (__check_arm_834220()() || (esr & ESR_ELx_FSC_TYPE) == FSC_PERM)) {
+           (cpus_have_const_cap(ARM64_WORKAROUND_834220) ||
+            (esr & ESR_ELx_FSC_TYPE) == FSC_PERM)) {
                if (!__translate_far_to_hpfar(far, &hpfar))
                        return false;
        } else {
index c466060..eb0efc5 100644 (file)
@@ -67,10 +67,14 @@ static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm,
        isb();
 }
 
-static hyp_alternate_select(__tlb_switch_to_guest,
-                           __tlb_switch_to_guest_nvhe,
-                           __tlb_switch_to_guest_vhe,
-                           ARM64_HAS_VIRT_HOST_EXTN);
+static void __hyp_text __tlb_switch_to_guest(struct kvm *kvm,
+                                            struct tlb_inv_context *cxt)
+{
+       if (has_vhe())
+               __tlb_switch_to_guest_vhe(kvm, cxt);
+       else
+               __tlb_switch_to_guest_nvhe(kvm, cxt);
+}
 
 static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm,
                                                struct tlb_inv_context *cxt)
@@ -98,10 +102,14 @@ static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm,
        write_sysreg(0, vttbr_el2);
 }
 
-static hyp_alternate_select(__tlb_switch_to_host,
-                           __tlb_switch_to_host_nvhe,
-                           __tlb_switch_to_host_vhe,
-                           ARM64_HAS_VIRT_HOST_EXTN);
+static void __hyp_text __tlb_switch_to_host(struct kvm *kvm,
+                                           struct tlb_inv_context *cxt)
+{
+       if (has_vhe())
+               __tlb_switch_to_host_vhe(kvm, cxt);
+       else
+               __tlb_switch_to_host_nvhe(kvm, cxt);
+}
 
 void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
 {
@@ -111,7 +119,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
 
        /* Switch to requested VMID */
        kvm = kern_hyp_va(kvm);
-       __tlb_switch_to_guest()(kvm, &cxt);
+       __tlb_switch_to_guest(kvm, &cxt);
 
        /*
         * We could do so much better if we had the VA as well.
@@ -154,7 +162,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
        if (!has_vhe() && icache_is_vpipt())
                __flush_icache_all();
 
-       __tlb_switch_to_host()(kvm, &cxt);
+       __tlb_switch_to_host(kvm, &cxt);
 }
 
 void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
@@ -165,13 +173,13 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
 
        /* Switch to requested VMID */
        kvm = kern_hyp_va(kvm);
-       __tlb_switch_to_guest()(kvm, &cxt);
+       __tlb_switch_to_guest(kvm, &cxt);
 
        __tlbi(vmalls12e1is);
        dsb(ish);
        isb();
 
-       __tlb_switch_to_host()(kvm, &cxt);
+       __tlb_switch_to_host(kvm, &cxt);
 }
 
 void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
@@ -180,13 +188,13 @@ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
        struct tlb_inv_context cxt;
 
        /* Switch to requested VMID */
-       __tlb_switch_to_guest()(kvm, &cxt);
+       __tlb_switch_to_guest(kvm, &cxt);
 
        __tlbi(vmalle1);
        dsb(nsh);
        isb();
 
-       __tlb_switch_to_host()(kvm, &cxt);
+       __tlb_switch_to_host(kvm, &cxt);
 }
 
 void __hyp_text __kvm_flush_vm_context(void)
index 115d7a0..855f2a7 100644 (file)
@@ -113,6 +113,15 @@ static inline bool is_ttbr1_addr(unsigned long addr)
        return arch_kasan_reset_tag(addr) >= PAGE_OFFSET;
 }
 
+static inline unsigned long mm_to_pgd_phys(struct mm_struct *mm)
+{
+       /* Either init_pg_dir or swapper_pg_dir */
+       if (mm == &init_mm)
+               return __pa_symbol(mm->pgd);
+
+       return (unsigned long)virt_to_phys(mm->pgd);
+}
+
 /*
  * Dump out the page tables associated with 'addr' in the currently active mm.
  */
@@ -141,7 +150,7 @@ static void show_pte(unsigned long addr)
 
        pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n",
                 mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
-                vabits_actual, (unsigned long)virt_to_phys(mm->pgd));
+                vabits_actual, mm_to_pgd_phys(mm));
        pgdp = pgd_offset(mm, addr);
        pgd = READ_ONCE(*pgdp);
        pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
@@ -266,7 +275,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr,
         * If we got a different type of fault from the AT instruction,
         * treat the translation fault as spurious.
         */
-       dfsc = FIELD_PREP(SYS_PAR_EL1_FST, par);
+       dfsc = FIELD_GET(SYS_PAR_EL1_FST, par);
        return (dfsc & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT;
 }
 
index a4fc65f..b66215e 100644 (file)
@@ -1,4 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 xen-arm-y      += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o mm.o)
 obj-y          := xen-arm.o hypercall.o
-obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
index 63a9f33..5cfc9d3 100644 (file)
@@ -99,7 +99,7 @@
 
                        miscintc: interrupt-controller@18060010 {
                                compatible = "qca,ar7240-misc-intc";
-                               reg = <0x18060010 0x4>;
+                               reg = <0x18060010 0x8>;
 
                                interrupt-parent = <&cpuintc>;
                                interrupts = <6>;
index af44b35..b4328b3 100644 (file)
@@ -160,7 +160,6 @@ void __init prom_meminit(void)
 
 void __init prom_free_prom_memory(void)
 {
-       unsigned long addr;
        int i;
 
        if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
index 8772617..80112f2 100644 (file)
@@ -43,7 +43,7 @@
 
 /* O32 stack has to be 8-byte aligned. */
 static u64 o32_stk[4096];
-#define O32_STK          &o32_stk[sizeof(o32_stk)]
+#define O32_STK          (&o32_stk[ARRAY_SIZE(o32_stk)])
 
 #define __PROM_O32(fun, arg) fun arg __asm__(#fun); \
                                     __asm__(#fun " = call_o32")
index 79bf34e..f613687 100644 (file)
@@ -77,8 +77,8 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
 extern unsigned long __xchg_small(volatile void *ptr, unsigned long val,
                                  unsigned int size);
 
-static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
-                                  int size)
+static __always_inline
+unsigned long __xchg(volatile void *ptr, unsigned long x, int size)
 {
        switch (size) {
        case 1:
@@ -153,8 +153,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
 extern unsigned long __cmpxchg_small(volatile void *ptr, unsigned long old,
                                     unsigned long new, unsigned int size);
 
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-                                     unsigned long new, unsigned int size)
+static __always_inline
+unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+                       unsigned long new, unsigned int size)
 {
        switch (size) {
        case 1:
index cbdc14b..adab7b5 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/octeon/octeon-feature.h>
 
 #include <asm/octeon/cvmx-ipd-defs.h>
+#include <asm/octeon/cvmx-pip-defs.h>
 
 enum cvmx_ipd_mode {
    CVMX_IPD_OPC_MODE_STT = 0LL,          /* All blocks DRAM, not cached in L2 */
index 071053e..5d70bab 100644 (file)
@@ -52,6 +52,7 @@
 # endif
 #define __ARCH_WANT_SYS_FORK
 #define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_CLONE3
 
 /* whitelists for checksyscalls */
 #define __IGNORE_fadvise64_64
index a2aba4b..1ade1da 100644 (file)
@@ -6,5 +6,16 @@
 #define HWCAP_MIPS_R6          (1 << 0)
 #define HWCAP_MIPS_MSA         (1 << 1)
 #define HWCAP_MIPS_CRC32       (1 << 2)
+#define HWCAP_MIPS_MIPS16      (1 << 3)
+#define HWCAP_MIPS_MDMX     (1 << 4)
+#define HWCAP_MIPS_MIPS3D   (1 << 5)
+#define HWCAP_MIPS_SMARTMIPS (1 << 6)
+#define HWCAP_MIPS_DSP      (1 << 7)
+#define HWCAP_MIPS_DSP2     (1 << 8)
+#define HWCAP_MIPS_DSP3     (1 << 9)
+#define HWCAP_MIPS_MIPS16E2 (1 << 10)
+#define HWCAP_LOONGSON_MMI  (1 << 11)
+#define HWCAP_LOONGSON_EXT  (1 << 12)
+#define HWCAP_LOONGSON_EXT2 (1 << 13)
 
 #endif /* _UAPI_ASM_HWCAP_H */
index fa62cd1..6a7afe7 100644 (file)
@@ -24,7 +24,8 @@ static char r4kwar[] __initdata =
 static char daddiwar[] __initdata =
        "Enable CPU_DADDI_WORKAROUNDS to rectify.";
 
-static inline void align_mod(const int align, const int mod)
+static __always_inline __init
+void align_mod(const int align, const int mod)
 {
        asm volatile(
                ".set   push\n\t"
@@ -38,8 +39,9 @@ static inline void align_mod(const int align, const int mod)
                : "n"(align), "n"(mod));
 }
 
-static __always_inline void mult_sh_align_mod(long *v1, long *v2, long *w,
-                                             const int align, const int mod)
+static __always_inline __init
+void mult_sh_align_mod(long *v1, long *v2, long *w,
+                      const int align, const int mod)
 {
        unsigned long flags;
        int m1, m2;
@@ -113,7 +115,7 @@ static __always_inline void mult_sh_align_mod(long *v1, long *v2, long *w,
        *w = lw;
 }
 
-static inline void check_mult_sh(void)
+static __always_inline __init void check_mult_sh(void)
 {
        long v1[8], v2[8], w[8];
        int bug, fix, i;
@@ -176,7 +178,7 @@ asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
        exception_exit(prev_state);
 }
 
-static inline void check_daddi(void)
+static __init void check_daddi(void)
 {
        extern asmlinkage void handle_daddi_ov(void);
        unsigned long flags;
@@ -242,7 +244,7 @@ static inline void check_daddi(void)
 
 int daddiu_bug = IS_ENABLED(CONFIG_CPU_MIPSR6) ? 0 : -1;
 
-static inline void check_daddiu(void)
+static __init void check_daddiu(void)
 {
        long v, w, tmp;
 
index c2eb392..f521cbf 100644 (file)
@@ -2180,6 +2180,39 @@ void cpu_probe(void)
                elf_hwcap |= HWCAP_MIPS_MSA;
        }
 
+       if (cpu_has_mips16)
+               elf_hwcap |= HWCAP_MIPS_MIPS16;
+
+       if (cpu_has_mdmx)
+               elf_hwcap |= HWCAP_MIPS_MDMX;
+
+       if (cpu_has_mips3d)
+               elf_hwcap |= HWCAP_MIPS_MIPS3D;
+
+       if (cpu_has_smartmips)
+               elf_hwcap |= HWCAP_MIPS_SMARTMIPS;
+
+       if (cpu_has_dsp)
+               elf_hwcap |= HWCAP_MIPS_DSP;
+
+       if (cpu_has_dsp2)
+               elf_hwcap |= HWCAP_MIPS_DSP2;
+
+       if (cpu_has_dsp3)
+               elf_hwcap |= HWCAP_MIPS_DSP3;
+
+       if (cpu_has_mips16e2)
+               elf_hwcap |= HWCAP_MIPS_MIPS16E2;
+
+       if (cpu_has_loongson_mmi)
+               elf_hwcap |= HWCAP_LOONGSON_MMI;
+
+       if (cpu_has_loongson_ext)
+               elf_hwcap |= HWCAP_LOONGSON_EXT;
+
+       if (cpu_has_loongson_ext2)
+               elf_hwcap |= HWCAP_LOONGSON_EXT2;
+
        if (cpu_has_vz)
                cpu_probe_vz(c);
 
index b8249c2..5eec13b 100644 (file)
@@ -108,6 +108,9 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
                return;
        }
 
+       if (start < PHYS_OFFSET)
+               return;
+
        memblock_add(start, size);
        /* Reserve any memory except the ordinary RAM ranges. */
        switch (type) {
@@ -321,7 +324,7 @@ static void __init bootmem_init(void)
         * Reserve any memory between the start of RAM and PHYS_OFFSET
         */
        if (ramstart > PHYS_OFFSET)
-               memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);
+               memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
 
        if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
                pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
index b0e25e9..3f16f38 100644 (file)
@@ -80,6 +80,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
 
 save_static_function(sys_fork);
 save_static_function(sys_clone);
+save_static_function(sys_clone3);
 
 SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
 {
index c9c879e..e7c5ab3 100644 (file)
 432    n32     fsmount                         sys_fsmount
 433    n32     fspick                          sys_fspick
 434    n32     pidfd_open                      sys_pidfd_open
-# 435 reserved for clone3
+435    n32     clone3                          __sys_clone3
index bbce915..13cd665 100644 (file)
 432    n64     fsmount                         sys_fsmount
 433    n64     fspick                          sys_fspick
 434    n64     pidfd_open                      sys_pidfd_open
-# 435 reserved for clone3
+435    n64     clone3                          __sys_clone3
index 9653591..353539e 100644 (file)
 432    o32     fsmount                         sys_fsmount
 433    o32     fspick                          sys_fspick
 434    o32     pidfd_open                      sys_pidfd_open
-# 435 reserved for clone3
+435    o32     clone3                          __sys_clone3
index c1a4d4d..9f79908 100644 (file)
@@ -66,6 +66,10 @@ else
       $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
 endif
 
+# Some -march= flags enable MMI instructions, and GCC complains about that
+# support being enabled alongside -msoft-float. Thus explicitly disable MMI.
+cflags-y += $(call cc-option,-mno-loongson-mmi)
+
 #
 # Loongson Machines' Support
 #
index 4abb92e..4254ac4 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include <linux/fs.h>
 #include <linux/fcntl.h>
+#include <linux/memblock.h>
 #include <linux/mm.h>
 
 #include <asm/bootinfo.h>
@@ -64,24 +65,22 @@ void __init prom_init_memory(void)
                node_id = loongson_memmap->map[i].node_id;
                mem_type = loongson_memmap->map[i].mem_type;
 
-               if (node_id == 0) {
-                       switch (mem_type) {
-                       case SYSTEM_RAM_LOW:
-                               add_memory_region(loongson_memmap->map[i].mem_start,
-                                       (u64)loongson_memmap->map[i].mem_size << 20,
-                                       BOOT_MEM_RAM);
-                               break;
-                       case SYSTEM_RAM_HIGH:
-                               add_memory_region(loongson_memmap->map[i].mem_start,
-                                       (u64)loongson_memmap->map[i].mem_size << 20,
-                                       BOOT_MEM_RAM);
-                               break;
-                       case SYSTEM_RAM_RESERVED:
-                               add_memory_region(loongson_memmap->map[i].mem_start,
-                                       (u64)loongson_memmap->map[i].mem_size << 20,
-                                       BOOT_MEM_RESERVED);
-                               break;
-                       }
+               if (node_id != 0)
+                       continue;
+
+               switch (mem_type) {
+               case SYSTEM_RAM_LOW:
+                       memblock_add(loongson_memmap->map[i].mem_start,
+                               (u64)loongson_memmap->map[i].mem_size << 20);
+                       break;
+               case SYSTEM_RAM_HIGH:
+                       memblock_add(loongson_memmap->map[i].mem_start,
+                               (u64)loongson_memmap->map[i].mem_size << 20);
+                       break;
+               case SYSTEM_RAM_RESERVED:
+                       memblock_reserve(loongson_memmap->map[i].mem_start,
+                               (u64)loongson_memmap->map[i].mem_size << 20);
+                       break;
                }
        }
 }
index ffefc1c..98c3a7f 100644 (file)
@@ -110,7 +110,7 @@ static int __init serial_init(void)
 }
 module_init(serial_init);
 
-static void __init serial_exit(void)
+static void __exit serial_exit(void)
 {
        platform_device_unregister(&uart8250_device);
 }
index 414e97d..8f20d2c 100644 (file)
@@ -142,8 +142,6 @@ static void __init szmem(unsigned int node)
                                (u32)node_id, mem_type, mem_start, mem_size);
                        pr_info("       start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
                                start_pfn, end_pfn, num_physpages);
-                       add_memory_region((node_id << 44) + mem_start,
-                               (u64)mem_size << 20, BOOT_MEM_RAM);
                        memblock_add_node(PFN_PHYS(start_pfn),
                                PFN_PHYS(end_pfn - start_pfn), node);
                        break;
@@ -156,16 +154,12 @@ static void __init szmem(unsigned int node)
                                (u32)node_id, mem_type, mem_start, mem_size);
                        pr_info("       start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
                                start_pfn, end_pfn, num_physpages);
-                       add_memory_region((node_id << 44) + mem_start,
-                               (u64)mem_size << 20, BOOT_MEM_RAM);
                        memblock_add_node(PFN_PHYS(start_pfn),
                                PFN_PHYS(end_pfn - start_pfn), node);
                        break;
                case SYSTEM_RAM_RESERVED:
                        pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n",
                                (u32)node_id, mem_type, mem_start, mem_size);
-                       add_memory_region((node_id << 44) + mem_start,
-                               (u64)mem_size << 20, BOOT_MEM_RESERVED);
                        memblock_reserve(((node_id << 44) + mem_start),
                                mem_size << 20);
                        break;
@@ -191,8 +185,6 @@ static void __init node_mem_init(unsigned int node)
        NODE_DATA(node)->node_start_pfn = start_pfn;
        NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
 
-       free_bootmem_with_active_regions(node, end_pfn);
-
        if (node == 0) {
                /* kernel end address */
                unsigned long kernel_end_pfn = PFN_UP(__pa_symbol(&_end));
@@ -209,8 +201,6 @@ static void __init node_mem_init(unsigned int node)
                        memblock_reserve((node_addrspace_offset | 0xfe000000),
                                         32 << 20);
        }
-
-       sparse_memory_present_with_active_regions(node);
 }
 
 static __init void prom_meminit(void)
@@ -227,6 +217,7 @@ static __init void prom_meminit(void)
                        cpumask_clear(&__node_data[(node)]->cpumask);
                }
        }
+       memblocks_present();
        max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
 
        for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) {
index dfb5279..800a21b 100644 (file)
@@ -61,6 +61,7 @@ int init_debug = 1;
 /* memory blocks */
 struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
 
+#define MAX_PROM_MEM 5
 static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
 static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
 static unsigned int nr_prom_mem __initdata;
@@ -358,7 +359,7 @@ void __init prom_meminit(void)
                p++;
 
                if (type == BOOT_MEM_ROM_DATA) {
-                       if (nr_prom_mem >= 5) {
+                       if (nr_prom_mem >= MAX_PROM_MEM) {
                                pr_err("Too many ROM DATA regions");
                                continue;
                        }
@@ -377,7 +378,6 @@ void __init prom_free_prom_memory(void)
        char    *ptr;
        int     len = 0;
        int     i;
-       unsigned long addr;
 
        /*
         * preserve environment variables and command line from pmon/bbload
index 69cfa0a..996a934 100644 (file)
@@ -15,6 +15,7 @@ ccflags-vdso := \
        $(filter -mmicromips,$(KBUILD_CFLAGS)) \
        $(filter -march=%,$(KBUILD_CFLAGS)) \
        $(filter -m%-float,$(KBUILD_CFLAGS)) \
+       $(filter -mno-loongson-%,$(KBUILD_CFLAGS)) \
        -D__VDSO__
 
 ifdef CONFIG_CC_IS_CLANG
@@ -59,7 +60,7 @@ CFLAGS_REMOVE_vgettimeofday.o = -pg
 ifndef CONFIG_CPU_MIPSR6
   ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
     $(warning MIPS VDSO requires binutils >= 2.25)
-    obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
+    obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y))
     ccflags-vdso += -DDISABLE_MIPS_VDSO
   endif
 endif
diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
deleted file mode 100644 (file)
index e8243c7..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2015 Imagination Technologies
- * Author: Alex Smith <alex.smith@imgtec.com>
- */
-
-#include "vdso.h"
-
-#include <linux/compiler.h>
-#include <linux/time.h>
-
-#include <asm/clocksource.h>
-#include <asm/io.h>
-#include <asm/unistd.h>
-#include <asm/vdso.h>
-
-#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
-
-static __always_inline long gettimeofday_fallback(struct timeval *_tv,
-                                         struct timezone *_tz)
-{
-       register struct timezone *tz asm("a1") = _tz;
-       register struct timeval *tv asm("a0") = _tv;
-       register long ret asm("v0");
-       register long nr asm("v0") = __NR_gettimeofday;
-       register long error asm("a3");
-
-       asm volatile(
-       "       syscall\n"
-       : "=r" (ret), "=r" (error)
-       : "r" (tv), "r" (tz), "r" (nr)
-       : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
-         "$14", "$15", "$24", "$25", "hi", "lo", "memory");
-
-       return error ? -ret : ret;
-}
-
-#endif
-
-static __always_inline long clock_gettime_fallback(clockid_t _clkid,
-                                          struct timespec *_ts)
-{
-       register struct timespec *ts asm("a1") = _ts;
-       register clockid_t clkid asm("a0") = _clkid;
-       register long ret asm("v0");
-       register long nr asm("v0") = __NR_clock_gettime;
-       register long error asm("a3");
-
-       asm volatile(
-       "       syscall\n"
-       : "=r" (ret), "=r" (error)
-       : "r" (clkid), "r" (ts), "r" (nr)
-       : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
-         "$14", "$15", "$24", "$25", "hi", "lo", "memory");
-
-       return error ? -ret : ret;
-}
-
-static __always_inline int do_realtime_coarse(struct timespec *ts,
-                                             const union mips_vdso_data *data)
-{
-       u32 start_seq;
-
-       do {
-               start_seq = vdso_data_read_begin(data);
-
-               ts->tv_sec = data->xtime_sec;
-               ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
-       } while (vdso_data_read_retry(data, start_seq));
-
-       return 0;
-}
-
-static __always_inline int do_monotonic_coarse(struct timespec *ts,
-                                              const union mips_vdso_data *data)
-{
-       u32 start_seq;
-       u64 to_mono_sec;
-       u64 to_mono_nsec;
-
-       do {
-               start_seq = vdso_data_read_begin(data);
-
-               ts->tv_sec = data->xtime_sec;
-               ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
-
-               to_mono_sec = data->wall_to_mono_sec;
-               to_mono_nsec = data->wall_to_mono_nsec;
-       } while (vdso_data_read_retry(data, start_seq));
-
-       ts->tv_sec += to_mono_sec;
-       timespec_add_ns(ts, to_mono_nsec);
-
-       return 0;
-}
-
-#ifdef CONFIG_CSRC_R4K
-
-static __always_inline u64 read_r4k_count(void)
-{
-       unsigned int count;
-
-       __asm__ __volatile__(
-       "       .set push\n"
-       "       .set mips32r2\n"
-       "       rdhwr   %0, $2\n"
-       "       .set pop\n"
-       : "=r" (count));
-
-       return count;
-}
-
-#endif
-
-#ifdef CONFIG_CLKSRC_MIPS_GIC
-
-static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
-{
-       void __iomem *gic = get_gic(data);
-       u32 hi, hi2, lo;
-
-       do {
-               hi = __raw_readl(gic + sizeof(lo));
-               lo = __raw_readl(gic);
-               hi2 = __raw_readl(gic + sizeof(lo));
-       } while (hi2 != hi);
-
-       return (((u64)hi) << 32) + lo;
-}
-
-#endif
-
-static __always_inline u64 get_ns(const union mips_vdso_data *data)
-{
-       u64 cycle_now, delta, nsec;
-
-       switch (data->clock_mode) {
-#ifdef CONFIG_CSRC_R4K
-       case VDSO_CLOCK_R4K:
-               cycle_now = read_r4k_count();
-               break;
-#endif
-#ifdef CONFIG_CLKSRC_MIPS_GIC
-       case VDSO_CLOCK_GIC:
-               cycle_now = read_gic_count(data);
-               break;
-#endif
-       default:
-               return 0;
-       }
-
-       delta = (cycle_now - data->cs_cycle_last) & data->cs_mask;
-
-       nsec = (delta * data->cs_mult) + data->xtime_nsec;
-       nsec >>= data->cs_shift;
-
-       return nsec;
-}
-
-static __always_inline int do_realtime(struct timespec *ts,
-                                      const union mips_vdso_data *data)
-{
-       u32 start_seq;
-       u64 ns;
-
-       do {
-               start_seq = vdso_data_read_begin(data);
-
-               if (data->clock_mode == VDSO_CLOCK_NONE)
-                       return -ENOSYS;
-
-               ts->tv_sec = data->xtime_sec;
-               ns = get_ns(data);
-       } while (vdso_data_read_retry(data, start_seq));
-
-       ts->tv_nsec = 0;
-       timespec_add_ns(ts, ns);
-
-       return 0;
-}
-
-static __always_inline int do_monotonic(struct timespec *ts,
-                                       const union mips_vdso_data *data)
-{
-       u32 start_seq;
-       u64 ns;
-       u64 to_mono_sec;
-       u64 to_mono_nsec;
-
-       do {
-               start_seq = vdso_data_read_begin(data);
-
-               if (data->clock_mode == VDSO_CLOCK_NONE)
-                       return -ENOSYS;
-
-               ts->tv_sec = data->xtime_sec;
-               ns = get_ns(data);
-
-               to_mono_sec = data->wall_to_mono_sec;
-               to_mono_nsec = data->wall_to_mono_nsec;
-       } while (vdso_data_read_retry(data, start_seq));
-
-       ts->tv_sec += to_mono_sec;
-       ts->tv_nsec = 0;
-       timespec_add_ns(ts, ns + to_mono_nsec);
-
-       return 0;
-}
-
-#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
-
-/*
- * This is behind the ifdef so that we don't provide the symbol when there's no
- * possibility of there being a usable clocksource, because there's nothing we
- * can do without it. When libc fails the symbol lookup it should fall back on
- * the standard syscall path.
- */
-int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
-       const union mips_vdso_data *data = get_vdso_data();
-       struct timespec ts;
-       int ret;
-
-       ret = do_realtime(&ts, data);
-       if (ret)
-               return gettimeofday_fallback(tv, tz);
-
-       if (tv) {
-               tv->tv_sec = ts.tv_sec;
-               tv->tv_usec = ts.tv_nsec / 1000;
-       }
-
-       if (tz) {
-               tz->tz_minuteswest = data->tz_minuteswest;
-               tz->tz_dsttime = data->tz_dsttime;
-       }
-
-       return 0;
-}
-
-#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */
-
-int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
-{
-       const union mips_vdso_data *data = get_vdso_data();
-       int ret = -1;
-
-       switch (clkid) {
-       case CLOCK_REALTIME_COARSE:
-               ret = do_realtime_coarse(ts, data);
-               break;
-       case CLOCK_MONOTONIC_COARSE:
-               ret = do_monotonic_coarse(ts, data);
-               break;
-       case CLOCK_REALTIME:
-               ret = do_realtime(ts, data);
-               break;
-       case CLOCK_MONOTONIC:
-               ret = do_monotonic(ts, data);
-               break;
-       default:
-               break;
-       }
-
-       if (ret)
-               ret = clock_gettime_fallback(clkid, ts);
-
-       return ret;
-}
index 6841bd5..dfbd7f2 100644 (file)
@@ -50,7 +50,7 @@ endif
 
 BOOTAFLAGS     := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc
 
-BOOTARFLAGS    := -cr$(KBUILD_ARFLAGS)
+BOOTARFLAGS    := -crD
 
 ifdef CONFIG_CC_IS_CLANG
 BOOTCFLAGS += $(CLANG_FLAGS)
index 4ce795d..ca8db19 100644 (file)
@@ -35,6 +35,10 @@ static inline void radix__flush_all_lpid(unsigned int lpid)
 {
        WARN_ON(1);
 }
+static inline void radix__flush_all_lpid_guest(unsigned int lpid)
+{
+       WARN_ON(1);
+}
 #endif
 
 extern void radix__flush_hugetlb_tlb_range(struct vm_area_struct *vma,
index d7fcdfa..ec2547c 100644 (file)
@@ -36,8 +36,8 @@
 #include "book3s.h"
 #include "trace.h"
 
-#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
-#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
+#define VM_STAT(x, ...) offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__
+#define VCPU_STAT(x, ...) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__
 
 /* #define EXIT_DEBUG */
 
@@ -69,8 +69,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "pthru_all",       VCPU_STAT(pthru_all) },
        { "pthru_host",      VCPU_STAT(pthru_host) },
        { "pthru_bad_aff",   VCPU_STAT(pthru_bad_aff) },
-       { "largepages_2M",    VM_STAT(num_2M_pages) },
-       { "largepages_1G",    VM_STAT(num_1G_pages) },
+       { "largepages_2M",    VM_STAT(num_2M_pages, .mode = 0444) },
+       { "largepages_1G",    VM_STAT(num_1G_pages, .mode = 0444) },
        { NULL }
 };
 
index 74a9cfe..faebcbb 100644 (file)
@@ -1921,6 +1921,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
        mtspr   SPRN_PCR, r6
 18:
        /* Signal secondary CPUs to continue */
+       li      r0, 0
        stb     r0,VCORE_IN_GUEST(r5)
 19:    lis     r8,0x7fff               /* MAX_INT@h */
        mtspr   SPRN_HDEC,r8
index 1d93e55..2dd452a 100644 (file)
@@ -761,6 +761,7 @@ static int spufs_init_fs_context(struct fs_context *fc)
        ctx->gid = current_gid();
        ctx->mode = 0755;
 
+       fc->fs_private = ctx;
        fc->s_fs_info = sbi;
        fc->ops = &spufs_context_ops;
        return 0;
index b533592..f87a5c6 100644 (file)
@@ -1419,6 +1419,9 @@ void __init pseries_lpar_read_hblkrm_characteristics(void)
        unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH];
        int call_status, len, idx, bpsize;
 
+       if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
+               return;
+
        spin_lock(&rtas_data_buf_lock);
        memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
        call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
index 5a02b7d..9c992a8 100644 (file)
@@ -22,6 +22,7 @@
 
 #define REG_L          __REG_SEL(ld, lw)
 #define REG_S          __REG_SEL(sd, sw)
+#define REG_SC         __REG_SEL(sc.d, sc.w)
 #define SZREG          __REG_SEL(8, 4)
 #define LGREG          __REG_SEL(3, 2)
 
index da7aa88..8ca4798 100644 (file)
@@ -98,7 +98,26 @@ _save_context:
  */
        .macro RESTORE_ALL
        REG_L a0, PT_SSTATUS(sp)
-       REG_L a2, PT_SEPC(sp)
+       /*
+        * The current load reservation is effectively part of the processor's
+        * state, in the sense that load reservations cannot be shared between
+        * different hart contexts.  We can't actually save and restore a load
+        * reservation, so instead here we clear any existing reservation --
+        * it's always legal for implementations to clear load reservations at
+        * any point (as long as the forward progress guarantee is kept, but
+        * we'll ignore that here).
+        *
+        * Dangling load reservations can be the result of taking a trap in the
+        * middle of an LR/SC sequence, but can also be the result of a taken
+        * forward branch around an SC -- which is how we implement CAS.  As a
+        * result we need to clear reservations between the last CAS and the
+        * jump back to the new context.  While it is unlikely the store
+        * completes, implementations are allowed to expand reservations to be
+        * arbitrarily large.
+        */
+       REG_L  a2, PT_SEPC(sp)
+       REG_SC x0, a2, PT_SEPC(sp)
+
        csrw CSR_SSTATUS, a0
        csrw CSR_SEPC, a2
 
@@ -254,12 +273,11 @@ restore_all:
 resume_kernel:
        REG_L s0, TASK_TI_PREEMPT_COUNT(tp)
        bnez s0, restore_all
-need_resched:
        REG_L s0, TASK_TI_FLAGS(tp)
        andi s0, s0, _TIF_NEED_RESCHED
        beqz s0, restore_all
        call preempt_schedule_irq
-       j need_resched
+       j restore_all
 #endif
 
 work_pending:
index 424eb72..93742df 100644 (file)
@@ -124,24 +124,24 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
 
 asmlinkage void do_trap_break(struct pt_regs *regs)
 {
-#ifdef CONFIG_GENERIC_BUG
        if (!user_mode(regs)) {
                enum bug_trap_type type;
 
                type = report_bug(regs->sepc, regs);
                switch (type) {
-               case BUG_TRAP_TYPE_NONE:
-                       break;
+#ifdef CONFIG_GENERIC_BUG
                case BUG_TRAP_TYPE_WARN:
                        regs->sepc += get_break_insn_length(regs->sepc);
-                       break;
+                       return;
                case BUG_TRAP_TYPE_BUG:
+#endif /* CONFIG_GENERIC_BUG */
+               default:
                        die(regs, "Kernel BUG");
                }
+       } else {
+               force_sig_fault(SIGTRAP, TRAP_BRKPT,
+                               (void __user *)(regs->sepc));
        }
-#endif /* CONFIG_GENERIC_BUG */
-
-       force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)(regs->sepc));
 }
 
 #ifdef CONFIG_GENERIC_BUG
index f0ba713..83f7d12 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/swap.h>
 #include <linux/sizes.h>
 #include <linux/of_fdt.h>
+#include <linux/libfdt.h>
 
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
@@ -82,6 +83,8 @@ disable:
 }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
+static phys_addr_t dtb_early_pa __initdata;
+
 void __init setup_bootmem(void)
 {
        struct memblock_region *reg;
@@ -117,7 +120,12 @@ void __init setup_bootmem(void)
        setup_initrd();
 #endif /* CONFIG_BLK_DEV_INITRD */
 
-       early_init_fdt_reserve_self();
+       /*
+        * Avoid using early_init_fdt_reserve_self() since __pa() does
+        * not work for DTB pointers that are fixmap addresses
+        */
+       memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
+
        early_init_fdt_scan_reserved_mem();
        memblock_allow_resize();
        memblock_dump_all();
@@ -393,6 +401,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 
        /* Save pointer to DTB for early FDT parsing */
        dtb_early_va = (void *)fix_to_virt(FIX_FDT) + (dtb_pa & ~PAGE_MASK);
+       /* Save physical address for memblock reservation */
+       dtb_early_pa = dtb_pa;
 }
 
 static void __init setup_vm_final(void)
index 347f487..38d6403 100644 (file)
@@ -44,6 +44,7 @@ CONFIG_NR_CPUS=512
 CONFIG_NUMA=y
 CONFIG_HZ_100=y
 CONFIG_KEXEC_FILE=y
+CONFIG_KEXEC_SIG=y
 CONFIG_EXPOLINE=y
 CONFIG_EXPOLINE_AUTO=y
 CONFIG_CHSC_SCH=y
@@ -69,12 +70,13 @@ 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_UNUSED_SYMBOLS=y
 CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_BLK_DEV_THROTTLING=y
 CONFIG_BLK_WBT=y
 CONFIG_BLK_CGROUP_IOLATENCY=y
+CONFIG_BLK_CGROUP_IOCOST=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_BSD_DISKLABEL=y
@@ -370,6 +372,7 @@ CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
+# CONFIG_NET_DROP_MONITOR is not set
 CONFIG_PCI=y
 CONFIG_PCI_DEBUG=y
 CONFIG_HOTPLUG_PCI=y
@@ -424,6 +427,7 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_THIN_PROVISIONING=m
 CONFIG_DM_WRITECACHE=m
+CONFIG_DM_CLONE=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_LOG_USERSPACE=m
 CONFIG_DM_RAID=m
@@ -435,6 +439,7 @@ CONFIG_DM_DELAY=m
 CONFIG_DM_UEVENT=y
 CONFIG_DM_FLAKEY=m
 CONFIG_DM_VERITY=m
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
 CONFIG_DM_SWITCH=m
 CONFIG_NETDEVICES=y
 CONFIG_BONDING=m
@@ -489,6 +494,7 @@ CONFIG_MLX5_CORE_EN=y
 # CONFIG_NET_VENDOR_NVIDIA is not set
 # CONFIG_NET_VENDOR_OKI is not set
 # CONFIG_NET_VENDOR_PACKET_ENGINES is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
 # CONFIG_NET_VENDOR_QLOGIC is not set
 # CONFIG_NET_VENDOR_QUALCOMM is not set
 # CONFIG_NET_VENDOR_RDC is not set
@@ -538,15 +544,16 @@ CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_WATCHDOG=m
 CONFIG_DIAG288_WATCHDOG=m
-CONFIG_DRM=y
-CONFIG_DRM_VIRTIO_GPU=y
+CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=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_SYNC_FILE=y
 CONFIG_VFIO=m
 CONFIG_VFIO_PCI=m
 CONFIG_VFIO_MDEV=m
@@ -580,6 +587,8 @@ CONFIG_NILFS2_FS=m
 CONFIG_FS_DAX=y
 CONFIG_EXPORTFS_BLOCK_OPS=y
 CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_VERITY=y
+CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
 CONFIG_FANOTIFY=y
 CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
@@ -589,6 +598,7 @@ CONFIG_QFMT_V2=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=m
+CONFIG_VIRTIO_FS=m
 CONFIG_OVERLAY_FS=m
 CONFIG_FSCACHE=m
 CONFIG_CACHEFILES=m
@@ -648,12 +658,15 @@ CONFIG_FORTIFY_SOURCE=y
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
 CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_LOCKDOWN_LSM=y
+CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=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_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
 CONFIG_CRYPTO_USER=m
 # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
 CONFIG_CRYPTO_PCRYPT=m
@@ -664,10 +677,6 @@ CONFIG_CRYPTO_ECDH=m
 CONFIG_CRYPTO_ECRDSA=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_AEGIS128=m
-CONFIG_CRYPTO_AEGIS128L=m
-CONFIG_CRYPTO_AEGIS256=m
-CONFIG_CRYPTO_MORUS640=m
-CONFIG_CRYPTO_MORUS1280=m
 CONFIG_CRYPTO_CFB=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
@@ -739,7 +748,6 @@ CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_GDB_SCRIPTS=y
 CONFIG_FRAME_WARN=1024
-CONFIG_UNUSED_SYMBOLS=y
 CONFIG_HEADERS_INSTALL=y
 CONFIG_HEADERS_CHECK=y
 CONFIG_DEBUG_SECTION_MISMATCH=y
index 8514b8b..25f7998 100644 (file)
@@ -44,6 +44,7 @@ CONFIG_NUMA=y
 # CONFIG_NUMA_EMU is not set
 CONFIG_HZ_100=y
 CONFIG_KEXEC_FILE=y
+CONFIG_KEXEC_SIG=y
 CONFIG_EXPOLINE=y
 CONFIG_EXPOLINE_AUTO=y
 CONFIG_CHSC_SCH=y
@@ -66,11 +67,12 @@ 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_UNUSED_SYMBOLS=y
 CONFIG_BLK_DEV_THROTTLING=y
 CONFIG_BLK_WBT=y
 CONFIG_BLK_CGROUP_IOLATENCY=y
+CONFIG_BLK_CGROUP_IOCOST=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_BSD_DISKLABEL=y
@@ -363,6 +365,7 @@ CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
+# CONFIG_NET_DROP_MONITOR is not set
 CONFIG_PCI=y
 CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_S390=y
@@ -418,6 +421,7 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_THIN_PROVISIONING=m
 CONFIG_DM_WRITECACHE=m
+CONFIG_DM_CLONE=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_LOG_USERSPACE=m
 CONFIG_DM_RAID=m
@@ -429,6 +433,7 @@ CONFIG_DM_DELAY=m
 CONFIG_DM_UEVENT=y
 CONFIG_DM_FLAKEY=m
 CONFIG_DM_VERITY=m
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
 CONFIG_DM_SWITCH=m
 CONFIG_DM_INTEGRITY=m
 CONFIG_NETDEVICES=y
@@ -484,6 +489,7 @@ CONFIG_MLX5_CORE_EN=y
 # CONFIG_NET_VENDOR_NVIDIA is not set
 # CONFIG_NET_VENDOR_OKI is not set
 # CONFIG_NET_VENDOR_PACKET_ENGINES is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
 # CONFIG_NET_VENDOR_QLOGIC is not set
 # CONFIG_NET_VENDOR_QUALCOMM is not set
 # CONFIG_NET_VENDOR_RDC is not set
@@ -533,16 +539,16 @@ CONFIG_WATCHDOG_CORE=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_WATCHDOG=m
 CONFIG_DIAG288_WATCHDOG=m
-CONFIG_DRM=y
-CONFIG_DRM_VIRTIO_GPU=y
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=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_SYNC_FILE=y
 CONFIG_VFIO=m
 CONFIG_VFIO_PCI=m
 CONFIG_VFIO_MDEV=m
@@ -573,6 +579,8 @@ CONFIG_NILFS2_FS=m
 CONFIG_FS_DAX=y
 CONFIG_EXPORTFS_BLOCK_OPS=y
 CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_VERITY=y
+CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
 CONFIG_FANOTIFY=y
 CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
@@ -581,6 +589,7 @@ CONFIG_QFMT_V2=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=m
+CONFIG_VIRTIO_FS=m
 CONFIG_OVERLAY_FS=m
 CONFIG_FSCACHE=m
 CONFIG_CACHEFILES=m
@@ -639,12 +648,15 @@ CONFIG_SECURITY_NETWORK=y
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
 CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_LOCKDOWN_LSM=y
+CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=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_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
 CONFIG_CRYPTO_FIPS=y
 CONFIG_CRYPTO_USER=m
 # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
@@ -656,10 +668,6 @@ CONFIG_CRYPTO_ECDH=m
 CONFIG_CRYPTO_ECRDSA=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_AEGIS128=m
-CONFIG_CRYPTO_AEGIS128L=m
-CONFIG_CRYPTO_AEGIS256=m
-CONFIG_CRYPTO_MORUS640=m
-CONFIG_CRYPTO_MORUS1280=m
 CONFIG_CRYPTO_CFB=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_OFB=m
@@ -727,7 +735,6 @@ CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_GDB_SCRIPTS=y
 CONFIG_FRAME_WARN=1024
-CONFIG_UNUSED_SYMBOLS=y
 CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_MEMORY_INIT=y
index be09a20..20c51e5 100644 (file)
@@ -61,7 +61,7 @@ CONFIG_RAW_DRIVER=y
 CONFIG_CONFIGFS_FS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
-# CONFIG_DIMLIB is not set
+CONFIG_LSM="yama,loadpin,safesetid,integrity"
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
index d3f0952..61467b9 100644 (file)
@@ -41,7 +41,7 @@ __ATOMIC_OPS(__atomic64_xor, long, "laxg")
 #undef __ATOMIC_OP
 
 #define __ATOMIC_CONST_OP(op_name, op_type, op_string, op_barrier)     \
-static inline void op_name(op_type val, op_type *ptr)                  \
+static __always_inline void op_name(op_type val, op_type *ptr)         \
 {                                                                      \
        asm volatile(                                                   \
                op_string "     %[ptr],%[val]\n"                        \
index b8833ac..eb7eed4 100644 (file)
@@ -56,7 +56,7 @@ __bitops_byte(unsigned long nr, volatile unsigned long *ptr)
        return ((unsigned char *)ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
 }
 
-static inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
+static __always_inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
 {
        unsigned long *addr = __bitops_word(nr, ptr);
        unsigned long mask;
@@ -77,7 +77,7 @@ static inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
        __atomic64_or(mask, (long *)addr);
 }
 
-static inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
+static __always_inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
 {
        unsigned long *addr = __bitops_word(nr, ptr);
        unsigned long mask;
@@ -98,8 +98,8 @@ static inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
        __atomic64_and(mask, (long *)addr);
 }
 
-static inline void arch_change_bit(unsigned long nr,
-                                  volatile unsigned long *ptr)
+static __always_inline void arch_change_bit(unsigned long nr,
+                                           volatile unsigned long *ptr)
 {
        unsigned long *addr = __bitops_word(nr, ptr);
        unsigned long mask;
index a092f63..c0f3bfe 100644 (file)
@@ -171,7 +171,7 @@ typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
  *
  * Returns 1 if @func is available for @opcode, 0 otherwise
  */
-static inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
+static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
 {
        register unsigned long r0 asm("0") = 0; /* query function */
        register unsigned long r1 asm("1") = (unsigned long) mask;
index ceeb552..819803a 100644 (file)
@@ -28,6 +28,8 @@ asm(".include \"asm/cpu_mf-insn.h\"\n");
                                 CPU_MF_INT_SF_PRA|CPU_MF_INT_SF_SACA|  \
                                 CPU_MF_INT_SF_LSDA)
 
+#define CPU_MF_SF_RIBM_NOTAV   0x1             /* Sampling unavailable */
+
 /* CPU measurement facility support */
 static inline int cpum_cf_avail(void)
 {
@@ -69,7 +71,8 @@ struct hws_qsi_info_block {       /* Bit(s) */
        unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/
        unsigned long tear;         /* 24-31: TEAR contents              */
        unsigned long dear;         /* 32-39: DEAR contents              */
-       unsigned int rsvrd0;        /* 40-43: reserved                   */
+       unsigned int rsvrd0:24;     /* 40-42: reserved                   */
+       unsigned int ribm:8;        /* 43: Reserved by IBM               */
        unsigned int cpu_speed;     /* 44-47: CPU speed                  */
        unsigned long long rsvrd1;  /* 48-55: reserved                   */
        unsigned long long rsvrd2;  /* 56-63: reserved                   */
@@ -220,7 +223,8 @@ enum stcctm_ctr_set {
        MT_DIAG = 5,
        MT_DIAG_CLEARING = 9,   /* clears loss-of-MT-ctr-data alert */
 };
-static inline int stcctm(enum stcctm_ctr_set set, u64 range, u64 *dest)
+
+static __always_inline int stcctm(enum stcctm_ctr_set set, u64 range, u64 *dest)
 {
        int cc;
 
index bb59dd9..de8f0bf 100644 (file)
@@ -12,8 +12,6 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-
-#define is_hugepage_only_range(mm, addr, len)  0
 #define hugetlb_free_pgd_range                 free_pgd_range
 #define hugepages_supported()                  (MACHINE_HAS_EDAT1)
 
@@ -23,6 +21,13 @@ pte_t huge_ptep_get(pte_t *ptep);
 pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
                              unsigned long addr, pte_t *ptep);
 
+static inline bool is_hugepage_only_range(struct mm_struct *mm,
+                                         unsigned long addr,
+                                         unsigned long len)
+{
+       return false;
+}
+
 /*
  * If the arch doesn't supply something else, assume that hugepage
  * size aligned regions are ok without further preparation.
index e548ec1..39f747d 100644 (file)
@@ -20,7 +20,7 @@
  * We use a brcl 0,2 instruction for jump labels at compile time so it
  * can be easily distinguished from a hotpatch generated instruction.
  */
-static inline bool arch_static_branch(struct static_key *key, bool branch)
+static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
 {
        asm_volatile_goto("0:   brcl    0,"__stringify(JUMP_LABEL_NOP_OFFSET)"\n"
                          ".pushsection __jump_table,\"aw\"\n"
@@ -34,7 +34,7 @@ label:
        return true;
 }
 
-static inline bool arch_static_branch_jump(struct static_key *key, bool branch)
+static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
 {
        asm_volatile_goto("0:   brcl 15,%l[label]\n"
                          ".pushsection __jump_table,\"aw\"\n"
index 36c578c..5ff98d7 100644 (file)
@@ -997,9 +997,9 @@ static inline pte_t pte_mkhuge(pte_t pte)
 #define IPTE_NODAT     0x400
 #define IPTE_GUEST_ASCE        0x800
 
-static inline void __ptep_ipte(unsigned long address, pte_t *ptep,
-                              unsigned long opt, unsigned long asce,
-                              int local)
+static __always_inline void __ptep_ipte(unsigned long address, pte_t *ptep,
+                                       unsigned long opt, unsigned long asce,
+                                       int local)
 {
        unsigned long pto = (unsigned long) ptep;
 
@@ -1020,8 +1020,8 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep,
                : [r1] "a" (pto), [m4] "i" (local) : "memory");
 }
 
-static inline void __ptep_ipte_range(unsigned long address, int nr,
-                                    pte_t *ptep, int local)
+static __always_inline void __ptep_ipte_range(unsigned long address, int nr,
+                                             pte_t *ptep, int local)
 {
        unsigned long pto = (unsigned long) ptep;
 
@@ -1269,7 +1269,8 @@ static inline pte_t *pte_offset(pmd_t *pmd, unsigned long address)
 
 #define pte_offset_kernel(pmd, address) pte_offset(pmd, address)
 #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
-#define pte_unmap(pte) do { } while (0)
+
+static inline void pte_unmap(pte_t *pte) { }
 
 static inline bool gup_fast_permitted(unsigned long start, unsigned long end)
 {
@@ -1435,9 +1436,9 @@ static inline void __pmdp_csp(pmd_t *pmdp)
 #define IDTE_NODAT     0x1000
 #define IDTE_GUEST_ASCE        0x2000
 
-static inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp,
-                              unsigned long opt, unsigned long asce,
-                              int local)
+static __always_inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp,
+                                       unsigned long opt, unsigned long asce,
+                                       int local)
 {
        unsigned long sto;
 
@@ -1461,9 +1462,9 @@ static inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp,
        }
 }
 
-static inline void __pudp_idte(unsigned long addr, pud_t *pudp,
-                              unsigned long opt, unsigned long asce,
-                              int local)
+static __always_inline void __pudp_idte(unsigned long addr, pud_t *pudp,
+                                       unsigned long opt, unsigned long asce,
+                                       int local)
 {
        unsigned long r3o;
 
index 78e8a88..e3f238e 100644 (file)
@@ -111,7 +111,7 @@ struct qib {
        /* private: */
        u8 res[88];
        /* public: */
-       u8 parm[QDIO_MAX_BUFFERS_PER_Q];
+       u8 parm[128];
 } __attribute__ ((packed, aligned(256)));
 
 /**
index bd2fd9a..a470f1f 100644 (file)
@@ -83,7 +83,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n);
        __rc;                                                   \
 })
 
-static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
+static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
 {
        unsigned long spec = 0x010000UL;
        int rc;
@@ -113,7 +113,7 @@ static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
        return rc;
 }
 
-static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
+static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
 {
        unsigned long spec = 0x01UL;
        int rc;
index 5f1fd15..2654e34 100644 (file)
@@ -390,7 +390,7 @@ static size_t cf_diag_getctrset(struct cf_ctrset_entry *ctrdata, int ctrset,
 
        debug_sprintf_event(cf_diag_dbg, 6,
                            "%s ctrset %d ctrset_size %zu cfvn %d csvn %d"
-                           " need %zd rc:%d\n",
+                           " need %zd rc %d\n",
                            __func__, ctrset, ctrset_size, cpuhw->info.cfvn,
                            cpuhw->info.csvn, need, rc);
        return need;
@@ -567,7 +567,7 @@ static int cf_diag_add(struct perf_event *event, int flags)
        int err = 0;
 
        debug_sprintf_event(cf_diag_dbg, 5,
-                           "%s event %p cpu %d flags %#x cpuhw:%p\n",
+                           "%s event %p cpu %d flags %#x cpuhw %p\n",
                            __func__, event, event->cpu, flags, cpuhw);
 
        if (cpuhw->flags & PMU_F_IN_USE) {
index 544a02e..3d8b12a 100644 (file)
@@ -803,6 +803,12 @@ static int __hw_perf_event_init(struct perf_event *event)
                goto out;
        }
 
+       if (si.ribm & CPU_MF_SF_RIBM_NOTAV) {
+               pr_warn("CPU Measurement Facility sampling is temporarily not available\n");
+               err = -EBUSY;
+               goto out;
+       }
+
        /* Always enable basic sampling */
        SAMPL_FLAGS(hwc) = PERF_CPUM_SF_BASIC_MODE;
 
@@ -895,7 +901,7 @@ static int cpumsf_pmu_event_init(struct perf_event *event)
 
        /* Check online status of the CPU to which the event is pinned */
        if (event->cpu >= 0 && !cpu_online(event->cpu))
-                       return -ENODEV;
+               return -ENODEV;
 
        /* Force reset of idle/hv excludes regardless of what the
         * user requested.
index f6db0f1..d047e84 100644 (file)
@@ -332,7 +332,7 @@ static inline int plo_test_bit(unsigned char nr)
        return cc == 0;
 }
 
-static inline void __insn32_query(unsigned int opcode, u8 query[32])
+static __always_inline void __insn32_query(unsigned int opcode, u8 *query)
 {
        register unsigned long r0 asm("0") = 0; /* query function */
        register unsigned long r1 asm("1") = (unsigned long) query;
@@ -340,9 +340,9 @@ static inline void __insn32_query(unsigned int opcode, u8 query[32])
        asm volatile(
                /* Parameter regs are ignored */
                "       .insn   rrf,%[opc] << 16,2,4,6,0\n"
-               : "=m" (*query)
+               :
                : "d" (r0), "a" (r1), [opc] "i" (opcode)
-               : "cc");
+               : "cc", "memory");
 }
 
 #define INSN_SORTL 0xb938
index 9bdff4d..e585a62 100644 (file)
@@ -66,7 +66,7 @@ static inline int clp_get_ilp(unsigned long *ilp)
 /*
  * Call Logical Processor with c=0, the give constant lps and an lpcb request.
  */
-static inline int clp_req(void *data, unsigned int lps)
+static __always_inline int clp_req(void *data, unsigned int lps)
 {
        struct { u8 _[CLP_BLK_SIZE]; } *req = data;
        u64 ignored;
index e7d35f6..64c3e70 100644 (file)
@@ -5,12 +5,14 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 #include <asm/apicdef.h>
 #include <asm/nmi.h>
 
 #include "../perf_event.h"
 
-static DEFINE_PER_CPU(unsigned int, perf_nmi_counter);
+static DEFINE_PER_CPU(unsigned long, perf_nmi_tstamp);
+static unsigned long perf_nmi_window;
 
 static __initconst const u64 amd_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
@@ -641,11 +643,12 @@ static void amd_pmu_disable_event(struct perf_event *event)
  * handler when multiple PMCs are active or PMC overflow while handling some
  * other source of an NMI.
  *
- * Attempt to mitigate this by using the number of active PMCs to determine
- * whether to return NMI_HANDLED if the perf NMI handler did not handle/reset
- * any PMCs. The per-CPU perf_nmi_counter variable is set to a minimum of the
- * number of active PMCs or 2. The value of 2 is used in case an NMI does not
- * arrive at the LAPIC in time to be collapsed into an already pending NMI.
+ * Attempt to mitigate this by creating an NMI window in which un-handled NMIs
+ * received during this window will be claimed. This prevents extending the
+ * window past when it is possible that latent NMIs should be received. The
+ * per-CPU perf_nmi_tstamp will be set to the window end time whenever perf has
+ * handled a counter. When an un-handled NMI is received, it will be claimed
+ * only if arriving within that window.
  */
 static int amd_pmu_handle_irq(struct pt_regs *regs)
 {
@@ -663,21 +666,19 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
        handled = x86_pmu_handle_irq(regs);
 
        /*
-        * If a counter was handled, record the number of possible remaining
-        * NMIs that can occur.
+        * If a counter was handled, record a timestamp such that un-handled
+        * NMIs will be claimed if arriving within that window.
         */
        if (handled) {
-               this_cpu_write(perf_nmi_counter,
-                              min_t(unsigned int, 2, active));
+               this_cpu_write(perf_nmi_tstamp,
+                              jiffies + perf_nmi_window);
 
                return handled;
        }
 
-       if (!this_cpu_read(perf_nmi_counter))
+       if (time_after(jiffies, this_cpu_read(perf_nmi_tstamp)))
                return NMI_DONE;
 
-       this_cpu_dec(perf_nmi_counter);
-
        return NMI_HANDLED;
 }
 
@@ -909,6 +910,9 @@ static int __init amd_core_pmu_init(void)
        if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE))
                return 0;
 
+       /* Avoid calulating the value each time in the NMI handler */
+       perf_nmi_window = msecs_to_jiffies(100);
+
        switch (boot_cpu_data.x86) {
        case 0x15:
                pr_cont("Fam15h ");
index 27ee47a..fcef678 100644 (file)
@@ -4983,6 +4983,8 @@ __init int intel_pmu_init(void)
        case INTEL_FAM6_SKYLAKE:
        case INTEL_FAM6_KABYLAKE_L:
        case INTEL_FAM6_KABYLAKE:
+       case INTEL_FAM6_COMETLAKE_L:
+       case INTEL_FAM6_COMETLAKE:
                x86_add_quirk(intel_pebs_isolation_quirk);
                x86_pmu.late_ack = true;
                memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
@@ -5031,6 +5033,8 @@ __init int intel_pmu_init(void)
                /* fall through */
        case INTEL_FAM6_ICELAKE_L:
        case INTEL_FAM6_ICELAKE:
+       case INTEL_FAM6_TIGERLAKE_L:
+       case INTEL_FAM6_TIGERLAKE:
                x86_pmu.late_ack = true;
                memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
                memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
index 9f2f390..e1daf41 100644 (file)
  *     MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
  *                            perf code: 0x01
  *                            Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM,
                                              CNL
*                                             CNL,KBL,CML
  *                            Scope: Core
  *     MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter
  *                            perf code: 0x02
  *                            Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
- *                                             SKL,KNL,GLM,CNL
+ *                                             SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL
  *                            Scope: Core
  *     MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
  *                            perf code: 0x03
- *                            Available model: SNB,IVB,HSW,BDW,SKL,CNL
+ *                            Available model: SNB,IVB,HSW,BDW,SKL,CNL,KBL,CML,
+ *                                             ICL,TGL
  *                            Scope: Core
  *     MSR_PKG_C2_RESIDENCY:  Package C2 Residency Counter.
  *                            perf code: 0x00
- *                            Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL
+ *                            Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL,
+ *                                             KBL,CML,ICL,TGL
  *                            Scope: Package (physical package)
  *     MSR_PKG_C3_RESIDENCY:  Package C3 Residency Counter.
  *                            perf code: 0x01
  *                            Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL,
- *                                             GLM,CNL
+ *                                             GLM,CNL,KBL,CML,ICL,TGL
  *                            Scope: Package (physical package)
  *     MSR_PKG_C6_RESIDENCY:  Package C6 Residency Counter.
  *                            perf code: 0x02
  *                            Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW
- *                                             SKL,KNL,GLM,CNL
+ *                                             SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL
  *                            Scope: Package (physical package)
  *     MSR_PKG_C7_RESIDENCY:  Package C7 Residency Counter.
  *                            perf code: 0x03
- *                            Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL
+ *                            Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL,
+ *                                             KBL,CML,ICL,TGL
  *                            Scope: Package (physical package)
  *     MSR_PKG_C8_RESIDENCY:  Package C8 Residency Counter.
  *                            perf code: 0x04
- *                            Available model: HSW ULT,KBL,CNL
+ *                            Available model: HSW ULT,KBL,CNL,CML,ICL,TGL
  *                            Scope: Package (physical package)
  *     MSR_PKG_C9_RESIDENCY:  Package C9 Residency Counter.
  *                            perf code: 0x05
- *                            Available model: HSW ULT,KBL,CNL
+ *                            Available model: HSW ULT,KBL,CNL,CML,ICL,TGL
  *                            Scope: Package (physical package)
  *     MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
  *                            perf code: 0x06
- *                            Available model: HSW ULT,KBL,GLM,CNL
+ *                            Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL
  *                            Scope: Package (physical package)
  *
  */
@@ -544,6 +547,19 @@ static const struct cstate_model cnl_cstates __initconst = {
                                  BIT(PERF_CSTATE_PKG_C10_RES),
 };
 
+static const struct cstate_model icl_cstates __initconst = {
+       .core_events            = BIT(PERF_CSTATE_CORE_C6_RES) |
+                                 BIT(PERF_CSTATE_CORE_C7_RES),
+
+       .pkg_events             = BIT(PERF_CSTATE_PKG_C2_RES) |
+                                 BIT(PERF_CSTATE_PKG_C3_RES) |
+                                 BIT(PERF_CSTATE_PKG_C6_RES) |
+                                 BIT(PERF_CSTATE_PKG_C7_RES) |
+                                 BIT(PERF_CSTATE_PKG_C8_RES) |
+                                 BIT(PERF_CSTATE_PKG_C9_RES) |
+                                 BIT(PERF_CSTATE_PKG_C10_RES),
+};
+
 static const struct cstate_model slm_cstates __initconst = {
        .core_events            = BIT(PERF_CSTATE_CORE_C1_RES) |
                                  BIT(PERF_CSTATE_CORE_C6_RES),
@@ -614,6 +630,8 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
 
        X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_L, hswult_cstates),
        X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE,   hswult_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_COMETLAKE_L, hswult_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_COMETLAKE, hswult_cstates),
 
        X86_CSTATES_MODEL(INTEL_FAM6_CANNONLAKE_L, cnl_cstates),
 
@@ -625,8 +643,10 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
 
        X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates),
 
-       X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, snb_cstates),
-       X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE,   snb_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, icl_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE,   icl_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_TIGERLAKE_L, icl_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_TIGERLAKE, icl_cstates),
        { },
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
index b1afc77..6f86650 100644 (file)
@@ -89,7 +89,14 @@ static bool test_intel(int idx, void *data)
        case INTEL_FAM6_SKYLAKE_X:
        case INTEL_FAM6_KABYLAKE_L:
        case INTEL_FAM6_KABYLAKE:
+       case INTEL_FAM6_COMETLAKE_L:
+       case INTEL_FAM6_COMETLAKE:
        case INTEL_FAM6_ICELAKE_L:
+       case INTEL_FAM6_ICELAKE:
+       case INTEL_FAM6_ICELAKE_X:
+       case INTEL_FAM6_ICELAKE_D:
+       case INTEL_FAM6_TIGERLAKE_L:
+       case INTEL_FAM6_TIGERLAKE:
                if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
                        return true;
                break;
index cff3f3f..8348f7d 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
 
 #ifndef _ASM_X86_CPU_ENTRY_AREA_H
 #define _ASM_X86_CPU_ENTRY_AREA_H
index f046225..c606c0b 100644 (file)
@@ -83,6 +83,9 @@
 #define INTEL_FAM6_TIGERLAKE_L         0x8C
 #define INTEL_FAM6_TIGERLAKE           0x8D
 
+#define INTEL_FAM6_COMETLAKE           0xA5
+#define INTEL_FAM6_COMETLAKE_L         0xA6
+
 /* "Small Core" Processors (Atom) */
 
 #define INTEL_FAM6_ATOM_BONNELL                0x1C /* Diamondville, Pineview */
index 23edf56..50eb430 100644 (file)
@@ -219,13 +219,6 @@ enum {
                                 PFERR_WRITE_MASK |             \
                                 PFERR_PRESENT_MASK)
 
-/*
- * The mask used to denote special SPTEs, which can be either MMIO SPTEs or
- * Access Tracking SPTEs. We use bit 62 instead of bit 63 to avoid conflicting
- * with the SVE bit in EPT PTEs.
- */
-#define SPTE_SPECIAL_MASK (1ULL << 62)
-
 /* apic attention bits */
 #define KVM_APIC_CHECK_VAPIC   0
 /*
index e28f8b7..9d5252c 100644 (file)
@@ -21,7 +21,7 @@
 #define MWAIT_ECX_INTERRUPT_BREAK      0x1
 #define MWAITX_ECX_TIMER_ENABLE                BIT(1)
 #define MWAITX_MAX_LOOPS               ((u32)-1)
-#define MWAITX_DISABLE_CSTATES         0xf
+#define MWAITX_DISABLE_CSTATES         0xf0
 
 static inline void __monitor(const void *eax, unsigned long ecx,
                             unsigned long edx)
index 5df09a0..07375b4 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _ASM_X86_PTI_H
 #define _ASM_X86_PTI_H
 #ifndef __ASSEMBLY__
index 35c225e..61d93f0 100644 (file)
@@ -734,5 +734,28 @@ do {                                                                               \
        if (unlikely(__gu_err)) goto err_label;                                 \
 } while (0)
 
+/*
+ * We want the unsafe accessors to always be inlined and use
+ * the error labels - thus the macro games.
+ */
+#define unsafe_copy_loop(dst, src, len, type, label)                   \
+       while (len >= sizeof(type)) {                                   \
+               unsafe_put_user(*(type *)src,(type __user *)dst,label); \
+               dst += sizeof(type);                                    \
+               src += sizeof(type);                                    \
+               len -= sizeof(type);                                    \
+       }
+
+#define unsafe_copy_to_user(_dst,_src,_len,label)                      \
+do {                                                                   \
+       char __user *__ucu_dst = (_dst);                                \
+       const char *__ucu_src = (_src);                                 \
+       size_t __ucu_len = (_len);                                      \
+       unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label);  \
+       unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label);  \
+       unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label);  \
+       unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label);   \
+} while (0)
+
 #endif /* _ASM_X86_UACCESS_H */
 
index 9735139..46d7326 100644 (file)
@@ -49,7 +49,7 @@
 #define VMWARE_CMD_VCPU_RESERVED 31
 
 #define VMWARE_PORT(cmd, eax, ebx, ecx, edx)                           \
-       __asm__("inl (%%dx)" :                                          \
+       __asm__("inl (%%dx), %%eax" :                                   \
                "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :            \
                "a"(VMWARE_HYPERVISOR_MAGIC),                           \
                "c"(VMWARE_CMD_##cmd),                                  \
index 320ab97..1d0797b 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
 //
 // Code shared between 32 and 64 bit
 
index 6331603..9c5029c 100644 (file)
@@ -485,6 +485,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
 
        /* cpuid 0x80000008.ebx */
        const u32 kvm_cpuid_8000_0008_ebx_x86_features =
+               F(CLZERO) | F(XSAVEERPTR) |
                F(WBNOINVD) | F(AMD_IBPB) | F(AMD_IBRS) | F(AMD_SSBD) | F(VIRT_SSBD) |
                F(AMD_SSB_NO) | F(AMD_STIBP) | F(AMD_STIBP_ALWAYS_ON);
 
@@ -618,16 +619,20 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
         */
        case 0x1f:
        case 0xb: {
-               int i, level_type;
+               int i;
 
-               /* read more entries until level_type is zero */
-               for (i = 1; ; ++i) {
+               /*
+                * We filled in entry[0] for CPUID(EAX=<function>,
+                * ECX=00H) above.  If its level type (ECX[15:8]) is
+                * zero, then the leaf is unimplemented, and we're
+                * done.  Otherwise, continue to populate entries
+                * until the level type (ECX[15:8]) of the previously
+                * added entry is zero.
+                */
+               for (i = 1; entry[i - 1].ecx & 0xff00; ++i) {
                        if (*nent >= maxnent)
                                goto out;
 
-                       level_type = entry[i - 1].ecx & 0xff00;
-                       if (!level_type)
-                               break;
                        do_host_cpuid(&entry[i], function, i);
                        ++*nent;
                }
@@ -969,53 +974,66 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
 EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
 
 /*
- * If no match is found, check whether we exceed the vCPU's limit
- * and return the content of the highest valid _standard_ leaf instead.
- * This is to satisfy the CPUID specification.
+ * If the basic or extended CPUID leaf requested is higher than the
+ * maximum supported basic or extended leaf, respectively, then it is
+ * out of range.
  */
-static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
-                                                  u32 function, u32 index)
+static bool cpuid_function_in_range(struct kvm_vcpu *vcpu, u32 function)
 {
-       struct kvm_cpuid_entry2 *maxlevel;
-
-       maxlevel = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
-       if (!maxlevel || maxlevel->eax >= function)
-               return NULL;
-       if (function & 0x80000000) {
-               maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0);
-               if (!maxlevel)
-                       return NULL;
-       }
-       return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
+       struct kvm_cpuid_entry2 *max;
+
+       max = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
+       return max && function <= max->eax;
 }
 
 bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
               u32 *ecx, u32 *edx, bool check_limit)
 {
        u32 function = *eax, index = *ecx;
-       struct kvm_cpuid_entry2 *best;
-       bool entry_found = true;
-
-       best = kvm_find_cpuid_entry(vcpu, function, index);
-
-       if (!best) {
-               entry_found = false;
-               if (!check_limit)
-                       goto out;
+       struct kvm_cpuid_entry2 *entry;
+       struct kvm_cpuid_entry2 *max;
+       bool found;
 
-               best = check_cpuid_limit(vcpu, function, index);
+       entry = kvm_find_cpuid_entry(vcpu, function, index);
+       found = entry;
+       /*
+        * Intel CPUID semantics treats any query for an out-of-range
+        * leaf as if the highest basic leaf (i.e. CPUID.0H:EAX) were
+        * requested. AMD CPUID semantics returns all zeroes for any
+        * undefined leaf, whether or not the leaf is in range.
+        */
+       if (!entry && check_limit && !guest_cpuid_is_amd(vcpu) &&
+           !cpuid_function_in_range(vcpu, function)) {
+               max = kvm_find_cpuid_entry(vcpu, 0, 0);
+               if (max) {
+                       function = max->eax;
+                       entry = kvm_find_cpuid_entry(vcpu, function, index);
+               }
        }
-
-out:
-       if (best) {
-               *eax = best->eax;
-               *ebx = best->ebx;
-               *ecx = best->ecx;
-               *edx = best->edx;
-       } else
+       if (entry) {
+               *eax = entry->eax;
+               *ebx = entry->ebx;
+               *ecx = entry->ecx;
+               *edx = entry->edx;
+       } else {
                *eax = *ebx = *ecx = *edx = 0;
-       trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, entry_found);
-       return entry_found;
+               /*
+                * When leaf 0BH or 1FH is defined, CL is pass-through
+                * and EDX is always the x2APIC ID, even for undefined
+                * subleaves. Index 1 will exist iff the leaf is
+                * implemented, so we pass through CL iff leaf 1
+                * exists. EDX can be copied from any existing index.
+                */
+               if (function == 0xb || function == 0x1f) {
+                       entry = kvm_find_cpuid_entry(vcpu, function, 1);
+                       if (entry) {
+                               *ecx = index & 0xff;
+                               *edx = entry->edx;
+                       }
+               }
+       }
+       trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, found);
+       return found;
 }
 EXPORT_SYMBOL_GPL(kvm_cpuid);
 
index 3a3a685..87b0fcc 100644 (file)
 #define X2APIC_BROADCAST               0xFFFFFFFFul
 
 static bool lapic_timer_advance_dynamic __read_mostly;
-#define LAPIC_TIMER_ADVANCE_ADJUST_MIN 100
-#define LAPIC_TIMER_ADVANCE_ADJUST_MAX 5000
-#define LAPIC_TIMER_ADVANCE_ADJUST_INIT 1000
+#define LAPIC_TIMER_ADVANCE_ADJUST_MIN 100     /* clock cycles */
+#define LAPIC_TIMER_ADVANCE_ADJUST_MAX 10000   /* clock cycles */
+#define LAPIC_TIMER_ADVANCE_NS_INIT    1000
+#define LAPIC_TIMER_ADVANCE_NS_MAX     5000
 /* step-by-step approximation to mitigate fluctuation */
 #define LAPIC_TIMER_ADVANCE_ADJUST_STEP 8
 
@@ -1504,8 +1505,8 @@ static inline void adjust_lapic_timer_advance(struct kvm_vcpu *vcpu,
                timer_advance_ns += ns/LAPIC_TIMER_ADVANCE_ADJUST_STEP;
        }
 
-       if (unlikely(timer_advance_ns > LAPIC_TIMER_ADVANCE_ADJUST_MAX))
-               timer_advance_ns = LAPIC_TIMER_ADVANCE_ADJUST_INIT;
+       if (unlikely(timer_advance_ns > LAPIC_TIMER_ADVANCE_NS_MAX))
+               timer_advance_ns = LAPIC_TIMER_ADVANCE_NS_INIT;
        apic->lapic_timer.timer_advance_ns = timer_advance_ns;
 }
 
@@ -2302,7 +2303,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
                     HRTIMER_MODE_ABS_HARD);
        apic->lapic_timer.timer.function = apic_timer_fn;
        if (timer_advance_ns == -1) {
-               apic->lapic_timer.timer_advance_ns = LAPIC_TIMER_ADVANCE_ADJUST_INIT;
+               apic->lapic_timer.timer_advance_ns = LAPIC_TIMER_ADVANCE_NS_INIT;
                lapic_timer_advance_dynamic = true;
        } else {
                apic->lapic_timer.timer_advance_ns = timer_advance_ns;
index 5269aa0..24c23c6 100644 (file)
@@ -83,7 +83,17 @@ module_param(dbg, bool, 0644);
 #define PTE_PREFETCH_NUM               8
 
 #define PT_FIRST_AVAIL_BITS_SHIFT 10
-#define PT64_SECOND_AVAIL_BITS_SHIFT 52
+#define PT64_SECOND_AVAIL_BITS_SHIFT 54
+
+/*
+ * The mask used to denote special SPTEs, which can be either MMIO SPTEs or
+ * Access Tracking SPTEs.
+ */
+#define SPTE_SPECIAL_MASK (3ULL << 52)
+#define SPTE_AD_ENABLED_MASK (0ULL << 52)
+#define SPTE_AD_DISABLED_MASK (1ULL << 52)
+#define SPTE_AD_WRPROT_ONLY_MASK (2ULL << 52)
+#define SPTE_MMIO_MASK (3ULL << 52)
 
 #define PT64_LEVEL_BITS 9
 
@@ -219,12 +229,11 @@ static u64 __read_mostly shadow_present_mask;
 static u64 __read_mostly shadow_me_mask;
 
 /*
- * SPTEs used by MMUs without A/D bits are marked with shadow_acc_track_value.
- * Non-present SPTEs with shadow_acc_track_value set are in place for access
- * tracking.
+ * SPTEs used by MMUs without A/D bits are marked with SPTE_AD_DISABLED_MASK;
+ * shadow_acc_track_mask is the set of bits to be cleared in non-accessed
+ * pages.
  */
 static u64 __read_mostly shadow_acc_track_mask;
-static const u64 shadow_acc_track_value = SPTE_SPECIAL_MASK;
 
 /*
  * The mask/shift to use for saving the original R/X bits when marking the PTE
@@ -304,7 +313,7 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask, u64 mmio_value, u64 access_mask)
 {
        BUG_ON((u64)(unsigned)access_mask != access_mask);
        BUG_ON((mmio_mask & mmio_value) != mmio_value);
-       shadow_mmio_value = mmio_value | SPTE_SPECIAL_MASK;
+       shadow_mmio_value = mmio_value | SPTE_MMIO_MASK;
        shadow_mmio_mask = mmio_mask | SPTE_SPECIAL_MASK;
        shadow_mmio_access_mask = access_mask;
 }
@@ -320,10 +329,27 @@ static inline bool sp_ad_disabled(struct kvm_mmu_page *sp)
        return sp->role.ad_disabled;
 }
 
+static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu)
+{
+       /*
+        * When using the EPT page-modification log, the GPAs in the log
+        * would come from L2 rather than L1.  Therefore, we need to rely
+        * on write protection to record dirty pages.  This also bypasses
+        * PML, since writes now result in a vmexit.
+        */
+       return vcpu->arch.mmu == &vcpu->arch.guest_mmu;
+}
+
 static inline bool spte_ad_enabled(u64 spte)
 {
        MMU_WARN_ON(is_mmio_spte(spte));
-       return !(spte & shadow_acc_track_value);
+       return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_DISABLED_MASK;
+}
+
+static inline bool spte_ad_need_write_protect(u64 spte)
+{
+       MMU_WARN_ON(is_mmio_spte(spte));
+       return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_ENABLED_MASK;
 }
 
 static inline u64 spte_shadow_accessed_mask(u64 spte)
@@ -461,7 +487,7 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
 {
        BUG_ON(!dirty_mask != !accessed_mask);
        BUG_ON(!accessed_mask && !acc_track_mask);
-       BUG_ON(acc_track_mask & shadow_acc_track_value);
+       BUG_ON(acc_track_mask & SPTE_SPECIAL_MASK);
 
        shadow_user_mask = user_mask;
        shadow_accessed_mask = accessed_mask;
@@ -1589,16 +1615,16 @@ static bool spte_clear_dirty(u64 *sptep)
 
        rmap_printk("rmap_clear_dirty: spte %p %llx\n", sptep, *sptep);
 
+       MMU_WARN_ON(!spte_ad_enabled(spte));
        spte &= ~shadow_dirty_mask;
-
        return mmu_spte_update(sptep, spte);
 }
 
-static bool wrprot_ad_disabled_spte(u64 *sptep)
+static bool spte_wrprot_for_clear_dirty(u64 *sptep)
 {
        bool was_writable = test_and_clear_bit(PT_WRITABLE_SHIFT,
                                               (unsigned long *)sptep);
-       if (was_writable)
+       if (was_writable && !spte_ad_enabled(*sptep))
                kvm_set_pfn_dirty(spte_to_pfn(*sptep));
 
        return was_writable;
@@ -1617,10 +1643,10 @@ static bool __rmap_clear_dirty(struct kvm *kvm, struct kvm_rmap_head *rmap_head)
        bool flush = false;
 
        for_each_rmap_spte(rmap_head, &iter, sptep)
-               if (spte_ad_enabled(*sptep))
-                       flush |= spte_clear_dirty(sptep);
+               if (spte_ad_need_write_protect(*sptep))
+                       flush |= spte_wrprot_for_clear_dirty(sptep);
                else
-                       flush |= wrprot_ad_disabled_spte(sptep);
+                       flush |= spte_clear_dirty(sptep);
 
        return flush;
 }
@@ -1631,6 +1657,11 @@ static bool spte_set_dirty(u64 *sptep)
 
        rmap_printk("rmap_set_dirty: spte %p %llx\n", sptep, *sptep);
 
+       /*
+        * Similar to the !kvm_x86_ops->slot_disable_log_dirty case,
+        * do not bother adding back write access to pages marked
+        * SPTE_AD_WRPROT_ONLY_MASK.
+        */
        spte |= shadow_dirty_mask;
 
        return mmu_spte_update(sptep, spte);
@@ -2622,7 +2653,7 @@ static void link_shadow_page(struct kvm_vcpu *vcpu, u64 *sptep,
               shadow_user_mask | shadow_x_mask | shadow_me_mask;
 
        if (sp_ad_disabled(sp))
-               spte |= shadow_acc_track_value;
+               spte |= SPTE_AD_DISABLED_MASK;
        else
                spte |= shadow_accessed_mask;
 
@@ -2968,7 +2999,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
 
        sp = page_header(__pa(sptep));
        if (sp_ad_disabled(sp))
-               spte |= shadow_acc_track_value;
+               spte |= SPTE_AD_DISABLED_MASK;
+       else if (kvm_vcpu_ad_need_write_protect(vcpu))
+               spte |= SPTE_AD_WRPROT_ONLY_MASK;
 
        /*
         * For the EPT case, shadow_present_mask is 0 if hardware
index 41abc62..e76eb4f 100644 (file)
@@ -2610,7 +2610,7 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu,
 
                /* VM-entry exception error code */
                if (CC(has_error_code &&
-                      vmcs12->vm_entry_exception_error_code & GENMASK(31, 15)))
+                      vmcs12->vm_entry_exception_error_code & GENMASK(31, 16)))
                        return -EINVAL;
 
                /* VM-entry interruption-info field: reserved bits */
index 4dea0e0..3e9c059 100644 (file)
@@ -262,6 +262,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 {
        struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+       struct x86_pmu_capability x86_pmu;
        struct kvm_cpuid_entry2 *entry;
        union cpuid10_eax eax;
        union cpuid10_edx edx;
@@ -283,8 +284,10 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
        if (!pmu->version)
                return;
 
+       perf_get_x86_pmu_capability(&x86_pmu);
+
        pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters,
-                                       INTEL_PMC_MAX_GENERIC);
+                                        x86_pmu.num_counters_gp);
        pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1;
        pmu->available_event_types = ~entry->ebx &
                                        ((1ull << eax.split.mask_length) - 1);
@@ -294,7 +297,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
        } else {
                pmu->nr_arch_fixed_counters =
                        min_t(int, edx.split.num_counters_fixed,
-                               INTEL_PMC_MAX_FIXED);
+                             x86_pmu.num_counters_fixed);
                pmu->counter_bitmask[KVM_PMC_FIXED] =
                        ((u64)1 << edx.split.bit_width_fixed) - 1;
        }
index d4575ff..e7970a2 100644 (file)
@@ -209,6 +209,11 @@ static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
        struct page *page;
        unsigned int i;
 
+       if (!boot_cpu_has_bug(X86_BUG_L1TF)) {
+               l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NOT_REQUIRED;
+               return 0;
+       }
+
        if (!enable_ept) {
                l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_EPT_DISABLED;
                return 0;
@@ -7995,12 +8000,10 @@ static int __init vmx_init(void)
         * contain 'auto' which will be turned into the default 'cond'
         * mitigation mode.
         */
-       if (boot_cpu_has(X86_BUG_L1TF)) {
-               r = vmx_setup_l1d_flush(vmentry_l1d_flush_param);
-               if (r) {
-                       vmx_exit();
-                       return r;
-               }
+       r = vmx_setup_l1d_flush(vmentry_l1d_flush_param);
+       if (r) {
+               vmx_exit();
+               return r;
        }
 
 #ifdef CONFIG_KEXEC_CORE
index 0ed07d8..661e2bf 100644 (file)
@@ -92,8 +92,8 @@ u64 __read_mostly efer_reserved_bits = ~((u64)(EFER_SCE | EFER_LME | EFER_LMA));
 static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
 #endif
 
-#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
-#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
+#define VM_STAT(x, ...) offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__
+#define VCPU_STAT(x, ...) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__
 
 #define KVM_X2APIC_API_VALID_FLAGS (KVM_X2APIC_API_USE_32BIT_IDS | \
                                     KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)
@@ -212,7 +212,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
        { "mmu_unsync", VM_STAT(mmu_unsync) },
        { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
-       { "largepages", VM_STAT(lpages) },
+       { "largepages", VM_STAT(lpages, .mode = 0444) },
        { "max_mmu_page_hash_collisions",
                VM_STAT(max_mmu_page_hash_collisions) },
        { NULL }
@@ -885,34 +885,42 @@ int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 }
 EXPORT_SYMBOL_GPL(kvm_set_xcr);
 
-int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
+static int kvm_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
-       unsigned long old_cr4 = kvm_read_cr4(vcpu);
-       unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
-                                  X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE;
-
        if (cr4 & CR4_RESERVED_BITS)
-               return 1;
+               return -EINVAL;
 
        if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) && (cr4 & X86_CR4_OSXSAVE))
-               return 1;
+               return -EINVAL;
 
        if (!guest_cpuid_has(vcpu, X86_FEATURE_SMEP) && (cr4 & X86_CR4_SMEP))
-               return 1;
+               return -EINVAL;
 
        if (!guest_cpuid_has(vcpu, X86_FEATURE_SMAP) && (cr4 & X86_CR4_SMAP))
-               return 1;
+               return -EINVAL;
 
        if (!guest_cpuid_has(vcpu, X86_FEATURE_FSGSBASE) && (cr4 & X86_CR4_FSGSBASE))
-               return 1;
+               return -EINVAL;
 
        if (!guest_cpuid_has(vcpu, X86_FEATURE_PKU) && (cr4 & X86_CR4_PKE))
-               return 1;
+               return -EINVAL;
 
        if (!guest_cpuid_has(vcpu, X86_FEATURE_LA57) && (cr4 & X86_CR4_LA57))
-               return 1;
+               return -EINVAL;
 
        if (!guest_cpuid_has(vcpu, X86_FEATURE_UMIP) && (cr4 & X86_CR4_UMIP))
+               return -EINVAL;
+
+       return 0;
+}
+
+int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
+{
+       unsigned long old_cr4 = kvm_read_cr4(vcpu);
+       unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
+                                  X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE;
+
+       if (kvm_valid_cr4(vcpu, cr4))
                return 1;
 
        if (is_long_mode(vcpu)) {
@@ -1161,13 +1169,6 @@ static u32 msrs_to_save[] = {
        MSR_ARCH_PERFMON_PERFCTR0 + 12, MSR_ARCH_PERFMON_PERFCTR0 + 13,
        MSR_ARCH_PERFMON_PERFCTR0 + 14, MSR_ARCH_PERFMON_PERFCTR0 + 15,
        MSR_ARCH_PERFMON_PERFCTR0 + 16, MSR_ARCH_PERFMON_PERFCTR0 + 17,
-       MSR_ARCH_PERFMON_PERFCTR0 + 18, MSR_ARCH_PERFMON_PERFCTR0 + 19,
-       MSR_ARCH_PERFMON_PERFCTR0 + 20, MSR_ARCH_PERFMON_PERFCTR0 + 21,
-       MSR_ARCH_PERFMON_PERFCTR0 + 22, MSR_ARCH_PERFMON_PERFCTR0 + 23,
-       MSR_ARCH_PERFMON_PERFCTR0 + 24, MSR_ARCH_PERFMON_PERFCTR0 + 25,
-       MSR_ARCH_PERFMON_PERFCTR0 + 26, MSR_ARCH_PERFMON_PERFCTR0 + 27,
-       MSR_ARCH_PERFMON_PERFCTR0 + 28, MSR_ARCH_PERFMON_PERFCTR0 + 29,
-       MSR_ARCH_PERFMON_PERFCTR0 + 30, MSR_ARCH_PERFMON_PERFCTR0 + 31,
        MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1,
        MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3,
        MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5,
@@ -1177,13 +1178,6 @@ static u32 msrs_to_save[] = {
        MSR_ARCH_PERFMON_EVENTSEL0 + 12, MSR_ARCH_PERFMON_EVENTSEL0 + 13,
        MSR_ARCH_PERFMON_EVENTSEL0 + 14, MSR_ARCH_PERFMON_EVENTSEL0 + 15,
        MSR_ARCH_PERFMON_EVENTSEL0 + 16, MSR_ARCH_PERFMON_EVENTSEL0 + 17,
-       MSR_ARCH_PERFMON_EVENTSEL0 + 18, MSR_ARCH_PERFMON_EVENTSEL0 + 19,
-       MSR_ARCH_PERFMON_EVENTSEL0 + 20, MSR_ARCH_PERFMON_EVENTSEL0 + 21,
-       MSR_ARCH_PERFMON_EVENTSEL0 + 22, MSR_ARCH_PERFMON_EVENTSEL0 + 23,
-       MSR_ARCH_PERFMON_EVENTSEL0 + 24, MSR_ARCH_PERFMON_EVENTSEL0 + 25,
-       MSR_ARCH_PERFMON_EVENTSEL0 + 26, MSR_ARCH_PERFMON_EVENTSEL0 + 27,
-       MSR_ARCH_PERFMON_EVENTSEL0 + 28, MSR_ARCH_PERFMON_EVENTSEL0 + 29,
-       MSR_ARCH_PERFMON_EVENTSEL0 + 30, MSR_ARCH_PERFMON_EVENTSEL0 + 31,
 };
 
 static unsigned num_msrs_to_save;
@@ -5097,13 +5091,14 @@ out:
 
 static void kvm_init_msr_list(void)
 {
+       struct x86_pmu_capability x86_pmu;
        u32 dummy[2];
        unsigned i, j;
 
        BUILD_BUG_ON_MSG(INTEL_PMC_MAX_FIXED != 4,
                         "Please update the fixed PMCs in msrs_to_save[]");
-       BUILD_BUG_ON_MSG(INTEL_PMC_MAX_GENERIC != 32,
-                        "Please update the generic perfctr/eventsel MSRs in msrs_to_save[]");
+
+       perf_get_x86_pmu_capability(&x86_pmu);
 
        for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) {
                if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0)
@@ -5145,6 +5140,15 @@ static void kvm_init_msr_list(void)
                                intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2)
                                continue;
                        break;
+               case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 17:
+                       if (msrs_to_save[i] - MSR_ARCH_PERFMON_PERFCTR0 >=
+                           min(INTEL_PMC_MAX_GENERIC, x86_pmu.num_counters_gp))
+                               continue;
+                       break;
+               case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 17:
+                       if (msrs_to_save[i] - MSR_ARCH_PERFMON_EVENTSEL0 >=
+                           min(INTEL_PMC_MAX_GENERIC, x86_pmu.num_counters_gp))
+                               continue;
                }
                default:
                        break;
@@ -8714,10 +8718,6 @@ EXPORT_SYMBOL_GPL(kvm_task_switch);
 
 static int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
-       if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) &&
-                       (sregs->cr4 & X86_CR4_OSXSAVE))
-               return  -EINVAL;
-
        if ((sregs->efer & EFER_LME) && (sregs->cr0 & X86_CR0_PG)) {
                /*
                 * When EFER.LME and CR0.PG are set, the processor is in
@@ -8736,7 +8736,7 @@ static int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
                        return -EINVAL;
        }
 
-       return 0;
+       return kvm_valid_cr4(vcpu, sregs->cr4);
 }
 
 static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
index b7375dc..c126571 100644 (file)
@@ -113,8 +113,8 @@ static void delay_mwaitx(unsigned long __loops)
                __monitorx(raw_cpu_ptr(&cpu_tss_rw), 0, 0);
 
                /*
-                * AMD, like Intel, supports the EAX hint and EAX=0xf
-                * means, do not enter any deep C-state and we use it
+                * AMD, like Intel's MWAIT version, supports the EAX hint and
+                * EAX=0xf0 means, do not enter any deep C-state and we use it
                 * here in delay() to minimize wakeup latency.
                 */
                __mwaitx(MWAITX_DISABLE_CSTATES, delay, MWAITX_ECX_TIMER_ENABLE);
index c202e1b..425e025 100644 (file)
@@ -917,9 +917,6 @@ static void __init kexec_enter_virtual_mode(void)
 
        if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
                runtime_code_page_mkexec();
-
-       /* clean DUMMY object */
-       efi_delete_dummy_variable();
 #endif
 }
 
index 0d3365c..a04551e 100644 (file)
@@ -57,19 +57,7 @@ static efi_system_table_t __init *xen_efi_probe(void)
                return NULL;
 
        /* Here we know that Xen runs on EFI platform. */
-
-       efi.get_time                 = xen_efi_get_time;
-       efi.set_time                 = xen_efi_set_time;
-       efi.get_wakeup_time          = xen_efi_get_wakeup_time;
-       efi.set_wakeup_time          = xen_efi_set_wakeup_time;
-       efi.get_variable             = xen_efi_get_variable;
-       efi.get_next_variable        = xen_efi_get_next_variable;
-       efi.set_variable             = xen_efi_set_variable;
-       efi.query_variable_info      = xen_efi_query_variable_info;
-       efi.update_capsule           = xen_efi_update_capsule;
-       efi.query_capsule_caps       = xen_efi_query_capsule_caps;
-       efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
-       efi.reset_system             = xen_efi_reset_system;
+       xen_efi_runtime_setup();
 
        efi_systab_xen.tables = info->cfg.addr;
        efi_systab_xen.nr_tables = info->cfg.nent;
index 750f46a..205b117 100644 (file)
@@ -269,19 +269,41 @@ void xen_reboot(int reason)
                BUG();
 }
 
+static int reboot_reason = SHUTDOWN_reboot;
+static bool xen_legacy_crash;
 void xen_emergency_restart(void)
 {
-       xen_reboot(SHUTDOWN_reboot);
+       xen_reboot(reboot_reason);
 }
 
 static int
 xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
-       if (!kexec_crash_loaded())
-               xen_reboot(SHUTDOWN_crash);
+       if (!kexec_crash_loaded()) {
+               if (xen_legacy_crash)
+                       xen_reboot(SHUTDOWN_crash);
+
+               reboot_reason = SHUTDOWN_crash;
+
+               /*
+                * If panic_timeout==0 then we are supposed to wait forever.
+                * However, to preserve original dom0 behavior we have to drop
+                * into hypervisor. (domU behavior is controlled by its
+                * config file)
+                */
+               if (panic_timeout == 0)
+                       panic_timeout = -1;
+       }
        return NOTIFY_DONE;
 }
 
+static int __init parse_xen_legacy_crash(char *arg)
+{
+       xen_legacy_crash = true;
+       return 0;
+}
+early_param("xen_legacy_crash", parse_xen_legacy_crash);
+
 static struct notifier_block xen_panic_block = {
        .notifier_call = xen_panic_event,
        .priority = INT_MIN
index 6e3b15f..ec79115 100644 (file)
@@ -1992,10 +1992,14 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
                /* bypass scheduler for flush rq */
                blk_insert_flush(rq);
                blk_mq_run_hw_queue(data.hctx, true);
-       } else if (plug && (q->nr_hw_queues == 1 || q->mq_ops->commit_rqs)) {
+       } else if (plug && (q->nr_hw_queues == 1 || q->mq_ops->commit_rqs ||
+                               !blk_queue_nonrot(q))) {
                /*
                 * Use plugging if we have a ->commit_rqs() hook as well, as
                 * we know the driver uses bd->last in a smart fashion.
+                *
+                * Use normal plugging if this disk is slow HDD, as sequential
+                * IO may benefit a lot from plug merging.
                 */
                unsigned int request_count = plug->rq_count;
                struct request *last = NULL;
@@ -2012,6 +2016,8 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
                }
 
                blk_add_rq_to_plug(plug, rq);
+       } else if (q->elevator) {
+               blk_mq_sched_insert_request(rq, false, true, true);
        } else if (plug && !blk_queue_nomerges(q)) {
                /*
                 * We do limited plugging. If the bio can be merged, do that.
@@ -2035,8 +2041,8 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
                        blk_mq_try_issue_directly(data.hctx, same_queue_rq,
                                        &cookie);
                }
-       } else if ((q->nr_hw_queues > 1 && is_sync) || (!q->elevator &&
-                       !data.hctx->dispatch_busy)) {
+       } else if ((q->nr_hw_queues > 1 && is_sync) ||
+                       !data.hctx->dispatch_busy) {
                blk_mq_try_issue_directly(data.hctx, rq, &cookie);
        } else {
                blk_mq_sched_insert_request(rq, false, true, true);
index 61b635b..6564606 100644 (file)
@@ -160,24 +160,27 @@ bool rq_depth_calc_max_depth(struct rq_depth *rqd)
        return ret;
 }
 
-void rq_depth_scale_up(struct rq_depth *rqd)
+/* Returns true on success and false if scaling up wasn't possible */
+bool rq_depth_scale_up(struct rq_depth *rqd)
 {
        /*
         * Hit max in previous round, stop here
         */
        if (rqd->scaled_max)
-               return;
+               return false;
 
        rqd->scale_step--;
 
        rqd->scaled_max = rq_depth_calc_max_depth(rqd);
+       return true;
 }
 
 /*
  * Scale rwb down. If 'hard_throttle' is set, do it quicker, since we
- * had a latency violation.
+ * had a latency violation. Returns true on success and returns false if
+ * scaling down wasn't possible.
  */
-void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle)
+bool rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle)
 {
        /*
         * Stop scaling down when we've hit the limit. This also prevents
@@ -185,7 +188,7 @@ void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle)
         * keep up.
         */
        if (rqd->max_depth == 1)
-               return;
+               return false;
 
        if (rqd->scale_step < 0 && hard_throttle)
                rqd->scale_step = 0;
@@ -194,6 +197,7 @@ void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle)
 
        rqd->scaled_max = false;
        rq_depth_calc_max_depth(rqd);
+       return true;
 }
 
 struct rq_qos_wait_data {
index 08a09db..e8cb68f 100644 (file)
@@ -130,8 +130,8 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
                 acquire_inflight_cb_t *acquire_inflight_cb,
                 cleanup_cb_t *cleanup_cb);
 bool rq_wait_inc_below(struct rq_wait *rq_wait, unsigned int limit);
-void rq_depth_scale_up(struct rq_depth *rqd);
-void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle);
+bool rq_depth_scale_up(struct rq_depth *rqd);
+bool rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle);
 bool rq_depth_calc_max_depth(struct rq_depth *rqd);
 
 void __rq_qos_cleanup(struct rq_qos *rqos, struct bio *bio);
index 8af553a..8641ba9 100644 (file)
@@ -308,7 +308,8 @@ static void calc_wb_limits(struct rq_wb *rwb)
 
 static void scale_up(struct rq_wb *rwb)
 {
-       rq_depth_scale_up(&rwb->rq_depth);
+       if (!rq_depth_scale_up(&rwb->rq_depth))
+               return;
        calc_wb_limits(rwb);
        rwb->unknown_cnt = 0;
        rwb_wake_all(rwb);
@@ -317,7 +318,8 @@ static void scale_up(struct rq_wb *rwb)
 
 static void scale_down(struct rq_wb *rwb, bool hard_throttle)
 {
-       rq_depth_scale_down(&rwb->rq_depth, hard_throttle);
+       if (!rq_depth_scale_down(&rwb->rq_depth, hard_throttle))
+               return;
        calc_wb_limits(rwb);
        rwb->unknown_cnt = 0;
        rwb_trace_step(rwb, "scale down");
index 4e95a97..b4c7619 100644 (file)
@@ -129,7 +129,7 @@ static const u8 opaluid[][OPAL_UID_LENGTH] = {
                { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
 
        /* tables */
-       [OPAL_TABLE_TABLE]
+       [OPAL_TABLE_TABLE] =
                { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
        [OPAL_LOCKINGRANGE_GLOBAL] =
                { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
@@ -372,8 +372,8 @@ static void check_geometry(struct opal_dev *dev, const void *data)
 {
        const struct d0_geometry_features *geo = data;
 
-       dev->align = geo->alignment_granularity;
-       dev->lowest_lba = geo->lowest_aligned_lba;
+       dev->align = be64_to_cpu(geo->alignment_granularity);
+       dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba);
 }
 
 static int execute_step(struct opal_dev *dev,
index 76d0f9d..58e09ff 100644 (file)
@@ -4791,27 +4791,6 @@ void ata_scsi_hotplug(struct work_struct *work)
                return;
        }
 
-       /*
-        * XXX - UGLY HACK
-        *
-        * The block layer suspend/resume path is fundamentally broken due
-        * to freezable kthreads and workqueue and may deadlock if a block
-        * device gets removed while resume is in progress.  I don't know
-        * what the solution is short of removing freezable kthreads and
-        * workqueues altogether.
-        *
-        * The following is an ugly hack to avoid kicking off device
-        * removal while freezer is active.  This is a joke but does avoid
-        * this particular deadlock scenario.
-        *
-        * https://bugzilla.kernel.org/show_bug.cgi?id=62801
-        * http://marc.info/?l=linux-kernel&m=138695698516487
-        */
-#ifdef CONFIG_FREEZER
-       while (pm_freezing)
-               msleep(10);
-#endif
-
        DPRINTK("ENTER\n");
        mutex_lock(&ap->scsi_scan_mutex);
 
index 1410fa8..f6f77ea 100644 (file)
@@ -994,6 +994,16 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
        if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
                blk_queue_write_cache(lo->lo_queue, true, false);
 
+       if (io_is_direct(lo->lo_backing_file) && inode->i_sb->s_bdev) {
+               /* In case of direct I/O, match underlying block size */
+               unsigned short bsize = bdev_logical_block_size(
+                       inode->i_sb->s_bdev);
+
+               blk_queue_logical_block_size(lo->lo_queue, bsize);
+               blk_queue_physical_block_size(lo->lo_queue, bsize);
+               blk_queue_io_min(lo->lo_queue, bsize);
+       }
+
        loop_update_rotational(lo);
        loop_update_dio(lo);
        set_capacity(lo->lo_disk, size);
index ac07e8c..478aa86 100644 (file)
@@ -248,8 +248,8 @@ static void nbd_put(struct nbd_device *nbd)
        if (refcount_dec_and_mutex_lock(&nbd->refs,
                                        &nbd_index_mutex)) {
                idr_remove(&nbd_index_idr, nbd->index);
-               mutex_unlock(&nbd_index_mutex);
                nbd_dev_remove(nbd);
+               mutex_unlock(&nbd_index_mutex);
        }
 }
 
index eabc116..3d7fdea 100644 (file)
@@ -142,8 +142,7 @@ static blk_status_t null_zone_reset(struct nullb_cmd *cmd, sector_t sector)
                zone->wp = zone->start;
                break;
        default:
-               cmd->error = BLK_STS_NOTSUPP;
-               break;
+               return BLK_STS_NOTSUPP;
        }
        return BLK_STS_OK;
 }
index c2f7de9..de434fe 100644 (file)
@@ -2520,4 +2520,4 @@ void add_bootloader_randomness(const void *buf, unsigned int size)
        else
                add_device_randomness(buf, size);
 }
-EXPORT_SYMBOL_GPL(add_bootloader_randomness);
\ No newline at end of file
+EXPORT_SYMBOL_GPL(add_bootloader_randomness);
index b57fe09..9dd6185 100644 (file)
@@ -683,7 +683,7 @@ static const struct omap_clkctrl_reg_data dra7_l4per2_clkctrl_regs[] __initconst
        { DRA7_L4PER2_MCASP2_CLKCTRL, dra7_mcasp2_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:0154:22" },
        { DRA7_L4PER2_MCASP3_CLKCTRL, dra7_mcasp3_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:015c:22" },
        { DRA7_L4PER2_MCASP5_CLKCTRL, dra7_mcasp5_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:016c:22" },
-       { DRA7_L4PER2_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:0184:24" },
+       { DRA7_L4PER2_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:0184:22" },
        { DRA7_L4PER2_MCASP4_CLKCTRL, dra7_mcasp4_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:018c:22" },
        { DRA7_L4PER2_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01c4:24" },
        { DRA7_L4PER2_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01d4:24" },
@@ -828,8 +828,8 @@ static struct ti_dt_clk dra7xx_clks[] = {
        DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "l4per2-clkctrl:01f8:22"),
        DT_CLK(NULL, "mcasp7_ahclkx_mux", "l4per2-clkctrl:01fc:24"),
        DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "l4per2-clkctrl:01fc:22"),
-       DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per2-clkctrl:0184:22"),
-       DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per2-clkctrl:0184:24"),
+       DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per2-clkctrl:0184:24"),
+       DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per2-clkctrl:0184:22"),
        DT_CLK(NULL, "mmc1_clk32k", "l3init-clkctrl:0008:8"),
        DT_CLK(NULL, "mmc1_fclk_div", "l3init-clkctrl:0008:25"),
        DT_CLK(NULL, "mmc1_fclk_mux", "l3init-clkctrl:0008:24"),
index d8c2bd4..11ff701 100644 (file)
@@ -25,7 +25,9 @@ static __init void timer_of_irq_exit(struct of_timer_irq *of_irq)
 
        struct clock_event_device *clkevt = &to->clkevt;
 
-       of_irq->percpu ? free_percpu_irq(of_irq->irq, clkevt) :
+       if (of_irq->percpu)
+               free_percpu_irq(of_irq->irq, clkevt);
+       else
                free_irq(of_irq->irq, clkevt);
 }
 
index addf074..b1af0de 100644 (file)
@@ -381,7 +381,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
                printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
                       pcie->device_id.vendor_id, pcie->device_id.device_id);
                p = pcie->device_id.class_code;
-               printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]);
+               printk("%s""class_code: %02x%02x%02x\n", pfx, p[2], p[1], p[0]);
        }
        if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
                printk("%s""serial number: 0x%04x, 0x%04x\n", pfx,
index 8d3e778..69f00f7 100644 (file)
@@ -267,6 +267,9 @@ static __init int efivar_ssdt_load(void)
        void *data;
        int ret;
 
+       if (!efivar_ssdt[0])
+               return 0;
+
        ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries);
 
        list_for_each_entry_safe(entry, aux, &entries, list) {
index 3e290f9..76b0c35 100644 (file)
@@ -76,7 +76,7 @@ static u16 checksum(void)
        return chksum;
 }
 
-int __init efi_rci2_sysfs_init(void)
+static int __init efi_rci2_sysfs_init(void)
 {
        struct kobject *tables_kobj;
        int ret = -ENOMEM;
index 1d3f5ca..ebd7977 100644 (file)
@@ -40,7 +40,7 @@ int __init efi_tpm_eventlog_init(void)
 {
        struct linux_efi_tpm_eventlog *log_tbl;
        struct efi_tcg2_final_events_table *final_tbl;
-       unsigned int tbl_size;
+       int tbl_size;
        int ret = 0;
 
        if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) {
@@ -75,16 +75,28 @@ int __init efi_tpm_eventlog_init(void)
                goto out;
        }
 
-       tbl_size = tpm2_calc_event_log_size((void *)efi.tpm_final_log
-                                           + sizeof(final_tbl->version)
-                                           + sizeof(final_tbl->nr_events),
-                                           final_tbl->nr_events,
-                                           log_tbl->log);
+       tbl_size = 0;
+       if (final_tbl->nr_events != 0) {
+               void *events = (void *)efi.tpm_final_log
+                               + sizeof(final_tbl->version)
+                               + sizeof(final_tbl->nr_events);
+
+               tbl_size = tpm2_calc_event_log_size(events,
+                                                   final_tbl->nr_events,
+                                                   log_tbl->log);
+       }
+
+       if (tbl_size < 0) {
+               pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n");
+               goto out_calc;
+       }
+
        memblock_reserve((unsigned long)final_tbl,
                         tbl_size + sizeof(*final_tbl));
-       early_memunmap(final_tbl, sizeof(*final_tbl));
        efi_tpm_final_log_size = tbl_size;
 
+out_calc:
+       early_memunmap(final_tbl, sizeof(*final_tbl));
 out:
        early_memunmap(log_tbl, sizeof(*log_tbl));
        return ret;
index fe7a73f..bb287f3 100644 (file)
@@ -530,11 +530,12 @@ static void sprd_eic_handle_one_type(struct gpio_chip *chip)
                }
 
                for_each_set_bit(n, &reg, SPRD_EIC_PER_BANK_NR) {
-                       girq = irq_find_mapping(chip->irq.domain,
-                                       bank * SPRD_EIC_PER_BANK_NR + n);
+                       u32 offset = bank * SPRD_EIC_PER_BANK_NR + n;
+
+                       girq = irq_find_mapping(chip->irq.domain, offset);
 
                        generic_handle_irq(girq);
-                       sprd_eic_toggle_trigger(chip, girq, n);
+                       sprd_eic_toggle_trigger(chip, girq, offset);
                }
        }
 }
index 47d05e3..faf86ea 100644 (file)
@@ -192,13 +192,13 @@ static int max77620_gpio_set_debounce(struct max77620_gpio *mgpio,
        case 0:
                val = MAX77620_CNFG_GPIO_DBNC_None;
                break;
-       case 1 ... 8:
+       case 1000 ... 8000:
                val = MAX77620_CNFG_GPIO_DBNC_8ms;
                break;
-       case 9 ... 16:
+       case 9000 ... 16000:
                val = MAX77620_CNFG_GPIO_DBNC_16ms;
                break;
-       case 17 ... 32:
+       case 17000 ... 32000:
                val = MAX77620_CNFG_GPIO_DBNC_32ms;
                break;
        default:
index 1eea2c6..80ea49f 100644 (file)
@@ -317,7 +317,7 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
        transitory = flags & OF_GPIO_TRANSITORY;
 
        ret = gpiod_request(desc, label);
-       if (ret == -EBUSY && (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
+       if (ret == -EBUSY && (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
                return desc;
        if (ret)
                return ERR_PTR(ret);
index bdbc164..5833e4f 100644 (file)
@@ -3070,8 +3070,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
                if (!ret)
                        goto set_output_value;
                /* Emulate open drain by not actively driving the line high */
-               if (value)
-                       return gpiod_direction_input(desc);
+               if (value) {
+                       ret = gpiod_direction_input(desc);
+                       goto set_output_flag;
+               }
        }
        else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
                ret = gpio_set_config(gc, gpio_chip_hwgpio(desc),
@@ -3079,8 +3081,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
                if (!ret)
                        goto set_output_value;
                /* Emulate open source by not actively driving the line low */
-               if (!value)
-                       return gpiod_direction_input(desc);
+               if (!value) {
+                       ret = gpiod_direction_input(desc);
+                       goto set_output_flag;
+               }
        } else {
                gpio_set_config(gc, gpio_chip_hwgpio(desc),
                                PIN_CONFIG_DRIVE_PUSH_PULL);
@@ -3088,6 +3092,17 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
 
 set_output_value:
        return gpiod_direction_output_raw_commit(desc, value);
+
+set_output_flag:
+       /*
+        * When emulating open-source or open-drain functionalities by not
+        * actively driving the line (setting mode to input) we still need to
+        * set the IS_OUT flag or otherwise we won't be able to set the line
+        * value anymore.
+        */
+       if (ret == 0)
+               set_bit(FLAG_IS_OUT, &desc->flags);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(gpiod_direction_output);
 
@@ -3448,8 +3463,6 @@ static void gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)
 
        if (value) {
                ret = chip->direction_input(chip, offset);
-               if (!ret)
-                       clear_bit(FLAG_IS_OUT, &desc->flags);
        } else {
                ret = chip->direction_output(chip, offset, 0);
                if (!ret)
@@ -3479,8 +3492,6 @@ static void gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value
                        set_bit(FLAG_IS_OUT, &desc->flags);
        } else {
                ret = chip->direction_input(chip, offset);
-               if (!ret)
-                       clear_bit(FLAG_IS_OUT, &desc->flags);
        }
        trace_gpio_direction(desc_to_gpio(desc), !value, ret);
        if (ret < 0)
index 42e2c1f..00962a6 100644 (file)
@@ -54,7 +54,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
        amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \
        amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \
        amdgpu_gmc.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \
-       amdgpu_vm_sdma.o amdgpu_pmu.o amdgpu_discovery.o amdgpu_ras_eeprom.o smu_v11_0_i2c.o
+       amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o smu_v11_0_i2c.o
 
 amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o
 
index eba42c7..82155ac 100644 (file)
@@ -189,7 +189,7 @@ static int acp_hw_init(void *handle)
        u32 val = 0;
        u32 count = 0;
        struct device *dev;
-       struct i2s_platform_data *i2s_pdata;
+       struct i2s_platform_data *i2s_pdata = NULL;
 
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
@@ -231,20 +231,21 @@ static int acp_hw_init(void *handle)
        adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
                                                        GFP_KERNEL);
 
-       if (adev->acp.acp_cell == NULL)
-               return -ENOMEM;
+       if (adev->acp.acp_cell == NULL) {
+               r = -ENOMEM;
+               goto failure;
+       }
 
        adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
        if (adev->acp.acp_res == NULL) {
-               kfree(adev->acp.acp_cell);
-               return -ENOMEM;
+               r = -ENOMEM;
+               goto failure;
        }
 
        i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
        if (i2s_pdata == NULL) {
-               kfree(adev->acp.acp_res);
-               kfree(adev->acp.acp_cell);
-               return -ENOMEM;
+               r = -ENOMEM;
+               goto failure;
        }
 
        switch (adev->asic_type) {
@@ -341,14 +342,14 @@ static int acp_hw_init(void *handle)
        r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
                                                                ACP_DEVS);
        if (r)
-               return r;
+               goto failure;
 
        for (i = 0; i < ACP_DEVS ; i++) {
                dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
                r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
                if (r) {
                        dev_err(dev, "Failed to add dev to genpd\n");
-                       return r;
+                       goto failure;
                }
        }
 
@@ -367,7 +368,8 @@ static int acp_hw_init(void *handle)
                        break;
                if (--count == 0) {
                        dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
-                       return -ETIMEDOUT;
+                       r = -ETIMEDOUT;
+                       goto failure;
                }
                udelay(100);
        }
@@ -384,7 +386,8 @@ static int acp_hw_init(void *handle)
                        break;
                if (--count == 0) {
                        dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
-                       return -ETIMEDOUT;
+                       r = -ETIMEDOUT;
+                       goto failure;
                }
                udelay(100);
        }
@@ -393,6 +396,13 @@ static int acp_hw_init(void *handle)
        val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
        cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
        return 0;
+
+failure:
+       kfree(i2s_pdata);
+       kfree(adev->acp.acp_res);
+       kfree(adev->acp.acp_cell);
+       kfree(adev->acp.acp_genpd);
+       return r;
 }
 
 /**
index 7bcf86c..61e38e4 100644 (file)
@@ -270,7 +270,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 
        r = amdgpu_bo_create_list_entry_array(&args->in, &info);
        if (r)
-               goto error_free;
+               return r;
 
        switch (args->in.operation) {
        case AMDGPU_BO_LIST_OP_CREATE:
@@ -283,8 +283,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
                r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
                mutex_unlock(&fpriv->bo_list_lock);
                if (r < 0) {
-                       amdgpu_bo_list_put(list);
-                       return r;
+                       goto error_put_list;
                }
 
                handle = r;
@@ -306,9 +305,8 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
                mutex_unlock(&fpriv->bo_list_lock);
 
                if (IS_ERR(old)) {
-                       amdgpu_bo_list_put(list);
                        r = PTR_ERR(old);
-                       goto error_free;
+                       goto error_put_list;
                }
 
                amdgpu_bo_list_put(old);
@@ -325,8 +323,10 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 
        return 0;
 
+error_put_list:
+       amdgpu_bo_list_put(list);
+
 error_free:
-       if (info)
-               kvfree(info);
+       kvfree(info);
        return r;
 }
index 264677a..6f8aaf6 100644 (file)
  * - 3.32.0 - Add syncobj timeline support to AMDGPU_CS.
  * - 3.33.0 - Fixes for GDS ENOMEM failures in AMDGPU_CS.
  * - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
+ * - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
  */
 #define KMS_DRIVER_MAJOR       3
-#define KMS_DRIVER_MINOR       34
+#define KMS_DRIVER_MINOR       35
 #define KMS_DRIVER_PATCHLEVEL  0
 
 #define AMDGPU_MAX_TIMEOUT_PARAM_LENTH 256
index 554a59b..6ee4021 100644 (file)
@@ -165,6 +165,7 @@ struct amdgpu_gfx_config {
        uint32_t num_sc_per_sh;
        uint32_t num_packer_per_sc;
        uint32_t pa_sc_tile_steering_override;
+       uint64_t tcc_disabled_mask;
 };
 
 struct amdgpu_cu_info {
index f614752..f2c0979 100644 (file)
@@ -787,6 +787,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
                        dev_info.pa_sc_tile_steering_override =
                                adev->gfx.config.pa_sc_tile_steering_override;
 
+               dev_info.tcc_disabled_mask = adev->gfx.config.tcc_disabled_mask;
+
                return copy_to_user(out, &dev_info,
                                    min((size_t)size, sizeof(dev_info))) ? -EFAULT : 0;
        }
index e2fb141..5251352 100644 (file)
@@ -603,14 +603,12 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
        struct ttm_bo_global *glob = adev->mman.bdev.glob;
        struct amdgpu_vm_bo_base *bo_base;
 
-#if 0
        if (vm->bulk_moveable) {
                spin_lock(&glob->lru_lock);
                ttm_bo_bulk_move_lru_tail(&vm->lru_bulk_move);
                spin_unlock(&glob->lru_lock);
                return;
        }
-#endif
 
        memset(&vm->lru_bulk_move, 0, sizeof(vm->lru_bulk_move));
 
index 638c821..957811b 100644 (file)
@@ -1691,6 +1691,17 @@ static void gfx_v10_0_tcp_harvest(struct amdgpu_device *adev)
        }
 }
 
+static void gfx_v10_0_get_tcc_info(struct amdgpu_device *adev)
+{
+       /* TCCs are global (not instanced). */
+       uint32_t tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) |
+                              RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE);
+
+       adev->gfx.config.tcc_disabled_mask =
+               REG_GET_FIELD(tcc_disable, CGTS_TCC_DISABLE, TCC_DISABLE) |
+               (REG_GET_FIELD(tcc_disable, CGTS_TCC_DISABLE, HI_TCC_DISABLE) << 16);
+}
+
 static void gfx_v10_0_constants_init(struct amdgpu_device *adev)
 {
        u32 tmp;
@@ -1702,6 +1713,7 @@ static void gfx_v10_0_constants_init(struct amdgpu_device *adev)
 
        gfx_v10_0_setup_rb(adev);
        gfx_v10_0_get_cu_info(adev, &adev->gfx.cu_info);
+       gfx_v10_0_get_tcc_info(adev);
        adev->gfx.config.pa_sc_tile_steering_override =
                gfx_v10_0_init_pa_sc_tile_steering_override(adev);
 
index 85393a9..de9b995 100644 (file)
@@ -317,10 +317,12 @@ static int nv_asic_reset(struct amdgpu_device *adev)
        struct smu_context *smu = &adev->smu;
 
        if (nv_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
-               amdgpu_inc_vram_lost(adev);
+               if (!adev->in_suspend)
+                       amdgpu_inc_vram_lost(adev);
                ret = smu_baco_reset(smu);
        } else {
-               amdgpu_inc_vram_lost(adev);
+               if (!adev->in_suspend)
+                       amdgpu_inc_vram_lost(adev);
                ret = nv_asic_mode1_reset(adev);
        }
 
index f70658a..f8ab80c 100644 (file)
@@ -558,12 +558,14 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
 {
        switch (soc15_asic_reset_method(adev)) {
                case AMD_RESET_METHOD_BACO:
-                       amdgpu_inc_vram_lost(adev);
+                       if (!adev->in_suspend)
+                               amdgpu_inc_vram_lost(adev);
                        return soc15_asic_baco_reset(adev);
                case AMD_RESET_METHOD_MODE2:
                        return soc15_mode2_reset(adev);
                default:
-                       amdgpu_inc_vram_lost(adev);
+                       if (!adev->in_suspend)
+                               amdgpu_inc_vram_lost(adev);
                        return soc15_asic_mode1_reset(adev);
        }
 }
@@ -771,8 +773,6 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
 #if defined(CONFIG_DRM_AMD_DC)
                 else if (amdgpu_device_has_dc_support(adev))
                         amdgpu_device_ip_block_add(adev, &dm_ip_block);
-#else
-#       warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15."
 #endif
                amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
                break;
index 8cab6da..a52f0b1 100644 (file)
@@ -2385,8 +2385,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 
        if (adev->asic_type != CHIP_CARRIZO && adev->asic_type != CHIP_STONEY)
                dm->dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true;
-       if (adev->asic_type == CHIP_RENOIR)
-               dm->dc->debug.disable_stutter = true;
 
        return 0;
 fail:
@@ -6019,7 +6017,9 @@ static void amdgpu_dm_enable_crtc_interrupts(struct drm_device *dev,
        struct drm_crtc *crtc;
        struct drm_crtc_state *old_crtc_state, *new_crtc_state;
        int i;
+#ifdef CONFIG_DEBUG_FS
        enum amdgpu_dm_pipe_crc_source source;
+#endif
 
        for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
                                      new_crtc_state, i) {
index 1787b9b..76d5488 100644 (file)
@@ -668,6 +668,7 @@ struct clock_source *dce100_clock_source_create(
                return &clk_src->base;
        }
 
+       kfree(clk_src);
        BREAK_TO_DEBUGGER();
        return NULL;
 }
index 318e9c2..89620ad 100644 (file)
@@ -714,6 +714,7 @@ struct clock_source *dce110_clock_source_create(
                return &clk_src->base;
        }
 
+       kfree(clk_src);
        BREAK_TO_DEBUGGER();
        return NULL;
 }
index 83e1878..21a657e 100644 (file)
@@ -687,6 +687,7 @@ struct clock_source *dce112_clock_source_create(
                return &clk_src->base;
        }
 
+       kfree(clk_src);
        BREAK_TO_DEBUGGER();
        return NULL;
 }
index 8b85e52..7c52f7f 100644 (file)
@@ -500,6 +500,7 @@ static struct clock_source *dce120_clock_source_create(
                return &clk_src->base;
        }
 
+       kfree(clk_src);
        BREAK_TO_DEBUGGER();
        return NULL;
 }
index 4625df9..643ccb0 100644 (file)
@@ -701,6 +701,7 @@ struct clock_source *dce80_clock_source_create(
                return &clk_src->base;
        }
 
+       kfree(clk_src);
        BREAK_TO_DEBUGGER();
        return NULL;
 }
index 59305e4..1599bb9 100644 (file)
@@ -786,6 +786,7 @@ struct clock_source *dcn10_clock_source_create(
                return &clk_src->base;
        }
 
+       kfree(clk_src);
        BREAK_TO_DEBUGGER();
        return NULL;
 }
index b4e3ce2..5a2763d 100644 (file)
@@ -1077,6 +1077,7 @@ struct clock_source *dcn20_clock_source_create(
                return &clk_src->base;
        }
 
+       kfree(clk_src);
        BREAK_TO_DEBUGGER();
        return NULL;
 }
index 8cd9de8..ef673bf 100644 (file)
@@ -3,7 +3,17 @@
 
 DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o
 
-CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse -mpreferred-stack-boundary=4
+ifneq ($(call cc-option, -mpreferred-stack-boundary=4),)
+       cc_stack_align := -mpreferred-stack-boundary=4
+else ifneq ($(call cc-option, -mstack-alignment=16),)
+       cc_stack_align := -mstack-alignment=16
+endif
+
+CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse $(cc_stack_align)
+
+ifdef CONFIG_CC_IS_CLANG
+CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -msse2
+endif
 
 AMD_DAL_DCN21 = $(addprefix $(AMDDALPATH)/dc/dcn21/,$(DCN21))
 
index 456cd0e..3b6ed60 100644 (file)
@@ -39,9 +39,6 @@
  * ways. Unless there is something clearly wrong with it the code should
  * remain as-is as it provides us with a guarantee from HW that it is correct.
  */
-
-typedef unsigned int uint;
-
 typedef struct {
        double DPPCLK;
        double DISPCLK;
@@ -4774,7 +4771,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                                mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = 0.0;
                                mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
                                for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
-                                       uint m;
+                                       unsigned int m;
 
                                        locals->cursor_bw[k] = 0;
                                        locals->cursor_bw_pre[k] = 0;
@@ -5285,7 +5282,7 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport(
        double SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank;
        double FullDETBufferingTimeYStutterCriticalPlane = 0;
        double TimeToFinishSwathTransferStutterCriticalPlane = 0;
-       uint k, j;
+       unsigned int k, j;
 
        mode_lib->vba.TotalActiveDPP = 0;
        mode_lib->vba.TotalDCCActiveDPP = 0;
@@ -5507,7 +5504,7 @@ static void CalculateDCFCLKDeepSleep(
                double DPPCLK[],
                double *DCFCLKDeepSleep)
 {
-       uint k;
+       unsigned int k;
        double DisplayPipeLineDeliveryTimeLuma;
        double DisplayPipeLineDeliveryTimeChroma;
        //double   DCFCLKDeepSleepPerPlane[DC__NUM_DPP__MAX];
@@ -5727,7 +5724,7 @@ static void CalculatePixelDeliveryTimes(
                double DisplayPipeRequestDeliveryTimeChromaPrefetch[])
 {
        double req_per_swath_ub;
-       uint k;
+       unsigned int k;
 
        for (k = 0; k < NumberOfActivePlanes; ++k) {
                if (VRatio[k] <= 1) {
@@ -5869,7 +5866,7 @@ static void CalculateMetaAndPTETimes(
        unsigned int dpte_groups_per_row_chroma_ub;
        unsigned int num_group_per_lower_vm_stage;
        unsigned int num_req_per_lower_vm_stage;
-       uint k;
+       unsigned int k;
 
        for (k = 0; k < NumberOfActivePlanes; ++k) {
                if (GPUVMEnable == true) {
index 33960fb..4acf139 100644 (file)
@@ -843,6 +843,8 @@ static int smu_sw_init(void *handle)
        smu->smu_baco.state = SMU_BACO_STATE_EXIT;
        smu->smu_baco.platform_support = false;
 
+       mutex_init(&smu->sensor_lock);
+
        smu->watermarks_bitmap = 0;
        smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
        smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
index f1f0720..d493a3f 100644 (file)
@@ -1018,6 +1018,7 @@ static int arcturus_read_sensor(struct smu_context *smu,
        if (!data || !size)
                return -EINVAL;
 
+       mutex_lock(&smu->sensor_lock);
        switch (sensor) {
        case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
                *(uint32_t *)data = pptable->FanMaximumRpm;
@@ -1044,6 +1045,7 @@ static int arcturus_read_sensor(struct smu_context *smu,
        default:
                ret = smu_smc_read_sensor(smu, sensor, data, size);
        }
+       mutex_unlock(&smu->sensor_lock);
 
        return ret;
 }
index 6109815..23171a4 100644 (file)
@@ -344,6 +344,7 @@ struct smu_context
        const struct smu_funcs          *funcs;
        const struct pptable_funcs      *ppt_funcs;
        struct mutex                    mutex;
+       struct mutex                    sensor_lock;
        uint64_t pool_size;
 
        struct smu_table_context        smu_table;
index 12c0e46..0b46140 100644 (file)
@@ -547,7 +547,7 @@ static int navi10_get_metrics_table(struct smu_context *smu,
        struct smu_table_context *smu_table= &smu->smu_table;
        int ret = 0;
 
-       if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) {
+       if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(100))) {
                ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
                                (void *)smu_table->metrics_table, false);
                if (ret) {
@@ -1386,6 +1386,7 @@ static int navi10_read_sensor(struct smu_context *smu,
        if(!data || !size)
                return -EINVAL;
 
+       mutex_lock(&smu->sensor_lock);
        switch (sensor) {
        case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
                *(uint32_t *)data = pptable->FanMaximumRpm;
@@ -1409,6 +1410,7 @@ static int navi10_read_sensor(struct smu_context *smu,
        default:
                ret = smu_smc_read_sensor(smu, sensor, data, size);
        }
+       mutex_unlock(&smu->sensor_lock);
 
        return ret;
 }
index 64386ee..bbd8ebd 100644 (file)
@@ -3023,6 +3023,7 @@ static int vega20_read_sensor(struct smu_context *smu,
        if(!data || !size)
                return -EINVAL;
 
+       mutex_lock(&smu->sensor_lock);
        switch (sensor) {
        case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
                *(uint32_t *)data = pptable->FanMaximumRpm;
@@ -3048,6 +3049,7 @@ static int vega20_read_sensor(struct smu_context *smu,
        default:
                ret = smu_smc_read_sensor(smu, sensor, data, size);
        }
+       mutex_unlock(&smu->sensor_lock);
 
        return ret;
 }
index 2851cac..b72840c 100644 (file)
@@ -43,9 +43,8 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
        struct komeda_data_flow_cfg dflow;
        int err;
 
-       if (!writeback_job || !writeback_job->fb) {
+       if (!writeback_job)
                return 0;
-       }
 
        if (!crtc_st->active) {
                DRM_DEBUG_ATOMIC("Cannot write the composition result out on a inactive CRTC.\n");
@@ -166,8 +165,10 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms,
                                           &komeda_wb_encoder_helper_funcs,
                                           formats, n_formats);
        komeda_put_fourcc_list(formats);
-       if (err)
+       if (err) {
+               kfree(kwb_conn);
                return err;
+       }
 
        drm_connector_helper_add(&wb_conn->base, &komeda_wb_conn_helper_funcs);
 
index 22c0847..875a3a9 100644 (file)
@@ -131,7 +131,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
        struct drm_framebuffer *fb;
        int i, n_planes;
 
-       if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+       if (!conn_state->writeback_job)
                return 0;
 
        fb = conn_state->writeback_job->fb;
@@ -248,7 +248,7 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
 
        mw_state = to_mw_state(conn_state);
 
-       if (conn_state->writeback_job && conn_state->writeback_job->fb) {
+       if (conn_state->writeback_job) {
                struct drm_framebuffer *fb = conn_state->writeback_job->fb;
 
                DRM_DEV_DEBUG_DRIVER(drm->dev,
index cebc8e6..8a8d605 100644 (file)
@@ -728,6 +728,8 @@ static int tc_set_video_mode(struct tc_data *tc,
        int lower_margin = mode->vsync_start - mode->vdisplay;
        int vsync_len = mode->vsync_end - mode->vsync_start;
        u32 dp0_syncval;
+       u32 bits_per_pixel = 24;
+       u32 in_bw, out_bw;
 
        /*
         * Recommended maximum number of symbols transferred in a transfer unit:
@@ -735,7 +737,10 @@ static int tc_set_video_mode(struct tc_data *tc,
         *              (output active video bandwidth in bytes))
         * Must be less than tu_size.
         */
-       max_tu_symbol = TU_SIZE_RECOMMENDED - 1;
+
+       in_bw = mode->clock * bits_per_pixel / 8;
+       out_bw = tc->link.base.num_lanes * tc->link.base.rate;
+       max_tu_symbol = DIV_ROUND_UP(in_bw * TU_SIZE_RECOMMENDED, out_bw);
 
        dev_dbg(tc->dev, "set mode %dx%d\n",
                mode->hdisplay, mode->vdisplay);
index 419381a..14aeaf7 100644 (file)
@@ -430,10 +430,15 @@ static int drm_atomic_connector_check(struct drm_connector *connector,
                return -EINVAL;
        }
 
-       if (writeback_job->out_fence && !writeback_job->fb) {
-               DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
-                                connector->base.id, connector->name);
-               return -EINVAL;
+       if (!writeback_job->fb) {
+               if (writeback_job->out_fence) {
+                       DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
+                                        connector->base.id, connector->name);
+                       return -EINVAL;
+               }
+
+               drm_writeback_cleanup_job(writeback_job);
+               state->writeback_job = NULL;
        }
 
        return 0;
index ff138b6..43d9e3b 100644 (file)
@@ -324,6 +324,9 @@ void drm_writeback_cleanup_job(struct drm_writeback_job *job)
        if (job->fb)
                drm_framebuffer_put(job->fb);
 
+       if (job->out_fence)
+               dma_fence_put(job->out_fence);
+
        kfree(job);
 }
 EXPORT_SYMBOL(drm_writeback_cleanup_job);
@@ -366,25 +369,29 @@ drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector,
 {
        unsigned long flags;
        struct drm_writeback_job *job;
+       struct dma_fence *out_fence;
 
        spin_lock_irqsave(&wb_connector->job_lock, flags);
        job = list_first_entry_or_null(&wb_connector->job_queue,
                                       struct drm_writeback_job,
                                       list_entry);
-       if (job) {
+       if (job)
                list_del(&job->list_entry);
-               if (job->out_fence) {
-                       if (status)
-                               dma_fence_set_error(job->out_fence, status);
-                       dma_fence_signal(job->out_fence);
-                       dma_fence_put(job->out_fence);
-               }
-       }
+
        spin_unlock_irqrestore(&wb_connector->job_lock, flags);
 
        if (WARN_ON(!job))
                return;
 
+       out_fence = job->out_fence;
+       if (out_fence) {
+               if (status)
+                       dma_fence_set_error(out_fence, status);
+               dma_fence_signal(out_fence);
+               dma_fence_put(out_fence);
+               job->out_fence = NULL;
+       }
+
        INIT_WORK(&job->cleanup_work, cleanup_work);
        queue_work(system_long_wq, &job->cleanup_work);
 }
index b51d1ce..aa54bb2 100644 (file)
@@ -3280,7 +3280,20 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb,
        switch (fb->modifier) {
        case DRM_FORMAT_MOD_LINEAR:
        case I915_FORMAT_MOD_X_TILED:
-               return 4096;
+               /*
+                * Validated limit is 4k, but has 5k should
+                * work apart from the following features:
+                * - Ytile (already limited to 4k)
+                * - FP16 (already limited to 4k)
+                * - render compression (already limited to 4k)
+                * - KVMR sprite and cursor (don't care)
+                * - horizontal panning (TODO verify this)
+                * - pipe and plane scaling (TODO verify this)
+                */
+               if (cpp == 8)
+                       return 4096;
+               else
+                       return 5120;
        case I915_FORMAT_MOD_Y_TILED_CCS:
        case I915_FORMAT_MOD_Yf_TILED_CCS:
                /* FIXME AUX plane? */
@@ -7261,7 +7274,7 @@ retry:
        pipe_config->fdi_lanes = lane;
 
        intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
-                              link_bw, &pipe_config->fdi_m_n, false);
+                              link_bw, &pipe_config->fdi_m_n, false, false);
 
        ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
        if (ret == -EDEADLK)
@@ -7508,11 +7521,15 @@ void
 intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
                       int pixel_clock, int link_clock,
                       struct intel_link_m_n *m_n,
-                      bool constant_n)
+                      bool constant_n, bool fec_enable)
 {
-       m_n->tu = 64;
+       u32 data_clock = bits_per_pixel * pixel_clock;
 
-       compute_m_n(bits_per_pixel * pixel_clock,
+       if (fec_enable)
+               data_clock = intel_dp_mode_to_fec_clock(data_clock);
+
+       m_n->tu = 64;
+       compute_m_n(data_clock,
                    link_clock * nlanes * 8,
                    &m_n->gmch_m, &m_n->gmch_n,
                    constant_n);
index e57e696..01fa87a 100644 (file)
@@ -414,7 +414,7 @@ enum phy_fia {
 void intel_link_compute_m_n(u16 bpp, int nlanes,
                            int pixel_clock, int link_clock,
                            struct intel_link_m_n *m_n,
-                           bool constant_n);
+                           bool constant_n, bool fec_enable);
 bool is_ccs_modifier(u64 modifier);
 void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
 u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
index 921ad0a..57e9f0b 100644 (file)
@@ -78,8 +78,8 @@
 #define DP_DSC_MAX_ENC_THROUGHPUT_0            340000
 #define DP_DSC_MAX_ENC_THROUGHPUT_1            400000
 
-/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
-#define DP_DSC_FEC_OVERHEAD_FACTOR             976
+/* DP DSC FEC Overhead factor = 1/(0.972261) */
+#define DP_DSC_FEC_OVERHEAD_FACTOR             972261
 
 /* Compliance test status bits  */
 #define INTEL_DP_RESOLUTION_SHIFT_MASK 0
@@ -494,6 +494,97 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
        return 0;
 }
 
+u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
+{
+       return div_u64(mul_u32_u32(mode_clock, 1000000U),
+                      DP_DSC_FEC_OVERHEAD_FACTOR);
+}
+
+static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
+                                      u32 mode_clock, u32 mode_hdisplay)
+{
+       u32 bits_per_pixel, max_bpp_small_joiner_ram;
+       int i;
+
+       /*
+        * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
+        * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
+        * for SST -> TimeSlotsPerMTP is 1,
+        * for MST -> TimeSlotsPerMTP has to be calculated
+        */
+       bits_per_pixel = (link_clock * lane_count * 8) /
+                        intel_dp_mode_to_fec_clock(mode_clock);
+       DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
+
+       /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+       max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
+       DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
+
+       /*
+        * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
+        * check, output bpp from small joiner RAM check)
+        */
+       bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
+
+       /* Error out if the max bpp is less than smallest allowed valid bpp */
+       if (bits_per_pixel < valid_dsc_bpp[0]) {
+               DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
+                             bits_per_pixel, valid_dsc_bpp[0]);
+               return 0;
+       }
+
+       /* Find the nearest match in the array of known BPPs from VESA */
+       for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
+               if (bits_per_pixel < valid_dsc_bpp[i + 1])
+                       break;
+       }
+       bits_per_pixel = valid_dsc_bpp[i];
+
+       /*
+        * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
+        * fractional part is 0
+        */
+       return bits_per_pixel << 4;
+}
+
+static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
+                                      int mode_clock, int mode_hdisplay)
+{
+       u8 min_slice_count, i;
+       int max_slice_width;
+
+       if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
+               min_slice_count = DIV_ROUND_UP(mode_clock,
+                                              DP_DSC_MAX_ENC_THROUGHPUT_0);
+       else
+               min_slice_count = DIV_ROUND_UP(mode_clock,
+                                              DP_DSC_MAX_ENC_THROUGHPUT_1);
+
+       max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
+       if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
+               DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
+                             max_slice_width);
+               return 0;
+       }
+       /* Also take into account max slice width */
+       min_slice_count = min_t(u8, min_slice_count,
+                               DIV_ROUND_UP(mode_hdisplay,
+                                            max_slice_width));
+
+       /* Find the closest match to the valid slice count values */
+       for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
+               if (valid_dsc_slicecount[i] >
+                   drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
+                                                   false))
+                       break;
+               if (min_slice_count  <= valid_dsc_slicecount[i])
+                       return valid_dsc_slicecount[i];
+       }
+
+       DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
+       return 0;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
@@ -2226,7 +2317,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
                               adjusted_mode->crtc_clock,
                               pipe_config->port_clock,
                               &pipe_config->dp_m_n,
-                              constant_n);
+                              constant_n, pipe_config->fec_enable);
 
        if (intel_connector->panel.downclock_mode != NULL &&
                dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
@@ -2236,7 +2327,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
                                               intel_connector->panel.downclock_mode->clock,
                                               pipe_config->port_clock,
                                               &pipe_config->dp_m2_n2,
-                                              constant_n);
+                                              constant_n, pipe_config->fec_enable);
        }
 
        if (!HAS_DDI(dev_priv))
@@ -4323,91 +4414,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
                DP_DPRX_ESI_LEN;
 }
 
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-                               int mode_clock, int mode_hdisplay)
-{
-       u16 bits_per_pixel, max_bpp_small_joiner_ram;
-       int i;
-
-       /*
-        * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
-        * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
-        * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
-        * for MST -> TimeSlotsPerMTP has to be calculated
-        */
-       bits_per_pixel = (link_clock * lane_count * 8 *
-                         DP_DSC_FEC_OVERHEAD_FACTOR) /
-               mode_clock;
-
-       /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-       max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
-               mode_hdisplay;
-
-       /*
-        * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
-        * check, output bpp from small joiner RAM check)
-        */
-       bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-       /* Error out if the max bpp is less than smallest allowed valid bpp */
-       if (bits_per_pixel < valid_dsc_bpp[0]) {
-               DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
-               return 0;
-       }
-
-       /* Find the nearest match in the array of known BPPs from VESA */
-       for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
-               if (bits_per_pixel < valid_dsc_bpp[i + 1])
-                       break;
-       }
-       bits_per_pixel = valid_dsc_bpp[i];
-
-       /*
-        * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-        * fractional part is 0
-        */
-       return bits_per_pixel << 4;
-}
-
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
-                               int mode_clock,
-                               int mode_hdisplay)
-{
-       u8 min_slice_count, i;
-       int max_slice_width;
-
-       if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
-               min_slice_count = DIV_ROUND_UP(mode_clock,
-                                              DP_DSC_MAX_ENC_THROUGHPUT_0);
-       else
-               min_slice_count = DIV_ROUND_UP(mode_clock,
-                                              DP_DSC_MAX_ENC_THROUGHPUT_1);
-
-       max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
-       if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
-               DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
-                             max_slice_width);
-               return 0;
-       }
-       /* Also take into account max slice width */
-       min_slice_count = min_t(u8, min_slice_count,
-                               DIV_ROUND_UP(mode_hdisplay,
-                                            max_slice_width));
-
-       /* Find the closest match to the valid slice count values */
-       for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
-               if (valid_dsc_slicecount[i] >
-                   drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
-                                                   false))
-                       break;
-               if (min_slice_count  <= valid_dsc_slicecount[i])
-                       return valid_dsc_slicecount[i];
-       }
-
-       DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
-       return 0;
-}
-
 static void
 intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
                               const struct intel_crtc_state *crtc_state)
index 657bbb1..00981fb 100644 (file)
@@ -102,10 +102,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-                               int mode_clock, int mode_hdisplay);
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
-                               int mode_hdisplay);
 
 bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
@@ -118,4 +114,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
        return ~((1 << lane_count) - 1) & 0xf;
 }
 
+u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
+
 #endif /* __INTEL_DP_H__ */
index 6df240a..600873c 100644 (file)
@@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
                               adjusted_mode->crtc_clock,
                               crtc_state->port_clock,
                               &crtc_state->dp_m_n,
-                              constant_n);
+                              constant_n, crtc_state->fec_enable);
        crtc_state->dp_m_n.tu = slots;
 
        return 0;
@@ -615,7 +615,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
        intel_encoder->type = INTEL_OUTPUT_DP_MST;
        intel_encoder->power_domain = intel_dig_port->base.power_domain;
        intel_encoder->port = intel_dig_port->base.port;
-       intel_encoder->crtc_mask = BIT(pipe);
+       intel_encoder->crtc_mask = 0x7;
        intel_encoder->cloneable = 0;
 
        intel_encoder->compute_config = intel_dp_mst_compute_config;
index dea63be..cae25e4 100644 (file)
@@ -1528,6 +1528,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
        int src_x, src_w, src_h, crtc_w, crtc_h;
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->base.adjusted_mode;
+       unsigned int stride = plane_state->color_plane[0].stride;
        unsigned int cpp = fb->format->cpp[0];
        unsigned int width_bytes;
        int min_width, min_height;
@@ -1569,9 +1570,9 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
                return -EINVAL;
        }
 
-       if (width_bytes > 4096 || fb->pitches[0] > 4096) {
+       if (stride > 4096) {
                DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
-                             fb->pitches[0], 4096);
+                             stride, 4096);
                return -EINVAL;
        }
 
index 261c9bd..91051e1 100644 (file)
@@ -245,11 +245,9 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
 
        wakeref = intel_runtime_pm_get(rpm);
 
-       srcu = intel_gt_reset_trylock(ggtt->vm.gt);
-       if (srcu < 0) {
-               ret = srcu;
+       ret = intel_gt_reset_trylock(ggtt->vm.gt, &srcu);
+       if (ret)
                goto err_rpm;
-       }
 
        ret = i915_mutex_lock_interruptible(dev);
        if (ret)
@@ -318,7 +316,11 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
                intel_wakeref_auto(&i915->ggtt.userfault_wakeref,
                                   msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
 
-       i915_vma_set_ggtt_write(vma);
+       if (write) {
+               GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
+               i915_vma_set_ggtt_write(vma);
+               obj->mm.dirty = true;
+       }
 
 err_fence:
        i915_vma_unpin_fence(vma);
index 92e53c2..ad2a63d 100644 (file)
@@ -241,9 +241,6 @@ void i915_gem_resume(struct drm_i915_private *i915)
        mutex_lock(&i915->drm.struct_mutex);
        intel_uncore_forcewake_get(&i915->uncore, FORCEWAKE_ALL);
 
-       i915_gem_restore_gtt_mappings(i915);
-       i915_gem_restore_fences(i915);
-
        if (i915_gem_init_hw(i915))
                goto err_wedged;
 
index d3c6993..22aab85 100644 (file)
@@ -136,6 +136,20 @@ execlists_active(const struct intel_engine_execlists *execlists)
        return READ_ONCE(*execlists->active);
 }
 
+static inline void
+execlists_active_lock_bh(struct intel_engine_execlists *execlists)
+{
+       local_bh_disable(); /* prevent local softirq and lock recursion */
+       tasklet_lock(&execlists->tasklet);
+}
+
+static inline void
+execlists_active_unlock_bh(struct intel_engine_execlists *execlists)
+{
+       tasklet_unlock(&execlists->tasklet);
+       local_bh_enable(); /* restore softirq, and kick ksoftirqd! */
+}
+
 struct i915_request *
 execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists);
 
index 82630db..4ce8626 100644 (file)
@@ -1197,9 +1197,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
                                         struct drm_printer *m)
 {
        struct drm_i915_private *dev_priv = engine->i915;
-       const struct intel_engine_execlists * const execlists =
-               &engine->execlists;
-       unsigned long flags;
+       struct intel_engine_execlists * const execlists = &engine->execlists;
        u64 addr;
 
        if (engine->id == RENDER_CLASS && IS_GEN_RANGE(dev_priv, 4, 7))
@@ -1281,7 +1279,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
                                   idx, hws[idx * 2], hws[idx * 2 + 1]);
                }
 
-               spin_lock_irqsave(&engine->active.lock, flags);
+               execlists_active_lock_bh(execlists);
                for (port = execlists->active; (rq = *port); port++) {
                        char hdr[80];
                        int len;
@@ -1309,7 +1307,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
                                 hwsp_seqno(rq));
                        print_request(m, rq, hdr);
                }
-               spin_unlock_irqrestore(&engine->active.lock, flags);
+               execlists_active_unlock_bh(execlists);
        } else if (INTEL_GEN(dev_priv) > 6) {
                drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n",
                           ENGINE_READ(engine, RING_PP_DIR_BASE));
@@ -1440,8 +1438,8 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine)
        if (!intel_engine_supports_stats(engine))
                return -ENODEV;
 
-       spin_lock_irqsave(&engine->active.lock, flags);
-       write_seqlock(&engine->stats.lock);
+       execlists_active_lock_bh(execlists);
+       write_seqlock_irqsave(&engine->stats.lock, flags);
 
        if (unlikely(engine->stats.enabled == ~0)) {
                err = -EBUSY;
@@ -1469,8 +1467,8 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine)
        }
 
 unlock:
-       write_sequnlock(&engine->stats.lock);
-       spin_unlock_irqrestore(&engine->active.lock, flags);
+       write_sequnlock_irqrestore(&engine->stats.lock, flags);
+       execlists_active_unlock_bh(execlists);
 
        return err;
 }
index d425844..bdfcc7b 100644 (file)
@@ -631,7 +631,6 @@ execlists_schedule_out(struct i915_request *rq)
        struct intel_engine_cs *cur, *old;
 
        trace_i915_request_out(rq);
-       GEM_BUG_ON(intel_context_inflight(ce) != rq->engine);
 
        old = READ_ONCE(ce->inflight);
        do
@@ -797,6 +796,17 @@ static bool can_merge_rq(const struct i915_request *prev,
        GEM_BUG_ON(prev == next);
        GEM_BUG_ON(!assert_priority_queue(prev, next));
 
+       /*
+        * We do not submit known completed requests. Therefore if the next
+        * request is already completed, we can pretend to merge it in
+        * with the previous context (and we will skip updating the ELSP
+        * and tracking). Thus hopefully keeping the ELSP full with active
+        * contexts, despite the best efforts of preempt-to-busy to confuse
+        * us.
+        */
+       if (i915_request_completed(next))
+               return true;
+
        if (!can_merge_ctx(prev->hw_context, next->hw_context))
                return false;
 
@@ -893,7 +903,7 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
 static struct i915_request *
 last_active(const struct intel_engine_execlists *execlists)
 {
-       struct i915_request * const *last = execlists->active;
+       struct i915_request * const *last = READ_ONCE(execlists->active);
 
        while (*last && i915_request_completed(*last))
                last++;
@@ -1172,21 +1182,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                                continue;
                        }
 
-                       if (i915_request_completed(rq)) {
-                               ve->request = NULL;
-                               ve->base.execlists.queue_priority_hint = INT_MIN;
-                               rb_erase_cached(rb, &execlists->virtual);
-                               RB_CLEAR_NODE(rb);
-
-                               rq->engine = engine;
-                               __i915_request_submit(rq);
-
-                               spin_unlock(&ve->base.active.lock);
-
-                               rb = rb_first_cached(&execlists->virtual);
-                               continue;
-                       }
-
                        if (last && !can_merge_rq(last, rq)) {
                                spin_unlock(&ve->base.active.lock);
                                return; /* leave this for another */
@@ -1237,11 +1232,23 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                                GEM_BUG_ON(ve->siblings[0] != engine);
                        }
 
-                       __i915_request_submit(rq);
-                       if (!i915_request_completed(rq)) {
+                       if (__i915_request_submit(rq)) {
                                submit = true;
                                last = rq;
                        }
+
+                       /*
+                        * Hmm, we have a bunch of virtual engine requests,
+                        * but the first one was already completed (thanks
+                        * preempt-to-busy!). Keep looking at the veng queue
+                        * until we have no more relevant requests (i.e.
+                        * the normal submit queue has higher priority).
+                        */
+                       if (!submit) {
+                               spin_unlock(&ve->base.active.lock);
+                               rb = rb_first_cached(&execlists->virtual);
+                               continue;
+                       }
                }
 
                spin_unlock(&ve->base.active.lock);
@@ -1254,8 +1261,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                int i;
 
                priolist_for_each_request_consume(rq, rn, p, i) {
-                       if (i915_request_completed(rq))
-                               goto skip;
+                       bool merge = true;
 
                        /*
                         * Can we combine this request with the current port?
@@ -1296,14 +1302,23 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                                    ctx_single_port_submission(rq->hw_context))
                                        goto done;
 
-                               *port = execlists_schedule_in(last, port - execlists->pending);
-                               port++;
+                               merge = false;
                        }
 
-                       last = rq;
-                       submit = true;
-skip:
-                       __i915_request_submit(rq);
+                       if (__i915_request_submit(rq)) {
+                               if (!merge) {
+                                       *port = execlists_schedule_in(last, port - execlists->pending);
+                                       port++;
+                                       last = NULL;
+                               }
+
+                               GEM_BUG_ON(last &&
+                                          !can_merge_ctx(last->hw_context,
+                                                         rq->hw_context));
+
+                               submit = true;
+                               last = rq;
+                       }
                }
 
                rb_erase_cached(&p->node, &execlists->queue);
@@ -1593,8 +1608,11 @@ static void process_csb(struct intel_engine_cs *engine)
 static void __execlists_submission_tasklet(struct intel_engine_cs *const engine)
 {
        lockdep_assert_held(&engine->active.lock);
-       if (!engine->execlists.pending[0])
+       if (!engine->execlists.pending[0]) {
+               rcu_read_lock(); /* protect peeking at execlists->active */
                execlists_dequeue(engine);
+               rcu_read_unlock();
+       }
 }
 
 /*
@@ -2399,10 +2417,14 @@ static void reset_csb_pointers(struct intel_engine_cs *engine)
 
 static struct i915_request *active_request(struct i915_request *rq)
 {
-       const struct list_head * const list = &rq->timeline->requests;
        const struct intel_context * const ce = rq->hw_context;
        struct i915_request *active = NULL;
+       struct list_head *list;
+
+       if (!i915_request_is_active(rq)) /* unwound, but incomplete! */
+               return rq;
 
+       list = &rq->timeline->requests;
        list_for_each_entry_from_reverse(rq, list, link) {
                if (i915_request_completed(rq))
                        break;
@@ -2565,7 +2587,6 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
                int i;
 
                priolist_for_each_request_consume(rq, rn, p, i) {
-                       list_del_init(&rq->sched.link);
                        __i915_request_submit(rq);
                        dma_fence_set_error(&rq->fence, -EIO);
                        i915_request_mark_complete(rq);
@@ -3631,18 +3652,22 @@ static void
 virtual_bond_execute(struct i915_request *rq, struct dma_fence *signal)
 {
        struct virtual_engine *ve = to_virtual_engine(rq->engine);
+       intel_engine_mask_t allowed, exec;
        struct ve_bond *bond;
 
+       allowed = ~to_request(signal)->engine->mask;
+
        bond = virtual_find_bond(ve, to_request(signal)->engine);
-       if (bond) {
-               intel_engine_mask_t old, new, cmp;
+       if (bond)
+               allowed &= bond->sibling_mask;
 
-               cmp = READ_ONCE(rq->execution_mask);
-               do {
-                       old = cmp;
-                       new = cmp & bond->sibling_mask;
-               } while ((cmp = cmpxchg(&rq->execution_mask, old, new)) != old);
-       }
+       /* Restrict the bonded request to run on only the available engines */
+       exec = READ_ONCE(rq->execution_mask);
+       while (!try_cmpxchg(&rq->execution_mask, &exec, exec & allowed))
+               ;
+
+       /* Prevent the master from being re-run on the bonded engines */
+       to_request(signal)->execution_mask &= ~allowed;
 }
 
 struct intel_context *
index b9d84d5..8cea423 100644 (file)
@@ -42,11 +42,10 @@ static void engine_skip_context(struct i915_request *rq)
        struct intel_engine_cs *engine = rq->engine;
        struct i915_gem_context *hung_ctx = rq->gem_context;
 
-       lockdep_assert_held(&engine->active.lock);
-
        if (!i915_request_is_active(rq))
                return;
 
+       lockdep_assert_held(&engine->active.lock);
        list_for_each_entry_continue(rq, &engine->active.requests, sched.link)
                if (rq->gem_context == hung_ctx)
                        i915_request_skip(rq, -EIO);
@@ -123,7 +122,6 @@ void __i915_request_reset(struct i915_request *rq, bool guilty)
                  rq->fence.seqno,
                  yesno(guilty));
 
-       lockdep_assert_held(&rq->engine->active.lock);
        GEM_BUG_ON(i915_request_completed(rq));
 
        if (guilty) {
@@ -1214,10 +1212,8 @@ out:
        intel_runtime_pm_put(&gt->i915->runtime_pm, wakeref);
 }
 
-int intel_gt_reset_trylock(struct intel_gt *gt)
+int intel_gt_reset_trylock(struct intel_gt *gt, int *srcu)
 {
-       int srcu;
-
        might_lock(&gt->reset.backoff_srcu);
        might_sleep();
 
@@ -1232,10 +1228,10 @@ int intel_gt_reset_trylock(struct intel_gt *gt)
 
                rcu_read_lock();
        }
-       srcu = srcu_read_lock(&gt->reset.backoff_srcu);
+       *srcu = srcu_read_lock(&gt->reset.backoff_srcu);
        rcu_read_unlock();
 
-       return srcu;
+       return 0;
 }
 
 void intel_gt_reset_unlock(struct intel_gt *gt, int tag)
index 37a987b..52c0019 100644 (file)
@@ -38,7 +38,7 @@ int intel_engine_reset(struct intel_engine_cs *engine,
 
 void __i915_request_reset(struct i915_request *rq, bool guilty);
 
-int __must_check intel_gt_reset_trylock(struct intel_gt *gt);
+int __must_check intel_gt_reset_trylock(struct intel_gt *gt, int *srcu);
 void intel_gt_reset_unlock(struct intel_gt *gt, int tag);
 
 void intel_gt_set_wedged(struct intel_gt *gt);
index 601c162..bacaa7b 100644 (file)
@@ -1573,7 +1573,7 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags)
        struct intel_engine_cs *engine = rq->engine;
        enum intel_engine_id id;
        const int num_engines =
-               IS_HSW_GT1(i915) ? RUNTIME_INFO(i915)->num_engines - 1 : 0;
+               IS_HASWELL(i915) ? RUNTIME_INFO(i915)->num_engines - 1 : 0;
        bool force_restore = false;
        int len;
        u32 *cs;
index 45481eb..5f6ec2f 100644 (file)
@@ -1063,6 +1063,9 @@ static void gen9_whitelist_build(struct i915_wa_list *w)
 
        /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
        whitelist_reg(w, GEN8_HDC_CHICKEN1);
+
+       /* WaSendPushConstantsFromMMIO:skl,bxt */
+       whitelist_reg(w, COMMON_SLICE_CHICKEN2);
 }
 
 static void skl_whitelist_build(struct intel_engine_cs *engine)
index 0206967..bb6f86c 100644 (file)
@@ -1924,6 +1924,11 @@ static int i915_drm_resume(struct drm_device *dev)
        if (ret)
                DRM_ERROR("failed to re-enable GGTT\n");
 
+       mutex_lock(&dev_priv->drm.struct_mutex);
+       i915_gem_restore_gtt_mappings(dev_priv);
+       i915_gem_restore_fences(dev_priv);
+       mutex_unlock(&dev_priv->drm.struct_mutex);
+
        intel_csr_ucode_resume(dev_priv);
 
        i915_restore_state(dev_priv);
index 167a7b5..6795f1d 100644 (file)
@@ -77,6 +77,12 @@ struct drm_i915_private;
 
 #define I915_GEM_IDLE_TIMEOUT (HZ / 5)
 
+static inline void tasklet_lock(struct tasklet_struct *t)
+{
+       while (!tasklet_trylock(t))
+               cpu_relax();
+}
+
 static inline void __tasklet_disable_sync_once(struct tasklet_struct *t)
 {
        if (!atomic_fetch_inc(&t->count))
index a53777d..1c55068 100644 (file)
@@ -194,6 +194,27 @@ static void free_capture_list(struct i915_request *request)
        }
 }
 
+static void remove_from_engine(struct i915_request *rq)
+{
+       struct intel_engine_cs *engine, *locked;
+
+       /*
+        * Virtual engines complicate acquiring the engine timeline lock,
+        * as their rq->engine pointer is not stable until under that
+        * engine lock. The simple ploy we use is to take the lock then
+        * check that the rq still belongs to the newly locked engine.
+        */
+       locked = READ_ONCE(rq->engine);
+       spin_lock(&locked->active.lock);
+       while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {
+               spin_unlock(&locked->active.lock);
+               spin_lock(&engine->active.lock);
+               locked = engine;
+       }
+       list_del(&rq->sched.link);
+       spin_unlock(&locked->active.lock);
+}
+
 static bool i915_request_retire(struct i915_request *rq)
 {
        struct i915_active_request *active, *next;
@@ -259,9 +280,7 @@ static bool i915_request_retire(struct i915_request *rq)
         * request that we have removed from the HW and put back on a run
         * queue.
         */
-       spin_lock(&rq->engine->active.lock);
-       list_del(&rq->sched.link);
-       spin_unlock(&rq->engine->active.lock);
+       remove_from_engine(rq);
 
        spin_lock(&rq->lock);
        i915_request_mark_complete(rq);
@@ -358,9 +377,10 @@ __i915_request_await_execution(struct i915_request *rq,
        return 0;
 }
 
-void __i915_request_submit(struct i915_request *request)
+bool __i915_request_submit(struct i915_request *request)
 {
        struct intel_engine_cs *engine = request->engine;
+       bool result = false;
 
        GEM_TRACE("%s fence %llx:%lld, current %d\n",
                  engine->name,
@@ -370,6 +390,25 @@ void __i915_request_submit(struct i915_request *request)
        GEM_BUG_ON(!irqs_disabled());
        lockdep_assert_held(&engine->active.lock);
 
+       /*
+        * With the advent of preempt-to-busy, we frequently encounter
+        * requests that we have unsubmitted from HW, but left running
+        * until the next ack and so have completed in the meantime. On
+        * resubmission of that completed request, we can skip
+        * updating the payload, and execlists can even skip submitting
+        * the request.
+        *
+        * We must remove the request from the caller's priority queue,
+        * and the caller must only call us when the request is in their
+        * priority queue, under the active.lock. This ensures that the
+        * request has *not* yet been retired and we can safely move
+        * the request into the engine->active.list where it will be
+        * dropped upon retiring. (Otherwise if resubmit a *retired*
+        * request, this would be a horrible use-after-free.)
+        */
+       if (i915_request_completed(request))
+               goto xfer;
+
        if (i915_gem_context_is_banned(request->gem_context))
                i915_request_skip(request, -EIO);
 
@@ -393,13 +432,18 @@ void __i915_request_submit(struct i915_request *request)
            i915_sw_fence_signaled(&request->semaphore))
                engine->saturated |= request->sched.semaphores;
 
-       /* We may be recursing from the signal callback of another i915 fence */
-       spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
+       engine->emit_fini_breadcrumb(request,
+                                    request->ring->vaddr + request->postfix);
 
-       list_move_tail(&request->sched.link, &engine->active.requests);
+       trace_i915_request_execute(request);
+       engine->serial++;
+       result = true;
+
+xfer:  /* We may be recursing from the signal callback of another i915 fence */
+       spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
 
-       GEM_BUG_ON(test_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags));
-       set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags);
+       if (!test_and_set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags))
+               list_move_tail(&request->sched.link, &engine->active.requests);
 
        if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) &&
            !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags) &&
@@ -410,12 +454,7 @@ void __i915_request_submit(struct i915_request *request)
 
        spin_unlock(&request->lock);
 
-       engine->emit_fini_breadcrumb(request,
-                                    request->ring->vaddr + request->postfix);
-
-       engine->serial++;
-
-       trace_i915_request_execute(request);
+       return result;
 }
 
 void i915_request_submit(struct i915_request *request)
index 8ac6e12..e4dd013 100644 (file)
@@ -292,7 +292,7 @@ int i915_request_await_execution(struct i915_request *rq,
 
 void i915_request_add(struct i915_request *rq);
 
-void __i915_request_submit(struct i915_request *request);
+bool __i915_request_submit(struct i915_request *request);
 void i915_request_submit(struct i915_request *request);
 
 void i915_request_skip(struct i915_request *request, int error);
index fa864d8..15f8bff 100644 (file)
@@ -69,6 +69,7 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
                WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_COFFEELAKE(dev_priv));
                return PCH_CNP;
        case INTEL_PCH_CMP_DEVICE_ID_TYPE:
+       case INTEL_PCH_CMP2_DEVICE_ID_TYPE:
                DRM_DEBUG_KMS("Found Comet Lake PCH (CMP)\n");
                WARN_ON(!IS_COFFEELAKE(dev_priv));
                /* CometPoint is CNP Compatible */
index e6a2d65..c29c81e 100644 (file)
@@ -41,6 +41,7 @@ enum intel_pch {
 #define INTEL_PCH_CNP_DEVICE_ID_TYPE           0xA300
 #define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE                0x9D80
 #define INTEL_PCH_CMP_DEVICE_ID_TYPE           0x0280
+#define INTEL_PCH_CMP2_DEVICE_ID_TYPE          0x0680
 #define INTEL_PCH_ICP_DEVICE_ID_TYPE           0x3480
 #define INTEL_PCH_MCC_DEVICE_ID_TYPE           0x4B00
 #define INTEL_PCH_MCC2_DEVICE_ID_TYPE          0x3880
index bb6dd54..3759383 100644 (file)
@@ -118,6 +118,12 @@ static void pm_resume(struct drm_i915_private *i915)
        with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
                intel_gt_sanitize(&i915->gt, false);
                i915_gem_sanitize(i915);
+
+               mutex_lock(&i915->drm.struct_mutex);
+               i915_gem_restore_gtt_mappings(i915);
+               i915_gem_restore_fences(i915);
+               mutex_unlock(&i915->drm.struct_mutex);
+
                i915_gem_resume(i915);
        }
 }
index e226324..4bdd63b 100644 (file)
@@ -1083,7 +1083,7 @@ static const struct dss_features omap34xx_dss_feats = {
 
 static const struct dss_features omap3630_dss_feats = {
        .model                  =       DSS_MODEL_OMAP3,
-       .fck_div_max            =       32,
+       .fck_div_max            =       31,
        .fck_freq_max           =       173000000,
        .dss_fck_multiplier     =       1,
        .parent_clk_name        =       "dpll4_ck",
index fc82a52..ee43797 100644 (file)
@@ -220,9 +220,17 @@ static const struct of_device_id lb035q02_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, lb035q02_of_match);
 
+static const struct spi_device_id lb035q02_ids[] = {
+       { "lb035q02", 0 },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(spi, lb035q02_ids);
+
 static struct spi_driver lb035q02_driver = {
        .probe          = lb035q02_probe,
        .remove         = lb035q02_remove,
+       .id_table       = lb035q02_ids,
        .driver         = {
                .name   = "panel-lg-lb035q02",
                .of_match_table = lb035q02_of_match,
@@ -231,7 +239,6 @@ static struct spi_driver lb035q02_driver = {
 
 module_spi_driver(lb035q02_driver);
 
-MODULE_ALIAS("spi:lgphilips,lb035q02");
 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
 MODULE_DESCRIPTION("LG.Philips LB035Q02 LCD Panel driver");
 MODULE_LICENSE("GPL");
index 299b217..20f17e4 100644 (file)
@@ -230,9 +230,17 @@ static const struct of_device_id nl8048_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, nl8048_of_match);
 
+static const struct spi_device_id nl8048_ids[] = {
+       { "nl8048hl11", 0 },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(spi, nl8048_ids);
+
 static struct spi_driver nl8048_driver = {
        .probe          = nl8048_probe,
        .remove         = nl8048_remove,
+       .id_table       = nl8048_ids,
        .driver         = {
                .name   = "panel-nec-nl8048hl11",
                .pm     = &nl8048_pm_ops,
@@ -242,7 +250,6 @@ static struct spi_driver nl8048_driver = {
 
 module_spi_driver(nl8048_driver);
 
-MODULE_ALIAS("spi:nec,nl8048hl11");
 MODULE_AUTHOR("Erik Gilling <konkers@android.com>");
 MODULE_DESCRIPTION("NEC-NL8048HL11 Driver");
 MODULE_LICENSE("GPL");
index 305259b..3d5b9c4 100644 (file)
@@ -684,9 +684,17 @@ static const struct of_device_id acx565akm_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, acx565akm_of_match);
 
+static const struct spi_device_id acx565akm_ids[] = {
+       { "acx565akm", 0 },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(spi, acx565akm_ids);
+
 static struct spi_driver acx565akm_driver = {
        .probe          = acx565akm_probe,
        .remove         = acx565akm_remove,
+       .id_table       = acx565akm_ids,
        .driver         = {
                .name   = "panel-sony-acx565akm",
                .of_match_table = acx565akm_of_match,
@@ -695,7 +703,6 @@ static struct spi_driver acx565akm_driver = {
 
 module_spi_driver(acx565akm_driver);
 
-MODULE_ALIAS("spi:sony,acx565akm");
 MODULE_AUTHOR("Nokia Corporation");
 MODULE_DESCRIPTION("Sony ACX565AKM LCD Panel Driver");
 MODULE_LICENSE("GPL");
index d7b2e34..f2baff8 100644 (file)
@@ -375,8 +375,7 @@ static const struct of_device_id td028ttec1_of_match[] = {
 MODULE_DEVICE_TABLE(of, td028ttec1_of_match);
 
 static const struct spi_device_id td028ttec1_ids[] = {
-       { "tpo,td028ttec1", 0},
-       { "toppoly,td028ttec1", 0 },
+       { "td028ttec1", 0 },
        { /* sentinel */ }
 };
 
index 8437056..ba163c7 100644 (file)
@@ -491,9 +491,17 @@ static const struct of_device_id td043mtea1_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, td043mtea1_of_match);
 
+static const struct spi_device_id td043mtea1_ids[] = {
+       { "td043mtea1", 0 },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(spi, td043mtea1_ids);
+
 static struct spi_driver td043mtea1_driver = {
        .probe          = td043mtea1_probe,
        .remove         = td043mtea1_remove,
+       .id_table       = td043mtea1_ids,
        .driver         = {
                .name   = "panel-tpo-td043mtea1",
                .pm     = &td043mtea1_pm_ops,
@@ -503,7 +511,6 @@ static struct spi_driver td043mtea1_driver = {
 
 module_spi_driver(td043mtea1_driver);
 
-MODULE_ALIAS("spi:tpo,td043mtea1");
 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
 MODULE_DESCRIPTION("TPO TD043MTEA1 Panel Driver");
 MODULE_LICENSE("GPL");
index ae07290..04efa78 100644 (file)
@@ -147,7 +147,7 @@ static int rcar_du_wb_enc_atomic_check(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct drm_framebuffer *fb;
 
-       if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+       if (!conn_state->writeback_job)
                return 0;
 
        fb = conn_state->writeback_job->fb;
@@ -221,7 +221,7 @@ void rcar_du_writeback_setup(struct rcar_du_crtc *rcrtc,
        unsigned int i;
 
        state = rcrtc->writeback.base.state;
-       if (!state || !state->writeback_job || !state->writeback_job->fb)
+       if (!state || !state->writeback_job)
                return;
 
        fb = state->writeback_job->fb;
index 525dc1c..530edb3 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/gpio.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 
 #include <drm/drm_atomic_helper.h>
index 1ce4d71..bf72020 100644 (file)
@@ -231,7 +231,7 @@ static int vc4_txp_connector_atomic_check(struct drm_connector *conn,
        int i;
 
        conn_state = drm_atomic_get_new_connector_state(state, conn);
-       if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+       if (!conn_state->writeback_job)
                return 0;
 
        crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
@@ -271,8 +271,7 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
        u32 ctrl;
        int i;
 
-       if (WARN_ON(!conn_state->writeback_job ||
-                   !conn_state->writeback_job->fb))
+       if (WARN_ON(!conn_state->writeback_job))
                return;
 
        mode = &conn_state->crtc->state->adjusted_mode;
index ba1828a..4be49c1 100644 (file)
@@ -718,17 +718,9 @@ static int xen_drv_probe(struct xenbus_device *xb_dev,
        struct device *dev = &xb_dev->dev;
        int ret;
 
-       /*
-        * The device is not spawn from a device tree, so arch_setup_dma_ops
-        * is not called, thus leaving the device with dummy DMA ops.
-        * This makes the device return error on PRIME buffer import, which
-        * is not correct: to fix this call of_dma_configure() with a NULL
-        * node to set default DMA ops.
-        */
-       dev->coherent_dma_mask = DMA_BIT_MASK(32);
-       ret = of_dma_configure(dev, NULL, true);
+       ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
        if (ret < 0) {
-               DRM_ERROR("Cannot setup DMA ops, ret %d", ret);
+               DRM_ERROR("Cannot setup DMA mask, ret %d", ret);
                return ret;
        }
 
index cc5b09b..79a28fc 100644 (file)
@@ -314,60 +314,24 @@ static void mousevsc_on_receive(struct hv_device *device,
 
 static void mousevsc_on_channel_callback(void *context)
 {
-       const int packet_size = 0x100;
-       int ret;
        struct hv_device *device = context;
-       u32 bytes_recvd;
-       u64 req_id;
        struct vmpacket_descriptor *desc;
-       unsigned char   *buffer;
-       int     bufferlen = packet_size;
-
-       buffer = kmalloc(bufferlen, GFP_ATOMIC);
-       if (!buffer)
-               return;
-
-       do {
-               ret = vmbus_recvpacket_raw(device->channel, buffer,
-                                       bufferlen, &bytes_recvd, &req_id);
-
-               switch (ret) {
-               case 0:
-                       if (bytes_recvd <= 0) {
-                               kfree(buffer);
-                               return;
-                       }
-                       desc = (struct vmpacket_descriptor *)buffer;
-
-                       switch (desc->type) {
-                       case VM_PKT_COMP:
-                               break;
-
-                       case VM_PKT_DATA_INBAND:
-                               mousevsc_on_receive(device, desc);
-                               break;
-
-                       default:
-                               pr_err("unhandled packet type %d, tid %llx len %d\n",
-                                       desc->type, req_id, bytes_recvd);
-                               break;
-                       }
 
+       foreach_vmbus_pkt(desc, device->channel) {
+               switch (desc->type) {
+               case VM_PKT_COMP:
                        break;
 
-               case -ENOBUFS:
-                       kfree(buffer);
-                       /* Handle large packet */
-                       bufferlen = bytes_recvd;
-                       buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
-
-                       if (!buffer)
-                               return;
+               case VM_PKT_DATA_INBAND:
+                       mousevsc_on_receive(device, desc);
+                       break;
 
+               default:
+                       pr_err("Unhandled packet type %d, tid %llx len %d\n",
+                              desc->type, desc->trans_id, desc->len8 * 8);
                        break;
                }
-       } while (1);
-
+       }
 }
 
 static int mousevsc_connect_to_vsp(struct hv_device *device)
index 391f0b2..53a60c8 100644 (file)
@@ -912,6 +912,7 @@ static void vmbus_shutdown(struct device *child_device)
                drv->shutdown(dev);
 }
 
+#ifdef CONFIG_PM_SLEEP
 /*
  * vmbus_suspend - Suspend a vmbus device
  */
@@ -949,6 +950,7 @@ static int vmbus_resume(struct device *child_device)
 
        return drv->resume(dev);
 }
+#endif /* CONFIG_PM_SLEEP */
 
 /*
  * vmbus_device_release - Final callback release of the vmbus child device
@@ -1070,6 +1072,7 @@ msg_handled:
        vmbus_signal_eom(msg, message_type);
 }
 
+#ifdef CONFIG_PM_SLEEP
 /*
  * Fake RESCIND_CHANNEL messages to clean up hv_sock channels by force for
  * hibernation, because hv_sock connections can not persist across hibernation.
@@ -1105,6 +1108,7 @@ static void vmbus_force_channel_rescinded(struct vmbus_channel *channel)
                      vmbus_connection.work_queue,
                      &ctx->work);
 }
+#endif /* CONFIG_PM_SLEEP */
 
 /*
  * Direct callback for channels using other deferred processing
@@ -2125,6 +2129,7 @@ acpi_walk_err:
        return ret_val;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int vmbus_bus_suspend(struct device *dev)
 {
        struct vmbus_channel *channel, *sc;
@@ -2247,6 +2252,7 @@ static int vmbus_bus_resume(struct device *dev)
 
        return 0;
 }
+#endif /* CONFIG_PM_SLEEP */
 
 static const struct acpi_device_id vmbus_acpi_device_ids[] = {
        {"VMBUS", 0},
index da10e6c..5920c00 100644 (file)
@@ -4399,6 +4399,7 @@ error2:
 error1:
        port_modify.set_port_cap_mask = 0;
        port_modify.clr_port_cap_mask = IB_PORT_CM_SUP;
+       kfree(port);
        while (--i) {
                if (!rdma_cap_ib_cm(ib_device, i))
                        continue;
@@ -4407,6 +4408,7 @@ error1:
                ib_modify_port(ib_device, port->port_num, 0, &port_modify);
                ib_unregister_mad_agent(port->mad_agent);
                cm_remove_port_fs(port);
+               kfree(port);
        }
 free:
        kfree(cm_dev);
@@ -4460,6 +4462,7 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
                spin_unlock_irq(&cm.state_lock);
                ib_unregister_mad_agent(cur_mad_agent);
                cm_remove_port_fs(port);
+               kfree(port);
        }
 
        kfree(cm_dev);
index 0e3cf34..d78f676 100644 (file)
@@ -2396,9 +2396,10 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
                conn_id->cm_id.iw = NULL;
                cma_exch(conn_id, RDMA_CM_DESTROYING);
                mutex_unlock(&conn_id->handler_mutex);
+               mutex_unlock(&listen_id->handler_mutex);
                cma_deref_id(conn_id);
                rdma_destroy_id(&conn_id->id);
-               goto out;
+               return ret;
        }
 
        mutex_unlock(&conn_id->handler_mutex);
index 99c4a55..2dd2cfe 100644 (file)
@@ -1987,8 +1987,6 @@ static int iw_query_port(struct ib_device *device,
        if (!netdev)
                return -ENODEV;
 
-       dev_put(netdev);
-
        port_attr->max_mtu = IB_MTU_4096;
        port_attr->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
 
@@ -1996,19 +1994,22 @@ static int iw_query_port(struct ib_device *device,
                port_attr->state = IB_PORT_DOWN;
                port_attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
        } else {
-               inetdev = in_dev_get(netdev);
+               rcu_read_lock();
+               inetdev = __in_dev_get_rcu(netdev);
 
                if (inetdev && inetdev->ifa_list) {
                        port_attr->state = IB_PORT_ACTIVE;
                        port_attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
-                       in_dev_put(inetdev);
                } else {
                        port_attr->state = IB_PORT_INIT;
                        port_attr->phys_state =
                                IB_PORT_PHYS_STATE_PORT_CONFIGURATION_TRAINING;
                }
+
+               rcu_read_unlock();
        }
 
+       dev_put(netdev);
        err = device->ops.query_port(device, port_num, port_attr);
        if (err)
                return err;
index 7a74740..65b3654 100644 (file)
@@ -1230,7 +1230,7 @@ static int res_get_common_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg) {
                ret = -ENOMEM;
-               goto err;
+               goto err_get;
        }
 
        nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
@@ -1787,10 +1787,6 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]);
        qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]);
-       ret = rdma_counter_unbind_qpn(device, port, qpn, cntn);
-       if (ret)
-               goto err_unbind;
-
        if (fill_nldev_handle(msg, device) ||
            nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port) ||
            nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, cntn) ||
@@ -1799,13 +1795,15 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto err_fill;
        }
 
+       ret = rdma_counter_unbind_qpn(device, port, qpn, cntn);
+       if (ret)
+               goto err_fill;
+
        nlmsg_end(msg, nlh);
        ib_device_put(device);
        return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
 
 err_fill:
-       rdma_counter_bind_qpn(device, port, qpn, cntn);
-err_unbind:
        nlmsg_free(msg);
 err:
        ib_device_put(device);
index 1ab423b..6eb6d27 100644 (file)
@@ -426,7 +426,7 @@ int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev)
        int ret;
 
        rdma_for_each_port (dev, i) {
-               is_ib = rdma_protocol_ib(dev, i++);
+               is_ib = rdma_protocol_ib(dev, i);
                if (is_ib)
                        break;
        }
index f67a30f..163ff7b 100644 (file)
@@ -451,8 +451,10 @@ void ib_umem_odp_release(struct ib_umem_odp *umem_odp)
         * that the hardware will not attempt to access the MR any more.
         */
        if (!umem_odp->is_implicit_odp) {
+               mutex_lock(&umem_odp->umem_mutex);
                ib_umem_odp_unmap_dma_pages(umem_odp, ib_umem_start(umem_odp),
                                            ib_umem_end(umem_odp));
+               mutex_unlock(&umem_odp->umem_mutex);
                kvfree(umem_odp->dma_list);
                kvfree(umem_odp->page_list);
        }
@@ -719,6 +721,8 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt,
        u64 addr;
        struct ib_device *dev = umem_odp->umem.ibdev;
 
+       lockdep_assert_held(&umem_odp->umem_mutex);
+
        virt = max_t(u64, virt, ib_umem_start(umem_odp));
        bound = min_t(u64, bound, ib_umem_end(umem_odp));
        /* Note that during the run of this function, the
@@ -726,7 +730,6 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt,
         * faults from completion. We might be racing with other
         * invalidations, so we must make sure we free each page only
         * once. */
-       mutex_lock(&umem_odp->umem_mutex);
        for (addr = virt; addr < bound; addr += BIT(umem_odp->page_shift)) {
                idx = (addr - ib_umem_start(umem_odp)) >> umem_odp->page_shift;
                if (umem_odp->page_list[idx]) {
@@ -757,7 +760,6 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt,
                        umem_odp->npages--;
                }
        }
-       mutex_unlock(&umem_odp->umem_mutex);
 }
 EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages);
 
index a8b9548..599340c 100644 (file)
@@ -242,10 +242,13 @@ static void set_ep_sin6_addrs(struct c4iw_ep *ep,
        }
 }
 
-static int dump_qp(struct c4iw_qp *qp, struct c4iw_debugfs_data *qpd)
+static int dump_qp(unsigned long id, struct c4iw_qp *qp,
+                  struct c4iw_debugfs_data *qpd)
 {
        int space;
        int cc;
+       if (id != qp->wq.sq.qid)
+               return 0;
 
        space = qpd->bufsize - qpd->pos - 1;
        if (space == 0)
@@ -350,7 +353,7 @@ static int qp_open(struct inode *inode, struct file *file)
 
        xa_lock_irq(&qpd->devp->qps);
        xa_for_each(&qpd->devp->qps, index, qp)
-               dump_qp(qp, qpd);
+               dump_qp(index, qp, qpd);
        xa_unlock_irq(&qpd->devp->qps);
 
        qpd->buf[qpd->pos++] = 0;
index aa772ee..35c284a 100644 (file)
@@ -275,13 +275,17 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
                           struct sk_buff *skb, struct c4iw_wr_wait *wr_waitp)
 {
        int err;
-       struct fw_ri_tpte tpt;
+       struct fw_ri_tpte *tpt;
        u32 stag_idx;
        static atomic_t key;
 
        if (c4iw_fatal_error(rdev))
                return -EIO;
 
+       tpt = kmalloc(sizeof(*tpt), GFP_KERNEL);
+       if (!tpt)
+               return -ENOMEM;
+
        stag_state = stag_state > 0;
        stag_idx = (*stag) >> 8;
 
@@ -291,6 +295,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
                        mutex_lock(&rdev->stats.lock);
                        rdev->stats.stag.fail++;
                        mutex_unlock(&rdev->stats.lock);
+                       kfree(tpt);
                        return -ENOMEM;
                }
                mutex_lock(&rdev->stats.lock);
@@ -305,28 +310,28 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
 
        /* write TPT entry */
        if (reset_tpt_entry)
-               memset(&tpt, 0, sizeof(tpt));
+               memset(tpt, 0, sizeof(*tpt));
        else {
-               tpt.valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
+               tpt->valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
                        FW_RI_TPTE_STAGKEY_V((*stag & FW_RI_TPTE_STAGKEY_M)) |
                        FW_RI_TPTE_STAGSTATE_V(stag_state) |
                        FW_RI_TPTE_STAGTYPE_V(type) | FW_RI_TPTE_PDID_V(pdid));
-               tpt.locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) |
+               tpt->locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) |
                        (bind_enabled ? FW_RI_TPTE_MWBINDEN_F : 0) |
                        FW_RI_TPTE_ADDRTYPE_V((zbva ? FW_RI_ZERO_BASED_TO :
                                                      FW_RI_VA_BASED_TO))|
                        FW_RI_TPTE_PS_V(page_size));
-               tpt.nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
+               tpt->nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
                        FW_RI_TPTE_PBLADDR_V(PBL_OFF(rdev, pbl_addr)>>3));
-               tpt.len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
-               tpt.va_hi = cpu_to_be32((u32)(to >> 32));
-               tpt.va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
-               tpt.dca_mwbcnt_pstag = cpu_to_be32(0);
-               tpt.len_hi = cpu_to_be32((u32)(len >> 32));
+               tpt->len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
+               tpt->va_hi = cpu_to_be32((u32)(to >> 32));
+               tpt->va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
+               tpt->dca_mwbcnt_pstag = cpu_to_be32(0);
+               tpt->len_hi = cpu_to_be32((u32)(len >> 32));
        }
        err = write_adapter_mem(rdev, stag_idx +
                                (rdev->lldi.vr->stag.start >> 5),
-                               sizeof(tpt), &tpt, skb, wr_waitp);
+                               sizeof(*tpt), tpt, skb, wr_waitp);
 
        if (reset_tpt_entry) {
                c4iw_put_resource(&rdev->resource.tpt_table, stag_idx);
@@ -334,6 +339,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
                rdev->stats.stag.cur -= 32;
                mutex_unlock(&rdev->stats.lock);
        }
+       kfree(tpt);
        return err;
 }
 
index eb9368b..bbcac53 100644 (file)
@@ -2737,15 +2737,11 @@ int c4iw_create_srq(struct ib_srq *ib_srq, struct ib_srq_init_attr *attrs,
        if (CHELSIO_CHIP_VERSION(rhp->rdev.lldi.adapter_type) > CHELSIO_T6)
                srq->flags = T4_SRQ_LIMIT_SUPPORT;
 
-       ret = xa_insert_irq(&rhp->qps, srq->wq.qid, srq, GFP_KERNEL);
-       if (ret)
-               goto err_free_queue;
-
        if (udata) {
                srq_key_mm = kmalloc(sizeof(*srq_key_mm), GFP_KERNEL);
                if (!srq_key_mm) {
                        ret = -ENOMEM;
-                       goto err_remove_handle;
+                       goto err_free_queue;
                }
                srq_db_key_mm = kmalloc(sizeof(*srq_db_key_mm), GFP_KERNEL);
                if (!srq_db_key_mm) {
@@ -2789,8 +2785,6 @@ err_free_srq_db_key_mm:
        kfree(srq_db_key_mm);
 err_free_srq_key_mm:
        kfree(srq_key_mm);
-err_remove_handle:
-       xa_erase_irq(&rhp->qps, srq->wq.qid);
 err_free_queue:
        free_srq_queue(srq, ucontext ? &ucontext->uctx : &rhp->rdev.uctx,
                       srq->wr_waitp);
@@ -2813,8 +2807,6 @@ void c4iw_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
        rhp = srq->rhp;
 
        pr_debug("%s id %d\n", __func__, srq->wq.qid);
-
-       xa_erase_irq(&rhp->qps, srq->wq.qid);
        ucontext = rdma_udata_to_drv_context(udata, struct c4iw_ucontext,
                                             ibucontext);
        free_srq_queue(srq, ucontext ? &ucontext->uctx : &rhp->rdev.uctx,
index 2395fd4..2ed7bfd 100644 (file)
@@ -1526,8 +1526,11 @@ int sdma_init(struct hfi1_devdata *dd, u8 port)
        }
 
        ret = rhashtable_init(tmp_sdma_rht, &sdma_rht_params);
-       if (ret < 0)
+       if (ret < 0) {
+               kfree(tmp_sdma_rht);
                goto bail;
+       }
+
        dd->sdma_rht = tmp_sdma_rht;
 
        dd_dev_info(dd, "SDMA num_sdma: %u\n", dd->num_sdma);
index 8056930..cd9ee16 100644 (file)
@@ -2773,6 +2773,10 @@ int i40iw_register_rdma_device(struct i40iw_device *iwdev)
                return -ENOMEM;
        iwibdev = iwdev->iwibdev;
        rdma_set_device_sysfs_group(&iwibdev->ibdev, &i40iw_attr_group);
+       ret = ib_device_set_netdev(&iwibdev->ibdev, iwdev->netdev, 1);
+       if (ret)
+               goto error;
+
        ret = ib_register_device(&iwibdev->ibdev, "i40iw%d");
        if (ret)
                goto error;
index 59022b7..d609f46 100644 (file)
@@ -1298,29 +1298,6 @@ static int devx_handle_mkey_create(struct mlx5_ib_dev *dev,
        return 0;
 }
 
-static void devx_free_indirect_mkey(struct rcu_head *rcu)
-{
-       kfree(container_of(rcu, struct devx_obj, devx_mr.rcu));
-}
-
-/* This function to delete from the radix tree needs to be called before
- * destroying the underlying mkey. Otherwise a race might occur in case that
- * other thread will get the same mkey before this one will be deleted,
- * in that case it will fail via inserting to the tree its own data.
- *
- * Note:
- * An error in the destroy is not expected unless there is some other indirect
- * mkey which points to this one. In a kernel cleanup flow it will be just
- * destroyed in the iterative destruction call. In a user flow, in case
- * the application didn't close in the expected order it's its own problem,
- * the mkey won't be part of the tree, in both cases the kernel is safe.
- */
-static void devx_cleanup_mkey(struct devx_obj *obj)
-{
-       xa_erase(&obj->ib_dev->mdev->priv.mkey_table,
-                mlx5_base_mkey(obj->devx_mr.mmkey.key));
-}
-
 static void devx_cleanup_subscription(struct mlx5_ib_dev *dev,
                                      struct devx_event_subscription *sub)
 {
@@ -1362,8 +1339,16 @@ static int devx_obj_cleanup(struct ib_uobject *uobject,
        int ret;
 
        dev = mlx5_udata_to_mdev(&attrs->driver_udata);
-       if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
-               devx_cleanup_mkey(obj);
+       if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) {
+               /*
+                * The pagefault_single_data_segment() does commands against
+                * the mmkey, we must wait for that to stop before freeing the
+                * mkey, as another allocation could get the same mkey #.
+                */
+               xa_erase(&obj->ib_dev->mdev->priv.mkey_table,
+                        mlx5_base_mkey(obj->devx_mr.mmkey.key));
+               synchronize_srcu(&dev->mr_srcu);
+       }
 
        if (obj->flags & DEVX_OBJ_FLAGS_DCT)
                ret = mlx5_core_destroy_dct(obj->ib_dev->mdev, &obj->core_dct);
@@ -1382,12 +1367,6 @@ static int devx_obj_cleanup(struct ib_uobject *uobject,
                devx_cleanup_subscription(dev, sub_entry);
        mutex_unlock(&devx_event_table->event_xa_lock);
 
-       if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) {
-               call_srcu(&dev->mr_srcu, &obj->devx_mr.rcu,
-                         devx_free_indirect_mkey);
-               return ret;
-       }
-
        kfree(obj);
        return ret;
 }
@@ -1491,26 +1470,21 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
                                   &obj_id);
        WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32));
 
-       if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) {
-               err = devx_handle_mkey_indirect(obj, dev, cmd_in, cmd_out);
-               if (err)
-                       goto obj_destroy;
-       }
-
        err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len);
        if (err)
-               goto err_copy;
+               goto obj_destroy;
 
        if (opcode == MLX5_CMD_OP_CREATE_GENERAL_OBJECT)
                obj_type = MLX5_GET(general_obj_in_cmd_hdr, cmd_in, obj_type);
-
        obj->obj_id = get_enc_obj_id(opcode | obj_type << 16, obj_id);
 
+       if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) {
+               err = devx_handle_mkey_indirect(obj, dev, cmd_in, cmd_out);
+               if (err)
+                       goto obj_destroy;
+       }
        return 0;
 
-err_copy:
-       if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY)
-               devx_cleanup_mkey(obj);
 obj_destroy:
        if (obj->flags & DEVX_OBJ_FLAGS_DCT)
                mlx5_core_destroy_dct(obj->ib_dev->mdev, &obj->core_dct);
index 2ceaef3..1a98ee2 100644 (file)
@@ -606,7 +606,7 @@ struct mlx5_ib_mr {
        struct mlx5_ib_dev     *dev;
        u32 out[MLX5_ST_SZ_DW(create_mkey_out)];
        struct mlx5_core_sig_ctx    *sig;
-       int                     live;
+       unsigned int            live;
        void                    *descs_alloc;
        int                     access_flags; /* Needed for rereg MR */
 
@@ -639,7 +639,6 @@ struct mlx5_ib_mw {
 struct mlx5_ib_devx_mr {
        struct mlx5_core_mkey   mmkey;
        int                     ndescs;
-       struct rcu_head         rcu;
 };
 
 struct mlx5_ib_umr_context {
index 1eff031..6305993 100644 (file)
@@ -84,32 +84,6 @@ static bool use_umr_mtt_update(struct mlx5_ib_mr *mr, u64 start, u64 length)
                length + (start & (MLX5_ADAPTER_PAGE_SIZE - 1));
 }
 
-static void update_odp_mr(struct mlx5_ib_mr *mr)
-{
-       if (is_odp_mr(mr)) {
-               /*
-                * This barrier prevents the compiler from moving the
-                * setting of umem->odp_data->private to point to our
-                * MR, before reg_umr finished, to ensure that the MR
-                * initialization have finished before starting to
-                * handle invalidations.
-                */
-               smp_wmb();
-               to_ib_umem_odp(mr->umem)->private = mr;
-               /*
-                * Make sure we will see the new
-                * umem->odp_data->private value in the invalidation
-                * routines, before we can get page faults on the
-                * MR. Page faults can happen once we put the MR in
-                * the tree, below this line. Without the barrier,
-                * there can be a fault handling and an invalidation
-                * before umem->odp_data->private == mr is visible to
-                * the invalidation handler.
-                */
-               smp_wmb();
-       }
-}
-
 static void reg_mr_callback(int status, struct mlx5_async_work *context)
 {
        struct mlx5_ib_mr *mr =
@@ -1346,8 +1320,6 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        mr->umem = umem;
        set_mr_fields(dev, mr, npages, length, access_flags);
 
-       update_odp_mr(mr);
-
        if (use_umr) {
                int update_xlt_flags = MLX5_IB_UPD_XLT_ENABLE;
 
@@ -1363,10 +1335,12 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                }
        }
 
-       if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) {
-               mr->live = 1;
+       if (is_odp_mr(mr)) {
+               to_ib_umem_odp(mr->umem)->private = mr;
                atomic_set(&mr->num_pending_prefetch, 0);
        }
+       if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING))
+               smp_store_release(&mr->live, 1);
 
        return &mr->ibmr;
 error:
@@ -1441,6 +1415,9 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
        if (!mr->umem)
                return -EINVAL;
 
+       if (is_odp_mr(mr))
+               return -EOPNOTSUPP;
+
        if (flags & IB_MR_REREG_TRANS) {
                addr = virt_addr;
                len = length;
@@ -1486,8 +1463,6 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
                }
 
                mr->allocated_from_cache = 0;
-               if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING))
-                       mr->live = 1;
        } else {
                /*
                 * Send a UMR WQE
@@ -1516,7 +1491,6 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
 
        set_mr_fields(dev, mr, npages, len, access_flags);
 
-       update_odp_mr(mr);
        return 0;
 
 err:
@@ -1607,15 +1581,16 @@ static void dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
                /* Prevent new page faults and
                 * prefetch requests from succeeding
                 */
-               mr->live = 0;
+               WRITE_ONCE(mr->live, 0);
+
+               /* Wait for all running page-fault handlers to finish. */
+               synchronize_srcu(&dev->mr_srcu);
 
                /* dequeue pending prefetch requests for the mr */
                if (atomic_read(&mr->num_pending_prefetch))
                        flush_workqueue(system_unbound_wq);
                WARN_ON(atomic_read(&mr->num_pending_prefetch));
 
-               /* Wait for all running page-fault handlers to finish. */
-               synchronize_srcu(&dev->mr_srcu);
                /* Destroy all page mappings */
                if (!umem_odp->is_implicit_odp)
                        mlx5_ib_invalidate_range(umem_odp,
@@ -1987,14 +1962,25 @@ free:
 
 int mlx5_ib_dealloc_mw(struct ib_mw *mw)
 {
+       struct mlx5_ib_dev *dev = to_mdev(mw->device);
        struct mlx5_ib_mw *mmw = to_mmw(mw);
        int err;
 
-       err =  mlx5_core_destroy_mkey((to_mdev(mw->device))->mdev,
-                                     &mmw->mmkey);
-       if (!err)
-               kfree(mmw);
-       return err;
+       if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) {
+               xa_erase(&dev->mdev->priv.mkey_table,
+                        mlx5_base_mkey(mmw->mmkey.key));
+               /*
+                * pagefault_single_data_segment() may be accessing mmw under
+                * SRCU if the user bound an ODP MR to this MW.
+                */
+               synchronize_srcu(&dev->mr_srcu);
+       }
+
+       err = mlx5_core_destroy_mkey(dev->mdev, &mmw->mmkey);
+       if (err)
+               return err;
+       kfree(mmw);
+       return 0;
 }
 
 int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
index 2e9b430..3f9478d 100644 (file)
@@ -178,6 +178,29 @@ void mlx5_odp_populate_klm(struct mlx5_klm *pklm, size_t offset,
                return;
        }
 
+       /*
+        * The locking here is pretty subtle. Ideally the implicit children
+        * list would be protected by the umem_mutex, however that is not
+        * possible. Instead this uses a weaker update-then-lock pattern:
+        *
+        *  srcu_read_lock()
+        *    <change children list>
+        *    mutex_lock(umem_mutex)
+        *     mlx5_ib_update_xlt()
+        *    mutex_unlock(umem_mutex)
+        *    destroy lkey
+        *
+        * ie any change the children list must be followed by the locked
+        * update_xlt before destroying.
+        *
+        * The umem_mutex provides the acquire/release semantic needed to make
+        * the children list visible to a racing thread. While SRCU is not
+        * technically required, using it gives consistent use of the SRCU
+        * locking around the children list.
+        */
+       lockdep_assert_held(&to_ib_umem_odp(mr->umem)->umem_mutex);
+       lockdep_assert_held(&mr->dev->mr_srcu);
+
        odp = odp_lookup(offset * MLX5_IMR_MTT_SIZE,
                         nentries * MLX5_IMR_MTT_SIZE, mr);
 
@@ -202,15 +225,22 @@ static void mr_leaf_free_action(struct work_struct *work)
        struct ib_umem_odp *odp = container_of(work, struct ib_umem_odp, work);
        int idx = ib_umem_start(odp) >> MLX5_IMR_MTT_SHIFT;
        struct mlx5_ib_mr *mr = odp->private, *imr = mr->parent;
+       struct ib_umem_odp *odp_imr = to_ib_umem_odp(imr->umem);
+       int srcu_key;
 
        mr->parent = NULL;
        synchronize_srcu(&mr->dev->mr_srcu);
 
-       ib_umem_odp_release(odp);
-       if (imr->live)
+       if (smp_load_acquire(&imr->live)) {
+               srcu_key = srcu_read_lock(&mr->dev->mr_srcu);
+               mutex_lock(&odp_imr->umem_mutex);
                mlx5_ib_update_xlt(imr, idx, 1, 0,
                                   MLX5_IB_UPD_XLT_INDIRECT |
                                   MLX5_IB_UPD_XLT_ATOMIC);
+               mutex_unlock(&odp_imr->umem_mutex);
+               srcu_read_unlock(&mr->dev->mr_srcu, srcu_key);
+       }
+       ib_umem_odp_release(odp);
        mlx5_mr_cache_free(mr->dev, mr);
 
        if (atomic_dec_and_test(&imr->num_leaf_free))
@@ -278,7 +308,6 @@ void mlx5_ib_invalidate_range(struct ib_umem_odp *umem_odp, unsigned long start,
                                   idx - blk_start_idx + 1, 0,
                                   MLX5_IB_UPD_XLT_ZAP |
                                   MLX5_IB_UPD_XLT_ATOMIC);
-       mutex_unlock(&umem_odp->umem_mutex);
        /*
         * We are now sure that the device will not access the
         * memory. We can safely unmap it, and mark it as dirty if
@@ -289,10 +318,12 @@ void mlx5_ib_invalidate_range(struct ib_umem_odp *umem_odp, unsigned long start,
 
        if (unlikely(!umem_odp->npages && mr->parent &&
                     !umem_odp->dying)) {
-               WRITE_ONCE(umem_odp->dying, 1);
+               WRITE_ONCE(mr->live, 0);
+               umem_odp->dying = 1;
                atomic_inc(&mr->parent->num_leaf_free);
                schedule_work(&umem_odp->work);
        }
+       mutex_unlock(&umem_odp->umem_mutex);
 }
 
 void mlx5_ib_internal_fill_odp_caps(struct mlx5_ib_dev *dev)
@@ -429,8 +460,6 @@ static struct mlx5_ib_mr *implicit_mr_alloc(struct ib_pd *pd,
        mr->ibmr.lkey = mr->mmkey.key;
        mr->ibmr.rkey = mr->mmkey.key;
 
-       mr->live = 1;
-
        mlx5_ib_dbg(dev, "key %x dev %p mr %p\n",
                    mr->mmkey.key, dev->mdev, mr);
 
@@ -484,6 +513,8 @@ next_mr:
                mtt->parent = mr;
                INIT_WORK(&odp->work, mr_leaf_free_action);
 
+               smp_store_release(&mtt->live, 1);
+
                if (!nentries)
                        start_idx = addr >> MLX5_IMR_MTT_SHIFT;
                nentries++;
@@ -536,6 +567,7 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd,
        init_waitqueue_head(&imr->q_leaf_free);
        atomic_set(&imr->num_leaf_free, 0);
        atomic_set(&imr->num_pending_prefetch, 0);
+       smp_store_release(&imr->live, 1);
 
        return imr;
 }
@@ -555,15 +587,19 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr)
                if (mr->parent != imr)
                        continue;
 
+               mutex_lock(&umem_odp->umem_mutex);
                ib_umem_odp_unmap_dma_pages(umem_odp, ib_umem_start(umem_odp),
                                            ib_umem_end(umem_odp));
 
-               if (umem_odp->dying)
+               if (umem_odp->dying) {
+                       mutex_unlock(&umem_odp->umem_mutex);
                        continue;
+               }
 
-               WRITE_ONCE(umem_odp->dying, 1);
+               umem_odp->dying = 1;
                atomic_inc(&imr->num_leaf_free);
                schedule_work(&umem_odp->work);
+               mutex_unlock(&umem_odp->umem_mutex);
        }
        up_read(&per_mm->umem_rwsem);
 
@@ -773,7 +809,7 @@ next_mr:
        switch (mmkey->type) {
        case MLX5_MKEY_MR:
                mr = container_of(mmkey, struct mlx5_ib_mr, mmkey);
-               if (!mr->live || !mr->ibmr.pd) {
+               if (!smp_load_acquire(&mr->live) || !mr->ibmr.pd) {
                        mlx5_ib_dbg(dev, "got dead MR\n");
                        ret = -EFAULT;
                        goto srcu_unlock;
@@ -1641,12 +1677,12 @@ static bool num_pending_prefetch_inc(struct ib_pd *pd,
 
                mr = container_of(mmkey, struct mlx5_ib_mr, mmkey);
 
-               if (mr->ibmr.pd != pd) {
+               if (!smp_load_acquire(&mr->live)) {
                        ret = false;
                        break;
                }
 
-               if (!mr->live) {
+               if (mr->ibmr.pd != pd) {
                        ret = false;
                        break;
                }
index 6cac0c8..36cdfbd 100644 (file)
@@ -230,8 +230,6 @@ static void pvrdma_free_srq(struct pvrdma_dev *dev, struct pvrdma_srq *srq)
 
        pvrdma_page_dir_cleanup(dev, &srq->pdir);
 
-       kfree(srq);
-
        atomic_dec(&dev->num_srqs);
 }
 
index 430314c..52d402f 100644 (file)
@@ -182,12 +182,19 @@ void siw_qp_llp_close(struct siw_qp *qp)
  */
 void siw_qp_llp_write_space(struct sock *sk)
 {
-       struct siw_cep *cep = sk_to_cep(sk);
+       struct siw_cep *cep;
 
-       cep->sk_write_space(sk);
+       read_lock(&sk->sk_callback_lock);
+
+       cep  = sk_to_cep(sk);
+       if (cep) {
+               cep->sk_write_space(sk);
 
-       if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
-               (void)siw_sq_start(cep->qp);
+               if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+                       (void)siw_sq_start(cep->qp);
+       }
+
+       read_unlock(&sk->sk_callback_lock);
 }
 
 static int siw_qp_readq_init(struct siw_qp *qp, int irq_size, int orq_size)
index 684aa51..b00274c 100644 (file)
@@ -705,7 +705,7 @@ qca8k_setup(struct dsa_switch *ds)
                    BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
 
        /* Setup connection between CPU port & user ports */
-       for (i = 0; i < DSA_MAX_PORTS; i++) {
+       for (i = 0; i < QCA8K_NUM_PORTS; i++) {
                /* CPU port gets connected to all user ports of the switch */
                if (dsa_is_cpu_port(ds, i)) {
                        qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
@@ -1077,7 +1077,7 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
        if (id != QCA8K_ID_QCA8337)
                return -ENODEV;
 
-       priv->ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS);
+       priv->ds = dsa_switch_alloc(&mdiodev->dev, QCA8K_NUM_PORTS);
        if (!priv->ds)
                return -ENOMEM;
 
index ca3d17e..ac88cac 100644 (file)
@@ -339,10 +339,12 @@ int rtl8366_vlan_prepare(struct dsa_switch *ds, int port,
                         const struct switchdev_obj_port_vlan *vlan)
 {
        struct realtek_smi *smi = ds->priv;
+       u16 vid;
        int ret;
 
-       if (!smi->ops->is_vlan_valid(smi, port))
-               return -EINVAL;
+       for (vid = vlan->vid_begin; vid < vlan->vid_end; vid++)
+               if (!smi->ops->is_vlan_valid(smi, vid))
+                       return -EINVAL;
 
        dev_info(smi->dev, "prepare VLANs %04x..%04x\n",
                 vlan->vid_begin, vlan->vid_end);
@@ -370,8 +372,9 @@ void rtl8366_vlan_add(struct dsa_switch *ds, int port,
        u16 vid;
        int ret;
 
-       if (!smi->ops->is_vlan_valid(smi, port))
-               return;
+       for (vid = vlan->vid_begin; vid < vlan->vid_end; vid++)
+               if (!smi->ops->is_vlan_valid(smi, vid))
+                       return;
 
        dev_info(smi->dev, "add VLAN on port %d, %s, %s\n",
                 port,
index a268085..f5cc8b0 100644 (file)
@@ -507,7 +507,8 @@ static int rtl8366rb_setup_cascaded_irq(struct realtek_smi *smi)
        irq = of_irq_get(intc, 0);
        if (irq <= 0) {
                dev_err(smi->dev, "failed to get parent IRQ\n");
-               return irq ? irq : -EINVAL;
+               ret = irq ? irq : -EINVAL;
+               goto out_put_node;
        }
 
        /* This clears the IRQ status register */
@@ -515,7 +516,7 @@ static int rtl8366rb_setup_cascaded_irq(struct realtek_smi *smi)
                          &val);
        if (ret) {
                dev_err(smi->dev, "can't read interrupt status\n");
-               return ret;
+               goto out_put_node;
        }
 
        /* Fetch IRQ edge information from the descriptor */
@@ -537,7 +538,7 @@ static int rtl8366rb_setup_cascaded_irq(struct realtek_smi *smi)
                                 val);
        if (ret) {
                dev_err(smi->dev, "could not configure IRQ polarity\n");
-               return ret;
+               goto out_put_node;
        }
 
        ret = devm_request_threaded_irq(smi->dev, irq, NULL,
@@ -545,7 +546,7 @@ static int rtl8366rb_setup_cascaded_irq(struct realtek_smi *smi)
                                        "RTL8366RB", smi);
        if (ret) {
                dev_err(smi->dev, "unable to request irq: %d\n", ret);
-               return ret;
+               goto out_put_node;
        }
        smi->irqdomain = irq_domain_add_linear(intc,
                                               RTL8366RB_NUM_INTERRUPT,
@@ -553,12 +554,15 @@ static int rtl8366rb_setup_cascaded_irq(struct realtek_smi *smi)
                                               smi);
        if (!smi->irqdomain) {
                dev_err(smi->dev, "failed to create IRQ domain\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_put_node;
        }
        for (i = 0; i < smi->num_ports; i++)
                irq_set_parent(irq_create_mapping(smi->irqdomain, i), irq);
 
-       return 0;
+out_put_node:
+       of_node_put(intc);
+       return ret;
 }
 
 static int rtl8366rb_set_addr(struct realtek_smi *smi)
index b9def74..7687ddc 100644 (file)
@@ -1897,7 +1897,9 @@ static int sja1105_set_ageing_time(struct dsa_switch *ds,
        return sja1105_static_config_reload(priv);
 }
 
-/* Caller must hold priv->tagger_data.meta_lock */
+/* Must be called only with priv->tagger_data.state bit
+ * SJA1105_HWTS_RX_EN cleared
+ */
 static int sja1105_change_rxtstamping(struct sja1105_private *priv,
                                      bool on)
 {
@@ -1954,16 +1956,17 @@ static int sja1105_hwtstamp_set(struct dsa_switch *ds, int port,
                break;
        }
 
-       if (rx_on != priv->tagger_data.hwts_rx_en) {
-               spin_lock(&priv->tagger_data.meta_lock);
+       if (rx_on != test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state)) {
+               clear_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state);
+
                rc = sja1105_change_rxtstamping(priv, rx_on);
-               spin_unlock(&priv->tagger_data.meta_lock);
                if (rc < 0) {
                        dev_err(ds->dev,
                                "Failed to change RX timestamping: %d\n", rc);
-                       return -EFAULT;
+                       return rc;
                }
-               priv->tagger_data.hwts_rx_en = rx_on;
+               if (rx_on)
+                       set_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state);
        }
 
        if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
@@ -1982,7 +1985,7 @@ static int sja1105_hwtstamp_get(struct dsa_switch *ds, int port,
                config.tx_type = HWTSTAMP_TX_ON;
        else
                config.tx_type = HWTSTAMP_TX_OFF;
-       if (priv->tagger_data.hwts_rx_en)
+       if (test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state))
                config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
        else
                config.rx_filter = HWTSTAMP_FILTER_NONE;
@@ -2005,12 +2008,12 @@ static void sja1105_rxtstamp_work(struct work_struct *work)
 
        mutex_lock(&priv->ptp_lock);
 
-       now = priv->tstamp_cc.read(&priv->tstamp_cc);
-
        while ((skb = skb_dequeue(&data->skb_rxtstamp_queue)) != NULL) {
                struct skb_shared_hwtstamps *shwt = skb_hwtstamps(skb);
                u64 ts;
 
+               now = priv->tstamp_cc.read(&priv->tstamp_cc);
+
                *shwt = (struct skb_shared_hwtstamps) {0};
 
                ts = SJA1105_SKB_CB(skb)->meta_tstamp;
@@ -2031,7 +2034,7 @@ static bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
        struct sja1105_private *priv = ds->priv;
        struct sja1105_tagger_data *data = &priv->tagger_data;
 
-       if (!data->hwts_rx_en)
+       if (!test_bit(SJA1105_HWTS_RX_EN, &data->state))
                return false;
 
        /* We need to read the full PTP clock to reconstruct the Rx
@@ -2201,6 +2204,7 @@ static int sja1105_probe(struct spi_device *spi)
        tagger_data = &priv->tagger_data;
        skb_queue_head_init(&tagger_data->skb_rxtstamp_queue);
        INIT_WORK(&tagger_data->rxtstamp_work, sja1105_rxtstamp_work);
+       spin_lock_init(&tagger_data->meta_lock);
 
        /* Connections between dsa_port and sja1105_port */
        for (i = 0; i < SJA1105_NUM_PORTS; i++) {
index 84dc603..58dd37e 100644 (file)
@@ -409,7 +409,8 @@ int sja1105_static_config_upload(struct sja1105_private *priv)
        rc = static_config_buf_prepare_for_upload(priv, config_buf, buf_len);
        if (rc < 0) {
                dev_err(dev, "Invalid config, cannot upload\n");
-               return -EINVAL;
+               rc = -EINVAL;
+               goto out;
        }
        /* Prevent PHY jabbering during switch reset by inhibiting
         * Tx on all ports and waiting for current packet to drain.
@@ -418,7 +419,8 @@ int sja1105_static_config_upload(struct sja1105_private *priv)
        rc = sja1105_inhibit_tx(priv, port_bitmap, true);
        if (rc < 0) {
                dev_err(dev, "Failed to inhibit Tx on ports\n");
-               return -ENXIO;
+               rc = -ENXIO;
+               goto out;
        }
        /* Wait for an eventual egress packet to finish transmission
         * (reach IFG). It is guaranteed that a second one will not
index 7548247..1b1a090 100644 (file)
@@ -526,7 +526,7 @@ static int ag71xx_mdio_probe(struct ag71xx *ag)
        struct device *dev = &ag->pdev->dev;
        struct net_device *ndev = ag->ndev;
        static struct mii_bus *mii_bus;
-       struct device_node *np;
+       struct device_node *np, *mnp;
        int err;
 
        np = dev->of_node;
@@ -571,7 +571,9 @@ static int ag71xx_mdio_probe(struct ag71xx *ag)
                msleep(200);
        }
 
-       err = of_mdiobus_register(mii_bus, np);
+       mnp = of_get_child_by_name(np, "mdio");
+       err = of_mdiobus_register(mii_bus, mnp);
+       of_node_put(mnp);
        if (err)
                goto mdio_err_put_clk;
 
index 5b60224..a4dead4 100644 (file)
@@ -137,13 +137,12 @@ static int uldrx_handler(struct sge_rspq *q, const __be64 *rsp,
 static int alloc_uld_rxqs(struct adapter *adap,
                          struct sge_uld_rxq_info *rxq_info, bool lro)
 {
-       struct sge *s = &adap->sge;
        unsigned int nq = rxq_info->nrxq + rxq_info->nciq;
+       int i, err, msi_idx, que_idx = 0, bmap_idx = 0;
        struct sge_ofld_rxq *q = rxq_info->uldrxq;
        unsigned short *ids = rxq_info->rspq_id;
-       unsigned int bmap_idx = 0;
+       struct sge *s = &adap->sge;
        unsigned int per_chan;
-       int i, err, msi_idx, que_idx = 0;
 
        per_chan = rxq_info->nrxq / adap->params.nports;
 
@@ -161,6 +160,10 @@ static int alloc_uld_rxqs(struct adapter *adap,
 
                if (msi_idx >= 0) {
                        bmap_idx = get_msix_idx_from_bmap(adap);
+                       if (bmap_idx < 0) {
+                               err = -ENOSPC;
+                               goto freeout;
+                       }
                        msi_idx = adap->msix_info_ulds[bmap_idx].idx;
                }
                err = t4_sge_alloc_rxq(adap, &q->rspq, false,
index 3e863a7..7df5d7d 100644 (file)
@@ -148,11 +148,15 @@ static int mdio_sc_cfg_reg_write(struct hns_mdio_device *mdio_dev,
 {
        u32 time_cnt;
        u32 reg_value;
+       int ret;
 
        regmap_write(mdio_dev->subctrl_vbase, cfg_reg, set_val);
 
        for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
-               regmap_read(mdio_dev->subctrl_vbase, st_reg, &reg_value);
+               ret = regmap_read(mdio_dev->subctrl_vbase, st_reg, &reg_value);
+               if (ret)
+                       return ret;
+
                reg_value &= st_msk;
                if ((!!check_st) == (!!reg_value))
                        break;
index 9231b39..c501bf2 100644 (file)
@@ -112,17 +112,11 @@ int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev,
        u32 out[MLX5_ST_SZ_DW(destroy_mkey_out)] = {0};
        u32 in[MLX5_ST_SZ_DW(destroy_mkey_in)]   = {0};
        struct xarray *mkeys = &dev->priv.mkey_table;
-       struct mlx5_core_mkey *deleted_mkey;
        unsigned long flags;
 
        xa_lock_irqsave(mkeys, flags);
-       deleted_mkey = __xa_erase(mkeys, mlx5_base_mkey(mkey->key));
+       __xa_erase(mkeys, mlx5_base_mkey(mkey->key));
        xa_unlock_irqrestore(mkeys, flags);
-       if (!deleted_mkey) {
-               mlx5_core_dbg(dev, "failed xarray delete of mkey 0x%x\n",
-                             mlx5_base_mkey(mkey->key));
-               return -ENOENT;
-       }
 
        MLX5_SET(destroy_mkey_in, in, opcode, MLX5_CMD_OP_DESTROY_MKEY);
        MLX5_SET(destroy_mkey_in, in, mkey_index, mlx5_mkey_to_idx(mkey->key));
index 913f1e5..d7c7467 100644 (file)
@@ -137,7 +137,8 @@ dr_icm_pool_mr_create(struct mlx5dr_icm_pool *pool,
 
        icm_mr->icm_start_addr = icm_mr->dm.addr;
 
-       align_diff = icm_mr->icm_start_addr % align_base;
+       /* align_base is always a power of 2 */
+       align_diff = icm_mr->icm_start_addr & (align_base - 1);
        if (align_diff)
                icm_mr->used_length = align_base - align_diff;
 
index b063eb7..aac1151 100644 (file)
@@ -388,13 +388,14 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
                        continue;
 
                phy = of_phy_find_device(phy_node);
+               of_node_put(phy_node);
                if (!phy)
                        continue;
 
                err = ocelot_probe_port(ocelot, port, regs, phy);
                if (err) {
                        of_node_put(portnp);
-                       return err;
+                       goto out_put_ports;
                }
 
                phy_mode = of_get_phy_mode(portnp);
@@ -422,7 +423,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
                                "invalid phy mode for port%d, (Q)SGMII only\n",
                                port);
                        of_node_put(portnp);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out_put_ports;
                }
 
                serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
@@ -435,7 +437,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
                                        "missing SerDes phys for port%d\n",
                                        port);
 
-                       goto err_probe_ports;
+                       of_node_put(portnp);
+                       goto out_put_ports;
                }
 
                ocelot->ports[port]->serdes = serdes;
@@ -447,9 +450,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
 
        dev_info(&pdev->dev, "Ocelot switch probed\n");
 
-       return 0;
-
-err_probe_ports:
+out_put_ports:
+       of_node_put(ports);
        return err;
 }
 
index bd0583e..d25b88f 100644 (file)
@@ -20,6 +20,7 @@ if NET_VENDOR_PENSANDO
 config IONIC
        tristate "Pensando Ethernet IONIC Support"
        depends on 64BIT && PCI
+       select NET_DEVLINK
        help
          This enables the support for the Pensando family of Ethernet
          adapters.  More specific information on this driver can be
index 4574448..b4b8ba0 100644 (file)
@@ -2787,6 +2787,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
                                netdev_err(qdev->ndev,
                                           "PCI mapping failed with error: %d\n",
                                           err);
+                               dev_kfree_skb_irq(skb);
                                ql_free_large_buffers(qdev);
                                return -ENOMEM;
                        }
index 55db7fb..f9e6744 100644 (file)
@@ -282,7 +282,6 @@ struct netsec_desc_ring {
        void *vaddr;
        u16 head, tail;
        u16 xdp_xmit; /* netsec_xdp_xmit packets */
-       bool is_xdp;
        struct page_pool *page_pool;
        struct xdp_rxq_info xdp_rxq;
        spinlock_t lock; /* XDP tx queue locking */
@@ -634,8 +633,7 @@ static bool netsec_clean_tx_dring(struct netsec_priv *priv)
        unsigned int bytes;
        int cnt = 0;
 
-       if (dring->is_xdp)
-               spin_lock(&dring->lock);
+       spin_lock(&dring->lock);
 
        bytes = 0;
        entry = dring->vaddr + DESC_SZ * tail;
@@ -682,8 +680,8 @@ next:
                entry = dring->vaddr + DESC_SZ * tail;
                cnt++;
        }
-       if (dring->is_xdp)
-               spin_unlock(&dring->lock);
+
+       spin_unlock(&dring->lock);
 
        if (!cnt)
                return false;
@@ -799,9 +797,6 @@ static void netsec_set_tx_de(struct netsec_priv *priv,
        de->data_buf_addr_lw = lower_32_bits(desc->dma_addr);
        de->buf_len_info = (tx_ctrl->tcp_seg_len << 16) | desc->len;
        de->attr = attr;
-       /* under spin_lock if using XDP */
-       if (!dring->is_xdp)
-               dma_wmb();
 
        dring->desc[idx] = *desc;
        if (desc->buf_type == TYPE_NETSEC_SKB)
@@ -1123,12 +1118,10 @@ static netdev_tx_t netsec_netdev_start_xmit(struct sk_buff *skb,
        u16 tso_seg_len = 0;
        int filled;
 
-       if (dring->is_xdp)
-               spin_lock_bh(&dring->lock);
+       spin_lock_bh(&dring->lock);
        filled = netsec_desc_used(dring);
        if (netsec_check_stop_tx(priv, filled)) {
-               if (dring->is_xdp)
-                       spin_unlock_bh(&dring->lock);
+               spin_unlock_bh(&dring->lock);
                net_warn_ratelimited("%s %s Tx queue full\n",
                                     dev_name(priv->dev), ndev->name);
                return NETDEV_TX_BUSY;
@@ -1161,8 +1154,7 @@ static netdev_tx_t netsec_netdev_start_xmit(struct sk_buff *skb,
        tx_desc.dma_addr = dma_map_single(priv->dev, skb->data,
                                          skb_headlen(skb), DMA_TO_DEVICE);
        if (dma_mapping_error(priv->dev, tx_desc.dma_addr)) {
-               if (dring->is_xdp)
-                       spin_unlock_bh(&dring->lock);
+               spin_unlock_bh(&dring->lock);
                netif_err(priv, drv, priv->ndev,
                          "%s: DMA mapping failed\n", __func__);
                ndev->stats.tx_dropped++;
@@ -1177,8 +1169,7 @@ static netdev_tx_t netsec_netdev_start_xmit(struct sk_buff *skb,
        netdev_sent_queue(priv->ndev, skb->len);
 
        netsec_set_tx_de(priv, dring, &tx_ctrl, &tx_desc, skb);
-       if (dring->is_xdp)
-               spin_unlock_bh(&dring->lock);
+       spin_unlock_bh(&dring->lock);
        netsec_write(priv, NETSEC_REG_NRM_TX_PKTCNT, 1); /* submit another tx */
 
        return NETDEV_TX_OK;
@@ -1262,7 +1253,6 @@ err:
 static void netsec_setup_tx_dring(struct netsec_priv *priv)
 {
        struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_TX];
-       struct bpf_prog *xdp_prog = READ_ONCE(priv->xdp_prog);
        int i;
 
        for (i = 0; i < DESC_NUM; i++) {
@@ -1275,12 +1265,6 @@ static void netsec_setup_tx_dring(struct netsec_priv *priv)
                 */
                de->attr = 1U << NETSEC_TX_SHIFT_OWN_FIELD;
        }
-
-       if (xdp_prog)
-               dring->is_xdp = true;
-       else
-               dring->is_xdp = false;
-
 }
 
 static int netsec_setup_rx_dring(struct netsec_priv *priv)
index 9b4b5f6..2cb9c53 100644 (file)
@@ -401,8 +401,11 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
        int numhashregs = (hw->multicast_filter_bins >> 5);
        int mcbitslog2 = hw->mcast_bits_log2;
        unsigned int value;
+       u32 mc_filter[8];
        int i;
 
+       memset(mc_filter, 0, sizeof(mc_filter));
+
        value = readl(ioaddr + GMAC_PACKET_FILTER);
        value &= ~GMAC_PACKET_FILTER_HMC;
        value &= ~GMAC_PACKET_FILTER_HPF;
@@ -416,16 +419,13 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
                /* Pass all multi */
                value |= GMAC_PACKET_FILTER_PM;
                /* Set all the bits of the HASH tab */
-               for (i = 0; i < numhashregs; i++)
-                       writel(0xffffffff, ioaddr + GMAC_HASH_TAB(i));
+               memset(mc_filter, 0xff, sizeof(mc_filter));
        } else if (!netdev_mc_empty(dev)) {
                struct netdev_hw_addr *ha;
-               u32 mc_filter[8];
 
                /* Hash filter for multicast */
                value |= GMAC_PACKET_FILTER_HMC;
 
-               memset(mc_filter, 0, sizeof(mc_filter));
                netdev_for_each_mc_addr(ha, dev) {
                        /* The upper n bits of the calculated CRC are used to
                         * index the contents of the hash table. The number of
@@ -440,10 +440,11 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
                         */
                        mc_filter[bit_nr >> 5] |= (1 << (bit_nr & 0x1f));
                }
-               for (i = 0; i < numhashregs; i++)
-                       writel(mc_filter[i], ioaddr + GMAC_HASH_TAB(i));
        }
 
+       for (i = 0; i < numhashregs; i++)
+               writel(mc_filter[i], ioaddr + GMAC_HASH_TAB(i));
+
        value |= GMAC_PACKET_FILTER_HPF;
 
        /* Handle multiple unicast addresses */
index 5923ca6..9903738 100644 (file)
@@ -84,7 +84,7 @@
 #define XGMAC_TSIE                     BIT(12)
 #define XGMAC_LPIIE                    BIT(5)
 #define XGMAC_PMTIE                    BIT(4)
-#define XGMAC_INT_DEFAULT_EN           (XGMAC_LPIIE | XGMAC_PMTIE | XGMAC_TSIE)
+#define XGMAC_INT_DEFAULT_EN           (XGMAC_LPIIE | XGMAC_PMTIE)
 #define XGMAC_Qx_TX_FLOW_CTRL(x)       (0x00000070 + (x) * 4)
 #define XGMAC_PT                       GENMASK(31, 16)
 #define XGMAC_PT_SHIFT                 16
 #define XGMAC_HWFEAT_GMIISEL           BIT(1)
 #define XGMAC_HW_FEATURE1              0x00000120
 #define XGMAC_HWFEAT_L3L4FNUM          GENMASK(30, 27)
+#define XGMAC_HWFEAT_HASHTBLSZ         GENMASK(25, 24)
 #define XGMAC_HWFEAT_RSSEN             BIT(20)
 #define XGMAC_HWFEAT_TSOEN             BIT(18)
 #define XGMAC_HWFEAT_SPHEN             BIT(17)
index 2b277b2..5031398 100644 (file)
@@ -472,7 +472,7 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw,
        dwxgmac2_set_mchash(ioaddr, mc_filter, mcbitslog2);
 
        /* Handle multiple unicast addresses */
-       if (netdev_uc_count(dev) > XGMAC_ADDR_MAX) {
+       if (netdev_uc_count(dev) > hw->unicast_filter_entries) {
                value |= XGMAC_FILTER_PR;
        } else {
                struct netdev_hw_addr *ha;
@@ -523,8 +523,8 @@ static int dwxgmac2_rss_configure(struct mac_device_info *hw,
                                  struct stmmac_rss *cfg, u32 num_rxq)
 {
        void __iomem *ioaddr = hw->pcsr;
+       u32 value, *key;
        int i, ret;
-       u32 value;
 
        value = readl(ioaddr + XGMAC_RSS_CTRL);
        if (!cfg || !cfg->enable) {
@@ -533,8 +533,9 @@ static int dwxgmac2_rss_configure(struct mac_device_info *hw,
                return 0;
        }
 
-       for (i = 0; i < (sizeof(cfg->key) / sizeof(u32)); i++) {
-               ret = dwxgmac2_rss_write_reg(ioaddr, true, i, cfg->key[i]);
+       key = (u32 *)cfg->key;
+       for (i = 0; i < (ARRAY_SIZE(cfg->key) / sizeof(u32)); i++) {
+               ret = dwxgmac2_rss_write_reg(ioaddr, true, i, key[i]);
                if (ret)
                        return ret;
        }
index 53c4a40..965cbe3 100644 (file)
@@ -380,6 +380,7 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
        /* MAC HW feature 1 */
        hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
        dma_cap->l3l4fnum = (hw_cap & XGMAC_HWFEAT_L3L4FNUM) >> 27;
+       dma_cap->hash_tb_sz = (hw_cap & XGMAC_HWFEAT_HASHTBLSZ) >> 24;
        dma_cap->rssen = (hw_cap & XGMAC_HWFEAT_RSSEN) >> 20;
        dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18;
        dma_cap->sphen = (hw_cap & XGMAC_HWFEAT_SPHEN) >> 17;
index d323273..c76a133 100644 (file)
@@ -629,6 +629,7 @@ static int stmmac_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
                        config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
                        ptp_v2 = PTP_TCR_TSVER2ENA;
                        snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
+                       ts_event_en = PTP_TCR_TSEVNTENA;
                        ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
                        ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
                        ptp_over_ethernet = PTP_TCR_TSIPENA;
@@ -4715,11 +4716,9 @@ int stmmac_suspend(struct device *dev)
        if (!ndev || !netif_running(ndev))
                return 0;
 
-       mutex_lock(&priv->lock);
+       phylink_mac_change(priv->phylink, false);
 
-       rtnl_lock();
-       phylink_stop(priv->phylink);
-       rtnl_unlock();
+       mutex_lock(&priv->lock);
 
        netif_device_detach(ndev);
        stmmac_stop_all_queues(priv);
@@ -4734,6 +4733,12 @@ int stmmac_suspend(struct device *dev)
                stmmac_pmt(priv, priv->hw, priv->wolopts);
                priv->irq_wake = 1;
        } else {
+               mutex_unlock(&priv->lock);
+               rtnl_lock();
+               phylink_stop(priv->phylink);
+               rtnl_unlock();
+               mutex_lock(&priv->lock);
+
                stmmac_mac_set(priv, priv->ioaddr, false);
                pinctrl_pm_select_sleep_state(priv->device);
                /* Disable clock in case of PWM is off */
@@ -4824,12 +4829,16 @@ int stmmac_resume(struct device *dev)
 
        stmmac_start_all_queues(priv);
 
-       rtnl_lock();
-       phylink_start(priv->phylink);
-       rtnl_unlock();
-
        mutex_unlock(&priv->lock);
 
+       if (!device_may_wakeup(priv->device)) {
+               rtnl_lock();
+               phylink_start(priv->phylink);
+               rtnl_unlock();
+       }
+
+       phylink_mac_change(priv->phylink, true);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(stmmac_resume);
index 5f66f61..cc76a42 100644 (file)
@@ -1564,10 +1564,6 @@ static int __stmmac_test_jumbo(struct stmmac_priv *priv, u16 queue)
        struct stmmac_packet_attrs attr = { };
        int size = priv->dma_buf_sz;
 
-       /* Only XGMAC has SW support for multiple RX descs in same packet */
-       if (priv->plat->has_xgmac)
-               size = priv->dev->max_mtu;
-
        attr.dst = priv->dev->dev_addr;
        attr.max_size = size - ETH_FCS_LEN;
        attr.queue_mapping = queue;
index ceddb42..0dd0ba9 100644 (file)
@@ -1137,10 +1137,11 @@ static void atusb_disconnect(struct usb_interface *interface)
 
        ieee802154_unregister_hw(atusb->hw);
 
+       usb_put_dev(atusb->usb_dev);
+
        ieee802154_free_hw(atusb->hw);
 
        usb_set_intfdata(interface, NULL);
-       usb_put_dev(atusb->usb_dev);
 
        pr_debug("%s done\n", __func__);
 }
index 11402dc..430c937 100644 (file)
@@ -3145,12 +3145,12 @@ static int ca8210_probe(struct spi_device *spi_device)
                goto error;
        }
 
+       priv->spi->dev.platform_data = pdata;
        ret = ca8210_get_platform_data(priv->spi, pdata);
        if (ret) {
                dev_crit(&spi_device->dev, "ca8210_get_platform_data failed\n");
                goto error;
        }
-       priv->spi->dev.platform_data = pdata;
 
        ret = ca8210_dev_com_init(priv);
        if (ret) {
index 17f2300..8dc04e2 100644 (file)
@@ -800,7 +800,7 @@ mcr20a_handle_rx_read_buf_complete(void *context)
        if (!skb)
                return;
 
-       memcpy(skb_put(skb, len), lp->rx_buf, len);
+       __skb_put_data(skb, lp->rx_buf, len);
        ieee802154_rx_irqsafe(lp->hw, skb, lp->rx_lqi[0]);
 
        print_hex_dump_debug("mcr20a rx: ", DUMP_PREFIX_OFFSET, 16, 1,
index 2aa7b2e..1eb5d4f 100644 (file)
 #include <linux/of_gpio.h>
 #include <linux/gpio/consumer.h>
 
+#define AT803X_SPECIFIC_STATUS                 0x11
+#define AT803X_SS_SPEED_MASK                   (3 << 14)
+#define AT803X_SS_SPEED_1000                   (2 << 14)
+#define AT803X_SS_SPEED_100                    (1 << 14)
+#define AT803X_SS_SPEED_10                     (0 << 14)
+#define AT803X_SS_DUPLEX                       BIT(13)
+#define AT803X_SS_SPEED_DUPLEX_RESOLVED                BIT(11)
+#define AT803X_SS_MDIX                         BIT(6)
+
 #define AT803X_INTR_ENABLE                     0x12
 #define AT803X_INTR_ENABLE_AUTONEG_ERR         BIT(15)
 #define AT803X_INTR_ENABLE_SPEED_CHANGED       BIT(14)
@@ -357,6 +366,64 @@ static int at803x_aneg_done(struct phy_device *phydev)
        return aneg_done;
 }
 
+static int at803x_read_status(struct phy_device *phydev)
+{
+       int ss, err, old_link = phydev->link;
+
+       /* Update the link, but return if there was an error */
+       err = genphy_update_link(phydev);
+       if (err)
+               return err;
+
+       /* why bother the PHY if nothing can have changed */
+       if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
+               return 0;
+
+       phydev->speed = SPEED_UNKNOWN;
+       phydev->duplex = DUPLEX_UNKNOWN;
+       phydev->pause = 0;
+       phydev->asym_pause = 0;
+
+       err = genphy_read_lpa(phydev);
+       if (err < 0)
+               return err;
+
+       /* Read the AT8035 PHY-Specific Status register, which indicates the
+        * speed and duplex that the PHY is actually using, irrespective of
+        * whether we are in autoneg mode or not.
+        */
+       ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
+       if (ss < 0)
+               return ss;
+
+       if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
+               switch (ss & AT803X_SS_SPEED_MASK) {
+               case AT803X_SS_SPEED_10:
+                       phydev->speed = SPEED_10;
+                       break;
+               case AT803X_SS_SPEED_100:
+                       phydev->speed = SPEED_100;
+                       break;
+               case AT803X_SS_SPEED_1000:
+                       phydev->speed = SPEED_1000;
+                       break;
+               }
+               if (ss & AT803X_SS_DUPLEX)
+                       phydev->duplex = DUPLEX_FULL;
+               else
+                       phydev->duplex = DUPLEX_HALF;
+               if (ss & AT803X_SS_MDIX)
+                       phydev->mdix = ETH_TP_MDI_X;
+               else
+                       phydev->mdix = ETH_TP_MDI;
+       }
+
+       if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
+               phy_resolve_aneg_pause(phydev);
+
+       return 0;
+}
+
 static struct phy_driver at803x_driver[] = {
 {
        /* ATHEROS 8035 */
@@ -370,6 +437,7 @@ static struct phy_driver at803x_driver[] = {
        .suspend                = at803x_suspend,
        .resume                 = at803x_resume,
        /* PHY_GBIT_FEATURES */
+       .read_status            = at803x_read_status,
        .ack_interrupt          = at803x_ack_interrupt,
        .config_intr            = at803x_config_intr,
 }, {
@@ -399,6 +467,7 @@ static struct phy_driver at803x_driver[] = {
        .suspend                = at803x_suspend,
        .resume                 = at803x_resume,
        /* PHY_GBIT_FEATURES */
+       .read_status            = at803x_read_status,
        .aneg_done              = at803x_aneg_done,
        .ack_interrupt          = &at803x_ack_interrupt,
        .config_intr            = &at803x_config_intr,
index e282600..c1d345c 100644 (file)
@@ -121,7 +121,7 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value)
                return;
 
        if (mdiodev->reset_gpio)
-               gpiod_set_value(mdiodev->reset_gpio, value);
+               gpiod_set_value_cansleep(mdiodev->reset_gpio, value);
 
        if (mdiodev->reset_ctrl) {
                if (value)
index 369903d..9412669 100644 (file)
@@ -283,6 +283,18 @@ void of_set_phy_eee_broken(struct phy_device *phydev)
        phydev->eee_broken_modes = broken;
 }
 
+void phy_resolve_aneg_pause(struct phy_device *phydev)
+{
+       if (phydev->duplex == DUPLEX_FULL) {
+               phydev->pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                                 phydev->lp_advertising);
+               phydev->asym_pause = linkmode_test_bit(
+                       ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                       phydev->lp_advertising);
+       }
+}
+EXPORT_SYMBOL_GPL(phy_resolve_aneg_pause);
+
 /**
  * phy_resolve_aneg_linkmode - resolve the advertisements into phy settings
  * @phydev: The phy_device struct
@@ -305,13 +317,7 @@ void phy_resolve_aneg_linkmode(struct phy_device *phydev)
                        break;
                }
 
-       if (phydev->duplex == DUPLEX_FULL) {
-               phydev->pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-                                                 phydev->lp_advertising);
-               phydev->asym_pause = linkmode_test_bit(
-                       ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-                       phydev->lp_advertising);
-       }
+       phy_resolve_aneg_pause(phydev);
 }
 EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);
 
index 7c92afd..119e6f4 100644 (file)
@@ -457,6 +457,11 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
                                                           val);
                                change_autoneg = true;
                                break;
+                       case MII_CTRL1000:
+                               mii_ctrl1000_mod_linkmode_adv_t(phydev->advertising,
+                                                               val);
+                               change_autoneg = true;
+                               break;
                        default:
                                /* do nothing */
                                break;
index d347ddc..9d2bbb1 100644 (file)
@@ -1783,32 +1783,9 @@ done:
 }
 EXPORT_SYMBOL(genphy_update_link);
 
-/**
- * genphy_read_status - check the link status and update current link state
- * @phydev: target phy_device struct
- *
- * Description: Check the link, then figure out the current state
- *   by comparing what we advertise with what the link partner
- *   advertises.  Start by checking the gigabit possibilities,
- *   then move on to 10/100.
- */
-int genphy_read_status(struct phy_device *phydev)
+int genphy_read_lpa(struct phy_device *phydev)
 {
-       int lpa, lpagb, err, old_link = phydev->link;
-
-       /* Update the link, but return if there was an error */
-       err = genphy_update_link(phydev);
-       if (err)
-               return err;
-
-       /* why bother the PHY if nothing can have changed */
-       if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-               return 0;
-
-       phydev->speed = SPEED_UNKNOWN;
-       phydev->duplex = DUPLEX_UNKNOWN;
-       phydev->pause = 0;
-       phydev->asym_pause = 0;
+       int lpa, lpagb;
 
        if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
                if (phydev->is_gigabit_capable) {
@@ -1838,6 +1815,44 @@ int genphy_read_status(struct phy_device *phydev)
                        return lpa;
 
                mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(genphy_read_lpa);
+
+/**
+ * genphy_read_status - check the link status and update current link state
+ * @phydev: target phy_device struct
+ *
+ * Description: Check the link, then figure out the current state
+ *   by comparing what we advertise with what the link partner
+ *   advertises.  Start by checking the gigabit possibilities,
+ *   then move on to 10/100.
+ */
+int genphy_read_status(struct phy_device *phydev)
+{
+       int err, old_link = phydev->link;
+
+       /* Update the link, but return if there was an error */
+       err = genphy_update_link(phydev);
+       if (err)
+               return err;
+
+       /* why bother the PHY if nothing can have changed */
+       if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
+               return 0;
+
+       phydev->speed = SPEED_UNKNOWN;
+       phydev->duplex = DUPLEX_UNKNOWN;
+       phydev->pause = 0;
+       phydev->asym_pause = 0;
+
+       err = genphy_read_lpa(phydev);
+       if (err < 0)
+               return err;
+
+       if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
                phy_resolve_aneg_linkmode(phydev);
        } else if (phydev->autoneg == AUTONEG_DISABLE) {
                int bmcr = phy_read(phydev, MII_BMCR);
index 734de7d..e1fabb3 100644 (file)
@@ -238,7 +238,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        skb_dst_drop(skb);
        skb_dst_set(skb, &rt->dst);
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        skb->ip_summed = CHECKSUM_NONE;
        ip_select_ident(net, skb, NULL);
@@ -358,7 +358,7 @@ static int pptp_rcv(struct sk_buff *skb)
        po = lookup_chan(htons(header->call_id), iph->saddr);
        if (po) {
                skb_dst_drop(skb);
-               nf_reset(skb);
+               nf_reset_ct(skb);
                return sk_receive_skb(sk_pppox(po), skb, 0);
        }
 drop:
index aab0be4..812dc3a 100644 (file)
@@ -1104,7 +1104,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        skb_orphan(skb);
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        if (ptr_ring_produce(&tfile->tx_ring, skb))
                goto drop;
index ce78714..a505b2a 100644 (file)
@@ -2620,14 +2620,18 @@ static struct hso_device *hso_create_bulk_serial_device(
                 */
                if (serial->tiocmget) {
                        tiocmget = serial->tiocmget;
+                       tiocmget->endp = hso_get_ep(interface,
+                                                   USB_ENDPOINT_XFER_INT,
+                                                   USB_DIR_IN);
+                       if (!tiocmget->endp) {
+                               dev_err(&interface->dev, "Failed to find INT IN ep\n");
+                               goto exit;
+                       }
+
                        tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL);
                        if (tiocmget->urb) {
                                mutex_init(&tiocmget->mutex);
                                init_waitqueue_head(&tiocmget->waitq);
-                               tiocmget->endp = hso_get_ep(
-                                       interface,
-                                       USB_ENDPOINT_XFER_INT,
-                                       USB_DIR_IN);
                        } else
                                hso_free_tiomget(serial);
                }
index b6dc5d7..3d77cd4 100644 (file)
@@ -1350,6 +1350,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1e2d, 0x0082, 4)},    /* Cinterion PHxx,PXxx (2 RmNet) */
        {QMI_FIXED_INTF(0x1e2d, 0x0082, 5)},    /* Cinterion PHxx,PXxx (2 RmNet) */
        {QMI_FIXED_INTF(0x1e2d, 0x0083, 4)},    /* Cinterion PHxx,PXxx (1 RmNet + USB Audio)*/
+       {QMI_QUIRK_SET_DTR(0x1e2d, 0x00b0, 4)}, /* Cinterion CLS8 */
        {QMI_FIXED_INTF(0x413c, 0x81a2, 8)},    /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81a3, 8)},    /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81a4, 8)},    /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
index 0872609..cee9fef 100644 (file)
@@ -4799,10 +4799,9 @@ static int rtl8152_reset_resume(struct usb_interface *intf)
        struct r8152 *tp = usb_get_intfdata(intf);
 
        clear_bit(SELECTIVE_SUSPEND, &tp->flags);
-       mutex_lock(&tp->control);
        tp->rtl_ops.init(tp);
        queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0);
-       mutex_unlock(&tp->control);
+       set_ethernet_addr(tp);
        return rtl8152_resume(intf);
 }
 
index ba98e09..5a635f0 100644 (file)
@@ -1585,7 +1585,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Don't wait up for transmitted skbs to be freed. */
        if (!use_napi) {
                skb_orphan(skb);
-               nf_reset(skb);
+               nf_reset_ct(skb);
        }
 
        /* If running out of space, stop queue to avoid getting packets that we
index a4b38a9..ee52bde 100644 (file)
@@ -366,7 +366,7 @@ static int vrf_finish_output6(struct net *net, struct sock *sk,
        struct neighbour *neigh;
        int ret;
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        skb->protocol = htons(ETH_P_IPV6);
        skb->dev = dev;
@@ -459,7 +459,7 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,
 
        /* reset skb device */
        if (likely(err == 1))
-               nf_reset(skb);
+               nf_reset_ct(skb);
        else
                skb = NULL;
 
@@ -560,7 +560,7 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
        bool is_v6gw = false;
        int ret = -EINVAL;
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        /* Be paranoid, rather than too clever. */
        if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
@@ -670,7 +670,7 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
 
        /* reset skb device */
        if (likely(err == 1))
-               nf_reset(skb);
+               nf_reset_ct(skb);
        else
                skb = NULL;
 
index 6359560..45c73a6 100644 (file)
@@ -1261,8 +1261,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
        skb_orphan(skb);
        skb_dst_drop(skb);
        skb->mark = 0;
-       secpath_reset(skb);
-       nf_reset(skb);
+       skb_ext_reset(skb);
+       nf_reset_ct(skb);
 
        /*
         * Get absolute mactime here so all HWs RX at the "same time", and
index e14ec75..482c6c8 100644 (file)
@@ -887,9 +887,9 @@ static int xennet_set_skb_gso(struct sk_buff *skb,
        return 0;
 }
 
-static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
-                                 struct sk_buff *skb,
-                                 struct sk_buff_head *list)
+static int xennet_fill_frags(struct netfront_queue *queue,
+                            struct sk_buff *skb,
+                            struct sk_buff_head *list)
 {
        RING_IDX cons = queue->rx.rsp_cons;
        struct sk_buff *nskb;
@@ -908,7 +908,7 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
                if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
                        queue->rx.rsp_cons = ++cons + skb_queue_len(list);
                        kfree_skb(nskb);
-                       return ~0U;
+                       return -ENOENT;
                }
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
@@ -919,7 +919,9 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
                kfree_skb(nskb);
        }
 
-       return cons;
+       queue->rx.rsp_cons = cons;
+
+       return 0;
 }
 
 static int checksum_setup(struct net_device *dev, struct sk_buff *skb)
@@ -1045,8 +1047,7 @@ err:
                skb->data_len = rx->status;
                skb->len += rx->status;
 
-               i = xennet_fill_frags(queue, skb, &tmpq);
-               if (unlikely(i == ~0U))
+               if (unlikely(xennet_fill_frags(queue, skb, &tmpq)))
                        goto err;
 
                if (rx->flags & XEN_NETRXF_csum_blank)
@@ -1056,7 +1057,7 @@ err:
 
                __skb_queue_tail(&rxq, skb);
 
-               queue->rx.rsp_cons = ++i;
+               i = ++queue->rx.rsp_cons;
                work_done++;
        }
 
index 108f60b..fd7dea3 100644 (file)
@@ -102,10 +102,13 @@ static void nvme_set_queue_dying(struct nvme_ns *ns)
         */
        if (!ns->disk || test_and_set_bit(NVME_NS_DEAD, &ns->flags))
                return;
-       revalidate_disk(ns->disk);
        blk_set_queue_dying(ns->queue);
        /* Forcibly unquiesce queues to avoid blocking dispatch */
        blk_mq_unquiesce_queue(ns->queue);
+       /*
+        * Revalidate after unblocking dispatchers that may be holding bd_butex
+        */
+       revalidate_disk(ns->disk);
 }
 
 static void nvme_queue_scan(struct nvme_ctrl *ctrl)
@@ -847,7 +850,7 @@ out:
 static int nvme_submit_user_cmd(struct request_queue *q,
                struct nvme_command *cmd, void __user *ubuffer,
                unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
-               u32 meta_seed, u32 *result, unsigned timeout)
+               u32 meta_seed, u64 *result, unsigned timeout)
 {
        bool write = nvme_is_write(cmd);
        struct nvme_ns *ns = q->queuedata;
@@ -888,7 +891,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,
        else
                ret = nvme_req(req)->status;
        if (result)
-               *result = le32_to_cpu(nvme_req(req)->result.u32);
+               *result = le64_to_cpu(nvme_req(req)->result.u64);
        if (meta && !ret && !write) {
                if (copy_to_user(meta_buffer, meta, meta_len))
                        ret = -EFAULT;
@@ -1335,6 +1338,54 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
        struct nvme_command c;
        unsigned timeout = 0;
        u32 effects;
+       u64 result;
+       int status;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+       if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
+               return -EFAULT;
+       if (cmd.flags)
+               return -EINVAL;
+
+       memset(&c, 0, sizeof(c));
+       c.common.opcode = cmd.opcode;
+       c.common.flags = cmd.flags;
+       c.common.nsid = cpu_to_le32(cmd.nsid);
+       c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
+       c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
+       c.common.cdw10 = cpu_to_le32(cmd.cdw10);
+       c.common.cdw11 = cpu_to_le32(cmd.cdw11);
+       c.common.cdw12 = cpu_to_le32(cmd.cdw12);
+       c.common.cdw13 = cpu_to_le32(cmd.cdw13);
+       c.common.cdw14 = cpu_to_le32(cmd.cdw14);
+       c.common.cdw15 = cpu_to_le32(cmd.cdw15);
+
+       if (cmd.timeout_ms)
+               timeout = msecs_to_jiffies(cmd.timeout_ms);
+
+       effects = nvme_passthru_start(ctrl, ns, cmd.opcode);
+       status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+                       (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+                       (void __user *)(uintptr_t)cmd.metadata,
+                       cmd.metadata_len, 0, &result, timeout);
+       nvme_passthru_end(ctrl, effects);
+
+       if (status >= 0) {
+               if (put_user(result, &ucmd->result))
+                       return -EFAULT;
+       }
+
+       return status;
+}
+
+static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+                       struct nvme_passthru_cmd64 __user *ucmd)
+{
+       struct nvme_passthru_cmd64 cmd;
+       struct nvme_command c;
+       unsigned timeout = 0;
+       u32 effects;
        int status;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -1405,6 +1456,41 @@ static void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx)
                srcu_read_unlock(&head->srcu, idx);
 }
 
+static bool is_ctrl_ioctl(unsigned int cmd)
+{
+       if (cmd == NVME_IOCTL_ADMIN_CMD || cmd == NVME_IOCTL_ADMIN64_CMD)
+               return true;
+       if (is_sed_ioctl(cmd))
+               return true;
+       return false;
+}
+
+static int nvme_handle_ctrl_ioctl(struct nvme_ns *ns, unsigned int cmd,
+                                 void __user *argp,
+                                 struct nvme_ns_head *head,
+                                 int srcu_idx)
+{
+       struct nvme_ctrl *ctrl = ns->ctrl;
+       int ret;
+
+       nvme_get_ctrl(ns->ctrl);
+       nvme_put_ns_from_disk(head, srcu_idx);
+
+       switch (cmd) {
+       case NVME_IOCTL_ADMIN_CMD:
+               ret = nvme_user_cmd(ctrl, NULL, argp);
+               break;
+       case NVME_IOCTL_ADMIN64_CMD:
+               ret = nvme_user_cmd64(ctrl, NULL, argp);
+               break;
+       default:
+               ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
+               break;
+       }
+       nvme_put_ctrl(ctrl);
+       return ret;
+}
+
 static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
                unsigned int cmd, unsigned long arg)
 {
@@ -1422,20 +1508,8 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
         * seperately and drop the ns SRCU reference early.  This avoids a
         * deadlock when deleting namespaces using the passthrough interface.
         */
-       if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) {
-               struct nvme_ctrl *ctrl = ns->ctrl;
-
-               nvme_get_ctrl(ns->ctrl);
-               nvme_put_ns_from_disk(head, srcu_idx);
-
-               if (cmd == NVME_IOCTL_ADMIN_CMD)
-                       ret = nvme_user_cmd(ctrl, NULL, argp);
-               else
-                       ret = sed_ioctl(ctrl->opal_dev, cmd, argp);
-
-               nvme_put_ctrl(ctrl);
-               return ret;
-       }
+       if (is_ctrl_ioctl(cmd))
+               return nvme_handle_ctrl_ioctl(ns, cmd, argp, head, srcu_idx);
 
        switch (cmd) {
        case NVME_IOCTL_ID:
@@ -1448,6 +1522,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
        case NVME_IOCTL_SUBMIT_IO:
                ret = nvme_submit_io(ns, argp);
                break;
+       case NVME_IOCTL_IO64_CMD:
+               ret = nvme_user_cmd64(ns->ctrl, ns, argp);
+               break;
        default:
                if (ns->ndev)
                        ret = nvme_nvm_ioctl(ns, cmd, arg);
@@ -2289,6 +2366,16 @@ static const struct nvme_core_quirk_entry core_quirks[] = {
                .vid = 0x14a4,
                .fr = "22301111",
                .quirks = NVME_QUIRK_SIMPLE_SUSPEND,
+       },
+       {
+               /*
+                * This Kingston E8FK11.T firmware version has no interrupt
+                * after resume with actions related to suspend to idle
+                * https://bugzilla.kernel.org/show_bug.cgi?id=204887
+                */
+               .vid = 0x2646,
+               .fr = "E8FK11.T",
+               .quirks = NVME_QUIRK_SIMPLE_SUSPEND,
        }
 };
 
@@ -2540,8 +2627,9 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
                list_add_tail(&subsys->entry, &nvme_subsystems);
        }
 
-       if (sysfs_create_link(&subsys->dev.kobj, &ctrl->device->kobj,
-                       dev_name(ctrl->device))) {
+       ret = sysfs_create_link(&subsys->dev.kobj, &ctrl->device->kobj,
+                               dev_name(ctrl->device));
+       if (ret) {
                dev_err(ctrl->device,
                        "failed to create sysfs link from subsystem.\n");
                goto out_put_subsystem;
@@ -2838,6 +2926,8 @@ static long nvme_dev_ioctl(struct file *file, unsigned int cmd,
        switch (cmd) {
        case NVME_IOCTL_ADMIN_CMD:
                return nvme_user_cmd(ctrl, NULL, argp);
+       case NVME_IOCTL_ADMIN64_CMD:
+               return nvme_user_cmd64(ctrl, NULL, argp);
        case NVME_IOCTL_IO_CMD:
                return nvme_dev_user_cmd(ctrl, argp);
        case NVME_IOCTL_RESET:
@@ -3045,6 +3135,8 @@ static DEVICE_ATTR(field, S_IRUGO, field##_show, NULL);
 
 nvme_show_int_function(cntlid);
 nvme_show_int_function(numa_node);
+nvme_show_int_function(queue_count);
+nvme_show_int_function(sqsize);
 
 static ssize_t nvme_sysfs_delete(struct device *dev,
                                struct device_attribute *attr, const char *buf,
@@ -3125,6 +3217,8 @@ static struct attribute *nvme_dev_attrs[] = {
        &dev_attr_address.attr,
        &dev_attr_state.attr,
        &dev_attr_numa_node.attr,
+       &dev_attr_queue_count.attr,
+       &dev_attr_sqsize.attr,
        NULL
 };
 
index b5013c1..38a83ef 100644 (file)
@@ -221,6 +221,7 @@ struct nvme_ctrl {
        u16 oacs;
        u16 nssa;
        u16 nr_streams;
+       u16 sqsize;
        u32 max_namespaces;
        atomic_t abort_limit;
        u8 vwc;
@@ -269,7 +270,6 @@ struct nvme_ctrl {
        u16 hmmaxd;
 
        /* Fabrics only */
-       u16 sqsize;
        u32 ioccsz;
        u32 iorcsz;
        u16 icdoff;
index c0808f9..bb88681 100644 (file)
@@ -2946,11 +2946,21 @@ static int nvme_suspend(struct device *dev)
        if (ret < 0)
                goto unfreeze;
 
+       /*
+        * A saved state prevents pci pm from generically controlling the
+        * device's power. If we're using protocol specific settings, we don't
+        * want pci interfering.
+        */
+       pci_save_state(pdev);
+
        ret = nvme_set_power_state(ctrl, ctrl->npss);
        if (ret < 0)
                goto unfreeze;
 
        if (ret) {
+               /* discard the saved state */
+               pci_load_saved_state(pdev, NULL);
+
                /*
                 * Clearing npss forces a controller reset on resume. The
                 * correct value will be resdicovered then.
@@ -2958,14 +2968,7 @@ static int nvme_suspend(struct device *dev)
                nvme_dev_disable(ndev, true);
                ctrl->npss = 0;
                ret = 0;
-               goto unfreeze;
        }
-       /*
-        * A saved state prevents pci pm from generically controlling the
-        * device's power. If we're using protocol specific settings, we don't
-        * want pci interfering.
-        */
-       pci_save_state(pdev);
 unfreeze:
        nvme_unfreeze(ctrl);
        return ret;
@@ -3090,6 +3093,9 @@ static const struct pci_device_id nvme_id_table[] = {
                .driver_data = NVME_QUIRK_LIGHTNVM, },
        { PCI_DEVICE(0x10ec, 0x5762),   /* ADATA SX6000LNP */
                .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+       { PCI_DEVICE(0x1cc1, 0x8201),   /* ADATA SX8200PNP 512GB */
+               .driver_data = NVME_QUIRK_NO_DEEPEST_PS |
+                               NVME_QUIRK_IGNORE_DEV_SUBNQN, },
        { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
        { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
        { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
index dfa07bb..4d28016 100644 (file)
@@ -427,7 +427,7 @@ static void nvme_rdma_destroy_queue_ib(struct nvme_rdma_queue *queue)
 static int nvme_rdma_get_max_fr_pages(struct ib_device *ibdev)
 {
        return min_t(u32, NVME_RDMA_MAX_SEGMENTS,
-                    ibdev->attrs.max_fast_reg_page_list_len);
+                    ibdev->attrs.max_fast_reg_page_list_len - 1);
 }
 
 static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
@@ -437,7 +437,7 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
        const int cq_factor = send_wr_factor + 1;       /* + RECV */
        int comp_vector, idx = nvme_rdma_queue_idx(queue);
        enum ib_poll_context poll_ctx;
-       int ret;
+       int ret, pages_per_mr;
 
        queue->device = nvme_rdma_find_get_device(queue->cm_id);
        if (!queue->device) {
@@ -479,10 +479,16 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
                goto out_destroy_qp;
        }
 
+       /*
+        * Currently we don't use SG_GAPS MR's so if the first entry is
+        * misaligned we'll end up using two entries for a single data page,
+        * so one additional entry is required.
+        */
+       pages_per_mr = nvme_rdma_get_max_fr_pages(ibdev) + 1;
        ret = ib_mr_pool_init(queue->qp, &queue->qp->rdma_mrs,
                              queue->queue_size,
                              IB_MR_TYPE_MEM_REG,
-                             nvme_rdma_get_max_fr_pages(ibdev), 0);
+                             pages_per_mr, 0);
        if (ret) {
                dev_err(queue->ctrl->ctrl.device,
                        "failed to initialize MR pool sized %d for QID %d\n",
@@ -614,7 +620,8 @@ static int nvme_rdma_start_queue(struct nvme_rdma_ctrl *ctrl, int idx)
        if (!ret) {
                set_bit(NVME_RDMA_Q_LIVE, &queue->flags);
        } else {
-               __nvme_rdma_stop_queue(queue);
+               if (test_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags))
+                       __nvme_rdma_stop_queue(queue);
                dev_info(ctrl->ctrl.device,
                        "failed to connect queue: %d ret=%d\n", idx, ret);
        }
@@ -820,8 +827,8 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl,
        if (error)
                goto out_stop_queue;
 
-       ctrl->ctrl.max_hw_sectors =
-               (ctrl->max_fr_pages - 1) << (ilog2(SZ_4K) - 9);
+       ctrl->ctrl.max_segments = ctrl->max_fr_pages;
+       ctrl->ctrl.max_hw_sectors = ctrl->max_fr_pages << (ilog2(SZ_4K) - 9);
 
        blk_mq_unquiesce_queue(ctrl->ctrl.admin_q);
 
index 4ffd595..385a521 100644 (file)
@@ -1042,7 +1042,7 @@ static void nvme_tcp_io_work(struct work_struct *w)
 {
        struct nvme_tcp_queue *queue =
                container_of(w, struct nvme_tcp_queue, io_work);
-       unsigned long start = jiffies + msecs_to_jiffies(1);
+       unsigned long deadline = jiffies + msecs_to_jiffies(1);
 
        do {
                bool pending = false;
@@ -1067,7 +1067,7 @@ static void nvme_tcp_io_work(struct work_struct *w)
                if (!pending)
                        return;
 
-       } while (time_after(jiffies, start)); /* quota is exhausted */
+       } while (!time_after(jiffies, deadline)); /* quota is exhausted */
 
        queue_work_on(queue->io_cpu, nvme_tcp_wq, &queue->io_work);
 }
index de0bff7..32008d8 100644 (file)
 void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id)
 {
        const struct queue_limits *ql = &bdev_get_queue(bdev)->limits;
-       /* Number of physical blocks per logical block. */
-       const u32 ppl = ql->physical_block_size / ql->logical_block_size;
-       /* Physical blocks per logical block, 0's based. */
-       const __le16 ppl0b = to0based(ppl);
+       /* Number of logical blocks per physical block. */
+       const u32 lpp = ql->physical_block_size / ql->logical_block_size;
+       /* Logical blocks per physical block, 0's based. */
+       const __le16 lpp0b = to0based(lpp);
 
        /*
         * For NVMe 1.2 and later, bit 1 indicates that the fields NAWUN,
@@ -25,9 +25,9 @@ void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id)
         * field from the identify controller data structure should be used.
         */
        id->nsfeat |= 1 << 1;
-       id->nawun = ppl0b;
-       id->nawupf = ppl0b;
-       id->nacwu = ppl0b;
+       id->nawun = lpp0b;
+       id->nawupf = lpp0b;
+       id->nacwu = lpp0b;
 
        /*
         * Bit 4 indicates that the fields NPWG, NPWA, NPDG, NPDA, and
@@ -36,7 +36,7 @@ void nvmet_bdev_set_limits(struct block_device *bdev, struct nvme_id_ns *id)
         */
        id->nsfeat |= 1 << 4;
        /* NPWG = Namespace Preferred Write Granularity. 0's based */
-       id->npwg = ppl0b;
+       id->npwg = lpp0b;
        /* NPWA = Namespace Preferred Write Alignment. 0's based */
        id->npwa = id->npwg;
        /* NPDG = Namespace Preferred Deallocate Granularity. 0's based */
index bf4f034..d535080 100644 (file)
@@ -348,8 +348,7 @@ static int nvmet_tcp_map_data(struct nvmet_tcp_cmd *cmd)
 
        return 0;
 err:
-       if (cmd->req.sg_cnt)
-               sgl_free(cmd->req.sg);
+       sgl_free(cmd->req.sg);
        return NVME_SC_INTERNAL;
 }
 
@@ -554,8 +553,7 @@ static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd)
 
        if (queue->nvme_sq.sqhd_disabled) {
                kfree(cmd->iov);
-               if (cmd->req.sg_cnt)
-                       sgl_free(cmd->req.sg);
+               sgl_free(cmd->req.sg);
        }
 
        return 1;
@@ -586,8 +584,7 @@ static int nvmet_try_send_response(struct nvmet_tcp_cmd *cmd,
                return -EAGAIN;
 
        kfree(cmd->iov);
-       if (cmd->req.sg_cnt)
-               sgl_free(cmd->req.sg);
+       sgl_free(cmd->req.sg);
        cmd->queue->snd_cmd = NULL;
        nvmet_tcp_put_cmd(cmd);
        return 1;
@@ -1310,8 +1307,7 @@ static void nvmet_tcp_finish_cmd(struct nvmet_tcp_cmd *cmd)
        nvmet_req_uninit(&cmd->req);
        nvmet_tcp_unmap_pdu_iovec(cmd);
        kfree(cmd->iov);
-       if (cmd->req.sg_cnt)
-               sgl_free(cmd->req.sg);
+       sgl_free(cmd->req.sg);
 }
 
 static void nvmet_tcp_uninit_data_in_cmds(struct nvmet_tcp_queue *queue)
index c61f00b..a577218 100644 (file)
@@ -507,6 +507,8 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base,
                ptp_qoriq->regs.etts_regs = base + ETTS_REGS_OFFSET;
        }
 
+       spin_lock_init(&ptp_qoriq->lock);
+
        ktime_get_real_ts64(&now);
        ptp_qoriq_settime(&ptp_qoriq->caps, &now);
 
@@ -514,7 +516,6 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base,
          (ptp_qoriq->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
          (ptp_qoriq->cksel & CKSEL_MASK) << CKSEL_SHIFT;
 
-       spin_lock_init(&ptp_qoriq->lock);
        spin_lock_irqsave(&ptp_qoriq->lock, flags);
 
        regs = &ptp_qoriq->regs;
index fc53e1e..c94184d 100644 (file)
@@ -1553,8 +1553,8 @@ static int dasd_eckd_read_vol_info(struct dasd_device *device)
        if (rc == 0) {
                memcpy(&private->vsq, vsq, sizeof(*vsq));
        } else {
-               dev_warn(&device->cdev->dev,
-                        "Reading the volume storage information failed with rc=%d\n", rc);
+               DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+                               "Reading the volume storage information failed with rc=%d", rc);
        }
 
        if (useglobal)
@@ -1737,8 +1737,8 @@ static int dasd_eckd_read_ext_pool_info(struct dasd_device *device)
        if (rc == 0) {
                dasd_eckd_cpy_ext_pool_data(device, lcq);
        } else {
-               dev_warn(&device->cdev->dev,
-                        "Reading the logical configuration failed with rc=%d\n", rc);
+               DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+                               "Reading the logical configuration failed with rc=%d", rc);
        }
 
        dasd_sfree_request(cqr, cqr->memdev);
@@ -2020,14 +2020,10 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
        dasd_eckd_read_features(device);
 
        /* Read Volume Information */
-       rc = dasd_eckd_read_vol_info(device);
-       if (rc)
-               goto out_err3;
+       dasd_eckd_read_vol_info(device);
 
        /* Read Extent Pool Information */
-       rc = dasd_eckd_read_ext_pool_info(device);
-       if (rc)
-               goto out_err3;
+       dasd_eckd_read_ext_pool_info(device);
 
        /* Read Device Characteristics */
        rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
@@ -2059,9 +2055,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
        if (readonly)
                set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
 
-       if (dasd_eckd_is_ese(device))
-               dasd_set_feature(device->cdev, DASD_FEATURE_DISCARD, 1);
-
        dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
                 "with %d cylinders, %d heads, %d sectors%s\n",
                 private->rdc_data.dev_type,
@@ -3695,14 +3688,6 @@ static int dasd_eckd_release_space(struct dasd_device *device,
                return -EINVAL;
 }
 
-static struct dasd_ccw_req *
-dasd_eckd_build_cp_discard(struct dasd_device *device, struct dasd_block *block,
-                          struct request *req, sector_t first_trk,
-                          sector_t last_trk)
-{
-       return dasd_eckd_dso_ras(device, block, req, first_trk, last_trk, 1);
-}
-
 static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
                                               struct dasd_device *startdev,
                                               struct dasd_block *block,
@@ -4447,10 +4432,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
        cmdwtd = private->features.feature[12] & 0x40;
        use_prefix = private->features.feature[8] & 0x01;
 
-       if (req_op(req) == REQ_OP_DISCARD)
-               return dasd_eckd_build_cp_discard(startdev, block, req,
-                                                 first_trk, last_trk);
-
        cqr = NULL;
        if (cdlspecial || dasd_page_cache) {
                /* do nothing, just fall through to the cmd mode single case */
@@ -4729,14 +4710,12 @@ static struct dasd_ccw_req *dasd_eckd_build_alias_cp(struct dasd_device *base,
                                                     struct dasd_block *block,
                                                     struct request *req)
 {
-       struct dasd_device *startdev = NULL;
        struct dasd_eckd_private *private;
-       struct dasd_ccw_req *cqr;
+       struct dasd_device *startdev;
        unsigned long flags;
+       struct dasd_ccw_req *cqr;
 
-       /* Discard requests can only be processed on base devices */
-       if (req_op(req) != REQ_OP_DISCARD)
-               startdev = dasd_alias_get_start_dev(base);
+       startdev = dasd_alias_get_start_dev(base);
        if (!startdev)
                startdev = base;
        private = startdev->private;
@@ -5663,14 +5642,10 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
        dasd_eckd_read_features(device);
 
        /* Read Volume Information */
-       rc = dasd_eckd_read_vol_info(device);
-       if (rc)
-               goto out_err2;
+       dasd_eckd_read_vol_info(device);
 
        /* Read Extent Pool Information */
-       rc = dasd_eckd_read_ext_pool_info(device);
-       if (rc)
-               goto out_err2;
+       dasd_eckd_read_ext_pool_info(device);
 
        /* Read Device Characteristics */
        rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
@@ -6521,20 +6496,8 @@ static void dasd_eckd_setup_blk_queue(struct dasd_block *block)
        unsigned int logical_block_size = block->bp_block;
        struct request_queue *q = block->request_queue;
        struct dasd_device *device = block->base;
-       struct dasd_eckd_private *private;
-       unsigned int max_discard_sectors;
-       unsigned int max_bytes;
-       unsigned int ext_bytes; /* Extent Size in Bytes */
-       int recs_per_trk;
-       int trks_per_cyl;
-       int ext_limit;
-       int ext_size; /* Extent Size in Cylinders */
        int max;
 
-       private = device->private;
-       trks_per_cyl = private->rdc_data.trk_per_cyl;
-       recs_per_trk = recs_per_track(&private->rdc_data, 0, logical_block_size);
-
        if (device->features & DASD_FEATURE_USERAW) {
                /*
                 * the max_blocks value for raw_track access is 256
@@ -6555,28 +6518,6 @@ static void dasd_eckd_setup_blk_queue(struct dasd_block *block)
        /* With page sized segments each segment can be translated into one idaw/tidaw */
        blk_queue_max_segment_size(q, PAGE_SIZE);
        blk_queue_segment_boundary(q, PAGE_SIZE - 1);
-
-       if (dasd_eckd_is_ese(device)) {
-               /*
-                * Depending on the extent size, up to UINT_MAX bytes can be
-                * accepted. However, neither DASD_ECKD_RAS_EXTS_MAX nor the
-                * device limits should be exceeded.
-                */
-               ext_size = dasd_eckd_ext_size(device);
-               ext_limit = min(private->real_cyl / ext_size, DASD_ECKD_RAS_EXTS_MAX);
-               ext_bytes = ext_size * trks_per_cyl * recs_per_trk *
-                       logical_block_size;
-               max_bytes = UINT_MAX - (UINT_MAX % ext_bytes);
-               if (max_bytes / ext_bytes > ext_limit)
-                       max_bytes = ext_bytes * ext_limit;
-
-               max_discard_sectors = max_bytes / 512;
-
-               blk_queue_max_discard_sectors(q, max_discard_sectors);
-               blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
-               q->limits.discard_granularity = ext_bytes;
-               q->limits.discard_alignment = ext_bytes;
-       }
 }
 
 static struct ccw_driver dasd_eckd_driver = {
index ba7d248..dcdaba6 100644 (file)
@@ -113,6 +113,7 @@ struct subchannel {
        enum sch_todo todo;
        struct work_struct todo_work;
        struct schib_config config;
+       u64 dma_mask;
        char *driver_override; /* Driver name to force a match */
 } __attribute__ ((aligned(8)));
 
index 1fbfb0a..8318504 100644 (file)
@@ -232,7 +232,12 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid,
         * belong to a subchannel need to fit 31 bit width (e.g. ccw).
         */
        sch->dev.coherent_dma_mask = DMA_BIT_MASK(31);
-       sch->dev.dma_mask = &sch->dev.coherent_dma_mask;
+       /*
+        * But we don't have such restrictions imposed on the stuff that
+        * is handled by the streaming API.
+        */
+       sch->dma_mask = DMA_BIT_MASK(64);
+       sch->dev.dma_mask = &sch->dma_mask;
        return sch;
 
 err:
index 131430b..0c6245f 100644 (file)
@@ -710,7 +710,7 @@ static struct ccw_device * io_subchannel_allocate_dev(struct subchannel *sch)
        if (!cdev->private)
                goto err_priv;
        cdev->dev.coherent_dma_mask = sch->dev.coherent_dma_mask;
-       cdev->dev.dma_mask = &cdev->dev.coherent_dma_mask;
+       cdev->dev.dma_mask = sch->dev.dma_mask;
        dma_pool = cio_gp_dma_create(&cdev->dev, 1);
        if (!dma_pool)
                goto err_dma_pool;
index f4ca1d2..cd16488 100644 (file)
@@ -113,7 +113,7 @@ static void set_impl_params(struct qdio_irq *irq_ptr,
        irq_ptr->qib.pfmt = qib_param_field_format;
        if (qib_param_field)
                memcpy(irq_ptr->qib.parm, qib_param_field,
-                      QDIO_MAX_BUFFERS_PER_Q);
+                      sizeof(irq_ptr->qib.parm));
 
        if (!input_slib_elements)
                goto output;
index a7868c8..dda2743 100644 (file)
@@ -4715,8 +4715,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
 
        QETH_CARD_TEXT(card, 2, "qdioest");
 
-       qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q,
-                                 GFP_KERNEL);
+       qib_param_field = kzalloc(FIELD_SIZEOF(struct qib, parm), GFP_KERNEL);
        if (!qib_param_field) {
                rc =  -ENOMEM;
                goto out_free_nothing;
index da00ca5..401743e 100644 (file)
@@ -1923,6 +1923,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
        struct fcoe_fcp_rsp_payload *fcp_rsp;
        struct bnx2fc_rport *tgt = io_req->tgt;
        struct scsi_cmnd *sc_cmd;
+       u16 scope = 0, qualifier = 0;
 
        /* scsi_cmd_cmpl is called with tgt lock held */
 
@@ -1990,12 +1991,30 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
 
                        if (io_req->cdb_status == SAM_STAT_TASK_SET_FULL ||
                            io_req->cdb_status == SAM_STAT_BUSY) {
-                               /* Set the jiffies + retry_delay_timer * 100ms
-                                  for the rport/tgt */
-                               tgt->retry_delay_timestamp = jiffies +
-                                       fcp_rsp->retry_delay_timer * HZ / 10;
+                               /* Newer array firmware with BUSY or
+                                * TASK_SET_FULL may return a status that needs
+                                * the scope bits masked.
+                                * Or a huge delay timestamp up to 27 minutes
+                                * can result.
+                                */
+                               if (fcp_rsp->retry_delay_timer) {
+                                       /* Upper 2 bits */
+                                       scope = fcp_rsp->retry_delay_timer
+                                               & 0xC000;
+                                       /* Lower 14 bits */
+                                       qualifier = fcp_rsp->retry_delay_timer
+                                               & 0x3FFF;
+                               }
+                               if (scope > 0 && qualifier > 0 &&
+                                       qualifier <= 0x3FEF) {
+                                       /* Set the jiffies +
+                                        * retry_delay_timer * 100ms
+                                        * for the rport/tgt
+                                        */
+                                       tgt->retry_delay_timestamp = jiffies +
+                                               (qualifier * HZ / 10);
+                               }
                        }
-
                }
                if (io_req->fcp_resid)
                        scsi_set_resid(sc_cmd, io_req->fcp_resid);
index d1513fd..0847e68 100644 (file)
@@ -3683,7 +3683,7 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work)
 }
 EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler);
 
-void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba)
+static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba)
 {
        struct device *dev = hisi_hba->dev;
        int i;
@@ -3705,7 +3705,7 @@ void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba)
                devm_kfree(dev, hisi_hba->debugfs_port_reg[i]);
 }
 
-int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba)
+static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba)
 {
        const struct hisi_sas_hw *hw = hisi_hba->hw;
        struct device *dev = hisi_hba->dev;
@@ -3796,7 +3796,7 @@ fail:
        return -ENOMEM;
 }
 
-void hisi_sas_debugfs_bist_init(struct hisi_hba *hisi_hba)
+static void hisi_sas_debugfs_bist_init(struct hisi_hba *hisi_hba)
 {
        hisi_hba->debugfs_bist_dentry =
                        debugfs_create_dir("bist", hisi_hba->debugfs_dir);
index 45a6604..ff6d4aa 100644 (file)
@@ -4183,11 +4183,11 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                 */
                if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
                    pdev->subsystem_device == 0xC000)
-                       return -ENODEV;
+                       goto out_disable_device;
                /* Now check the magic signature byte */
                pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
                if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
-                       return -ENODEV;
+                       goto out_disable_device;
                /* Ok it is probably a megaraid */
        }
 
index 1659d35..59ca98f 100644 (file)
@@ -596,7 +596,7 @@ static void qedf_dcbx_handler(void *dev, struct qed_dcbx_get *get, u32 mib_type)
                tmp_prio = get->operational.app_prio.fcoe;
                if (qedf_default_prio > -1)
                        qedf->prio = qedf_default_prio;
-               else if (tmp_prio < 0 || tmp_prio > 7) {
+               else if (tmp_prio > 7) {
                        QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
                            "FIP/FCoE prio %d out of range, setting to %d.\n",
                            tmp_prio, QEDF_DEFAULT_PRIO);
index 8190c2a..30bafd9 100644 (file)
@@ -2920,6 +2920,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
        struct qla_hw_data *ha = vha->hw;
        uint16_t id = vha->vp_idx;
 
+       set_bit(VPORT_DELETE, &vha->dpc_flags);
+
        while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
            test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
                msleep(1000);
index 873a6ae..6ffa987 100644 (file)
@@ -2396,6 +2396,7 @@ typedef struct fc_port {
        unsigned int query:1;
        unsigned int id_changed:1;
        unsigned int scan_needed:1;
+       unsigned int n2n_flag:1;
 
        struct completion nvme_del_done;
        uint32_t nvme_prli_service_param;
@@ -2446,7 +2447,6 @@ typedef struct fc_port {
        uint8_t fc4_type;
        uint8_t fc4f_nvme;
        uint8_t scan_state;
-       uint8_t n2n_flag;
 
        unsigned long last_queue_full;
        unsigned long last_ramp_up;
@@ -3036,6 +3036,7 @@ enum scan_flags_t {
 enum fc4type_t {
        FS_FC4TYPE_FCP  = BIT_0,
        FS_FC4TYPE_NVME = BIT_1,
+       FS_FCP_IS_N2N = BIT_7,
 };
 
 struct fab_scan_rp {
@@ -4394,6 +4395,7 @@ typedef struct scsi_qla_host {
 #define IOCB_WORK_ACTIVE       31
 #define SET_ZIO_THRESHOLD_NEEDED 32
 #define ISP_ABORT_TO_ROM       33
+#define VPORT_DELETE           34
 
        unsigned long   pci_flags;
 #define PFLG_DISCONNECTED      0       /* PCI device removed */
index dc0e366..5298ed1 100644 (file)
@@ -3102,7 +3102,8 @@ int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
 {
        struct qla_work_evt *e;
 
-       if (test_bit(UNLOADING, &vha->dpc_flags))
+       if (test_bit(UNLOADING, &vha->dpc_flags) ||
+           (vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)))
                return 0;
 
        e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
index 643d232..1d04131 100644 (file)
@@ -746,12 +746,15 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
                        break;
                default:
                        if ((id.b24 != fcport->d_id.b24 &&
-                           fcport->d_id.b24) ||
+                           fcport->d_id.b24 &&
+                           fcport->loop_id != FC_NO_LOOP_ID) ||
                            (fcport->loop_id != FC_NO_LOOP_ID &&
                                fcport->loop_id != loop_id)) {
                                ql_dbg(ql_dbg_disc, vha, 0x20e3,
                                    "%s %d %8phC post del sess\n",
                                    __func__, __LINE__, fcport->port_name);
+                               if (fcport->n2n_flag)
+                                       fcport->d_id.b24 = 0;
                                qlt_schedule_sess_for_deletion(fcport);
                                return;
                        }
@@ -759,6 +762,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
                }
 
                fcport->loop_id = loop_id;
+               if (fcport->n2n_flag)
+                       fcport->d_id.b24 = id.b24;
 
                wwn = wwn_to_u64(fcport->port_name);
                qlt_find_sess_invalidate_other(vha, wwn,
@@ -972,7 +977,7 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
                wwn = wwn_to_u64(e->port_name);
 
                ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8,
-                   "%s %8phC %02x:%02x:%02x state %d/%d lid %x \n",
+                   "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n",
                    __func__, (void *)&wwn, e->port_id[2], e->port_id[1],
                    e->port_id[0], e->current_login_state, e->last_login_state,
                    (loop_id & 0x7fff));
@@ -1499,7 +1504,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
             (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
                return 0;
 
-       if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
+       if (fcport->fw_login_state == DSC_LS_PLOGI_COMP &&
+           !N2N_TOPO(vha->hw)) {
                if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
                        set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
                        return 0;
@@ -1570,8 +1576,9 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
                                qla24xx_post_gpdb_work(vha, fcport, 0);
                        }  else {
                                ql_dbg(ql_dbg_disc, vha, 0x2118,
-                                   "%s %d %8phC post NVMe PRLI\n",
-                                   __func__, __LINE__, fcport->port_name);
+                                   "%s %d %8phC post %s PRLI\n",
+                                   __func__, __LINE__, fcport->port_name,
+                                   fcport->fc4f_nvme ? "NVME" : "FC");
                                qla24xx_post_prli_work(vha, fcport);
                        }
                        break;
@@ -1853,17 +1860,38 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                        break;
                }
 
-               if (ea->fcport->n2n_flag) {
+               if (ea->fcport->fc4f_nvme) {
                        ql_dbg(ql_dbg_disc, vha, 0x2118,
                                "%s %d %8phC post fc4 prli\n",
                                __func__, __LINE__, ea->fcport->port_name);
                        ea->fcport->fc4f_nvme = 0;
-                       ea->fcport->n2n_flag = 0;
                        qla24xx_post_prli_work(vha, ea->fcport);
+                       return;
+               }
+
+               /* at this point both PRLI NVME & PRLI FCP failed */
+               if (N2N_TOPO(vha->hw)) {
+                       if (ea->fcport->n2n_link_reset_cnt < 3) {
+                               ea->fcport->n2n_link_reset_cnt++;
+                               /*
+                                * remote port is not sending Plogi. Reset
+                                * link to kick start his state machine
+                                */
+                               set_bit(N2N_LINK_RESET, &vha->dpc_flags);
+                       } else {
+                               ql_log(ql_log_warn, vha, 0x2119,
+                                   "%s %d %8phC Unable to reconnect\n",
+                                   __func__, __LINE__, ea->fcport->port_name);
+                       }
+               } else {
+                       /*
+                        * switch connect. login failed. Take connection
+                        * down and allow relogin to retrigger
+                        */
+                       ea->fcport->flags &= ~FCF_ASYNC_SENT;
+                       ea->fcport->keep_nport_handle = 0;
+                       qlt_schedule_sess_for_deletion(ea->fcport);
                }
-               ql_dbg(ql_dbg_disc, vha, 0x2119,
-                   "%s %d %8phC unhandle event of %x\n",
-                   __func__, __LINE__, ea->fcport->port_name, ea->data[0]);
                break;
        }
 }
@@ -3190,7 +3218,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
 
                for (j = 0; j < 2; j++, fwdt++) {
                        if (!fwdt->template) {
-                               ql_log(ql_log_warn, vha, 0x00ba,
+                               ql_dbg(ql_dbg_init, vha, 0x00ba,
                                    "-> fwdt%u no template\n", j);
                                continue;
                        }
@@ -4986,28 +5014,47 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
        unsigned long flags;
 
        /* Inititae N2N login. */
-       if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
-               /* borrowing */
-               u32 *bp, i, sz;
-
-               memset(ha->init_cb, 0, ha->init_cb_size);
-               sz = min_t(int, sizeof(struct els_plogi_payload),
-                   ha->init_cb_size);
-               rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
-                   (void *)ha->init_cb, sz);
-               if (rval == QLA_SUCCESS) {
-                       bp = (uint32_t *)ha->init_cb;
-                       for (i = 0; i < sz/4 ; i++, bp++)
-                               *bp = cpu_to_be32(*bp);
+       if (N2N_TOPO(ha)) {
+               if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
+                       /* borrowing */
+                       u32 *bp, i, sz;
+
+                       memset(ha->init_cb, 0, ha->init_cb_size);
+                       sz = min_t(int, sizeof(struct els_plogi_payload),
+                           ha->init_cb_size);
+                       rval = qla24xx_get_port_login_templ(vha,
+                           ha->init_cb_dma, (void *)ha->init_cb, sz);
+                       if (rval == QLA_SUCCESS) {
+                               bp = (uint32_t *)ha->init_cb;
+                               for (i = 0; i < sz/4 ; i++, bp++)
+                                       *bp = cpu_to_be32(*bp);
 
-                       memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb,
-                           sizeof(ha->plogi_els_payld.data));
-                       set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
-               } else {
-                       ql_dbg(ql_dbg_init, vha, 0x00d1,
-                           "PLOGI ELS param read fail.\n");
+                               memcpy(&ha->plogi_els_payld.data,
+                                   (void *)ha->init_cb,
+                                   sizeof(ha->plogi_els_payld.data));
+                               set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+                       } else {
+                               ql_dbg(ql_dbg_init, vha, 0x00d1,
+                                   "PLOGI ELS param read fail.\n");
+                               goto skip_login;
+                       }
+               }
+
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->n2n_flag) {
+                               qla24xx_fcport_handle_login(vha, fcport);
+                               return QLA_SUCCESS;
+                       }
+               }
+skip_login:
+               spin_lock_irqsave(&vha->work_lock, flags);
+               vha->scan.scan_retry++;
+               spin_unlock_irqrestore(&vha->work_lock, flags);
+
+               if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
+                       set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+                       set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
                }
-               return QLA_SUCCESS;
        }
 
        found_devs = 0;
index e92e52a..518eb95 100644 (file)
@@ -2656,9 +2656,10 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
        els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
        els_iocb->port_id[1] = sp->fcport->d_id.b.area;
        els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
-       els_iocb->s_id[0] = vha->d_id.b.al_pa;
-       els_iocb->s_id[1] = vha->d_id.b.area;
-       els_iocb->s_id[2] = vha->d_id.b.domain;
+       /* For SID the byte order is different than DID */
+       els_iocb->s_id[1] = vha->d_id.b.al_pa;
+       els_iocb->s_id[2] = vha->d_id.b.area;
+       els_iocb->s_id[0] = vha->d_id.b.domain;
 
        if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) {
                els_iocb->control_flags = 0;
index 4c858e2..1cc6913 100644 (file)
@@ -2249,7 +2249,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha)
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
+       ql_dbg(ql_dbg_disc, vha, 0x105a,
            "Entered %s.\n", __func__);
 
        if (IS_CNA_CAPABLE(vha->hw)) {
@@ -3883,14 +3883,24 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                case TOPO_N2N:
                        ha->current_topology = ISP_CFG_N;
                        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+                       list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                               fcport->scan_state = QLA_FCPORT_SCAN;
+                               fcport->n2n_flag = 0;
+                       }
+
                        fcport = qla2x00_find_fcport_by_wwpn(vha,
                            rptid_entry->u.f1.port_name, 1);
                        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
                        if (fcport) {
                                fcport->plogi_nack_done_deadline = jiffies + HZ;
-                               fcport->dm_login_expire = jiffies + 3*HZ;
+                               fcport->dm_login_expire = jiffies + 2*HZ;
                                fcport->scan_state = QLA_FCPORT_FOUND;
+                               fcport->n2n_flag = 1;
+                               fcport->keep_nport_handle = 1;
+                               if (vha->flags.nvme_enabled)
+                                       fcport->fc4f_nvme = 1;
+
                                switch (fcport->disc_state) {
                                case DSC_DELETED:
                                        set_bit(RELOGIN_NEEDED,
@@ -3924,7 +3934,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                                    rptid_entry->u.f1.port_name,
                                    rptid_entry->u.f1.node_name,
                                    NULL,
-                                   FC4_TYPE_UNKNOWN);
+                                   FS_FCP_IS_N2N);
                        }
 
                        /* if our portname is higher then initiate N2N login */
@@ -4023,6 +4033,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
 
                list_for_each_entry(fcport, &vha->vp_fcports, list) {
                        fcport->scan_state = QLA_FCPORT_SCAN;
+                       fcport->n2n_flag = 0;
                }
 
                fcport = qla2x00_find_fcport_by_wwpn(vha,
@@ -4032,6 +4043,14 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                        fcport->login_retry = vha->hw->login_retry_count;
                        fcport->plogi_nack_done_deadline = jiffies + HZ;
                        fcport->scan_state = QLA_FCPORT_FOUND;
+                       fcport->keep_nport_handle = 1;
+                       fcport->n2n_flag = 1;
+                       fcport->d_id.b.domain =
+                               rptid_entry->u.f2.remote_nport_id[2];
+                       fcport->d_id.b.area =
+                               rptid_entry->u.f2.remote_nport_id[1];
+                       fcport->d_id.b.al_pa =
+                               rptid_entry->u.f2.remote_nport_id[0];
                }
        }
 }
index 1a9a11a..6afad68 100644 (file)
@@ -66,6 +66,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
        uint16_t vp_id;
        struct qla_hw_data *ha = vha->hw;
        unsigned long flags = 0;
+       u8 i;
 
        mutex_lock(&ha->vport_lock);
        /*
@@ -75,8 +76,9 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
         * ensures no active vp_list traversal while the vport is removed
         * from the queue)
         */
-       wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count),
-           10*HZ);
+       for (i = 0; i < 10 && atomic_read(&vha->vref_count); i++)
+               wait_event_timeout(vha->vref_waitq,
+                   atomic_read(&vha->vref_count), HZ);
 
        spin_lock_irqsave(&ha->vport_slock, flags);
        if (atomic_read(&vha->vref_count)) {
@@ -262,6 +264,9 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
        spin_lock_irqsave(&ha->vport_slock, flags);
        list_for_each_entry(vha, &ha->vp_list, list) {
                if (vha->vp_idx) {
+                       if (test_bit(VPORT_DELETE, &vha->dpc_flags))
+                               continue;
+
                        atomic_inc(&vha->vref_count);
                        spin_unlock_irqrestore(&ha->vport_slock, flags);
 
@@ -300,6 +305,20 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
 int
 qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
 {
+       fc_port_t *fcport;
+
+       /*
+        * To exclusively reset vport, we need to log it out first.
+        * Note: This control_vp can fail if ISP reset is already
+        * issued, this is expected, as the vp would be already
+        * logged out due to ISP reset.
+        */
+       if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
+               qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
+               list_for_each_entry(fcport, &vha->vp_fcports, list)
+                       fcport->logout_on_delete = 0;
+       }
+
        /*
         * Physical port will do most of the abort and recovery work. We can
         * just treat it as a loop down
@@ -312,16 +331,9 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
                        atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
        }
 
-       /*
-        * To exclusively reset vport, we need to log it out first.  Note: this
-        * control_vp can fail if ISP reset is already issued, this is
-        * expected, as the vp would be already logged out due to ISP reset.
-        */
-       if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
-               qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
-
        ql_dbg(ql_dbg_taskm, vha, 0x801d,
            "Scheduling enable of Vport %d.\n", vha->vp_idx);
+
        return qla24xx_enable_vp(vha);
 }
 
index 73db01e..3568031 100644 (file)
@@ -1115,9 +1115,15 @@ static inline int test_fcport_count(scsi_qla_host_t *vha)
 void
 qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
 {
+       u8 i;
+
        qla2x00_mark_all_devices_lost(vha, 0);
 
-       wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ);
+       for (i = 0; i < 10; i++)
+               wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha),
+                   HZ);
+
+       flush_workqueue(vha->hw->wq);
 }
 
 /*
@@ -5036,6 +5042,10 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
 
                        memcpy(fcport->port_name, e->u.new_sess.port_name,
                            WWN_SIZE);
+
+                       if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N)
+                               fcport->n2n_flag = 1;
+
                } else {
                        ql_dbg(ql_dbg_disc, vha, 0xffff,
                                   "%s %8phC mem alloc fail.\n",
@@ -5134,11 +5144,9 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
                        if (dfcp)
                                qlt_schedule_sess_for_deletion(tfcp);
 
-
-                       if (N2N_TOPO(vha->hw))
-                               fcport->flags &= ~FCF_FABRIC_DEVICE;
-
                        if (N2N_TOPO(vha->hw)) {
+                               fcport->flags &= ~FCF_FABRIC_DEVICE;
+                               fcport->keep_nport_handle = 1;
                                if (vha->flags.nvme_enabled) {
                                        fcport->fc4f_nvme = 1;
                                        fcport->n2n_flag = 1;
index 0ffda61..a06e562 100644 (file)
@@ -953,7 +953,7 @@ void qlt_free_session_done(struct work_struct *work)
        struct qla_hw_data *ha = vha->hw;
        unsigned long flags;
        bool logout_started = false;
-       scsi_qla_host_t *base_vha;
+       scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
        struct qlt_plogi_ack_t *own =
                sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
 
@@ -1020,6 +1020,7 @@ void qlt_free_session_done(struct work_struct *work)
 
        if (logout_started) {
                bool traced = false;
+               u16 cnt = 0;
 
                while (!READ_ONCE(sess->logout_completed)) {
                        if (!traced) {
@@ -1029,6 +1030,9 @@ void qlt_free_session_done(struct work_struct *work)
                                traced = true;
                        }
                        msleep(100);
+                       cnt++;
+                       if (cnt > 200)
+                               break;
                }
 
                ql_dbg(ql_dbg_disc, vha, 0xf087,
@@ -1101,6 +1105,7 @@ void qlt_free_session_done(struct work_struct *work)
        }
 
        spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+       sess->free_pending = 0;
 
        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
            "Unregistration of sess %p %8phC finished fcp_cnt %d\n",
@@ -1109,17 +1114,9 @@ void qlt_free_session_done(struct work_struct *work)
        if (tgt && (tgt->sess_count == 0))
                wake_up_all(&tgt->waitQ);
 
-       if (vha->fcport_count == 0)
-               wake_up_all(&vha->fcport_waitQ);
-
-       base_vha = pci_get_drvdata(ha->pdev);
-
-       sess->free_pending = 0;
-
-       if (test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags))
-               return;
-
-       if ((!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
+       if (!test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags) &&
+           !(vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)) &&
+           (!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
                switch (vha->host->active_mode) {
                case MODE_INITIATOR:
                case MODE_DUAL:
@@ -1132,6 +1129,9 @@ void qlt_free_session_done(struct work_struct *work)
                        break;
                }
        }
+
+       if (vha->fcport_count == 0)
+               wake_up_all(&vha->fcport_waitQ);
 }
 
 /* ha->tgt.sess_lock supposed to be held on entry */
@@ -1161,7 +1161,7 @@ void qlt_unreg_sess(struct fc_port *sess)
        sess->last_login_gen = sess->login_gen;
 
        INIT_WORK(&sess->free_work, qlt_free_session_done);
-       schedule_work(&sess->free_work);
+       queue_work(sess->vha->hw->wq, &sess->free_work);
 }
 EXPORT_SYMBOL(qlt_unreg_sess);
 
index ed8b9ac..542d2ba 100644 (file)
@@ -1837,8 +1837,7 @@ static int storvsc_probe(struct hv_device *device,
        /*
         * Set the number of HW queues we are supporting.
         */
-       if (stor_device->num_sc != 0)
-               host->nr_hw_queues = stor_device->num_sc + 1;
+       host->nr_hw_queues = num_present_cpus();
 
        /*
         * Set the error handler work queue.
index 034dd9c..11a87f5 100644 (file)
@@ -8143,6 +8143,9 @@ int ufshcd_shutdown(struct ufs_hba *hba)
 {
        int ret = 0;
 
+       if (!hba->is_powered)
+               goto out;
+
        if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba))
                goto out;
 
index c64728f..a620575 100644 (file)
@@ -349,10 +349,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        dst_release(skb_dst(skb));
        skb_dst_set(skb, NULL);
-#ifdef CONFIG_XFRM
-       secpath_reset(skb);
-#endif
-       nf_reset(skb);
+       skb_ext_reset(skb);
+       nf_reset_ct(skb);
 
 #ifdef CONFIG_NET_SCHED
        skb->tc_index = 0;
index 228a89b..16f60c1 100644 (file)
@@ -18,23 +18,6 @@ obj-$(CONFIG_SPU_BASE)                       += logo_spe_clut224.o
 
 # How to generate logo's
 
-# Use logo-cfiles to retrieve list of .c files to be built
-logo-cfiles = $(notdir $(patsubst %.$(2), %.c, \
-              $(wildcard $(srctree)/$(src)/*$(1).$(2))))
-
-
-# Mono logos
-extra-y += $(call logo-cfiles,_mono,pbm)
-
-# VGA16 logos
-extra-y += $(call logo-cfiles,_vga16,ppm)
-
-# 224 Logos
-extra-y += $(call logo-cfiles,_clut224,ppm)
-
-# Gray 256
-extra-y += $(call logo-cfiles,_gray256,pgm)
-
 pnmtologo := scripts/pnmtologo
 
 # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..."
@@ -55,5 +38,5 @@ $(obj)/%_clut224.c: $(src)/%_clut224.ppm $(pnmtologo) FORCE
 $(obj)/%_gray256.c: $(src)/%_gray256.pgm $(pnmtologo) FORCE
        $(call if_changed,logo)
 
-# Files generated that shall be removed upon make clean
-clean-files := *.o *_mono.c *_vga16.c *_clut224.c *_gray256.c
+# generated C files
+targets += *_mono.c *_vga16.c *_clut224.c *_gray256.c
index 4e11de6..5bae515 100644 (file)
@@ -156,8 +156,10 @@ static DECLARE_DELAYED_WORK(balloon_worker, balloon_process);
        (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
 
 /* balloon_append: add the given page to the balloon. */
-static void __balloon_append(struct page *page)
+static void balloon_append(struct page *page)
 {
+       __SetPageOffline(page);
+
        /* Lowmem is re-populated first, so highmem pages go at list tail. */
        if (PageHighMem(page)) {
                list_add_tail(&page->lru, &ballooned_pages);
@@ -169,11 +171,6 @@ static void __balloon_append(struct page *page)
        wake_up(&balloon_wq);
 }
 
-static void balloon_append(struct page *page)
-{
-       __balloon_append(page);
-}
-
 /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
 static struct page *balloon_retrieve(bool require_lowmem)
 {
@@ -192,6 +189,7 @@ static struct page *balloon_retrieve(bool require_lowmem)
        else
                balloon_stats.balloon_low--;
 
+       __ClearPageOffline(page);
        return page;
 }
 
@@ -377,8 +375,7 @@ static void xen_online_page(struct page *page, unsigned int order)
        for (i = 0; i < size; i++) {
                p = pfn_to_page(start_pfn + i);
                __online_page_set_limits(p);
-               __SetPageOffline(p);
-               __balloon_append(p);
+               balloon_append(p);
        }
        mutex_unlock(&balloon_mutex);
 }
@@ -444,7 +441,6 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
                xenmem_reservation_va_mapping_update(1, &page, &frame_list[i]);
 
                /* Relinquish the page back to the allocator. */
-               __ClearPageOffline(page);
                free_reserved_page(page);
        }
 
@@ -471,7 +467,6 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
                        state = BP_EAGAIN;
                        break;
                }
-               __SetPageOffline(page);
                adjust_managed_page_count(page, -1);
                xenmem_reservation_scrub_page(page);
                list_add(&page->lru, &pages);
@@ -611,7 +606,6 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages)
        while (pgno < nr_pages) {
                page = balloon_retrieve(true);
                if (page) {
-                       __ClearPageOffline(page);
                        pages[pgno++] = page;
 #ifdef CONFIG_XEN_HAVE_PVMMU
                        /*
@@ -653,10 +647,8 @@ void free_xenballooned_pages(int nr_pages, struct page **pages)
        mutex_lock(&balloon_mutex);
 
        for (i = 0; i < nr_pages; i++) {
-               if (pages[i]) {
-                       __SetPageOffline(pages[i]);
+               if (pages[i])
                        balloon_append(pages[i]);
-               }
        }
 
        balloon_stats.target_unpopulated -= nr_pages;
@@ -674,7 +666,6 @@ static void __init balloon_add_region(unsigned long start_pfn,
                                      unsigned long pages)
 {
        unsigned long pfn, extra_pfn_end;
-       struct page *page;
 
        /*
         * If the amount of usable memory has been limited (e.g., with
@@ -684,11 +675,10 @@ static void __init balloon_add_region(unsigned long start_pfn,
        extra_pfn_end = min(max_pfn, start_pfn + pages);
 
        for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) {
-               page = pfn_to_page(pfn);
                /* totalram_pages and totalhigh_pages do not
                   include the boot-time balloon extension, so
                   don't subtract from it. */
-               __balloon_append(page);
+               balloon_append(pfn_to_page(pfn));
        }
 
        balloon_stats.total_pages += extra_pfn_end - start_pfn;
index 89d60f8..d1ff218 100644 (file)
@@ -40,7 +40,7 @@
 
 #define efi_data(op)   (op.u.efi_runtime_call)
 
-efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
        struct xen_platform_op op = INIT_EFI_OP(get_time);
 
@@ -61,9 +61,8 @@ efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_get_time);
 
-efi_status_t xen_efi_set_time(efi_time_t *tm)
+static efi_status_t xen_efi_set_time(efi_time_t *tm)
 {
        struct xen_platform_op op = INIT_EFI_OP(set_time);
 
@@ -75,10 +74,10 @@ efi_status_t xen_efi_set_time(efi_time_t *tm)
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_set_time);
 
-efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
-                                    efi_time_t *tm)
+static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
+                                           efi_bool_t *pending,
+                                           efi_time_t *tm)
 {
        struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
 
@@ -98,9 +97,8 @@ efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_get_wakeup_time);
 
-efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
 {
        struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
 
@@ -117,11 +115,10 @@ efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_set_wakeup_time);
 
-efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
-                                 u32 *attr, unsigned long *data_size,
-                                 void *data)
+static efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
+                                        u32 *attr, unsigned long *data_size,
+                                        void *data)
 {
        struct xen_platform_op op = INIT_EFI_OP(get_variable);
 
@@ -141,11 +138,10 @@ efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_get_variable);
 
-efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
-                                      efi_char16_t *name,
-                                      efi_guid_t *vendor)
+static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
+                                             efi_char16_t *name,
+                                             efi_guid_t *vendor)
 {
        struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
 
@@ -165,11 +161,10 @@ efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_get_next_variable);
 
-efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
-                                u32 attr, unsigned long data_size,
-                                void *data)
+static efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+                                        u32 attr, unsigned long data_size,
+                                        void *data)
 {
        struct xen_platform_op op = INIT_EFI_OP(set_variable);
 
@@ -186,11 +181,10 @@ efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_set_variable);
 
-efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
-                                        u64 *remaining_space,
-                                        u64 *max_variable_size)
+static efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
+                                               u64 *remaining_space,
+                                               u64 *max_variable_size)
 {
        struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
 
@@ -208,9 +202,8 @@ efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_query_variable_info);
 
-efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
+static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
 {
        struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
 
@@ -221,10 +214,9 @@ efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_get_next_high_mono_count);
 
-efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
-                                   unsigned long count, unsigned long sg_list)
+static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
+                               unsigned long count, unsigned long sg_list)
 {
        struct xen_platform_op op = INIT_EFI_OP(update_capsule);
 
@@ -241,11 +233,9 @@ efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_update_capsule);
 
-efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
-                                       unsigned long count, u64 *max_size,
-                                       int *reset_type)
+static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+                       unsigned long count, u64 *max_size, int *reset_type)
 {
        struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
 
@@ -264,10 +254,9 @@ efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
 
        return efi_data(op).status;
 }
-EXPORT_SYMBOL_GPL(xen_efi_query_capsule_caps);
 
-void xen_efi_reset_system(int reset_type, efi_status_t status,
-                         unsigned long data_size, efi_char16_t *data)
+static void xen_efi_reset_system(int reset_type, efi_status_t status,
+                                unsigned long data_size, efi_char16_t *data)
 {
        switch (reset_type) {
        case EFI_RESET_COLD:
@@ -281,4 +270,25 @@ void xen_efi_reset_system(int reset_type, efi_status_t status,
                BUG();
        }
 }
-EXPORT_SYMBOL_GPL(xen_efi_reset_system);
+
+/*
+ * Set XEN EFI runtime services function pointers. Other fields of struct efi,
+ * e.g. efi.systab, will be set like normal EFI.
+ */
+void __init xen_efi_runtime_setup(void)
+{
+       efi.get_time                    = xen_efi_get_time;
+       efi.set_time                    = xen_efi_set_time;
+       efi.get_wakeup_time             = xen_efi_get_wakeup_time;
+       efi.set_wakeup_time             = xen_efi_set_wakeup_time;
+       efi.get_variable                = xen_efi_get_variable;
+       efi.get_next_variable           = xen_efi_get_next_variable;
+       efi.set_variable                = xen_efi_set_variable;
+       efi.set_variable_nonblocking    = xen_efi_set_variable;
+       efi.query_variable_info         = xen_efi_query_variable_info;
+       efi.query_variable_info_nonblocking = xen_efi_query_variable_info;
+       efi.update_capsule              = xen_efi_update_capsule;
+       efi.query_capsule_caps          = xen_efi_query_capsule_caps;
+       efi.get_next_high_mono_count    = xen_efi_get_next_high_mono_count;
+       efi.reset_system                = xen_efi_reset_system;
+}
index a446a72..81401f3 100644 (file)
@@ -22,6 +22,7 @@
 
 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
 
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -34,9 +35,6 @@
 #include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/refcount.h>
-#ifdef CONFIG_XEN_GRANT_DMA_ALLOC
-#include <linux/of_device.h>
-#endif
 
 #include <xen/xen.h>
 #include <xen/grant_table.h>
@@ -625,14 +623,7 @@ static int gntdev_open(struct inode *inode, struct file *flip)
        flip->private_data = priv;
 #ifdef CONFIG_XEN_GRANT_DMA_ALLOC
        priv->dma_dev = gntdev_miscdev.this_device;
-
-       /*
-        * The device is not spawn from a device tree, so arch_setup_dma_ops
-        * is not called, thus leaving the device with dummy DMA ops.
-        * Fix this by calling of_dma_configure() with a NULL node to set
-        * default DMA ops.
-        */
-       of_dma_configure(priv->dma_dev, NULL, true);
+       dma_coerce_mask_and_coherent(priv->dma_dev, DMA_BIT_MASK(64));
 #endif
        pr_debug("priv %p\n", priv);
 
index 7ea6fb6..49b381e 100644 (file)
@@ -1363,8 +1363,7 @@ static int gnttab_setup(void)
        if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) {
                gnttab_shared.addr = xen_auto_xlat_grant_frames.vaddr;
                if (gnttab_shared.addr == NULL) {
-                       pr_warn("gnttab share frames (addr=0x%08lx) is not mapped!\n",
-                               (unsigned long)xen_auto_xlat_grant_frames.vaddr);
+                       pr_warn("gnttab share frames is not mapped!\n");
                        return -ENOMEM;
                }
        }
index 08adc59..597af45 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/miscdevice.h>
+#include <linux/workqueue.h>
 
 #include <xen/xenbus.h>
 #include <xen/xen.h>
@@ -116,6 +117,8 @@ struct xenbus_file_priv {
        wait_queue_head_t read_waitq;
 
        struct kref kref;
+
+       struct work_struct wq;
 };
 
 /* Read out any raw xenbus messages queued up. */
@@ -300,14 +303,14 @@ static void watch_fired(struct xenbus_watch *watch,
        mutex_unlock(&adap->dev_data->reply_mutex);
 }
 
-static void xenbus_file_free(struct kref *kref)
+static void xenbus_worker(struct work_struct *wq)
 {
        struct xenbus_file_priv *u;
        struct xenbus_transaction_holder *trans, *tmp;
        struct watch_adapter *watch, *tmp_watch;
        struct read_buffer *rb, *tmp_rb;
 
-       u = container_of(kref, struct xenbus_file_priv, kref);
+       u = container_of(wq, struct xenbus_file_priv, wq);
 
        /*
         * No need for locking here because there are no other users,
@@ -333,6 +336,18 @@ static void xenbus_file_free(struct kref *kref)
        kfree(u);
 }
 
+static void xenbus_file_free(struct kref *kref)
+{
+       struct xenbus_file_priv *u;
+
+       /*
+        * We might be called in xenbus_thread().
+        * Use workqueue to avoid deadlock.
+        */
+       u = container_of(kref, struct xenbus_file_priv, kref);
+       schedule_work(&u->wq);
+}
+
 static struct xenbus_transaction_holder *xenbus_get_transaction(
        struct xenbus_file_priv *u, uint32_t tx_id)
 {
@@ -650,6 +665,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp)
        INIT_LIST_HEAD(&u->watches);
        INIT_LIST_HEAD(&u->read_buffers);
        init_waitqueue_head(&u->read_waitq);
+       INIT_WORK(&u->wq, xenbus_worker);
 
        mutex_init(&u->reply_mutex);
        mutex_init(&u->msgbuffer_mutex);
index ad4c6b1..c5642bc 100644 (file)
@@ -879,7 +879,7 @@ out_free_interp:
           the correct location in memory. */
        for(i = 0, elf_ppnt = elf_phdata;
            i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
-               int elf_prot, elf_flags, elf_fixed = MAP_FIXED_NOREPLACE;
+               int elf_prot, elf_flags;
                unsigned long k, vaddr;
                unsigned long total_size = 0;
 
@@ -911,13 +911,6 @@ out_free_interp:
                                         */
                                }
                        }
-
-                       /*
-                        * Some binaries have overlapping elf segments and then
-                        * we have to forcefully map over an existing mapping
-                        * e.g. over this newly established brk mapping.
-                        */
-                       elf_fixed = MAP_FIXED;
                }
 
                elf_prot = make_prot(elf_ppnt->p_flags);
@@ -930,7 +923,7 @@ out_free_interp:
                 * the ET_DYN load_addr calculations, proceed normally.
                 */
                if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
-                       elf_flags |= elf_fixed;
+                       elf_flags |= MAP_FIXED;
                } else if (loc->elf_ex.e_type == ET_DYN) {
                        /*
                         * This logic is run once for the first LOAD Program
@@ -966,7 +959,7 @@ out_free_interp:
                                load_bias = ELF_ET_DYN_BASE;
                                if (current->flags & PF_RANDOMIZE)
                                        load_bias += arch_mmap_rnd();
-                               elf_flags |= elf_fixed;
+                               elf_flags |= MAP_FIXED;
                        } else
                                load_bias = 0;
 
index 8fe4eb7..27e5b26 100644 (file)
@@ -1591,7 +1591,6 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct page **pages = NULL;
-       struct extent_state *cached_state = NULL;
        struct extent_changeset *data_reserved = NULL;
        u64 release_bytes = 0;
        u64 lockstart;
@@ -1611,6 +1610,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
                return -ENOMEM;
 
        while (iov_iter_count(i) > 0) {
+               struct extent_state *cached_state = NULL;
                size_t offset = offset_in_page(pos);
                size_t sector_offset;
                size_t write_bytes = min(iov_iter_count(i),
@@ -1758,9 +1758,20 @@ again:
                if (copied > 0)
                        ret = btrfs_dirty_pages(inode, pages, dirty_pages,
                                                pos, copied, &cached_state);
+
+               /*
+                * If we have not locked the extent range, because the range's
+                * start offset is >= i_size, we might still have a non-NULL
+                * cached extent state, acquired while marking the extent range
+                * as delalloc through btrfs_dirty_pages(). Therefore free any
+                * possible cached extent state to avoid a memory leak.
+                */
                if (extents_locked)
                        unlock_extent_cached(&BTRFS_I(inode)->io_tree,
                                             lockstart, lockend, &cached_state);
+               else
+                       free_extent_state(cached_state);
+
                btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes,
                                               true);
                if (ret) {
index a054640..0f2754e 100644 (file)
@@ -6305,13 +6305,16 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        u32 sizes[2];
        int nitems = name ? 2 : 1;
        unsigned long ptr;
+       unsigned int nofs_flag;
        int ret;
 
        path = btrfs_alloc_path();
        if (!path)
                return ERR_PTR(-ENOMEM);
 
+       nofs_flag = memalloc_nofs_save();
        inode = new_inode(fs_info->sb);
+       memalloc_nofs_restore(nofs_flag);
        if (!inode) {
                btrfs_free_path(path);
                return ERR_PTR(-ENOMEM);
index e87cbda..b57f361 100644 (file)
@@ -500,7 +500,7 @@ static int process_leaf(struct btrfs_root *root,
        struct btrfs_extent_data_ref *dref;
        struct btrfs_shared_data_ref *sref;
        u32 count;
-       int i = 0, tree_block_level = 0, ret;
+       int i = 0, tree_block_level = 0, ret = 0;
        struct btrfs_key key;
        int nritems = btrfs_header_nritems(leaf);
 
index f321502..123ac54 100644 (file)
@@ -5085,7 +5085,7 @@ static int clone_range(struct send_ctx *sctx,
        struct btrfs_path *path;
        struct btrfs_key key;
        int ret;
-       u64 clone_src_i_size;
+       u64 clone_src_i_size = 0;
 
        /*
         * Prevent cloning from a zero offset with a length matching the sector
index 29b82a7..8a6cc60 100644 (file)
@@ -2932,7 +2932,8 @@ out:
  * in the tree of log roots
  */
 static int update_log_root(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *log)
+                          struct btrfs_root *log,
+                          struct btrfs_root_item *root_item)
 {
        struct btrfs_fs_info *fs_info = log->fs_info;
        int ret;
@@ -2940,10 +2941,10 @@ static int update_log_root(struct btrfs_trans_handle *trans,
        if (log->log_transid == 1) {
                /* insert root item on the first sync */
                ret = btrfs_insert_root(trans, fs_info->log_root_tree,
-                               &log->root_key, &log->root_item);
+                               &log->root_key, root_item);
        } else {
                ret = btrfs_update_root(trans, fs_info->log_root_tree,
-                               &log->root_key, &log->root_item);
+                               &log->root_key, root_item);
        }
        return ret;
 }
@@ -3041,6 +3042,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct btrfs_root *log = root->log_root;
        struct btrfs_root *log_root_tree = fs_info->log_root_tree;
+       struct btrfs_root_item new_root_item;
        int log_transid = 0;
        struct btrfs_log_ctx root_log_ctx;
        struct blk_plug plug;
@@ -3104,17 +3106,25 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                goto out;
        }
 
+       /*
+        * We _must_ update under the root->log_mutex in order to make sure we
+        * have a consistent view of the log root we are trying to commit at
+        * this moment.
+        *
+        * We _must_ copy this into a local copy, because we are not holding the
+        * log_root_tree->log_mutex yet.  This is important because when we
+        * commit the log_root_tree we must have a consistent view of the
+        * log_root_tree when we update the super block to point at the
+        * log_root_tree bytenr.  If we update the log_root_tree here we'll race
+        * with the commit and possibly point at the new block which we may not
+        * have written out.
+        */
        btrfs_set_root_node(&log->root_item, log->node);
+       memcpy(&new_root_item, &log->root_item, sizeof(new_root_item));
 
        root->log_transid++;
        log->log_transid = root->log_transid;
        root->log_start_pid = 0;
-       /*
-        * Update or create log root item under the root's log_mutex to prevent
-        * races with concurrent log syncs that can lead to failure to update
-        * log root item because it was not created yet.
-        */
-       ret = update_log_root(trans, log);
        /*
         * IO has been started, blocks of the log tree have WRITTEN flag set
         * in their headers. new modifications of the log will be written to
@@ -3135,6 +3145,14 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        mutex_unlock(&log_root_tree->log_mutex);
 
        mutex_lock(&log_root_tree->log_mutex);
+
+       /*
+        * Now we are safe to update the log_root_tree because we're under the
+        * log_mutex, and we're a current writer so we're holding the commit
+        * open until we drop the log_mutex.
+        */
+       ret = update_log_root(trans, log, &new_root_item);
+
        if (atomic_dec_and_test(&log_root_tree->log_writers)) {
                /* atomic_dec_and_test implies a barrier */
                cond_wake_up_nomb(&log_root_tree->log_writer_wait);
index cdd7af4..bdfe449 100644 (file)
@@ -3845,7 +3845,11 @@ static int alloc_profile_is_valid(u64 flags, int extended)
                return !extended; /* "0" is valid for usual profiles */
 
        /* true if exactly one bit set */
-       return is_power_of_2(flags);
+       /*
+        * Don't use is_power_of_2(unsigned long) because it won't work
+        * for the single profile (1ULL << 48) on 32-bit CPUs.
+        */
+       return flags != 0 && (flags & (flags - 1)) == 0;
 }
 
 static inline int balance_need_close(struct btrfs_fs_info *fs_info)
index 2e9c7f4..c049c7b 100644 (file)
@@ -169,18 +169,26 @@ cifs_read_super(struct super_block *sb)
        else
                sb->s_maxbytes = MAX_NON_LFS;
 
-       /* BB FIXME fix time_gran to be larger for LANMAN sessions */
-       sb->s_time_gran = 100;
-
-       if (tcon->unix_ext) {
-               ts = cifs_NTtimeToUnix(0);
+       /* Some very old servers like DOS and OS/2 used 2 second granularity */
+       if ((tcon->ses->server->vals->protocol_id == SMB10_PROT_ID) &&
+           ((tcon->ses->capabilities &
+             tcon->ses->server->vals->cap_nt_find) == 0) &&
+           !tcon->unix_ext) {
+               sb->s_time_gran = 1000000000; /* 1 second is max allowed gran */
+               ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0);
                sb->s_time_min = ts.tv_sec;
-               ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX));
+               ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX),
+                                   cpu_to_le16(SMB_TIME_MAX), 0);
                sb->s_time_max = ts.tv_sec;
        } else {
-               ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0);
+               /*
+                * Almost every server, including all SMB2+, uses DCE TIME
+                * ie 100 nanosecond units, since 1601.  See MS-DTYP and MS-FSCC
+                */
+               sb->s_time_gran = 100;
+               ts = cifs_NTtimeToUnix(0);
                sb->s_time_min = ts.tv_sec;
-               ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), cpu_to_le16(SMB_TIME_MAX), 0);
+               ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX));
                sb->s_time_max = ts.tv_sec;
        }
 
index 2e960e1..50dfd90 100644 (file)
@@ -1210,7 +1210,7 @@ struct cifs_search_info {
        bool smallBuf:1; /* so we know which buf_release function to call */
 };
 
-#define ACL_NO_MODE    -1
+#define ACL_NO_MODE    ((umode_t)(-1))
 struct cifs_open_parms {
        struct cifs_tcon *tcon;
        struct cifs_sb_info *cifs_sb;
index 2850c3c..a64dfa9 100644 (file)
@@ -4264,7 +4264,7 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
                server->ops->qfs_tcon(*xid, tcon);
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) {
                        if (tcon->fsDevInfo.DeviceCharacteristics &
-                           FILE_READ_ONLY_DEVICE)
+                           cpu_to_le32(FILE_READ_ONLY_DEVICE))
                                cifs_dbg(VFS, "mounted to read only share\n");
                        else if ((cifs_sb->mnt_cifs_flags &
                                  CIFS_MOUNT_RW_CACHE) == 0)
@@ -4445,7 +4445,7 @@ static int setup_dfs_tgt_conn(const char *path,
        int rc;
        struct dfs_info3_param ref = {0};
        char *mdata = NULL, *fake_devname = NULL;
-       struct smb_vol fake_vol = {0};
+       struct smb_vol fake_vol = {NULL};
 
        cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path);
 
index dd5ac84..7ce689d 100644 (file)
@@ -738,10 +738,16 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 static int
 cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
 {
+       struct inode *inode;
+
        if (flags & LOOKUP_RCU)
                return -ECHILD;
 
        if (d_really_is_positive(direntry)) {
+               inode = d_inode(direntry);
+               if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode)))
+                       CIFS_I(inode)->time = 0; /* force reval */
+
                if (cifs_revalidate_dentry(direntry))
                        return 0;
                else {
@@ -752,7 +758,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
                         * attributes will have been updated by
                         * cifs_revalidate_dentry().
                         */
-                       if (IS_AUTOMOUNT(d_inode(direntry)) &&
+                       if (IS_AUTOMOUNT(inode) &&
                           !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) {
                                spin_lock(&direntry->d_lock);
                                direntry->d_flags |= DCACHE_NEED_AUTOMOUNT;
index 4b95700..5ad15de 100644 (file)
@@ -253,6 +253,12 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
                rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
                                         xid, fid);
 
+       if (rc) {
+               server->ops->close(xid, tcon, fid);
+               if (rc == -ESTALE)
+                       rc = -EOPENSTALE;
+       }
+
 out:
        kfree(buf);
        return rc;
@@ -1840,13 +1846,12 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
 {
        struct cifsFileInfo *open_file = NULL;
        struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
-       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
 
        /* only filter by fsuid on multiuser mounts */
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
                fsuid_only = false;
 
-       spin_lock(&tcon->open_file_lock);
+       spin_lock(&cifs_inode->open_file_lock);
        /* we could simply get the first_list_entry since write-only entries
           are always at the end of the list but since the first entry might
           have a close pending, we go through the whole list */
@@ -1858,7 +1863,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
                                /* found a good file */
                                /* lock it so it will not be closed on us */
                                cifsFileInfo_get(open_file);
-                               spin_unlock(&tcon->open_file_lock);
+                               spin_unlock(&cifs_inode->open_file_lock);
                                return open_file;
                        } /* else might as well continue, and look for
                             another, or simply have the caller reopen it
@@ -1866,7 +1871,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
                } else /* write only file */
                        break; /* write only files are last so must be done */
        }
-       spin_unlock(&tcon->open_file_lock);
+       spin_unlock(&cifs_inode->open_file_lock);
        return NULL;
 }
 
@@ -1877,7 +1882,6 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
 {
        struct cifsFileInfo *open_file, *inv_file = NULL;
        struct cifs_sb_info *cifs_sb;
-       struct cifs_tcon *tcon;
        bool any_available = false;
        int rc = -EBADF;
        unsigned int refind = 0;
@@ -1897,16 +1901,15 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
        }
 
        cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
-       tcon = cifs_sb_master_tcon(cifs_sb);
 
        /* only filter by fsuid on multiuser mounts */
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
                fsuid_only = false;
 
-       spin_lock(&tcon->open_file_lock);
+       spin_lock(&cifs_inode->open_file_lock);
 refind_writable:
        if (refind > MAX_REOPEN_ATT) {
-               spin_unlock(&tcon->open_file_lock);
+               spin_unlock(&cifs_inode->open_file_lock);
                return rc;
        }
        list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
@@ -1918,7 +1921,7 @@ refind_writable:
                        if (!open_file->invalidHandle) {
                                /* found a good writable file */
                                cifsFileInfo_get(open_file);
-                               spin_unlock(&tcon->open_file_lock);
+                               spin_unlock(&cifs_inode->open_file_lock);
                                *ret_file = open_file;
                                return 0;
                        } else {
@@ -1938,7 +1941,7 @@ refind_writable:
                cifsFileInfo_get(inv_file);
        }
 
-       spin_unlock(&tcon->open_file_lock);
+       spin_unlock(&cifs_inode->open_file_lock);
 
        if (inv_file) {
                rc = cifs_reopen_file(inv_file, false);
@@ -1953,7 +1956,7 @@ refind_writable:
                cifsFileInfo_put(inv_file);
                ++refind;
                inv_file = NULL;
-               spin_lock(&tcon->open_file_lock);
+               spin_lock(&cifs_inode->open_file_lock);
                goto refind_writable;
        }
 
@@ -4461,17 +4464,15 @@ static int cifs_readpage(struct file *file, struct page *page)
 static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
 {
        struct cifsFileInfo *open_file;
-       struct cifs_tcon *tcon =
-               cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb));
 
-       spin_lock(&tcon->open_file_lock);
+       spin_lock(&cifs_inode->open_file_lock);
        list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
                if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
-                       spin_unlock(&tcon->open_file_lock);
+                       spin_unlock(&cifs_inode->open_file_lock);
                        return 1;
                }
        }
-       spin_unlock(&tcon->open_file_lock);
+       spin_unlock(&cifs_inode->open_file_lock);
        return 0;
 }
 
index 3bae2e5..5dcc95b 100644 (file)
@@ -414,6 +414,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                /* if uniqueid is different, return error */
                if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
                    CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
+                       CIFS_I(*pinode)->time = 0; /* force reval */
                        rc = -ESTALE;
                        goto cgiiu_exit;
                }
@@ -421,6 +422,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                /* if filetype is different, return error */
                if (unlikely(((*pinode)->i_mode & S_IFMT) !=
                    (fattr.cf_mode & S_IFMT))) {
+                       CIFS_I(*pinode)->time = 0; /* force reval */
                        rc = -ESTALE;
                        goto cgiiu_exit;
                }
@@ -933,6 +935,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
                /* if uniqueid is different, return error */
                if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
                    CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) {
+                       CIFS_I(*inode)->time = 0; /* force reval */
                        rc = -ESTALE;
                        goto cgii_exit;
                }
@@ -940,6 +943,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
                /* if filetype is different, return error */
                if (unlikely(((*inode)->i_mode & S_IFMT) !=
                    (fattr.cf_mode & S_IFMT))) {
+                       CIFS_I(*inode)->time = 0; /* force reval */
                        rc = -ESTALE;
                        goto cgii_exit;
                }
index 49c17ee..9b41436 100644 (file)
@@ -117,10 +117,6 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
        {0, 0}
 };
 
-static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
-       {0, 0}
-};
-
 /*
  * Convert a string containing text IPv4 or IPv6 address to binary form.
  *
index 85f9d61..0514986 100644 (file)
@@ -751,8 +751,8 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
        unsigned int num = *num_iovec;
 
        iov[num].iov_base = create_posix_buf(mode);
-       if (mode == -1)
-               cifs_dbg(VFS, "illegal mode\n"); /* BB REMOVEME */
+       if (mode == ACL_NO_MODE)
+               cifs_dbg(FYI, "illegal mode\n");
        if (iov[num].iov_base == NULL)
                return -ENOMEM;
        iov[num].iov_len = sizeof(struct create_posix);
@@ -2521,11 +2521,8 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
                        return rc;
        }
 
-       /* TODO: add handling for the mode on create */
-       if (oparms->disposition == FILE_CREATE)
-               cifs_dbg(VFS, "mode is 0x%x\n", oparms->mode); /* BB REMOVEME */
-
-       if ((oparms->disposition == FILE_CREATE) && (oparms->mode != -1)) {
+       if ((oparms->disposition == FILE_CREATE) &&
+           (oparms->mode != ACL_NO_MODE)) {
                if (n_iov > 2) {
                        struct create_context *ccontext =
                            (struct create_context *)iov[n_iov-1].iov_base;
@@ -3217,7 +3214,8 @@ SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst,
 
        req->PersistentFileId = persistent_fid;
        req->VolatileFileId = volatile_fid;
-       req->OutputBufferLength = SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE;
+       req->OutputBufferLength =
+               cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE);
        req->CompletionFilter = cpu_to_le32(completion_filter);
        if (watch_tree)
                req->Flags = cpu_to_le16(SMB2_WATCH_TREE);
index da3a6d5..71b2930 100644 (file)
@@ -150,6 +150,10 @@ extern int SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
                           bool is_fsctl, char *in_data, u32 indatalen,
                           __u32 max_response_size);
 extern void SMB2_ioctl_free(struct smb_rqst *rqst);
+extern int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
+                       u64 persistent_fid, u64 volatile_fid, bool watch_tree,
+                       u32 completion_filter);
+
 extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
                      u64 persistent_file_id, u64 volatile_file_id);
 extern int SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
index 8a9fcbd..fc3a8d8 100644 (file)
@@ -34,11 +34,15 @@ static void erofs_readendio(struct bio *bio)
 
 struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr)
 {
-       struct inode *const bd_inode = sb->s_bdev->bd_inode;
-       struct address_space *const mapping = bd_inode->i_mapping;
+       struct address_space *const mapping = sb->s_bdev->bd_inode->i_mapping;
+       struct page *page;
 
-       return read_cache_page_gfp(mapping, blkaddr,
+       page = read_cache_page_gfp(mapping, blkaddr,
                                   mapping_gfp_constraint(mapping, ~__GFP_FS));
+       /* should already be PageUptodate */
+       if (!IS_ERR(page))
+               lock_page(page);
+       return page;
 }
 
 static int erofs_map_blocks_flatmode(struct inode *inode,
index caf9a95..0e36949 100644 (file)
@@ -105,9 +105,9 @@ static int erofs_read_superblock(struct super_block *sb)
        int ret;
 
        page = read_mapping_page(sb->s_bdev->bd_inode->i_mapping, 0, NULL);
-       if (!page) {
+       if (IS_ERR(page)) {
                erofs_err(sb, "cannot read erofs superblock");
-               return -EIO;
+               return PTR_ERR(page);
        }
 
        sbi = EROFS_SB(sb);
index 96e34c9..fad80c9 100644 (file)
@@ -575,7 +575,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe,
        struct erofs_map_blocks *const map = &fe->map;
        struct z_erofs_collector *const clt = &fe->clt;
        const loff_t offset = page_offset(page);
-       bool tight = (clt->mode >= COLLECT_PRIMARY_HOOKED);
+       bool tight = true;
 
        enum z_erofs_cache_alloctype cache_strategy;
        enum z_erofs_page_type page_type;
@@ -628,8 +628,16 @@ restart_now:
        preload_compressed_pages(clt, MNGD_MAPPING(sbi),
                                 cache_strategy, pagepool);
 
-       tight &= (clt->mode >= COLLECT_PRIMARY_HOOKED);
 hitted:
+       /*
+        * Ensure the current partial page belongs to this submit chain rather
+        * than other concurrent submit chains or the noio(bypass) chain since
+        * those chains are handled asynchronously thus the page cannot be used
+        * for inplace I/O or pagevec (should be processed in strict order.)
+        */
+       tight &= (clt->mode >= COLLECT_PRIMARY_HOOKED &&
+                 clt->mode != COLLECT_PRIMARY_FOLLOWED_NOINPLACE);
+
        cur = end - min_t(unsigned int, offset + end - map->m_la, end);
        if (!(map->m_flags & EROFS_MAP_MAPPED)) {
                zero_user_segment(page, cur, end);
index 8aaa7ee..e88421d 100644 (file)
@@ -164,8 +164,13 @@ static void finish_writeback_work(struct bdi_writeback *wb,
 
        if (work->auto_free)
                kfree(work);
-       if (done && atomic_dec_and_test(&done->cnt))
-               wake_up_all(done->waitq);
+       if (done) {
+               wait_queue_head_t *waitq = done->waitq;
+
+               /* @done can't be accessed after the following dec */
+               if (atomic_dec_and_test(&done->cnt))
+                       wake_up_all(waitq);
+       }
 }
 
 static void wb_queue_work(struct bdi_writeback *wb,
index aa8ac55..92972b5 100644 (file)
@@ -591,14 +591,6 @@ static void io_cqring_add_event(struct io_ring_ctx *ctx, u64 user_data,
        io_cqring_ev_posted(ctx);
 }
 
-static void io_ring_drop_ctx_refs(struct io_ring_ctx *ctx, unsigned refs)
-{
-       percpu_ref_put_many(&ctx->refs, refs);
-
-       if (waitqueue_active(&ctx->wait))
-               wake_up(&ctx->wait);
-}
-
 static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx,
                                   struct io_submit_state *state)
 {
@@ -646,7 +638,7 @@ static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx,
        req->result = 0;
        return req;
 out:
-       io_ring_drop_ctx_refs(ctx, 1);
+       percpu_ref_put(&ctx->refs);
        return NULL;
 }
 
@@ -654,7 +646,7 @@ static void io_free_req_many(struct io_ring_ctx *ctx, void **reqs, int *nr)
 {
        if (*nr) {
                kmem_cache_free_bulk(req_cachep, *nr, reqs);
-               io_ring_drop_ctx_refs(ctx, *nr);
+               percpu_ref_put_many(&ctx->refs, *nr);
                *nr = 0;
        }
 }
@@ -663,7 +655,7 @@ static void __io_free_req(struct io_kiocb *req)
 {
        if (req->file && !(req->flags & REQ_F_FIXED_FILE))
                fput(req->file);
-       io_ring_drop_ctx_refs(req->ctx, 1);
+       percpu_ref_put(&req->ctx->refs);
        kmem_cache_free(req_cachep, req);
 }
 
@@ -1892,15 +1884,15 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        unsigned count, req_dist, tail_index;
        struct io_ring_ctx *ctx = req->ctx;
        struct list_head *entry;
-       struct timespec ts;
+       struct timespec64 ts;
 
        if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
                return -EINVAL;
        if (sqe->flags || sqe->ioprio || sqe->buf_index || sqe->timeout_flags ||
            sqe->len != 1)
                return -EINVAL;
-       if (copy_from_user(&ts, (void __user *) (unsigned long) sqe->addr,
-           sizeof(ts)))
+
+       if (get_timespec64(&ts, u64_to_user_ptr(sqe->addr)))
                return -EFAULT;
 
        /*
@@ -1934,7 +1926,7 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 
        hrtimer_init(&req->timeout.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        req->timeout.timer.function = io_timeout_fn;
-       hrtimer_start(&req->timeout.timer, timespec_to_ktime(ts),
+       hrtimer_start(&req->timeout.timer, timespec64_to_ktime(ts),
                        HRTIMER_MODE_REL);
        return 0;
 }
@@ -2761,7 +2753,7 @@ out:
 
        if (link)
                io_queue_link_head(ctx, link, &link->submit, shadow_req,
-                                       block_for_last);
+                                       !block_for_last);
        if (statep)
                io_submit_state_end(statep);
 
@@ -2920,8 +2912,12 @@ static void io_finish_async(struct io_ring_ctx *ctx)
 static void io_destruct_skb(struct sk_buff *skb)
 {
        struct io_ring_ctx *ctx = skb->sk->sk_user_data;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ctx->sqo_wq); i++)
+               if (ctx->sqo_wq[i])
+                       flush_workqueue(ctx->sqo_wq[i]);
 
-       io_finish_async(ctx);
        unix_destruct_scm(skb);
 }
 
@@ -3630,7 +3626,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
                }
        }
 
-       io_ring_drop_ctx_refs(ctx, 1);
+       percpu_ref_put(&ctx->refs);
 out_fput:
        fdput(f);
        return submitted ? submitted : ret;
index c9b2850..540611b 100644 (file)
@@ -89,58 +89,45 @@ int dcache_dir_close(struct inode *inode, struct file *file)
 EXPORT_SYMBOL(dcache_dir_close);
 
 /* parent is locked at least shared */
-static struct dentry *next_positive(struct dentry *parent,
-                                   struct list_head *from,
-                                   int count)
+/*
+ * Returns an element of siblings' list.
+ * We are looking for <count>th positive after <p>; if
+ * found, dentry is grabbed and returned to caller.
+ * If no such element exists, NULL is returned.
+ */
+static struct dentry *scan_positives(struct dentry *cursor,
+                                       struct list_head *p,
+                                       loff_t count,
+                                       struct dentry *last)
 {
-       unsigned *seq = &parent->d_inode->i_dir_seq, n;
-       struct dentry *res;
-       struct list_head *p;
-       bool skipped;
-       int i;
+       struct dentry *dentry = cursor->d_parent, *found = NULL;
 
-retry:
-       i = count;
-       skipped = false;
-       n = smp_load_acquire(seq) & ~1;
-       res = NULL;
-       rcu_read_lock();
-       for (p = from->next; p != &parent->d_subdirs; p = p->next) {
+       spin_lock(&dentry->d_lock);
+       while ((p = p->next) != &dentry->d_subdirs) {
                struct dentry *d = list_entry(p, struct dentry, d_child);
-               if (!simple_positive(d)) {
-                       skipped = true;
-               } else if (!--i) {
-                       res = d;
-                       break;
+               // we must at least skip cursors, to avoid livelocks
+               if (d->d_flags & DCACHE_DENTRY_CURSOR)
+                       continue;
+               if (simple_positive(d) && !--count) {
+                       spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
+                       if (simple_positive(d))
+                               found = dget_dlock(d);
+                       spin_unlock(&d->d_lock);
+                       if (likely(found))
+                               break;
+                       count = 1;
+               }
+               if (need_resched()) {
+                       list_move(&cursor->d_child, p);
+                       p = &cursor->d_child;
+                       spin_unlock(&dentry->d_lock);
+                       cond_resched();
+                       spin_lock(&dentry->d_lock);
                }
        }
-       rcu_read_unlock();
-       if (skipped) {
-               smp_rmb();
-               if (unlikely(*seq != n))
-                       goto retry;
-       }
-       return res;
-}
-
-static void move_cursor(struct dentry *cursor, struct list_head *after)
-{
-       struct dentry *parent = cursor->d_parent;
-       unsigned n, *seq = &parent->d_inode->i_dir_seq;
-       spin_lock(&parent->d_lock);
-       for (;;) {
-               n = *seq;
-               if (!(n & 1) && cmpxchg(seq, n, n + 1) == n)
-                       break;
-               cpu_relax();
-       }
-       __list_del(cursor->d_child.prev, cursor->d_child.next);
-       if (after)
-               list_add(&cursor->d_child, after);
-       else
-               list_add_tail(&cursor->d_child, &parent->d_subdirs);
-       smp_store_release(seq, n + 2);
-       spin_unlock(&parent->d_lock);
+       spin_unlock(&dentry->d_lock);
+       dput(last);
+       return found;
 }
 
 loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
@@ -158,17 +145,25 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
                        return -EINVAL;
        }
        if (offset != file->f_pos) {
+               struct dentry *cursor = file->private_data;
+               struct dentry *to = NULL;
+
+               inode_lock_shared(dentry->d_inode);
+
+               if (offset > 2)
+                       to = scan_positives(cursor, &dentry->d_subdirs,
+                                           offset - 2, NULL);
+               spin_lock(&dentry->d_lock);
+               if (to)
+                       list_move(&cursor->d_child, &to->d_child);
+               else
+                       list_del_init(&cursor->d_child);
+               spin_unlock(&dentry->d_lock);
+               dput(to);
+
                file->f_pos = offset;
-               if (file->f_pos >= 2) {
-                       struct dentry *cursor = file->private_data;
-                       struct dentry *to;
-                       loff_t n = file->f_pos - 2;
-
-                       inode_lock_shared(dentry->d_inode);
-                       to = next_positive(dentry, &dentry->d_subdirs, n);
-                       move_cursor(cursor, to ? &to->d_child : NULL);
-                       inode_unlock_shared(dentry->d_inode);
-               }
+
+               inode_unlock_shared(dentry->d_inode);
        }
        return offset;
 }
@@ -190,25 +185,35 @@ int dcache_readdir(struct file *file, struct dir_context *ctx)
 {
        struct dentry *dentry = file->f_path.dentry;
        struct dentry *cursor = file->private_data;
-       struct list_head *p = &cursor->d_child;
-       struct dentry *next;
-       bool moved = false;
+       struct list_head *anchor = &dentry->d_subdirs;
+       struct dentry *next = NULL;
+       struct list_head *p;
 
        if (!dir_emit_dots(file, ctx))
                return 0;
 
        if (ctx->pos == 2)
-               p = &dentry->d_subdirs;
-       while ((next = next_positive(dentry, p, 1)) != NULL) {
+               p = anchor;
+       else if (!list_empty(&cursor->d_child))
+               p = &cursor->d_child;
+       else
+               return 0;
+
+       while ((next = scan_positives(cursor, p, 1, next)) != NULL) {
                if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
                              d_inode(next)->i_ino, dt_type(d_inode(next))))
                        break;
-               moved = true;
-               p = &next->d_child;
                ctx->pos++;
+               p = &next->d_child;
        }
-       if (moved)
-               move_cursor(cursor, p);
+       spin_lock(&dentry->d_lock);
+       if (next)
+               list_move_tail(&cursor->d_child, &next->d_child);
+       else
+               list_del_init(&cursor->d_child);
+       spin_unlock(&dentry->d_lock);
+       dput(next);
+
        return 0;
 }
 EXPORT_SYMBOL(dcache_readdir);
index 222d711..040a50f 100644 (file)
 
 static struct kmem_cache *nfs_direct_cachep;
 
-/*
- * This represents a set of asynchronous requests that we're waiting on
- */
-struct nfs_direct_mirror {
-       ssize_t count;
-};
-
 struct nfs_direct_req {
        struct kref             kref;           /* release manager */
 
@@ -84,9 +77,6 @@ struct nfs_direct_req {
        atomic_t                io_count;       /* i/os we're waiting for */
        spinlock_t              lock;           /* protect completion state */
 
-       struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX];
-       int                     mirror_count;
-
        loff_t                  io_start;       /* Start offset for I/O */
        ssize_t                 count,          /* bytes actually processed */
                                max_count,      /* max expected count */
@@ -123,32 +113,42 @@ static inline int put_dreq(struct nfs_direct_req *dreq)
 }
 
 static void
-nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr)
+nfs_direct_handle_truncated(struct nfs_direct_req *dreq,
+                           const struct nfs_pgio_header *hdr,
+                           ssize_t dreq_len)
 {
-       int i;
-       ssize_t count;
+       if (!(test_bit(NFS_IOHDR_ERROR, &hdr->flags) ||
+             test_bit(NFS_IOHDR_EOF, &hdr->flags)))
+               return;
+       if (dreq->max_count >= dreq_len) {
+               dreq->max_count = dreq_len;
+               if (dreq->count > dreq_len)
+                       dreq->count = dreq_len;
+
+               if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
+                       dreq->error = hdr->error;
+               else /* Clear outstanding error if this is EOF */
+                       dreq->error = 0;
+       }
+}
 
-       WARN_ON_ONCE(dreq->count >= dreq->max_count);
+static void
+nfs_direct_count_bytes(struct nfs_direct_req *dreq,
+                      const struct nfs_pgio_header *hdr)
+{
+       loff_t hdr_end = hdr->io_start + hdr->good_bytes;
+       ssize_t dreq_len = 0;
 
-       if (dreq->mirror_count == 1) {
-               dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes;
-               dreq->count += hdr->good_bytes;
-       } else {
-               /* mirrored writes */
-               count = dreq->mirrors[hdr->pgio_mirror_idx].count;
-               if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) {
-                       count = hdr->io_start + hdr->good_bytes - dreq->io_start;
-                       dreq->mirrors[hdr->pgio_mirror_idx].count = count;
-               }
-               /* update the dreq->count by finding the minimum agreed count from all
-                * mirrors */
-               count = dreq->mirrors[0].count;
+       if (hdr_end > dreq->io_start)
+               dreq_len = hdr_end - dreq->io_start;
 
-               for (i = 1; i < dreq->mirror_count; i++)
-                       count = min(count, dreq->mirrors[i].count);
+       nfs_direct_handle_truncated(dreq, hdr, dreq_len);
 
-               dreq->count = count;
-       }
+       if (dreq_len > dreq->max_count)
+               dreq_len = dreq->max_count;
+
+       if (dreq->count < dreq_len)
+               dreq->count = dreq_len;
 }
 
 /*
@@ -293,18 +293,6 @@ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
        cinfo->completion_ops = &nfs_direct_commit_completion_ops;
 }
 
-static inline void nfs_direct_setup_mirroring(struct nfs_direct_req *dreq,
-                                            struct nfs_pageio_descriptor *pgio,
-                                            struct nfs_page *req)
-{
-       int mirror_count = 1;
-
-       if (pgio->pg_ops->pg_get_mirror_count)
-               mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);
-
-       dreq->mirror_count = mirror_count;
-}
-
 static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
 {
        struct nfs_direct_req *dreq;
@@ -319,7 +307,6 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
        INIT_LIST_HEAD(&dreq->mds_cinfo.list);
        dreq->verf.committed = NFS_INVALID_STABLE_HOW;  /* not set yet */
        INIT_WORK(&dreq->work, nfs_direct_write_schedule_work);
-       dreq->mirror_count = 1;
        spin_lock_init(&dreq->lock);
 
        return dreq;
@@ -402,20 +389,12 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
        struct nfs_direct_req *dreq = hdr->dreq;
 
        spin_lock(&dreq->lock);
-       if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
-               dreq->error = hdr->error;
-
        if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
                spin_unlock(&dreq->lock);
                goto out_put;
        }
 
-       if (hdr->good_bytes != 0)
-               nfs_direct_good_bytes(dreq, hdr);
-
-       if (test_bit(NFS_IOHDR_EOF, &hdr->flags))
-               dreq->error = 0;
-
+       nfs_direct_count_bytes(dreq, hdr);
        spin_unlock(&dreq->lock);
 
        while (!list_empty(&hdr->pages)) {
@@ -646,29 +625,22 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
        LIST_HEAD(reqs);
        struct nfs_commit_info cinfo;
        LIST_HEAD(failed);
-       int i;
 
        nfs_init_cinfo_from_dreq(&cinfo, dreq);
        nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
 
        dreq->count = 0;
+       dreq->max_count = 0;
+       list_for_each_entry(req, &reqs, wb_list)
+               dreq->max_count += req->wb_bytes;
        dreq->verf.committed = NFS_INVALID_STABLE_HOW;
        nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo);
-       for (i = 0; i < dreq->mirror_count; i++)
-               dreq->mirrors[i].count = 0;
        get_dreq(dreq);
 
        nfs_pageio_init_write(&desc, dreq->inode, FLUSH_STABLE, false,
                              &nfs_direct_write_completion_ops);
        desc.pg_dreq = dreq;
 
-       req = nfs_list_entry(reqs.next);
-       nfs_direct_setup_mirroring(dreq, &desc, req);
-       if (desc.pg_error < 0) {
-               list_splice_init(&reqs, &failed);
-               goto out_failed;
-       }
-
        list_for_each_entry_safe(req, tmp, &reqs, wb_list) {
                /* Bump the transmission count */
                req->wb_nio++;
@@ -686,7 +658,6 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
        }
        nfs_pageio_complete(&desc);
 
-out_failed:
        while (!list_empty(&failed)) {
                req = nfs_list_entry(failed.next);
                nfs_list_remove_request(req);
@@ -791,17 +762,13 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
        nfs_init_cinfo_from_dreq(&cinfo, dreq);
 
        spin_lock(&dreq->lock);
-
-       if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
-               dreq->error = hdr->error;
-
        if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
                spin_unlock(&dreq->lock);
                goto out_put;
        }
 
+       nfs_direct_count_bytes(dreq, hdr);
        if (hdr->good_bytes != 0) {
-               nfs_direct_good_bytes(dreq, hdr);
                if (nfs_write_need_commit(hdr)) {
                        if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
                                request_commit = true;
@@ -923,7 +890,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
                                break;
                        }
 
-                       nfs_direct_setup_mirroring(dreq, &desc, req);
                        if (desc.pg_error < 0) {
                                nfs_free_request(req);
                                result = desc.pg_error;
index 11eafcf..ab8ca20 100644 (file)
@@ -6106,6 +6106,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
 
        status = nfs4_call_sync_custom(&task_setup_data);
        if (setclientid.sc_cred) {
+               kfree(clp->cl_acceptor);
                clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred);
                put_rpccred(setclientid.sc_cred);
        }
index 85ca495..52cab65 100644 (file)
@@ -786,7 +786,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
        struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs_page *head;
 
-       atomic_long_dec(&nfsi->nrequests);
        if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) {
                head = req->wb_head;
 
@@ -799,8 +798,10 @@ static void nfs_inode_remove_request(struct nfs_page *req)
                spin_unlock(&mapping->private_lock);
        }
 
-       if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags))
+       if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) {
                nfs_release_request(req);
+               atomic_long_dec(&nfsi->nrequests);
+       }
 }
 
 static void
index 8de1c9d..9cd0a68 100644 (file)
@@ -2049,7 +2049,8 @@ out_write_size:
                inode->i_mtime = inode->i_ctime = current_time(inode);
                di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec);
                di->i_mtime_nsec = di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
-               ocfs2_update_inode_fsync_trans(handle, inode, 1);
+               if (handle)
+                       ocfs2_update_inode_fsync_trans(handle, inode, 1);
        }
        if (handle)
                ocfs2_journal_dirty(handle, wc->w_di_bh);
@@ -2146,13 +2147,30 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
        struct ocfs2_dio_write_ctxt *dwc = NULL;
        struct buffer_head *di_bh = NULL;
        u64 p_blkno;
-       loff_t pos = iblock << inode->i_sb->s_blocksize_bits;
+       unsigned int i_blkbits = inode->i_sb->s_blocksize_bits;
+       loff_t pos = iblock << i_blkbits;
+       sector_t endblk = (i_size_read(inode) - 1) >> i_blkbits;
        unsigned len, total_len = bh_result->b_size;
        int ret = 0, first_get_block = 0;
 
        len = osb->s_clustersize - (pos & (osb->s_clustersize - 1));
        len = min(total_len, len);
 
+       /*
+        * bh_result->b_size is count in get_more_blocks according to write
+        * "pos" and "end", we need map twice to return different buffer state:
+        * 1. area in file size, not set NEW;
+        * 2. area out file size, set  NEW.
+        *
+        *                 iblock    endblk
+        * |--------|---------|---------|---------
+        * |<-------area in file------->|
+        */
+
+       if ((iblock <= endblk) &&
+           ((iblock + ((len - 1) >> i_blkbits)) > endblk))
+               len = (endblk - iblock + 1) << i_blkbits;
+
        mlog(0, "get block of %lu at %llu:%u req %u\n",
                        inode->i_ino, pos, len, total_len);
 
@@ -2236,6 +2254,9 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
        if (desc->c_needs_zero)
                set_buffer_new(bh_result);
 
+       if (iblock > endblk)
+               set_buffer_new(bh_result);
+
        /* May sleep in end_io. It should not happen in a irq context. So defer
         * it to dio work queue. */
        set_buffer_defer_completion(bh_result);
index d6f7b29..efeea20 100644 (file)
@@ -283,7 +283,7 @@ static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb,
        if (inode_alloc)
                inode_lock(inode_alloc);
 
-       if (o2info_coherent(&fi->ifi_req)) {
+       if (inode_alloc && o2info_coherent(&fi->ifi_req)) {
                status = ocfs2_inode_lock(inode_alloc, &bh, 0);
                if (status < 0) {
                        mlog_errno(status);
index 90c830e..d850797 100644 (file)
@@ -1490,18 +1490,6 @@ static int ocfs2_xa_check_space(struct ocfs2_xa_loc *loc,
        return loc->xl_ops->xlo_check_space(loc, xi);
 }
 
-static void ocfs2_xa_add_entry(struct ocfs2_xa_loc *loc, u32 name_hash)
-{
-       loc->xl_ops->xlo_add_entry(loc, name_hash);
-       loc->xl_entry->xe_name_hash = cpu_to_le32(name_hash);
-       /*
-        * We can't leave the new entry's xe_name_offset at zero or
-        * add_namevalue() will go nuts.  We set it to the size of our
-        * storage so that it can never be less than any other entry.
-        */
-       loc->xl_entry->xe_name_offset = cpu_to_le16(loc->xl_size);
-}
-
 static void ocfs2_xa_add_namevalue(struct ocfs2_xa_loc *loc,
                                   struct ocfs2_xattr_info *xi)
 {
@@ -2133,29 +2121,31 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
        if (rc)
                goto out;
 
-       if (loc->xl_entry) {
-               if (ocfs2_xa_can_reuse_entry(loc, xi)) {
-                       orig_value_size = loc->xl_entry->xe_value_size;
-                       rc = ocfs2_xa_reuse_entry(loc, xi, ctxt);
-                       if (rc)
-                               goto out;
-                       goto alloc_value;
-               }
+       if (!loc->xl_entry) {
+               rc = -EINVAL;
+               goto out;
+       }
 
-               if (!ocfs2_xattr_is_local(loc->xl_entry)) {
-                       orig_clusters = ocfs2_xa_value_clusters(loc);
-                       rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
-                       if (rc) {
-                               mlog_errno(rc);
-                               ocfs2_xa_cleanup_value_truncate(loc,
-                                                               "overwriting",
-                                                               orig_clusters);
-                               goto out;
-                       }
+       if (ocfs2_xa_can_reuse_entry(loc, xi)) {
+               orig_value_size = loc->xl_entry->xe_value_size;
+               rc = ocfs2_xa_reuse_entry(loc, xi, ctxt);
+               if (rc)
+                       goto out;
+               goto alloc_value;
+       }
+
+       if (!ocfs2_xattr_is_local(loc->xl_entry)) {
+               orig_clusters = ocfs2_xa_value_clusters(loc);
+               rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
+               if (rc) {
+                       mlog_errno(rc);
+                       ocfs2_xa_cleanup_value_truncate(loc,
+                                                       "overwriting",
+                                                       orig_clusters);
+                       goto out;
                }
-               ocfs2_xa_wipe_namevalue(loc);
-       } else
-               ocfs2_xa_add_entry(loc, name_hash);
+       }
+       ocfs2_xa_wipe_namevalue(loc);
 
        /*
         * If we get here, we have a blank entry.  Fill it.  We grow our
index 2f6a453..6e2623e 100644 (file)
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
 #include <linux/compat.h>
-
 #include <linux/uaccess.h>
 
+#include <asm/unaligned.h>
+
+/*
+ * Note the "unsafe_put_user() semantics: we goto a
+ * label for errors.
+ */
+#define unsafe_copy_dirent_name(_dst, _src, _len, label) do {  \
+       char __user *dst = (_dst);                              \
+       const char *src = (_src);                               \
+       size_t len = (_len);                                    \
+       unsafe_put_user(0, dst+len, label);                     \
+       unsafe_copy_to_user(dst, src, len, label);              \
+} while (0)
+
+
 int iterate_dir(struct file *file, struct dir_context *ctx)
 {
        struct inode *inode = file_inode(file);
@@ -64,6 +78,40 @@ out:
 }
 EXPORT_SYMBOL(iterate_dir);
 
+/*
+ * POSIX says that a dirent name cannot contain NULL or a '/'.
+ *
+ * It's not 100% clear what we should really do in this case.
+ * The filesystem is clearly corrupted, but returning a hard
+ * error means that you now don't see any of the other names
+ * either, so that isn't a perfect alternative.
+ *
+ * And if you return an error, what error do you use? Several
+ * filesystems seem to have decided on EUCLEAN being the error
+ * code for EFSCORRUPTED, and that may be the error to use. Or
+ * just EIO, which is perhaps more obvious to users.
+ *
+ * In order to see the other file names in the directory, the
+ * caller might want to make this a "soft" error: skip the
+ * entry, and return the error at the end instead.
+ *
+ * Note that this should likely do a "memchr(name, 0, len)"
+ * check too, since that would be filesystem corruption as
+ * well. However, that case can't actually confuse user space,
+ * which has to do a strlen() on the name anyway to find the
+ * filename length, and the above "soft error" worry means
+ * that it's probably better left alone until we have that
+ * issue clarified.
+ */
+static int verify_dirent_name(const char *name, int len)
+{
+       if (WARN_ON_ONCE(!len))
+               return -EIO;
+       if (WARN_ON_ONCE(memchr(name, '/', len)))
+               return -EIO;
+       return 0;
+}
+
 /*
  * Traditional linux readdir() handling..
  *
@@ -173,6 +221,9 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
        int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2,
                sizeof(long));
 
+       buf->error = verify_dirent_name(name, namlen);
+       if (unlikely(buf->error))
+               return buf->error;
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
@@ -182,28 +233,31 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
                return -EOVERFLOW;
        }
        dirent = buf->previous;
-       if (dirent) {
-               if (signal_pending(current))
-                       return -EINTR;
-               if (__put_user(offset, &dirent->d_off))
-                       goto efault;
-       }
-       dirent = buf->current_dir;
-       if (__put_user(d_ino, &dirent->d_ino))
-               goto efault;
-       if (__put_user(reclen, &dirent->d_reclen))
-               goto efault;
-       if (copy_to_user(dirent->d_name, name, namlen))
-               goto efault;
-       if (__put_user(0, dirent->d_name + namlen))
-               goto efault;
-       if (__put_user(d_type, (char __user *) dirent + reclen - 1))
+       if (dirent && signal_pending(current))
+               return -EINTR;
+
+       /*
+        * Note! This range-checks 'previous' (which may be NULL).
+        * The real range was checked in getdents
+        */
+       if (!user_access_begin(dirent, sizeof(*dirent)))
                goto efault;
+       if (dirent)
+               unsafe_put_user(offset, &dirent->d_off, efault_end);
+       dirent = buf->current_dir;
+       unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
+       unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
+       unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end);
+       unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
+       user_access_end();
+
        buf->previous = dirent;
        dirent = (void __user *)dirent + reclen;
        buf->current_dir = dirent;
        buf->count -= reclen;
        return 0;
+efault_end:
+       user_access_end();
 efault:
        buf->error = -EFAULT;
        return -EFAULT;
@@ -259,34 +313,38 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
        int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
                sizeof(u64));
 
+       buf->error = verify_dirent_name(name, namlen);
+       if (unlikely(buf->error))
+               return buf->error;
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
                return -EINVAL;
        dirent = buf->previous;
-       if (dirent) {
-               if (signal_pending(current))
-                       return -EINTR;
-               if (__put_user(offset, &dirent->d_off))
-                       goto efault;
-       }
-       dirent = buf->current_dir;
-       if (__put_user(ino, &dirent->d_ino))
-               goto efault;
-       if (__put_user(0, &dirent->d_off))
-               goto efault;
-       if (__put_user(reclen, &dirent->d_reclen))
-               goto efault;
-       if (__put_user(d_type, &dirent->d_type))
-               goto efault;
-       if (copy_to_user(dirent->d_name, name, namlen))
-               goto efault;
-       if (__put_user(0, dirent->d_name + namlen))
+       if (dirent && signal_pending(current))
+               return -EINTR;
+
+       /*
+        * Note! This range-checks 'previous' (which may be NULL).
+        * The real range was checked in getdents
+        */
+       if (!user_access_begin(dirent, sizeof(*dirent)))
                goto efault;
+       if (dirent)
+               unsafe_put_user(offset, &dirent->d_off, efault_end);
+       dirent = buf->current_dir;
+       unsafe_put_user(ino, &dirent->d_ino, efault_end);
+       unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
+       unsafe_put_user(d_type, &dirent->d_type, efault_end);
+       unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
+       user_access_end();
+
        buf->previous = dirent;
        dirent = (void __user *)dirent + reclen;
        buf->current_dir = dirent;
        buf->count -= reclen;
        return 0;
+efault_end:
+       user_access_end();
 efault:
        buf->error = -EFAULT;
        return -EFAULT;
index eea7af6..2616424 100644 (file)
@@ -318,19 +318,10 @@ COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *,
 static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf)
 {
        struct compat_statfs64 buf;
-       if (sizeof(ubuf->f_bsize) == 4) {
-               if ((kbuf->f_type | kbuf->f_bsize | kbuf->f_namelen |
-                    kbuf->f_frsize | kbuf->f_flags) & 0xffffffff00000000ULL)
-                       return -EOVERFLOW;
-               /* f_files and f_ffree may be -1; it's okay
-                * to stuff that into 32 bits */
-               if (kbuf->f_files != 0xffffffffffffffffULL
-                && (kbuf->f_files & 0xffffffff00000000ULL))
-                       return -EOVERFLOW;
-               if (kbuf->f_ffree != 0xffffffffffffffffULL
-                && (kbuf->f_ffree & 0xffffffff00000000ULL))
-                       return -EOVERFLOW;
-       }
+
+       if ((kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL)
+               return -EOVERFLOW;
+
        memset(&buf, 0, sizeof(struct compat_statfs64));
        buf.f_type = kbuf->f_type;
        buf.f_bsize = kbuf->f_bsize;
index f627b7c..cfadab2 100644 (file)
@@ -1300,6 +1300,7 @@ int get_tree_bdev(struct fs_context *fc,
        mutex_lock(&bdev->bd_fsfreeze_mutex);
        if (bdev->bd_fsfreeze_count > 0) {
                mutex_unlock(&bdev->bd_fsfreeze_mutex);
+               blkdev_put(bdev, mode);
                warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev);
                return -EBUSY;
        }
@@ -1308,8 +1309,10 @@ int get_tree_bdev(struct fs_context *fc,
        fc->sget_key = bdev;
        s = sget_fc(fc, test_bdev_super_fc, set_bdev_super_fc);
        mutex_unlock(&bdev->bd_fsfreeze_mutex);
-       if (IS_ERR(s))
+       if (IS_ERR(s)) {
+               blkdev_put(bdev, mode);
                return PTR_ERR(s);
+       }
 
        if (s->s_root) {
                /* Don't summarily change the RO/RW state. */
index 5de296b..14fbdf2 100644 (file)
@@ -28,12 +28,11 @@ xfs_get_aghdr_buf(
        struct xfs_mount        *mp,
        xfs_daddr_t             blkno,
        size_t                  numblks,
-       int                     flags,
        const struct xfs_buf_ops *ops)
 {
        struct xfs_buf          *bp;
 
-       bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags);
+       bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0);
        if (!bp)
                return NULL;
 
@@ -345,7 +344,7 @@ xfs_ag_init_hdr(
 {
        struct xfs_buf          *bp;
 
-       bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, 0, ops);
+       bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, ops);
        if (!bp)
                return -ENOMEM;
 
index b9f0196..f0089e8 100644 (file)
@@ -826,32 +826,17 @@ xfs_attr_shortform_to_leaf(
        sf = (xfs_attr_shortform_t *)tmpbuffer;
 
        xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
-       xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK);
+       xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
 
        bp = NULL;
        error = xfs_da_grow_inode(args, &blkno);
-       if (error) {
-               /*
-                * If we hit an IO error middle of the transaction inside
-                * grow_inode(), we may have inconsistent data. Bail out.
-                */
-               if (error == -EIO)
-                       goto out;
-               xfs_idata_realloc(dp, size, XFS_ATTR_FORK);     /* try to put */
-               memcpy(ifp->if_u1.if_data, tmpbuffer, size);    /* it back */
+       if (error)
                goto out;
-       }
 
        ASSERT(blkno == 0);
        error = xfs_attr3_leaf_create(args, blkno, &bp);
-       if (error) {
-               /* xfs_attr3_leaf_create may not have instantiated a block */
-               if (bp && (xfs_da_shrink_inode(args, 0, bp) != 0))
-                       goto out;
-               xfs_idata_realloc(dp, size, XFS_ATTR_FORK);     /* try to put */
-               memcpy(ifp->if_u1.if_data, tmpbuffer, size);    /* it back */
+       if (error)
                goto out;
-       }
 
        memset((char *)&nargs, 0, sizeof(nargs));
        nargs.dp = dp;
index 4edc25a..02469d5 100644 (file)
@@ -792,6 +792,7 @@ out_root_realloc:
  */
 void
 xfs_bmap_local_to_extents_empty(
+       struct xfs_trans        *tp,
        struct xfs_inode        *ip,
        int                     whichfork)
 {
@@ -808,6 +809,7 @@ xfs_bmap_local_to_extents_empty(
        ifp->if_u1.if_root = NULL;
        ifp->if_height = 0;
        XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 }
 
 
@@ -840,7 +842,7 @@ xfs_bmap_local_to_extents(
        ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
 
        if (!ifp->if_bytes) {
-               xfs_bmap_local_to_extents_empty(ip, whichfork);
+               xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
                flags = XFS_ILOG_CORE;
                goto done;
        }
@@ -887,7 +889,7 @@ xfs_bmap_local_to_extents(
 
        /* account for the change in fork size */
        xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
-       xfs_bmap_local_to_extents_empty(ip, whichfork);
+       xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
        flags |= XFS_ILOG_CORE;
 
        ifp->if_u1.if_root = NULL;
index 5bb446d..e2798c6 100644 (file)
@@ -182,7 +182,8 @@ void        xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
                xfs_filblks_t len);
 int    xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
 int    xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version);
-void   xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork);
+void   xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
+               struct xfs_inode *ip, int whichfork);
 void   __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,
                xfs_filblks_t len, const struct xfs_owner_info *oinfo,
                bool skip_discard);
index 9595ced..49e4bc3 100644 (file)
@@ -1096,7 +1096,7 @@ xfs_dir2_sf_to_block(
        memcpy(sfp, oldsfp, ifp->if_bytes);
 
        xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK);
-       xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK);
+       xfs_bmap_local_to_extents_empty(tp, dp, XFS_DATA_FORK);
        dp->i_d.di_size = 0;
 
        /*
index 93b3793..0cab11a 100644 (file)
@@ -341,7 +341,6 @@ xchk_refcountbt_rec(
        xfs_extlen_t            len;
        xfs_nlink_t             refcount;
        bool                    has_cowflag;
-       int                     error = 0;
 
        bno = be32_to_cpu(rec->refc.rc_startblock);
        len = be32_to_cpu(rec->refc.rc_blockcount);
@@ -366,7 +365,7 @@ xchk_refcountbt_rec(
 
        xchk_refcountbt_xref(bs->sc, bno, len, refcount);
 
-       return error;
+       return 0;
 }
 
 /* Make sure we have as many refc blocks as the rmap says. */
index 0910cb7..4f44370 100644 (file)
@@ -864,6 +864,7 @@ xfs_alloc_file_space(
        xfs_filblks_t           allocatesize_fsb;
        xfs_extlen_t            extsz, temp;
        xfs_fileoff_t           startoffset_fsb;
+       xfs_fileoff_t           endoffset_fsb;
        int                     nimaps;
        int                     quota_flag;
        int                     rt;
@@ -891,7 +892,8 @@ xfs_alloc_file_space(
        imapp = &imaps[0];
        nimaps = 1;
        startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
-       allocatesize_fsb = XFS_B_TO_FSB(mp, count);
+       endoffset_fsb = XFS_B_TO_FSB(mp, offset + count);
+       allocatesize_fsb = endoffset_fsb - startoffset_fsb;
 
        /*
         * Allocate file space until done or until there is an error
index 21c2436..0abba17 100644 (file)
@@ -345,6 +345,15 @@ xfs_buf_allocate_memory(
        unsigned short          page_count, i;
        xfs_off_t               start, end;
        int                     error;
+       xfs_km_flags_t          kmflag_mask = 0;
+
+       /*
+        * assure zeroed buffer for non-read cases.
+        */
+       if (!(flags & XBF_READ)) {
+               kmflag_mask |= KM_ZERO;
+               gfp_mask |= __GFP_ZERO;
+       }
 
        /*
         * for buffers that are contained within a single page, just allocate
@@ -354,7 +363,8 @@ xfs_buf_allocate_memory(
        size = BBTOB(bp->b_length);
        if (size < PAGE_SIZE) {
                int align_mask = xfs_buftarg_dma_alignment(bp->b_target);
-               bp->b_addr = kmem_alloc_io(size, align_mask, KM_NOFS);
+               bp->b_addr = kmem_alloc_io(size, align_mask,
+                                          KM_NOFS | kmflag_mask);
                if (!bp->b_addr) {
                        /* low memory - use alloc_page loop instead */
                        goto use_alloc_page;
index a2beee9..641d07f 100644 (file)
@@ -1443,7 +1443,7 @@ xlog_alloc_log(
                prev_iclog = iclog;
 
                iclog->ic_data = kmem_alloc_io(log->l_iclog_size, align_mask,
-                                               KM_MAYFAIL);
+                                               KM_MAYFAIL | KM_ZERO);
                if (!iclog->ic_data)
                        goto out_free_iclog;
 #ifdef DEBUG
index 5083190..c1a514f 100644 (file)
@@ -127,7 +127,7 @@ xlog_alloc_buffer(
        if (nbblks > 1 && log->l_sectBBsize > 1)
                nbblks += log->l_sectBBsize;
        nbblks = round_up(nbblks, log->l_sectBBsize);
-       return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL);
+       return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL | KM_ZERO);
 }
 
 /*
index cf074bc..c94a9ff 100644 (file)
@@ -4,6 +4,13 @@
 #include <asm/types.h>
 #include <linux/bits.h>
 
+/* Set bits in the first 'n' bytes when loaded from memory */
+#ifdef __LITTLE_ENDIAN
+#  define aligned_byte_mask(n) ((1UL << 8*(n))-1)
+#else
+#  define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n)))
+#endif
+
 #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
 #define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
 
index 6b318ef..cdf0165 100644 (file)
@@ -40,6 +40,7 @@
 # define __GCC4_has_attribute___noclone__             1
 # define __GCC4_has_attribute___nonstring__           0
 # define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8)
+# define __GCC4_has_attribute___fallthrough__         0
 #endif
 
 /*
 # define __noclone
 #endif
 
+/*
+ * Add the pseudo keyword 'fallthrough' so case statement blocks
+ * must end with any of these keywords:
+ *   break;
+ *   fallthrough;
+ *   goto <label>;
+ *   return [expression];
+ *
+ *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
+ */
+#if __has_attribute(__fallthrough__)
+# define fallthrough                    __attribute__((__fallthrough__))
+#else
+# define fallthrough                    do {} while (0)  /* fallthrough */
+#endif
+
 /*
  * Note the missing underscores.
  *
index 79435cf..897e799 100644 (file)
@@ -31,6 +31,8 @@
 #define SJA1105_META_SMAC                      0x222222222222ull
 #define SJA1105_META_DMAC                      0x0180C200000Eull
 
+#define SJA1105_HWTS_RX_EN                     0
+
 /* Global tagger data: each struct sja1105_port has a reference to
  * the structure defined in struct sja1105_private.
  */
@@ -42,7 +44,7 @@ struct sja1105_tagger_data {
         * from taggers running on multiple ports on SMP systems
         */
        spinlock_t meta_lock;
-       bool hwts_rx_en;
+       unsigned long state;
 };
 
 struct sja1105_skb_cb {
index 95f55b7..621158e 100644 (file)
@@ -52,10 +52,10 @@ extern struct module __this_module;
        __ADDRESSABLE(sym)                                              \
        asm("   .section \"___ksymtab" sec "+" #sym "\", \"a\"  \n"     \
            "   .balign 4                                       \n"     \
-           "__ksymtab_" #sym NS_SEPARATOR #ns ":               \n"     \
+           "__ksymtab_" #ns NS_SEPARATOR #sym ":               \n"     \
            "   .long   " #sym "- .                             \n"     \
            "   .long   __kstrtab_" #sym "- .                   \n"     \
-           "   .long   __kstrtab_ns_" #sym "- .                \n"     \
+           "   .long   __kstrtabns_" #sym "- .                 \n"     \
            "   .previous                                       \n")
 
 #define __KSYMTAB_ENTRY(sym, sec)                                      \
@@ -76,10 +76,10 @@ struct kernel_symbol {
 #else
 #define __KSYMTAB_ENTRY_NS(sym, sec, ns)                               \
        static const struct kernel_symbol __ksymtab_##sym##__##ns       \
-       asm("__ksymtab_" #sym NS_SEPARATOR #ns)                         \
+       asm("__ksymtab_" #ns NS_SEPARATOR #sym)                         \
        __attribute__((section("___ksymtab" sec "+" #sym), used))       \
        __aligned(sizeof(void *))                                       \
-       = { (unsigned long)&sym, __kstrtab_##sym, __kstrtab_ns_##sym }
+       = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym }
 
 #define __KSYMTAB_ENTRY(sym, sec)                                      \
        static const struct kernel_symbol __ksymtab_##sym               \
@@ -112,7 +112,7 @@ struct kernel_symbol {
 /* For every exported symbol, place a struct in the __ksymtab section */
 #define ___EXPORT_SYMBOL_NS(sym, sec, ns)                              \
        ___export_symbol_common(sym, sec);                              \
-       static const char __kstrtab_ns_##sym[]                          \
+       static const char __kstrtabns_##sym[]                           \
        __attribute__((section("__ksymtab_strings"), used, aligned(1))) \
        = #ns;                                                          \
        __KSYMTAB_ENTRY_NS(sym, sec, ns)
index fcb46b3..719fc3e 100644 (file)
@@ -1090,6 +1090,7 @@ enum kvm_stat_kind {
 
 struct kvm_stat_data {
        int offset;
+       int mode;
        struct kvm *kvm;
 };
 
@@ -1097,6 +1098,7 @@ struct kvm_stats_debugfs_item {
        const char *name;
        int offset;
        enum kvm_stat_kind kind;
+       int mode;
 };
 extern struct kvm_stats_debugfs_item debugfs_entries[];
 extern struct dentry *kvm_debugfs_dir;
index b8df711..efb309d 100644 (file)
@@ -247,7 +247,7 @@ extern void led_set_brightness(struct led_classdev *led_cdev,
 /**
  * led_set_brightness_sync - set LED brightness synchronously
  * @led_cdev: the LED to set
- * @brightness: the brightness to set it to
+ * @value: the brightness to set it to
  *
  * Set an LED's brightness immediately. This function will block
  * the caller for the time required for accessing device registers,
@@ -301,8 +301,7 @@ extern void led_sysfs_enable(struct led_classdev *led_cdev);
 /**
  * led_compose_name - compose LED class device name
  * @dev: LED controller device object
- * @child: child fwnode_handle describing a LED or a group of synchronized LEDs;
- *        it must be provided only for fwnode based LEDs
+ * @init_data: the LED class device initialization data
  * @led_classdev_name: composed LED class device name
  *
  * Create LED class device name basing on the provided init_data argument.
index 9b60863..ae703ea 100644 (file)
@@ -356,6 +356,19 @@ static inline bool mem_cgroup_disabled(void)
        return !cgroup_subsys_enabled(memory_cgrp_subsys);
 }
 
+static inline unsigned long mem_cgroup_protection(struct mem_cgroup *memcg,
+                                                 bool in_low_reclaim)
+{
+       if (mem_cgroup_disabled())
+               return 0;
+
+       if (in_low_reclaim)
+               return READ_ONCE(memcg->memory.emin);
+
+       return max(READ_ONCE(memcg->memory.emin),
+                  READ_ONCE(memcg->memory.elow));
+}
+
 enum mem_cgroup_protection mem_cgroup_protected(struct mem_cgroup *root,
                                                struct mem_cgroup *memcg);
 
@@ -537,6 +550,8 @@ void mem_cgroup_handle_over_high(void);
 
 unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg);
 
+unsigned long mem_cgroup_size(struct mem_cgroup *memcg);
+
 void mem_cgroup_print_oom_context(struct mem_cgroup *memcg,
                                struct task_struct *p);
 
@@ -829,6 +844,12 @@ static inline void memcg_memory_event_mm(struct mm_struct *mm,
 {
 }
 
+static inline unsigned long mem_cgroup_protection(struct mem_cgroup *memcg,
+                                                 bool in_low_reclaim)
+{
+       return 0;
+}
+
 static inline enum mem_cgroup_protection mem_cgroup_protected(
        struct mem_cgroup *root, struct mem_cgroup *memcg)
 {
@@ -968,6 +989,11 @@ static inline unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg)
        return 0;
 }
 
+static inline unsigned long mem_cgroup_size(struct mem_cgroup *memcg)
+{
+       return 0;
+}
+
 static inline void
 mem_cgroup_print_oom_context(struct mem_cgroup *memcg, struct task_struct *p)
 {
@@ -1264,6 +1290,9 @@ void mem_cgroup_track_foreign_dirty_slowpath(struct page *page,
 static inline void mem_cgroup_track_foreign_dirty(struct page *page,
                                                  struct bdi_writeback *wb)
 {
+       if (mem_cgroup_disabled())
+               return;
+
        if (unlikely(&page->mem_cgroup->css != wb->memcg_css))
                mem_cgroup_track_foreign_dirty_slowpath(page, wb);
 }
index 5cd824c..4ce8901 100644 (file)
@@ -455,6 +455,15 @@ static inline void mii_lpa_mod_linkmode_lpa_t(unsigned long *lp_advertising,
                         lp_advertising, lpa & LPA_LPACK);
 }
 
+static inline void mii_ctrl1000_mod_linkmode_adv_t(unsigned long *advertising,
+                                                  u32 ctrl1000)
+{
+       linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising,
+                        ctrl1000 & ADVERTISE_1000HALF);
+       linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising,
+                        ctrl1000 & ADVERTISE_1000FULL);
+}
+
 /**
  * linkmode_adv_to_lcl_adv_t
  * @advertising:pointer to linkmode advertising
index a7ecbe0..9a0e981 100644 (file)
@@ -678,6 +678,7 @@ static inline bool phy_is_started(struct phy_device *phydev)
        return phydev->state >= PHY_UP;
 }
 
+void phy_resolve_aneg_pause(struct phy_device *phydev);
 void phy_resolve_aneg_linkmode(struct phy_device *phydev);
 
 /**
@@ -1076,6 +1077,7 @@ int genphy_config_eee_advert(struct phy_device *phydev);
 int __genphy_config_aneg(struct phy_device *phydev, bool changed);
 int genphy_aneg_done(struct phy_device *phydev);
 int genphy_update_link(struct phy_device *phydev);
+int genphy_read_lpa(struct phy_device *phydev);
 int genphy_read_status(struct phy_device *phydev);
 int genphy_suspend(struct phy_device *phydev);
 int genphy_resume(struct phy_device *phydev);
index e7d3b1a..4351577 100644 (file)
@@ -4160,15 +4160,12 @@ static inline void __skb_ext_copy(struct sk_buff *d, const struct sk_buff *s) {}
 static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {}
 #endif /* CONFIG_SKB_EXTENSIONS */
 
-static inline void nf_reset(struct sk_buff *skb)
+static inline void nf_reset_ct(struct sk_buff *skb)
 {
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        nf_conntrack_put(skb_nfct(skb));
        skb->_nfct = 0;
 #endif
-#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-       skb_ext_del(skb, SKB_EXT_BRIDGE_NF);
-#endif
 }
 
 static inline void nf_reset_trace(struct sk_buff *skb)
index ab2b98a..4d2a2fa 100644 (file)
@@ -493,6 +493,10 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
  * kmalloc is the normal method of allocating memory
  * for objects smaller than page size in the kernel.
  *
+ * The allocated object address is aligned to at least ARCH_KMALLOC_MINALIGN
+ * bytes. For @size of power of two bytes, the alignment is also guaranteed
+ * to be at least to the size.
+ *
  * The @flags argument may be one of the GFP flags defined at
  * include/linux/gfp.h and described at
  * :ref:`Documentation/core-api/mm-api.rst <mm-api-gfp-flags>`
index b2f9df7..b6ccdc2 100644 (file)
@@ -227,7 +227,26 @@ static inline bool strstarts(const char *str, const char *prefix)
 }
 
 size_t memweight(const void *ptr, size_t bytes);
-void memzero_explicit(void *s, size_t count);
+
+/**
+ * memzero_explicit - Fill a region of memory (e.g. sensitive
+ *                   keying data) with 0s.
+ * @s: Pointer to the start of the area.
+ * @count: The size of the area.
+ *
+ * Note: usually using memset() is just fine (!), but in cases
+ * where clearing out _local_ data at the end of a scope is
+ * necessary, memzero_explicit() should be used instead in
+ * order to prevent the compiler from optimising away zeroing.
+ *
+ * memzero_explicit() doesn't need an arch-specific version as
+ * it just invokes the one of memset() implicitly.
+ */
+static inline void memzero_explicit(void *s, size_t count)
+{
+       memset(s, 0, count);
+       barrier_data(s);
+}
 
 /**
  * kbasename - return the last part of a pathname.
index 7638dbe..a940de0 100644 (file)
@@ -61,6 +61,7 @@ struct sock_xprt {
        struct mutex            recv_mutex;
        struct sockaddr_storage srcaddr;
        unsigned short          srcport;
+       int                     xprt_err;
 
        /*
         * UDP socket buffer size parameters
index 63238c8..131ea1b 100644 (file)
@@ -152,7 +152,7 @@ struct tcg_algorithm_info {
  * total. Once we've done this we know the offset of the data length field,
  * and can calculate the total size of the event.
  *
- * Return: size of the event on success, <0 on failure
+ * Return: size of the event on success, 0 on failure
  */
 
 static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
@@ -170,6 +170,7 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
        u16 halg;
        int i;
        int j;
+       u32 count, event_type;
 
        marker = event;
        marker_start = marker;
@@ -190,16 +191,22 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
        }
 
        event = (struct tcg_pcr_event2_head *)mapping;
+       /*
+        * The loop below will unmap these fields if the log is larger than
+        * one page, so save them here for reference:
+        */
+       count = READ_ONCE(event->count);
+       event_type = READ_ONCE(event->event_type);
 
        efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
 
        /* Check if event is malformed. */
-       if (event->count > efispecid->num_algs) {
+       if (count > efispecid->num_algs) {
                size = 0;
                goto out;
        }
 
-       for (i = 0; i < event->count; i++) {
+       for (i = 0; i < count; i++) {
                halg_size = sizeof(event->digests[i].alg_id);
 
                /* Map the digest's algorithm identifier */
@@ -256,8 +263,9 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
                + event_field->event_size;
        size = marker - marker_start;
 
-       if ((event->event_type == 0) && (event_field->event_size == 0))
+       if (event_type == 0 && event_field->event_size == 0)
                size = 0;
+
 out:
        if (do_mapping)
                TPM_MEMUNMAP(mapping, mapping_size);
index 70bbdc3..d4ee6e9 100644 (file)
@@ -231,6 +231,76 @@ __copy_from_user_inatomic_nocache(void *to, const void __user *from,
 
 #endif         /* ARCH_HAS_NOCACHE_UACCESS */
 
+extern __must_check int check_zeroed_user(const void __user *from, size_t size);
+
+/**
+ * copy_struct_from_user: copy a struct from userspace
+ * @dst:   Destination address, in kernel space. This buffer must be @ksize
+ *         bytes long.
+ * @ksize: Size of @dst struct.
+ * @src:   Source address, in userspace.
+ * @usize: (Alleged) size of @src struct.
+ *
+ * Copies a struct from userspace to kernel space, in a way that guarantees
+ * backwards-compatibility for struct syscall arguments (as long as future
+ * struct extensions are made such that all new fields are *appended* to the
+ * old struct, and zeroed-out new fields have the same meaning as the old
+ * struct).
+ *
+ * @ksize is just sizeof(*dst), and @usize should've been passed by userspace.
+ * The recommended usage is something like the following:
+ *
+ *   SYSCALL_DEFINE2(foobar, const struct foo __user *, uarg, size_t, usize)
+ *   {
+ *      int err;
+ *      struct foo karg = {};
+ *
+ *      if (usize > PAGE_SIZE)
+ *        return -E2BIG;
+ *      if (usize < FOO_SIZE_VER0)
+ *        return -EINVAL;
+ *
+ *      err = copy_struct_from_user(&karg, sizeof(karg), uarg, usize);
+ *      if (err)
+ *        return err;
+ *
+ *      // ...
+ *   }
+ *
+ * There are three cases to consider:
+ *  * If @usize == @ksize, then it's copied verbatim.
+ *  * If @usize < @ksize, then the userspace has passed an old struct to a
+ *    newer kernel. The rest of the trailing bytes in @dst (@ksize - @usize)
+ *    are to be zero-filled.
+ *  * If @usize > @ksize, then the userspace has passed a new struct to an
+ *    older kernel. The trailing bytes unknown to the kernel (@usize - @ksize)
+ *    are checked to ensure they are zeroed, otherwise -E2BIG is returned.
+ *
+ * Returns (in all cases, some data may have been copied):
+ *  * -E2BIG:  (@usize > @ksize) and there are non-zero trailing bytes in @src.
+ *  * -EFAULT: access to userspace failed.
+ */
+static __always_inline __must_check int
+copy_struct_from_user(void *dst, size_t ksize, const void __user *src,
+                     size_t usize)
+{
+       size_t size = min(ksize, usize);
+       size_t rest = max(ksize, usize) - size;
+
+       /* Deal with trailing bytes. */
+       if (usize < ksize) {
+               memset(dst + size, 0, rest);
+       } else if (usize > ksize) {
+               int ret = check_zeroed_user(src + size, rest);
+               if (ret <= 0)
+                       return ret ?: -E2BIG;
+       }
+       /* Copy the interoperable parts of the struct. */
+       if (copy_from_user(dst, src, size))
+               return -EFAULT;
+       return 0;
+}
+
 /*
  * probe_kernel_read(): safely attempt to read from a location
  * @dst: pointer to the buffer that shall take the data
@@ -285,8 +355,10 @@ extern long strnlen_unsafe_user(const void __user *unsafe_addr, long count);
 #ifndef user_access_begin
 #define user_access_begin(ptr,len) access_ok(ptr, len)
 #define user_access_end() do { } while (0)
-#define unsafe_get_user(x, ptr, err) do { if (unlikely(__get_user(x, ptr))) goto err; } while (0)
-#define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0)
+#define unsafe_op_wrap(op, err) do { if (unlikely(op)) goto err; } while (0)
+#define unsafe_get_user(x,p,e) unsafe_op_wrap(__get_user(x,p),e)
+#define unsafe_put_user(x,p,e) unsafe_op_wrap(__put_user(x,p),e)
+#define unsafe_copy_to_user(d,s,l,e) unsafe_op_wrap(__copy_to_user(d,s,l),e)
 static inline unsigned long user_access_save(void) { return 0UL; }
 static inline void user_access_restore(unsigned long flags) { }
 #endif
index a13a62d..edc5c88 100644 (file)
@@ -1068,7 +1068,7 @@ TRACE_EVENT(rxrpc_recvmsg,
                             ),
 
            TP_fast_assign(
-                   __entry->call = call->debug_id;
+                   __entry->call = call ? call->debug_id : 0;
                    __entry->why = why;
                    __entry->seq = seq;
                    __entry->offset = offset;
index c99b4f2..4fe35d6 100644 (file)
@@ -1003,6 +1003,8 @@ struct drm_amdgpu_info_device {
        __u64 high_va_max;
        /* gfx10 pa_sc_tile_steering_override */
        __u32 pa_sc_tile_steering_override;
+       /* disabled TCCs */
+       __u64 tcc_disabled_mask;
 };
 
 struct drm_amdgpu_info_hw_ip {
index 1c215ea..e168dc5 100644 (file)
@@ -45,6 +45,27 @@ struct nvme_passthru_cmd {
        __u32   result;
 };
 
+struct nvme_passthru_cmd64 {
+       __u8    opcode;
+       __u8    flags;
+       __u16   rsvd1;
+       __u32   nsid;
+       __u32   cdw2;
+       __u32   cdw3;
+       __u64   metadata;
+       __u64   addr;
+       __u32   metadata_len;
+       __u32   data_len;
+       __u32   cdw10;
+       __u32   cdw11;
+       __u32   cdw12;
+       __u32   cdw13;
+       __u32   cdw14;
+       __u32   cdw15;
+       __u32   timeout_ms;
+       __u64   result;
+};
+
 #define nvme_admin_cmd nvme_passthru_cmd
 
 #define NVME_IOCTL_ID          _IO('N', 0x40)
@@ -54,5 +75,7 @@ struct nvme_passthru_cmd {
 #define NVME_IOCTL_RESET       _IO('N', 0x44)
 #define NVME_IOCTL_SUBSYS_RESET        _IO('N', 0x45)
 #define NVME_IOCTL_RESCAN      _IO('N', 0x46)
+#define NVME_IOCTL_ADMIN64_CMD _IOWR('N', 0x47, struct nvme_passthru_cmd64)
+#define NVME_IOCTL_IO64_CMD    _IOWR('N', 0x48, struct nvme_passthru_cmd64)
 
 #endif /* _UAPI_LINUX_NVME_IOCTL_H */
index 364c350..62b6f69 100644 (file)
@@ -35,6 +35,9 @@
 
 */
 
+#ifndef _UAPI_LINUX_PG_H
+#define _UAPI_LINUX_PG_H
+
 #define PG_MAGIC       'P'
 #define PG_RESET       'Z'
 #define PG_COMMAND     'C'
@@ -61,4 +64,4 @@ struct pg_read_hdr {
 
 };
 
-/* end of pg.h */
+#endif /* _UAPI_LINUX_PG_H */
index b3105ac..99335e1 100644 (file)
 #define CLONE_NEWNET           0x40000000      /* New network namespace */
 #define CLONE_IO               0x80000000      /* Clone io context */
 
-/*
- * Arguments for the clone3 syscall
+#ifndef __ASSEMBLY__
+/**
+ * struct clone_args - arguments for the clone3 syscall
+ * @flags:       Flags for the new process as listed above.
+ *               All flags are valid except for CSIGNAL and
+ *               CLONE_DETACHED.
+ * @pidfd:       If CLONE_PIDFD is set, a pidfd will be
+ *               returned in this argument.
+ * @child_tid:   If CLONE_CHILD_SETTID is set, the TID of the
+ *               child process will be returned in the child's
+ *               memory.
+ * @parent_tid:  If CLONE_PARENT_SETTID is set, the TID of
+ *               the child process will be returned in the
+ *               parent's memory.
+ * @exit_signal: The exit_signal the parent process will be
+ *               sent when the child exits.
+ * @stack:       Specify the location of the stack for the
+ *               child process.
+ * @stack_size:  The size of the stack for the child process.
+ * @tls:         If CLONE_SETTLS is set, the tls descriptor
+ *               is set to tls.
+ *
+ * The structure is versioned by size and thus extensible.
+ * New struct members must go at the end of the struct and
+ * must be properly 64bit aligned.
  */
 struct clone_args {
        __aligned_u64 flags;
@@ -46,6 +69,9 @@ struct clone_args {
        __aligned_u64 stack_size;
        __aligned_u64 tls;
 };
+#endif
+
+#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */
 
 /*
  * Scheduling policies
index 98b30c1..d89969a 100644 (file)
@@ -212,30 +212,7 @@ int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr,
 
 bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
 
-efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc);
-efi_status_t xen_efi_set_time(efi_time_t *tm);
-efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
-                                    efi_time_t *tm);
-efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm);
-efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
-                                 u32 *attr, unsigned long *data_size,
-                                 void *data);
-efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
-                                      efi_char16_t *name, efi_guid_t *vendor);
-efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
-                                 u32 attr, unsigned long data_size,
-                                 void *data);
-efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
-                                        u64 *remaining_space,
-                                        u64 *max_variable_size);
-efi_status_t xen_efi_get_next_high_mono_count(u32 *count);
-efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
-                                   unsigned long count, unsigned long sg_list);
-efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
-                                       unsigned long count, u64 *max_size,
-                                       int *reset_type);
-void xen_efi_reset_system(int reset_type, efi_status_t status,
-                         unsigned long data_size, efi_char16_t *data);
+void xen_efi_runtime_setup(void);
 
 
 #ifdef CONFIG_PREEMPT
index ca4e5d4..c00b925 100644 (file)
@@ -87,9 +87,9 @@ void *dma_common_contiguous_remap(struct page *page, size_t size,
  */
 void dma_common_free_remap(void *cpu_addr, size_t size)
 {
-       struct page **pages = dma_common_find_pages(cpu_addr);
+       struct vm_struct *area = find_vm_area(cpu_addr);
 
-       if (!pages) {
+       if (!area || area->flags != VM_DMA_COHERENT) {
                WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
                return;
        }
index 4655adb..9ec0b0b 100644 (file)
@@ -3779,11 +3779,23 @@ static void rotate_ctx(struct perf_event_context *ctx, struct perf_event *event)
        perf_event_groups_insert(&ctx->flexible_groups, event);
 }
 
+/* pick an event from the flexible_groups to rotate */
 static inline struct perf_event *
-ctx_first_active(struct perf_event_context *ctx)
+ctx_event_to_rotate(struct perf_event_context *ctx)
 {
-       return list_first_entry_or_null(&ctx->flexible_active,
-                                       struct perf_event, active_list);
+       struct perf_event *event;
+
+       /* pick the first active flexible event */
+       event = list_first_entry_or_null(&ctx->flexible_active,
+                                        struct perf_event, active_list);
+
+       /* if no active flexible event, pick the first event */
+       if (!event) {
+               event = rb_entry_safe(rb_first(&ctx->flexible_groups.tree),
+                                     typeof(*event), group_node);
+       }
+
+       return event;
 }
 
 static bool perf_rotate_context(struct perf_cpu_context *cpuctx)
@@ -3808,9 +3820,9 @@ static bool perf_rotate_context(struct perf_cpu_context *cpuctx)
        perf_pmu_disable(cpuctx->ctx.pmu);
 
        if (task_rotate)
-               task_event = ctx_first_active(task_ctx);
+               task_event = ctx_event_to_rotate(task_ctx);
        if (cpu_rotate)
-               cpu_event = ctx_first_active(&cpuctx->ctx);
+               cpu_event = ctx_event_to_rotate(&cpuctx->ctx);
 
        /*
         * As per the order given at ctx_resched() first 'pop' task flexible
@@ -5668,7 +5680,8 @@ again:
         * undo the VM accounting.
         */
 
-       atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm);
+       atomic_long_sub((size >> PAGE_SHIFT) + 1 - mmap_locked,
+                       &mmap_user->locked_vm);
        atomic64_sub(mmap_locked, &vma->vm_mm->pinned_vm);
        free_uid(mmap_user);
 
@@ -5812,8 +5825,20 @@ accounting:
 
        user_locked = atomic_long_read(&user->locked_vm) + user_extra;
 
-       if (user_locked > user_lock_limit)
+       if (user_locked <= user_lock_limit) {
+               /* charge all to locked_vm */
+       } else if (atomic_long_read(&user->locked_vm) >= user_lock_limit) {
+               /* charge all to pinned_vm */
+               extra = user_extra;
+               user_extra = 0;
+       } else {
+               /*
+                * charge locked_vm until it hits user_lock_limit;
+                * charge the rest from pinned_vm
+                */
                extra = user_locked - user_lock_limit;
+               user_extra -= extra;
+       }
 
        lock_limit = rlimit(RLIMIT_MEMLOCK);
        lock_limit >>= PAGE_SHIFT;
@@ -10586,55 +10611,26 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
        u32 size;
        int ret;
 
-       if (!access_ok(uattr, PERF_ATTR_SIZE_VER0))
-               return -EFAULT;
-
-       /*
-        * zero the full structure, so that a short copy will be nice.
-        */
+       /* Zero the full structure, so that a short copy will be nice. */
        memset(attr, 0, sizeof(*attr));
 
        ret = get_user(size, &uattr->size);
        if (ret)
                return ret;
 
-       if (size > PAGE_SIZE)   /* silly large */
-               goto err_size;
-
-       if (!size)              /* abi compat */
+       /* ABI compatibility quirk: */
+       if (!size)
                size = PERF_ATTR_SIZE_VER0;
-
-       if (size < PERF_ATTR_SIZE_VER0)
+       if (size < PERF_ATTR_SIZE_VER0 || size > PAGE_SIZE)
                goto err_size;
 
-       /*
-        * If we're handed a bigger struct than we know of,
-        * ensure all the unknown bits are 0 - i.e. new
-        * user-space does not rely on any kernel feature
-        * extensions we dont know about yet.
-        */
-       if (size > sizeof(*attr)) {
-               unsigned char __user *addr;
-               unsigned char __user *end;
-               unsigned char val;
-
-               addr = (void __user *)uattr + sizeof(*attr);
-               end  = (void __user *)uattr + size;
-
-               for (; addr < end; addr++) {
-                       ret = get_user(val, addr);
-                       if (ret)
-                               return ret;
-                       if (val)
-                               goto err_size;
-               }
-               size = sizeof(*attr);
+       ret = copy_struct_from_user(attr, sizeof(*attr), uattr, size);
+       if (ret) {
+               if (ret == -E2BIG)
+                       goto err_size;
+               return ret;
        }
 
-       ret = copy_from_user(attr, uattr, size);
-       if (ret)
-               return -EFAULT;
-
        attr->size = size;
 
        if (attr->__reserved_1)
@@ -11891,6 +11887,10 @@ static int inherit_group(struct perf_event *parent_event,
                                            child, leader, child_ctx);
                if (IS_ERR(child_ctr))
                        return PTR_ERR(child_ctr);
+
+               if (sub->aux_event == parent_event &&
+                   !perf_get_aux_event(child_ctr, leader))
+                       return -EINVAL;
        }
        return 0;
 }
index f9572f4..bcdf531 100644 (file)
@@ -2525,39 +2525,19 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
 #ifdef __ARCH_WANT_SYS_CLONE3
 noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
                                              struct clone_args __user *uargs,
-                                             size_t size)
+                                             size_t usize)
 {
+       int err;
        struct clone_args args;
 
-       if (unlikely(size > PAGE_SIZE))
+       if (unlikely(usize > PAGE_SIZE))
                return -E2BIG;
-
-       if (unlikely(size < sizeof(struct clone_args)))
+       if (unlikely(usize < CLONE_ARGS_SIZE_VER0))
                return -EINVAL;
 
-       if (unlikely(!access_ok(uargs, size)))
-               return -EFAULT;
-
-       if (size > sizeof(struct clone_args)) {
-               unsigned char __user *addr;
-               unsigned char __user *end;
-               unsigned char val;
-
-               addr = (void __user *)uargs + sizeof(struct clone_args);
-               end = (void __user *)uargs + size;
-
-               for (; addr < end; addr++) {
-                       if (get_user(val, addr))
-                               return -EFAULT;
-                       if (val)
-                               return -E2BIG;
-               }
-
-               size = sizeof(struct clone_args);
-       }
-
-       if (copy_from_user(&args, uargs, size))
-               return -EFAULT;
+       err = copy_struct_from_user(&args, sizeof(args), uargs, usize);
+       if (err)
+               return err;
 
        /*
         * Verify that higher 32bits of exit_signal are unset and that
@@ -2604,6 +2584,17 @@ static bool clone3_args_valid(const struct kernel_clone_args *kargs)
        return true;
 }
 
+/**
+ * clone3 - create a new process with specific properties
+ * @uargs: argument structure
+ * @size:  size of @uargs
+ *
+ * clone3() is the extensible successor to clone()/clone2().
+ * It takes a struct as argument that is versioned by its size.
+ *
+ * Return: On success, a positive PID for the child process.
+ *         On error, a negative errno number.
+ */
 SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size)
 {
        int err;
@@ -2934,7 +2925,7 @@ int sysctl_max_threads(struct ctl_table *table, int write,
        struct ctl_table t;
        int ret;
        int threads = max_threads;
-       int min = MIN_THREADS;
+       int min = 1;
        int max = MAX_THREADS;
 
        t = *table;
@@ -2946,7 +2937,7 @@ int sysctl_max_threads(struct ctl_table *table, int write,
        if (ret || !write)
                return ret;
 
-       set_max_threads(threads);
+       max_threads = threads;
 
        return 0;
 }
index c073842..dc520f0 100644 (file)
@@ -22,12 +22,6 @@ EXPORT_SYMBOL(system_freezing_cnt);
 bool pm_freezing;
 bool pm_nosig_freezing;
 
-/*
- * Temporary export for the deadlock workaround in ata_scsi_hotplug().
- * Remove once the hack becomes unnecessary.
- */
-EXPORT_SYMBOL_GPL(pm_freezing);
-
 /* protects freezing and frozen transitions */
 static DEFINE_SPINLOCK(freezer_lock);
 
index 9ff4498..aff79e4 100755 (executable)
@@ -71,7 +71,10 @@ done | cpio --quiet -pd $cpio_dir >/dev/null 2>&1
 find $cpio_dir -type f -print0 |
        xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;'
 
-tar -Jcf $tarfile -C $cpio_dir/ . > /dev/null
+# Create archive and try to normalize metadata for reproducibility
+tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
+    --owner=0 --group=0 --sort=name --numeric-owner \
+    -Jcf $tarfile -C $cpio_dir/ . > /dev/null
 
 echo "$src_files_md5" >  kernel/kheaders.md5
 echo "$obj_files_md5" >> kernel/kheaders.md5
index 47e8ebc..f470a03 100644 (file)
@@ -180,6 +180,7 @@ void panic(const char *fmt, ...)
         * after setting panic_cpu) from invoking panic() again.
         */
        local_irq_disable();
+       preempt_disable_notrace();
 
        /*
         * It's possible to come here directly from a panic-assertion and
index 7880f4f..dd05a37 100644 (file)
@@ -5106,9 +5106,6 @@ static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *a
        u32 size;
        int ret;
 
-       if (!access_ok(uattr, SCHED_ATTR_SIZE_VER0))
-               return -EFAULT;
-
        /* Zero the full structure, so that a short copy will be nice: */
        memset(attr, 0, sizeof(*attr));
 
@@ -5116,45 +5113,19 @@ static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *a
        if (ret)
                return ret;
 
-       /* Bail out on silly large: */
-       if (size > PAGE_SIZE)
-               goto err_size;
-
        /* ABI compatibility quirk: */
        if (!size)
                size = SCHED_ATTR_SIZE_VER0;
-
-       if (size < SCHED_ATTR_SIZE_VER0)
+       if (size < SCHED_ATTR_SIZE_VER0 || size > PAGE_SIZE)
                goto err_size;
 
-       /*
-        * If we're handed a bigger struct than we know of,
-        * ensure all the unknown bits are 0 - i.e. new
-        * user-space does not rely on any kernel feature
-        * extensions we dont know about yet.
-        */
-       if (size > sizeof(*attr)) {
-               unsigned char __user *addr;
-               unsigned char __user *end;
-               unsigned char val;
-
-               addr = (void __user *)uattr + sizeof(*attr);
-               end  = (void __user *)uattr + size;
-
-               for (; addr < end; addr++) {
-                       ret = get_user(val, addr);
-                       if (ret)
-                               return ret;
-                       if (val)
-                               goto err_size;
-               }
-               size = sizeof(*attr);
+       ret = copy_struct_from_user(attr, sizeof(*attr), uattr, size);
+       if (ret) {
+               if (ret == -E2BIG)
+                       goto err_size;
+               return ret;
        }
 
-       ret = copy_from_user(attr, uattr, size);
-       if (ret)
-               return -EFAULT;
-
        if ((attr->sched_flags & SCHED_FLAG_UTIL_CLAMP) &&
            size < SCHED_ATTR_SIZE_VER1)
                return -EINVAL;
@@ -5354,7 +5325,7 @@ sched_attr_copy_to_user(struct sched_attr __user *uattr,
  * sys_sched_getattr - similar to sched_getparam, but with sched_attr
  * @pid: the pid in question.
  * @uattr: structure containing the extended parameters.
- * @usize: sizeof(attr) that user-space knows about, for forwards and backwards compatibility.
+ * @usize: sizeof(attr) for fwd/bwd comp.
  * @flags: for future extension.
  */
 SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
index 2305ce8..46ed4e1 100644 (file)
@@ -740,7 +740,7 @@ void vtime_account_system(struct task_struct *tsk)
 
        write_seqcount_begin(&vtime->seqcount);
        /* We might have scheduled out from guest path */
-       if (current->flags & PF_VCPU)
+       if (tsk->flags & PF_VCPU)
                vtime_account_guest(tsk, vtime);
        else
                __vtime_account_system(tsk, vtime);
@@ -783,7 +783,7 @@ void vtime_guest_enter(struct task_struct *tsk)
         */
        write_seqcount_begin(&vtime->seqcount);
        __vtime_account_system(tsk, vtime);
-       current->flags |= PF_VCPU;
+       tsk->flags |= PF_VCPU;
        write_seqcount_end(&vtime->seqcount);
 }
 EXPORT_SYMBOL_GPL(vtime_guest_enter);
@@ -794,7 +794,7 @@ void vtime_guest_exit(struct task_struct *tsk)
 
        write_seqcount_begin(&vtime->seqcount);
        vtime_account_guest(tsk, vtime);
-       current->flags &= ~PF_VCPU;
+       tsk->flags &= ~PF_VCPU;
        write_seqcount_end(&vtime->seqcount);
 }
 EXPORT_SYMBOL_GPL(vtime_guest_exit);
index 83ab35e..682a754 100644 (file)
@@ -4926,20 +4926,28 @@ static enum hrtimer_restart sched_cfs_period_timer(struct hrtimer *timer)
                if (++count > 3) {
                        u64 new, old = ktime_to_ns(cfs_b->period);
 
-                       new = (old * 147) / 128; /* ~115% */
-                       new = min(new, max_cfs_quota_period);
-
-                       cfs_b->period = ns_to_ktime(new);
-
-                       /* since max is 1s, this is limited to 1e9^2, which fits in u64 */
-                       cfs_b->quota *= new;
-                       cfs_b->quota = div64_u64(cfs_b->quota, old);
-
-                       pr_warn_ratelimited(
-       "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us %lld, cfs_quota_us = %lld)\n",
-                               smp_processor_id(),
-                               div_u64(new, NSEC_PER_USEC),
-                               div_u64(cfs_b->quota, NSEC_PER_USEC));
+                       /*
+                        * Grow period by a factor of 2 to avoid losing precision.
+                        * Precision loss in the quota/period ratio can cause __cfs_schedulable
+                        * to fail.
+                        */
+                       new = old * 2;
+                       if (new < max_cfs_quota_period) {
+                               cfs_b->period = ns_to_ktime(new);
+                               cfs_b->quota *= 2;
+
+                               pr_warn_ratelimited(
+       "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us = %lld, cfs_quota_us = %lld)\n",
+                                       smp_processor_id(),
+                                       div_u64(new, NSEC_PER_USEC),
+                                       div_u64(cfs_b->quota, NSEC_PER_USEC));
+                       } else {
+                               pr_warn_ratelimited(
+       "cfs_period_timer[cpu%d]: period too short, but cannot scale up without losing precision (cfs_period_us = %lld, cfs_quota_us = %lld)\n",
+                                       smp_processor_id(),
+                                       div_u64(old, NSEC_PER_USEC),
+                                       div_u64(cfs_b->quota, NSEC_PER_USEC));
+                       }
 
                        /* reset count so we don't come right back in here */
                        count = 0;
index a39bed2..168479a 100644 (file)
@@ -174,7 +174,6 @@ static int membarrier_private_expedited(int flags)
                 */
                if (cpu == raw_smp_processor_id())
                        continue;
-               rcu_read_lock();
                p = rcu_dereference(cpu_rq(cpu)->curr);
                if (p && p->mm == mm)
                        __cpumask_set_cpu(cpu, tmpmask);
index c1f5bb5..b5a65e2 100644 (file)
@@ -42,39 +42,39 @@ static int bc_shutdown(struct clock_event_device *evt)
  */
 static int bc_set_next(ktime_t expires, struct clock_event_device *bc)
 {
-       int bc_moved;
        /*
-        * We try to cancel the timer first. If the callback is on
-        * flight on some other cpu then we let it handle it. If we
-        * were able to cancel the timer nothing can rearm it as we
-        * own broadcast_lock.
+        * This is called either from enter/exit idle code or from the
+        * broadcast handler. In all cases tick_broadcast_lock is held.
         *
-        * However we can also be called from the event handler of
-        * ce_broadcast_hrtimer itself when it expires. We cannot
-        * restart the timer because we are in the callback, but we
-        * can set the expiry time and let the callback return
-        * HRTIMER_RESTART.
+        * hrtimer_cancel() cannot be called here neither from the
+        * broadcast handler nor from the enter/exit idle code. The idle
+        * code can run into the problem described in bc_shutdown() and the
+        * broadcast handler cannot wait for itself to complete for obvious
+        * reasons.
         *
-        * Since we are in the idle loop at this point and because
-        * hrtimer_{start/cancel} functions call into tracing,
-        * calls to these functions must be bound within RCU_NONIDLE.
+        * Each caller tries to arm the hrtimer on its own CPU, but if the
+        * hrtimer callbback function is currently running, then
+        * hrtimer_start() cannot move it and the timer stays on the CPU on
+        * which it is assigned at the moment.
+        *
+        * As this can be called from idle code, the hrtimer_start()
+        * invocation has to be wrapped with RCU_NONIDLE() as
+        * hrtimer_start() can call into tracing.
         */
-       RCU_NONIDLE(
-               {
-                       bc_moved = hrtimer_try_to_cancel(&bctimer) >= 0;
-                       if (bc_moved) {
-                               hrtimer_start(&bctimer, expires,
-                                             HRTIMER_MODE_ABS_PINNED_HARD);
-                       }
-               }
-       );
-
-       if (bc_moved) {
-               /* Bind the "device" to the cpu */
-               bc->bound_on = smp_processor_id();
-       } else if (bc->bound_on == smp_processor_id()) {
-               hrtimer_set_expires(&bctimer, expires);
-       }
+       RCU_NONIDLE( {
+               hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED_HARD);
+               /*
+                * The core tick broadcast mode expects bc->bound_on to be set
+                * correctly to prevent a CPU which has the broadcast hrtimer
+                * armed from going deep idle.
+                *
+                * As tick_broadcast_lock is held, nothing can change the cpu
+                * base which was just established in hrtimer_start() above. So
+                * the below access is safe even without holding the hrtimer
+                * base lock.
+                */
+               bc->bound_on = bctimer.base->cpu_base->cpu;
+       } );
        return 0;
 }
 
@@ -100,10 +100,6 @@ static enum hrtimer_restart bc_handler(struct hrtimer *t)
 {
        ce_broadcast_hrtimer.event_handler(&ce_broadcast_hrtimer);
 
-       if (clockevent_state_oneshot(&ce_broadcast_hrtimer))
-               if (ce_broadcast_hrtimer.next_event != KTIME_MAX)
-                       return HRTIMER_RESTART;
-
        return HRTIMER_NORESTART;
 }
 
index cd7a10c..08ec58c 100644 (file)
@@ -748,27 +748,6 @@ void *memset(void *s, int c, size_t count)
 EXPORT_SYMBOL(memset);
 #endif
 
-/**
- * memzero_explicit - Fill a region of memory (e.g. sensitive
- *                   keying data) with 0s.
- * @s: Pointer to the start of the area.
- * @count: The size of the area.
- *
- * Note: usually using memset() is just fine (!), but in cases
- * where clearing out _local_ data at the end of a scope is
- * necessary, memzero_explicit() should be used instead in
- * order to prevent the compiler from optimising away zeroing.
- *
- * memzero_explicit() doesn't need an arch-specific version as
- * it just invokes the one of memset() implicitly.
- */
-void memzero_explicit(void *s, size_t count)
-{
-       memset(s, 0, count);
-       barrier_data(s);
-}
-EXPORT_SYMBOL(memzero_explicit);
-
 #ifndef __HAVE_ARCH_MEMSET16
 /**
  * memset16() - Fill a memory area with a uint16_t
index 28ff554..6c0005d 100644 (file)
@@ -3,16 +3,10 @@
 #include <linux/export.h>
 #include <linux/uaccess.h>
 #include <linux/mm.h>
+#include <linux/bitops.h>
 
 #include <asm/word-at-a-time.h>
 
-/* Set bits in the first 'n' bytes when loaded from memory */
-#ifdef __LITTLE_ENDIAN
-#  define aligned_byte_mask(n) ((1ul << 8*(n))-1)
-#else
-#  define aligned_byte_mask(n) (~0xfful << (BITS_PER_LONG - 8 - 8*(n)))
-#endif
-
 /*
  * Do a strnlen, return length of string *with* final '\0'.
  * 'count' is the user-supplied count, while 'max' is the
index 67bcd5d..e365ace 100644 (file)
 # define TEST_U64
 #endif
 
-#define test(condition, msg)           \
-({                                     \
-       int cond = (condition);         \
-       if (cond)                       \
-               pr_warn("%s\n", msg);   \
-       cond;                           \
+#define test(condition, msg, ...)                                      \
+({                                                                     \
+       int cond = (condition);                                         \
+       if (cond)                                                       \
+               pr_warn("[%d] " msg "\n", __LINE__, ##__VA_ARGS__);     \
+       cond;                                                           \
 })
 
+static bool is_zeroed(void *from, size_t size)
+{
+       return memchr_inv(from, 0x0, size) == NULL;
+}
+
+static int test_check_nonzero_user(char *kmem, char __user *umem, size_t size)
+{
+       int ret = 0;
+       size_t start, end, i;
+       size_t zero_start = size / 4;
+       size_t zero_end = size - zero_start;
+
+       /*
+        * We conduct a series of check_nonzero_user() tests on a block of memory
+        * with the following byte-pattern (trying every possible [start,end]
+        * pair):
+        *
+        *   [ 00 ff 00 ff ... 00 00 00 00 ... ff 00 ff 00 ]
+        *
+        * And we verify that check_nonzero_user() acts identically to memchr_inv().
+        */
+
+       memset(kmem, 0x0, size);
+       for (i = 1; i < zero_start; i += 2)
+               kmem[i] = 0xff;
+       for (i = zero_end; i < size; i += 2)
+               kmem[i] = 0xff;
+
+       ret |= test(copy_to_user(umem, kmem, size),
+                   "legitimate copy_to_user failed");
+
+       for (start = 0; start <= size; start++) {
+               for (end = start; end <= size; end++) {
+                       size_t len = end - start;
+                       int retval = check_zeroed_user(umem + start, len);
+                       int expected = is_zeroed(kmem + start, len);
+
+                       ret |= test(retval != expected,
+                                   "check_nonzero_user(=%d) != memchr_inv(=%d) mismatch (start=%zu, end=%zu)",
+                                   retval, expected, start, end);
+               }
+       }
+
+       return ret;
+}
+
+static int test_copy_struct_from_user(char *kmem, char __user *umem,
+                                     size_t size)
+{
+       int ret = 0;
+       char *umem_src = NULL, *expected = NULL;
+       size_t ksize, usize;
+
+       umem_src = kmalloc(size, GFP_KERNEL);
+       if ((ret |= test(umem_src == NULL, "kmalloc failed")))
+               goto out_free;
+
+       expected = kmalloc(size, GFP_KERNEL);
+       if ((ret |= test(expected == NULL, "kmalloc failed")))
+               goto out_free;
+
+       /* Fill umem with a fixed byte pattern. */
+       memset(umem_src, 0x3e, size);
+       ret |= test(copy_to_user(umem, umem_src, size),
+                   "legitimate copy_to_user failed");
+
+       /* Check basic case -- (usize == ksize). */
+       ksize = size;
+       usize = size;
+
+       memcpy(expected, umem_src, ksize);
+
+       memset(kmem, 0x0, size);
+       ret |= test(copy_struct_from_user(kmem, ksize, umem, usize),
+                   "copy_struct_from_user(usize == ksize) failed");
+       ret |= test(memcmp(kmem, expected, ksize),
+                   "copy_struct_from_user(usize == ksize) gives unexpected copy");
+
+       /* Old userspace case -- (usize < ksize). */
+       ksize = size;
+       usize = size / 2;
+
+       memcpy(expected, umem_src, usize);
+       memset(expected + usize, 0x0, ksize - usize);
+
+       memset(kmem, 0x0, size);
+       ret |= test(copy_struct_from_user(kmem, ksize, umem, usize),
+                   "copy_struct_from_user(usize < ksize) failed");
+       ret |= test(memcmp(kmem, expected, ksize),
+                   "copy_struct_from_user(usize < ksize) gives unexpected copy");
+
+       /* New userspace (-E2BIG) case -- (usize > ksize). */
+       ksize = size / 2;
+       usize = size;
+
+       memset(kmem, 0x0, size);
+       ret |= test(copy_struct_from_user(kmem, ksize, umem, usize) != -E2BIG,
+                   "copy_struct_from_user(usize > ksize) didn't give E2BIG");
+
+       /* New userspace (success) case -- (usize > ksize). */
+       ksize = size / 2;
+       usize = size;
+
+       memcpy(expected, umem_src, ksize);
+       ret |= test(clear_user(umem + ksize, usize - ksize),
+                   "legitimate clear_user failed");
+
+       memset(kmem, 0x0, size);
+       ret |= test(copy_struct_from_user(kmem, ksize, umem, usize),
+                   "copy_struct_from_user(usize > ksize) failed");
+       ret |= test(memcmp(kmem, expected, ksize),
+                   "copy_struct_from_user(usize > ksize) gives unexpected copy");
+
+out_free:
+       kfree(expected);
+       kfree(umem_src);
+       return ret;
+}
+
 static int __init test_user_copy_init(void)
 {
        int ret = 0;
@@ -106,6 +225,11 @@ static int __init test_user_copy_init(void)
 #endif
 #undef test_legit
 
+       /* Test usage of check_nonzero_user(). */
+       ret |= test_check_nonzero_user(kmem, usermem, 2 * PAGE_SIZE);
+       /* Test usage of copy_struct_from_user(). */
+       ret |= test_copy_struct_from_user(kmem, usermem, 2 * PAGE_SIZE);
+
        /*
         * Invalid usage: none of these copies should succeed.
         */
index 4f16eec..f68dea8 100644 (file)
@@ -89,9 +89,9 @@
  *       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);
  */
index c2bfbca..cbb4d9e 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/uaccess.h>
+#include <linux/bitops.h>
 
 /* out-of-line parts */
 
@@ -31,3 +32,57 @@ unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n)
 }
 EXPORT_SYMBOL(_copy_to_user);
 #endif
+
+/**
+ * check_zeroed_user: check if a userspace buffer only contains zero bytes
+ * @from: Source address, in userspace.
+ * @size: Size of buffer.
+ *
+ * This is effectively shorthand for "memchr_inv(from, 0, size) == NULL" for
+ * userspace addresses (and is more efficient because we don't care where the
+ * first non-zero byte is).
+ *
+ * Returns:
+ *  * 0: There were non-zero bytes present in the buffer.
+ *  * 1: The buffer was full of zero bytes.
+ *  * -EFAULT: access to userspace failed.
+ */
+int check_zeroed_user(const void __user *from, size_t size)
+{
+       unsigned long val;
+       uintptr_t align = (uintptr_t) from % sizeof(unsigned long);
+
+       if (unlikely(size == 0))
+               return 1;
+
+       from -= align;
+       size += align;
+
+       if (!user_access_begin(from, size))
+               return -EFAULT;
+
+       unsafe_get_user(val, (unsigned long __user *) from, err_fault);
+       if (align)
+               val &= ~aligned_byte_mask(align);
+
+       while (size > sizeof(unsigned long)) {
+               if (unlikely(val))
+                       goto done;
+
+               from += sizeof(unsigned long);
+               size -= sizeof(unsigned long);
+
+               unsafe_get_user(val, (unsigned long __user *) from, err_fault);
+       }
+
+       if (size < sizeof(unsigned long))
+               val &= aligned_byte_mask(size);
+
+done:
+       user_access_end();
+       return (val == 0);
+err_fault:
+       user_access_end();
+       return -EFAULT;
+}
+EXPORT_SYMBOL(check_zeroed_user);
index cc00364..9fe698f 100644 (file)
@@ -24,13 +24,4 @@ config GENERIC_COMPAT_VDSO
        help
          This config option enables the compat VDSO layer.
 
-config CROSS_COMPILE_COMPAT_VDSO
-       string "32 bit Toolchain prefix for compat vDSO"
-       default ""
-       depends on GENERIC_COMPAT_VDSO
-       help
-         Defines the cross-compiler prefix for compiling compat vDSO.
-         If a 64 bit compiler (i.e. x86_64) can compile the VDSO for
-         32 bit, it does not need to define this parameter.
-
 endif
index d9daa3e..c360f6a 100644 (file)
@@ -239,8 +239,8 @@ static int __init default_bdi_init(void)
 {
        int err;
 
-       bdi_wq = alloc_workqueue("writeback", WQ_MEM_RECLAIM | WQ_FREEZABLE |
-                                             WQ_UNBOUND | WQ_SYSFS, 0);
+       bdi_wq = alloc_workqueue("writeback", WQ_MEM_RECLAIM | WQ_UNBOUND |
+                                WQ_SYSFS, 0);
        if (!bdi_wq)
                return -ENOMEM;
 
index c313c49..bdac560 100644 (file)
@@ -1567,6 +1567,11 @@ unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg)
        return max;
 }
 
+unsigned long mem_cgroup_size(struct mem_cgroup *memcg)
+{
+       return page_counter_read(&memcg->memory);
+}
+
 static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
                                     int order)
 {
index 32c79b5..6820491 100644 (file)
@@ -13,8 +13,6 @@
 #include <linux/xarray.h>
 
 static DEFINE_XARRAY(pgmap_array);
-#define SECTION_MASK ~((1UL << PA_SECTION_SHIFT) - 1)
-#define SECTION_SIZE (1UL << PA_SECTION_SHIFT)
 
 #ifdef CONFIG_DEV_PAGEMAP_OPS
 DEFINE_STATIC_KEY_FALSE(devmap_managed_key);
index 15c2050..c0b2e03 100644 (file)
@@ -1175,11 +1175,17 @@ static __always_inline bool free_pages_prepare(struct page *page,
                debug_check_no_obj_freed(page_address(page),
                                           PAGE_SIZE << order);
        }
-       arch_free_page(page, order);
        if (want_init_on_free())
                kernel_init_free_pages(page, 1 << order);
 
        kernel_poison_pages(page, 1 << order, 0);
+       /*
+        * arch_free_page() can make the page's contents inaccessible.  s390
+        * does this.  So nothing which can access the page's contents should
+        * happen after this.
+        */
+       arch_free_page(page, order);
+
        if (debug_pagealloc_enabled())
                kernel_map_pages(page, 1 << order, 0);
 
index cd570cc..220be9f 100644 (file)
@@ -3482,6 +3482,12 @@ static int shmem_parse_options(struct fs_context *fc, void *data)
 {
        char *options = data;
 
+       if (options) {
+               int err = security_sb_eat_lsm_opts(options, &fc->security);
+               if (err)
+                       return err;
+       }
+
        while (options != NULL) {
                char *this_char = options;
                for (;;) {
index 3ce1248..b3fe97f 100644 (file)
@@ -33,7 +33,7 @@ __meminit void page_alloc_shuffle(enum mm_shuffle_ctl ctl)
 }
 
 static bool shuffle_param;
-extern int shuffle_show(char *buffer, const struct kernel_param *kp)
+static int shuffle_show(char *buffer, const struct kernel_param *kp)
 {
        return sprintf(buffer, "%c\n", test_bit(SHUFFLE_ENABLE, &shuffle_state)
                        ? 'Y' : 'N');
index 6491c3a..c29f03a 100644 (file)
@@ -1030,10 +1030,19 @@ void __init create_boot_cache(struct kmem_cache *s, const char *name,
                unsigned int useroffset, unsigned int usersize)
 {
        int err;
+       unsigned int align = ARCH_KMALLOC_MINALIGN;
 
        s->name = name;
        s->size = s->object_size = size;
-       s->align = calculate_alignment(flags, ARCH_KMALLOC_MINALIGN, size);
+
+       /*
+        * For power of two sizes, guarantee natural alignment for kmalloc
+        * caches, regardless of SL*B debugging options.
+        */
+       if (is_power_of_2(size))
+               align = max(align, size);
+       s->align = calculate_alignment(flags, align, size);
+
        s->useroffset = useroffset;
        s->usersize = usersize;
 
@@ -1287,12 +1296,16 @@ void __init create_kmalloc_caches(slab_flags_t flags)
  */
 void *kmalloc_order(size_t size, gfp_t flags, unsigned int order)
 {
-       void *ret;
+       void *ret = NULL;
        struct page *page;
 
        flags |= __GFP_COMP;
        page = alloc_pages(flags, order);
-       ret = page ? page_address(page) : NULL;
+       if (likely(page)) {
+               ret = page_address(page);
+               mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE,
+                                   1 << order);
+       }
        ret = kasan_kmalloc_large(ret, size, flags);
        /* As ret might get tagged, call kmemleak hook after KASAN. */
        kmemleak_alloc(ret, size, 1, flags);
index cf377be..fa53e9f 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -190,7 +190,7 @@ static int slob_last(slob_t *s)
 
 static void *slob_new_pages(gfp_t gfp, int order, int node)
 {
-       void *page;
+       struct page *page;
 
 #ifdef CONFIG_NUMA
        if (node != NUMA_NO_NODE)
@@ -202,14 +202,21 @@ static void *slob_new_pages(gfp_t gfp, int order, int node)
        if (!page)
                return NULL;
 
+       mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE,
+                           1 << order);
        return page_address(page);
 }
 
 static void slob_free_pages(void *b, int order)
 {
+       struct page *sp = virt_to_page(b);
+
        if (current->reclaim_state)
                current->reclaim_state->reclaimed_slab += 1 << order;
-       free_pages((unsigned long)b, order);
+
+       mod_node_page_state(page_pgdat(sp), NR_SLAB_UNRECLAIMABLE,
+                           -(1 << order));
+       __free_pages(sp, order);
 }
 
 /*
@@ -217,6 +224,7 @@ static void slob_free_pages(void *b, int order)
  * @sp: Page to look in.
  * @size: Size of the allocation.
  * @align: Allocation alignment.
+ * @align_offset: Offset in the allocated block that will be aligned.
  * @page_removed_from_list: Return parameter.
  *
  * Tries to find a chunk of memory at least @size bytes big within @page.
@@ -227,7 +235,7 @@ static void slob_free_pages(void *b, int order)
  *         true (set to false otherwise).
  */
 static void *slob_page_alloc(struct page *sp, size_t size, int align,
-                            bool *page_removed_from_list)
+                             int align_offset, bool *page_removed_from_list)
 {
        slob_t *prev, *cur, *aligned = NULL;
        int delta = 0, units = SLOB_UNITS(size);
@@ -236,8 +244,17 @@ static void *slob_page_alloc(struct page *sp, size_t size, int align,
        for (prev = NULL, cur = sp->freelist; ; prev = cur, cur = slob_next(cur)) {
                slobidx_t avail = slob_units(cur);
 
+               /*
+                * 'aligned' will hold the address of the slob block so that the
+                * address 'aligned'+'align_offset' is aligned according to the
+                * 'align' parameter. This is for kmalloc() which prepends the
+                * allocated block with its size, so that the block itself is
+                * aligned when needed.
+                */
                if (align) {
-                       aligned = (slob_t *)ALIGN((unsigned long)cur, align);
+                       aligned = (slob_t *)
+                               (ALIGN((unsigned long)cur + align_offset, align)
+                                - align_offset);
                        delta = aligned - cur;
                }
                if (avail >= units + delta) { /* room enough? */
@@ -281,7 +298,8 @@ static void *slob_page_alloc(struct page *sp, size_t size, int align,
 /*
  * slob_alloc: entry point into the slob allocator.
  */
-static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
+static void *slob_alloc(size_t size, gfp_t gfp, int align, int node,
+                                                       int align_offset)
 {
        struct page *sp;
        struct list_head *slob_list;
@@ -312,7 +330,7 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
                if (sp->units < SLOB_UNITS(size))
                        continue;
 
-               b = slob_page_alloc(sp, size, align, &page_removed_from_list);
+               b = slob_page_alloc(sp, size, align, align_offset, &page_removed_from_list);
                if (!b)
                        continue;
 
@@ -349,7 +367,7 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
                INIT_LIST_HEAD(&sp->slab_list);
                set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
                set_slob_page_free(sp, slob_list);
-               b = slob_page_alloc(sp, size, align, &_unused);
+               b = slob_page_alloc(sp, size, align, align_offset, &_unused);
                BUG_ON(!b);
                spin_unlock_irqrestore(&slob_lock, flags);
        }
@@ -451,7 +469,7 @@ static __always_inline void *
 __do_kmalloc_node(size_t size, gfp_t gfp, int node, unsigned long caller)
 {
        unsigned int *m;
-       int align = max_t(size_t, ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+       int minalign = max_t(size_t, ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
        void *ret;
 
        gfp &= gfp_allowed_mask;
@@ -459,19 +477,28 @@ __do_kmalloc_node(size_t size, gfp_t gfp, int node, unsigned long caller)
        fs_reclaim_acquire(gfp);
        fs_reclaim_release(gfp);
 
-       if (size < PAGE_SIZE - align) {
+       if (size < PAGE_SIZE - minalign) {
+               int align = minalign;
+
+               /*
+                * For power of two sizes, guarantee natural alignment for
+                * kmalloc()'d objects.
+                */
+               if (is_power_of_2(size))
+                       align = max(minalign, (int) size);
+
                if (!size)
                        return ZERO_SIZE_PTR;
 
-               m = slob_alloc(size + align, gfp, align, node);
+               m = slob_alloc(size + minalign, gfp, align, node, minalign);
 
                if (!m)
                        return NULL;
                *m = size;
-               ret = (void *)m + align;
+               ret = (void *)m + minalign;
 
                trace_kmalloc_node(caller, ret,
-                                  size, size + align, gfp, node);
+                                  size, size + minalign, gfp, node);
        } else {
                unsigned int order = get_order(size);
 
@@ -521,8 +548,13 @@ void kfree(const void *block)
                int align = max_t(size_t, ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
                unsigned int *m = (unsigned int *)(block - align);
                slob_free(m, *m + align);
-       } else
-               __free_pages(sp, compound_order(sp));
+       } else {
+               unsigned int order = compound_order(sp);
+               mod_node_page_state(page_pgdat(sp), NR_SLAB_UNRECLAIMABLE,
+                                   -(1 << order));
+               __free_pages(sp, order);
+
+       }
 }
 EXPORT_SYMBOL(kfree);
 
@@ -567,7 +599,7 @@ static void *slob_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
        fs_reclaim_release(flags);
 
        if (c->size < PAGE_SIZE) {
-               b = slob_alloc(c->size, flags, c->align, node);
+               b = slob_alloc(c->size, flags, c->align, node, 0);
                trace_kmem_cache_alloc_node(_RET_IP_, b, c->object_size,
                                            SLOB_UNITS(c->size) * SLOB_UNIT,
                                            flags, node);
index 42c1b3a..3d63ae3 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3821,11 +3821,15 @@ static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
 {
        struct page *page;
        void *ptr = NULL;
+       unsigned int order = get_order(size);
 
        flags |= __GFP_COMP;
-       page = alloc_pages_node(node, flags, get_order(size));
-       if (page)
+       page = alloc_pages_node(node, flags, order);
+       if (page) {
                ptr = page_address(page);
+               mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE,
+                                   1 << order);
+       }
 
        return kmalloc_large_node_hook(ptr, size, flags);
 }
@@ -3951,9 +3955,13 @@ void kfree(const void *x)
 
        page = virt_to_head_page(x);
        if (unlikely(!PageSlab(page))) {
+               unsigned int order = compound_order(page);
+
                BUG_ON(!PageCompound(page));
                kfree_hook(object);
-               __free_pages(page, compound_order(page));
+               mod_node_page_state(page_pgdat(page), NR_SLAB_UNRECLAIMABLE,
+                                   -(1 << order));
+               __free_pages(page, order);
                return;
        }
        slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_);
index bf32de9..f6891c1 100644 (file)
@@ -219,7 +219,7 @@ static inline unsigned long first_present_section_nr(void)
        return next_present_section_nr(-1);
 }
 
-void subsection_mask_set(unsigned long *map, unsigned long pfn,
+static void subsection_mask_set(unsigned long *map, unsigned long pfn,
                unsigned long nr_pages)
 {
        int idx = subsection_map_index(pfn);
index f3b5081..4bac22f 100644 (file)
@@ -355,6 +355,9 @@ void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio)
  * "hierarchy" or "local").
  *
  * To be used as memcg event method.
+ *
+ * Return: 0 on success, -ENOMEM on memory failure or -EINVAL if @args could
+ * not be parsed.
  */
 int vmpressure_register_event(struct mem_cgroup *memcg,
                              struct eventfd_ctx *eventfd, const char *args)
@@ -362,7 +365,7 @@ int vmpressure_register_event(struct mem_cgroup *memcg,
        struct vmpressure *vmpr = memcg_to_vmpressure(memcg);
        struct vmpressure_event *ev;
        enum vmpressure_modes mode = VMPRESSURE_NO_PASSTHROUGH;
-       enum vmpressure_levels level = -1;
+       enum vmpressure_levels level;
        char *spec, *spec_orig;
        char *token;
        int ret = 0;
@@ -375,20 +378,18 @@ int vmpressure_register_event(struct mem_cgroup *memcg,
 
        /* Find required level */
        token = strsep(&spec, ",");
-       level = match_string(vmpressure_str_levels, VMPRESSURE_NUM_LEVELS, token);
-       if (level < 0) {
-               ret = level;
+       ret = match_string(vmpressure_str_levels, VMPRESSURE_NUM_LEVELS, token);
+       if (ret < 0)
                goto out;
-       }
+       level = ret;
 
        /* Find optional mode */
        token = strsep(&spec, ",");
        if (token) {
-               mode = match_string(vmpressure_str_modes, VMPRESSURE_NUM_MODES, token);
-               if (mode < 0) {
-                       ret = mode;
+               ret = match_string(vmpressure_str_modes, VMPRESSURE_NUM_MODES, token);
+               if (ret < 0)
                        goto out;
-               }
+               mode = ret;
        }
 
        ev = kzalloc(sizeof(*ev), GFP_KERNEL);
@@ -404,6 +405,7 @@ int vmpressure_register_event(struct mem_cgroup *memcg,
        mutex_lock(&vmpr->events_lock);
        list_add(&ev->node, &vmpr->events);
        mutex_unlock(&vmpr->events_lock);
+       ret = 0;
 out:
        kfree(spec_orig);
        return ret;
index e5d52d6..c6659bb 100644 (file)
@@ -2459,17 +2459,70 @@ out:
        *lru_pages = 0;
        for_each_evictable_lru(lru) {
                int file = is_file_lru(lru);
-               unsigned long size;
+               unsigned long lruvec_size;
                unsigned long scan;
+               unsigned long protection;
+
+               lruvec_size = lruvec_lru_size(lruvec, lru, sc->reclaim_idx);
+               protection = mem_cgroup_protection(memcg,
+                                                  sc->memcg_low_reclaim);
+
+               if (protection) {
+                       /*
+                        * Scale a cgroup's reclaim pressure by proportioning
+                        * its current usage to its memory.low or memory.min
+                        * setting.
+                        *
+                        * This is important, as otherwise scanning aggression
+                        * becomes extremely binary -- from nothing as we
+                        * approach the memory protection threshold, to totally
+                        * nominal as we exceed it.  This results in requiring
+                        * setting extremely liberal protection thresholds. It
+                        * also means we simply get no protection at all if we
+                        * set it too low, which is not ideal.
+                        *
+                        * If there is any protection in place, we reduce scan
+                        * pressure by how much of the total memory used is
+                        * within protection thresholds.
+                        *
+                        * There is one special case: in the first reclaim pass,
+                        * we skip over all groups that are within their low
+                        * protection. If that fails to reclaim enough pages to
+                        * satisfy the reclaim goal, we come back and override
+                        * the best-effort low protection. However, we still
+                        * ideally want to honor how well-behaved groups are in
+                        * that case instead of simply punishing them all
+                        * equally. As such, we reclaim them based on how much
+                        * memory they are using, reducing the scan pressure
+                        * again by how much of the total memory used is under
+                        * hard protection.
+                        */
+                       unsigned long cgroup_size = mem_cgroup_size(memcg);
+
+                       /* Avoid TOCTOU with earlier protection check */
+                       cgroup_size = max(cgroup_size, protection);
+
+                       scan = lruvec_size - lruvec_size * protection /
+                               cgroup_size;
+
+                       /*
+                        * Minimally target SWAP_CLUSTER_MAX pages to keep
+                        * reclaim moving forwards, avoiding decremeting
+                        * sc->priority further than desirable.
+                        */
+                       scan = max(scan, SWAP_CLUSTER_MAX);
+               } else {
+                       scan = lruvec_size;
+               }
+
+               scan >>= sc->priority;
 
-               size = lruvec_lru_size(lruvec, lru, sc->reclaim_idx);
-               scan = size >> sc->priority;
                /*
                 * If the cgroup's already been deleted, make sure to
                 * scrape out the remaining cache.
                 */
                if (!scan && !mem_cgroup_online(memcg))
-                       scan = min(size, SWAP_CLUSTER_MAX);
+                       scan = min(lruvec_size, SWAP_CLUSTER_MAX);
 
                switch (scan_balance) {
                case SCAN_EQUAL:
@@ -2489,7 +2542,7 @@ out:
                case SCAN_ANON:
                        /* Scan one type exclusively */
                        if ((scan_balance == SCAN_FILE) != file) {
-                               size = 0;
+                               lruvec_size = 0;
                                scan = 0;
                        }
                        break;
@@ -2498,7 +2551,7 @@ out:
                        BUG();
                }
 
-               *lru_pages += size;
+               *lru_pages += lruvec_size;
                nr[lru] = scan;
        }
 }
@@ -2742,6 +2795,13 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc)
                                memcg_memory_event(memcg, MEMCG_LOW);
                                break;
                        case MEMCG_PROT_NONE:
+                               /*
+                                * All protection thresholds breached. We may
+                                * still choose to vary the scan pressure
+                                * applied based on by how much the cgroup in
+                                * question has exceeded its protection
+                                * thresholds (see get_scan_count).
+                                */
                                break;
                        }
 
index 05bdf90..6d3d3f6 100644 (file)
@@ -998,9 +998,11 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
        struct z3fold_header *zhdr;
        struct page *page;
        enum buddy bud;
+       bool page_claimed;
 
        zhdr = handle_to_z3fold_header(handle);
        page = virt_to_page(zhdr);
+       page_claimed = test_and_set_bit(PAGE_CLAIMED, &page->private);
 
        if (test_bit(PAGE_HEADLESS, &page->private)) {
                /* if a headless page is under reclaim, just leave.
@@ -1008,7 +1010,7 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
                 * has not been set before, we release this page
                 * immediately so we don't care about its value any more.
                 */
-               if (!test_and_set_bit(PAGE_CLAIMED, &page->private)) {
+               if (!page_claimed) {
                        spin_lock(&pool->lock);
                        list_del(&page->lru);
                        spin_unlock(&pool->lock);
@@ -1044,13 +1046,15 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
                atomic64_dec(&pool->pages_nr);
                return;
        }
-       if (test_bit(PAGE_CLAIMED, &page->private)) {
+       if (page_claimed) {
+               /* the page has not been claimed by us */
                z3fold_page_unlock(zhdr);
                return;
        }
        if (unlikely(PageIsolated(page)) ||
            test_and_set_bit(NEEDS_COMPACTING, &page->private)) {
                z3fold_page_unlock(zhdr);
+               clear_bit(PAGE_CLAIMED, &page->private);
                return;
        }
        if (zhdr->cpu < 0 || !cpu_online(zhdr->cpu)) {
@@ -1060,10 +1064,12 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
                zhdr->cpu = -1;
                kref_get(&zhdr->refcount);
                do_compact_page(zhdr, true);
+               clear_bit(PAGE_CLAIMED, &page->private);
                return;
        }
        kref_get(&zhdr->refcount);
        queue_work_on(zhdr->cpu, pool->compact_wq, &zhdr->work);
+       clear_bit(PAGE_CLAIMED, &page->private);
        z3fold_page_unlock(zhdr);
 }
 
index a1146cb..9cbed6f 100644 (file)
@@ -436,7 +436,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
        /* clean the netfilter state now that the batman-adv header has been
         * removed
         */
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
                goto dropped;
index e48680e..f80151e 100644 (file)
@@ -3172,7 +3172,7 @@ static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
                                                    NETLINK_CB(cb->skb).portid,
                                                    cb->nlh->nlmsg_seq,
                                                    NLM_F_MULTI);
-                       if (err) {
+                       if (err && err != -EOPNOTSUPP) {
                                mutex_unlock(&devlink->lock);
                                goto out;
                        }
@@ -3432,7 +3432,7 @@ static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
                                                NETLINK_CB(cb->skb).portid,
                                                cb->nlh->nlmsg_seq,
                                                NLM_F_MULTI);
-                               if (err) {
+                               if (err && err != -EOPNOTSUPP) {
                                        mutex_unlock(&devlink->lock);
                                        goto out;
                                }
@@ -4088,7 +4088,7 @@ static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
                                           cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                           cb->extack);
                mutex_unlock(&devlink->lock);
-               if (err)
+               if (err && err != -EOPNOTSUPP)
                        break;
                idx++;
        }
index 01d6520..5291336 100644 (file)
@@ -5120,7 +5120,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
        skb->ignore_df = 0;
        skb_dst_drop(skb);
        skb_ext_reset(skb);
-       nf_reset(skb);
+       nf_reset_ct(skb);
        nf_reset_trace(skb);
 
 #ifdef CONFIG_NET_SWITCHDEV
index 07863ed..fac2b4d 100644 (file)
@@ -1700,8 +1700,6 @@ static void __sk_destruct(struct rcu_head *head)
                sk_filter_uncharge(sk, filter);
                RCU_INIT_POINTER(sk->sk_filter, NULL);
        }
-       if (rcu_access_pointer(sk->sk_reuseport_cb))
-               reuseport_detach_sock(sk);
 
        sock_disable_timestamp(sk, SK_FLAGS_TIMESTAMP);
 
@@ -1728,7 +1726,14 @@ static void __sk_destruct(struct rcu_head *head)
 
 void sk_destruct(struct sock *sk)
 {
-       if (sock_flag(sk, SOCK_RCU_FREE))
+       bool use_call_rcu = sock_flag(sk, SOCK_RCU_FREE);
+
+       if (rcu_access_pointer(sk->sk_reuseport_cb)) {
+               reuseport_detach_sock(sk);
+               use_call_rcu = true;
+       }
+
+       if (use_call_rcu)
                call_rcu(&sk->sk_rcu, __sk_destruct);
        else
                __sk_destruct(&sk->sk_rcu);
@@ -3492,7 +3497,7 @@ static long sock_prot_memory_allocated(struct proto *proto)
        return proto->memory_allocated != NULL ? proto_memory_allocated(proto) : -1L;
 }
 
-static char *sock_prot_memory_pressure(struct proto *proto)
+static const char *sock_prot_memory_pressure(struct proto *proto)
 {
        return proto->memory_pressure != NULL ?
        proto_memory_pressure(proto) ? "yes" : "no" : "NI";
index b685bc8..d9b4200 100644 (file)
@@ -871,7 +871,7 @@ lookup:
 
        if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_and_relse;
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4, refcounted);
 
index 9c9aff3..63ef2a1 100644 (file)
@@ -156,7 +156,11 @@ static struct sk_buff
        /* Step 1: A timestampable frame was received.
         * Buffer it until we get its meta frame.
         */
-       if (is_link_local && sp->data->hwts_rx_en) {
+       if (is_link_local) {
+               if (!test_bit(SJA1105_HWTS_RX_EN, &sp->data->state))
+                       /* Do normal processing. */
+                       return skb;
+
                spin_lock(&sp->data->meta_lock);
                /* Was this a link-local frame instead of the meta
                 * that we were expecting?
@@ -187,6 +191,12 @@ static struct sk_buff
        } else if (is_meta) {
                struct sk_buff *stampable_skb;
 
+               /* Drop the meta frame if we're not in the right state
+                * to process it.
+                */
+               if (!test_bit(SJA1105_HWTS_RX_EN, &sp->data->state))
+                       return NULL;
+
                spin_lock(&sp->data->meta_lock);
 
                stampable_skb = sp->data->stampable_skb;
index a53a543..52690bb 100644 (file)
@@ -1446,6 +1446,7 @@ static void erspan_setup(struct net_device *dev)
        struct ip_tunnel *t = netdev_priv(dev);
 
        ether_setup(dev);
+       dev->max_mtu = 0;
        dev->netdev_ops = &erspan_netdev_ops;
        dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
index 1e2392b..c59a78a 100644 (file)
@@ -199,7 +199,7 @@ resubmit:
                                kfree_skb(skb);
                                return;
                        }
-                       nf_reset(skb);
+                       nf_reset_ct(skb);
                }
                ret = INDIRECT_CALL_2(ipprot->handler, tcp_v4_rcv, udp_rcv,
                                      skb);
index 313470f..716d547 100644 (file)
@@ -1794,7 +1794,7 @@ static void ip_encap(struct net *net, struct sk_buff *skb,
        ip_send_check(iph);
 
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-       nf_reset(skb);
+       nf_reset_ct(skb);
 }
 
 static inline int ipmr_forward_finish(struct net *net, struct sock *sk,
@@ -2140,7 +2140,7 @@ int ip_mr_input(struct sk_buff *skb)
 
                        mroute_sk = rcu_dereference(mrt->mroute_sk);
                        if (mroute_sk) {
-                               nf_reset(skb);
+                               nf_reset_ct(skb);
                                raw_rcv(mroute_sk, skb);
                                return 0;
                        }
index af3fbf7..6cc5743 100644 (file)
@@ -65,7 +65,7 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum,
 
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
        /* Avoid counting cloned packets towards the original connection. */
-       nf_reset(skb);
+       nf_reset_ct(skb);
        nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
 #endif
        /*
index 80da5a6..3183413 100644 (file)
@@ -332,7 +332,7 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb)
                kfree_skb(skb);
                return NET_RX_DROP;
        }
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        skb_push(skb, skb->data - skb_network_header(skb));
 
index 7dcce72..1465487 100644 (file)
@@ -916,16 +916,15 @@ void ip_rt_send_redirect(struct sk_buff *skb)
        if (peer->rate_tokens == 0 ||
            time_after(jiffies,
                       (peer->rate_last +
-                       (ip_rt_redirect_load << peer->rate_tokens)))) {
+                       (ip_rt_redirect_load << peer->n_redirects)))) {
                __be32 gw = rt_nexthop(rt, ip_hdr(skb)->daddr);
 
                icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw);
                peer->rate_last = jiffies;
-               ++peer->rate_tokens;
                ++peer->n_redirects;
 #ifdef CONFIG_IP_ROUTE_VERBOSE
                if (log_martians &&
-                   peer->rate_tokens == ip_rt_redirect_number)
+                   peer->n_redirects == ip_rt_redirect_number)
                        net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n",
                                             &ip_hdr(skb)->saddr, inet_iif(skb),
                                             &ip_hdr(skb)->daddr, &gw);
index 79c325a..f98a188 100644 (file)
@@ -1798,13 +1798,11 @@ static int tcp_zerocopy_receive(struct sock *sk,
                }
                if (skb_frag_size(frags) != PAGE_SIZE || skb_frag_off(frags)) {
                        int remaining = zc->recv_skip_hint;
-                       int size = skb_frag_size(frags);
 
-                       while (remaining && (size != PAGE_SIZE ||
+                       while (remaining && (skb_frag_size(frags) != PAGE_SIZE ||
                                             skb_frag_off(frags))) {
-                               remaining -= size;
+                               remaining -= skb_frag_size(frags);
                                frags++;
-                               size = skb_frag_size(frags);
                        }
                        zc->recv_skip_hint -= remaining;
                        break;
index 2ee45e3..bf124b1 100644 (file)
@@ -1916,7 +1916,7 @@ process:
        if (tcp_v4_inbound_md5_hash(sk, skb))
                goto discard_and_relse;
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        if (tcp_filter(sk, skb))
                goto discard_and_relse;
index 40de2d2..05be564 100644 (file)
@@ -198,8 +198,13 @@ static bool retransmits_timed_out(struct sock *sk,
                return false;
 
        start_ts = tcp_sk(sk)->retrans_stamp;
-       if (likely(timeout == 0))
-               timeout = tcp_model_timeout(sk, boundary, TCP_RTO_MIN);
+       if (likely(timeout == 0)) {
+               unsigned int rto_base = TCP_RTO_MIN;
+
+               if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))
+                       rto_base = tcp_timeout_init(sk);
+               timeout = tcp_model_timeout(sk, boundary, rto_base);
+       }
 
        return (s32)(tcp_time_stamp(tcp_sk(sk)) - start_ts - timeout) >= 0;
 }
index cf75515..14bc654 100644 (file)
@@ -821,6 +821,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
        int is_udplite = IS_UDPLITE(sk);
        int offset = skb_transport_offset(skb);
        int len = skb->len - offset;
+       int datalen = len - sizeof(*uh);
        __wsum csum = 0;
 
        /*
@@ -854,10 +855,12 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
                        return -EIO;
                }
 
-               skb_shinfo(skb)->gso_size = cork->gso_size;
-               skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
-               skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(len - sizeof(uh),
-                                                        cork->gso_size);
+               if (datalen > cork->gso_size) {
+                       skb_shinfo(skb)->gso_size = cork->gso_size;
+                       skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
+                       skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
+                                                                cork->gso_size);
+               }
                goto csum_partial;
        }
 
@@ -1969,7 +1972,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
         */
        if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
                goto drop;
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        if (static_branch_unlikely(&udp_encap_needed_key) && up->encap_type) {
                int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
@@ -2298,7 +2301,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
                goto drop;
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        /* No socket. Drop packet silently, if checksum is wrong */
        if (udp_lib_checksum_complete(skb))
index 6a576ff..34ccef1 100644 (file)
@@ -5964,13 +5964,20 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
        switch (event) {
        case RTM_NEWADDR:
                /*
-                * If the address was optimistic
-                * we inserted the route at the start of
-                * our DAD process, so we don't need
-                * to do it again
+                * If the address was optimistic we inserted the route at the
+                * start of our DAD process, so we don't need to do it again.
+                * If the device was taken down in the middle of the DAD
+                * cycle there is a race where we could get here without a
+                * host route, so nothing to insert. That will be fixed when
+                * the device is brought up.
                 */
-               if (!rcu_access_pointer(ifp->rt->fib6_node))
+               if (ifp->rt && !rcu_access_pointer(ifp->rt->fib6_node)) {
                        ip6_ins_rt(net, ifp->rt);
+               } else if (!ifp->rt && (ifp->idev->dev->flags & IFF_UP)) {
+                       pr_warn("BUG: Address %pI6c on device %s is missing its host route.\n",
+                               &ifp->addr, ifp->idev->dev->name);
+               }
+
                if (ifp->idev->cnf.forwarding)
                        addrconf_join_anycast(ifp);
                if (!ipv6_addr_any(&ifp->peer_addr))
index d432d00..3d71c7d 100644 (file)
@@ -223,6 +223,16 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
        if (ipv6_addr_is_multicast(&hdr->saddr))
                goto err;
 
+       /* While RFC4291 is not explicit about v4mapped addresses
+        * in IPv6 headers, it seems clear linux dual-stack
+        * model can not deal properly with these.
+        * Security models could be fooled by ::ffff:127.0.0.1 for example.
+        *
+        * https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02
+        */
+       if (ipv6_addr_v4mapped(&hdr->saddr))
+               goto err;
+
        skb->transport_header = skb->network_header + sizeof(*hdr);
        IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
 
@@ -371,7 +381,7 @@ resubmit_final:
                        /* Free reference early: we don't need it any more,
                           and it may hold ip_conntrack module loaded
                           indefinitely. */
-                       nf_reset(skb);
+                       nf_reset_ct(skb);
 
                        skb_postpull_rcsum(skb, skb_network_header(skb),
                                           skb_network_header_len(skb));
index e6c9da9..a0a2de3 100644 (file)
@@ -54,7 +54,7 @@ void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum,
                return;
 
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
-       nf_reset(skb);
+       nf_reset_ct(skb);
        nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
 #endif
        if (hooknum == NF_INET_PRE_ROUTING ||
index 6e1888e..a77f6b7 100644 (file)
@@ -215,7 +215,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
 
                        /* Not releasing hash table! */
                        if (clone) {
-                               nf_reset(clone);
+                               nf_reset_ct(clone);
                                rawv6_rcv(sk, clone);
                        }
                }
index aae4938..6324d3a 100644 (file)
@@ -1109,6 +1109,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
        __wsum csum = 0;
        int offset = skb_transport_offset(skb);
        int len = skb->len - offset;
+       int datalen = len - sizeof(*uh);
 
        /*
         * Create a UDP header
@@ -1141,8 +1142,12 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
                        return -EIO;
                }
 
-               skb_shinfo(skb)->gso_size = cork->gso_size;
-               skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
+               if (datalen > cork->gso_size) {
+                       skb_shinfo(skb)->gso_size = cork->gso_size;
+                       skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
+                       skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
+                                                                cork->gso_size);
+               }
                goto csum_partial;
        }
 
index 105e5a7..f82ea12 100644 (file)
@@ -1078,7 +1078,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
        IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
                              IPSKB_REROUTED);
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        bh_lock_sock(sk);
        if (sock_owned_by_user(sk)) {
index bd3f393..fd5ac27 100644 (file)
@@ -151,7 +151,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
        skb->ip_summed = CHECKSUM_NONE;
 
        skb_dst_drop(skb);
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        rcu_read_lock();
        dev = rcu_dereference(spriv->dev);
index 6228333..0d7c887 100644 (file)
@@ -193,7 +193,7 @@ pass_up:
        if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_put;
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        return sk_receive_skb(sk, skb, 1);
 
index 687e23a..802f19a 100644 (file)
@@ -206,7 +206,7 @@ pass_up:
        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_put;
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        return sk_receive_skb(sk, skb, 1);
 
index b1438fd..64b544a 100644 (file)
@@ -487,9 +487,14 @@ static ssize_t ieee80211_if_fmt_aqm(
        const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 {
        struct ieee80211_local *local = sdata->local;
-       struct txq_info *txqi = to_txq_info(sdata->vif.txq);
+       struct txq_info *txqi;
        int len;
 
+       if (!sdata->vif.txq)
+               return 0;
+
+       txqi = to_txq_info(sdata->vif.txq);
+
        spin_lock_bh(&local->fq.lock);
        rcu_read_lock();
 
@@ -658,7 +663,9 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)
        DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz);
        DEBUGFS_ADD(hw_queues);
 
-       if (sdata->local->ops->wake_tx_queue)
+       if (sdata->local->ops->wake_tx_queue &&
+           sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
+           sdata->vif.type != NL80211_IFTYPE_NAN)
                DEBUGFS_ADD(aqm);
 }
 
index 051a02d..32a7a53 100644 (file)
@@ -247,7 +247,8 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
        struct sta_info *sta;
        int i;
 
-       spin_lock_bh(&fq->lock);
+       local_bh_disable();
+       spin_lock(&fq->lock);
 
        if (sdata->vif.type == NL80211_IFTYPE_AP)
                ps = &sdata->bss->ps;
@@ -273,9 +274,9 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
                                                &txqi->flags))
                                continue;
 
-                       spin_unlock_bh(&fq->lock);
+                       spin_unlock(&fq->lock);
                        drv_wake_tx_queue(local, txqi);
-                       spin_lock_bh(&fq->lock);
+                       spin_lock(&fq->lock);
                }
        }
 
@@ -288,12 +289,14 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
            (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac)
                goto out;
 
-       spin_unlock_bh(&fq->lock);
+       spin_unlock(&fq->lock);
 
        drv_wake_tx_queue(local, txqi);
+       local_bh_enable();
        return;
 out:
-       spin_unlock_bh(&fq->lock);
+       spin_unlock(&fq->lock);
+       local_bh_enable();
 }
 
 static void
index 9c464d2..888d306 100644 (file)
@@ -613,7 +613,7 @@ static inline int ip_vs_tunnel_xmit_prepare(struct sk_buff *skb,
        if (unlikely(cp->flags & IP_VS_CONN_F_NFCT))
                ret = ip_vs_confirm_conntrack(skb);
        if (ret == NF_ACCEPT) {
-               nf_reset(skb);
+               nf_reset_ct(skb);
                skb_forward_csum(skb);
        }
        return ret;
index af1497a..69d6173 100644 (file)
@@ -218,8 +218,13 @@ static void nft_connlimit_destroy_clone(const struct nft_ctx *ctx,
 static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr)
 {
        struct nft_connlimit *priv = nft_expr_priv(expr);
+       bool ret;
 
-       return nf_conncount_gc_list(net, &priv->list);
+       local_bh_disable();
+       ret = nf_conncount_gc_list(net, &priv->list);
+       local_bh_enable();
+
+       return ret;
 }
 
 static struct nft_expr_type nft_connlimit_type;
index 8dfea26..ccdd790 100644 (file)
@@ -107,9 +107,14 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
        llcp_sock->service_name = kmemdup(llcp_addr.service_name,
                                          llcp_sock->service_name_len,
                                          GFP_KERNEL);
-
+       if (!llcp_sock->service_name) {
+               ret = -ENOMEM;
+               goto put_dev;
+       }
        llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
        if (llcp_sock->ssap == LLCP_SAP_MAX) {
+               kfree(llcp_sock->service_name);
+               llcp_sock->service_name = NULL;
                ret = -EADDRINUSE;
                goto put_dev;
        }
index d2437b5..21c90d3 100644 (file)
@@ -237,7 +237,7 @@ static netdev_tx_t internal_dev_recv(struct sk_buff *skb)
        }
 
        skb_dst_drop(skb);
-       nf_reset(skb);
+       nf_reset_ct(skb);
        secpath_reset(skb);
 
        skb->pkt_type = PACKET_HOST;
index e2742b0..82a50e8 100644 (file)
@@ -1821,7 +1821,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,
        skb_dst_drop(skb);
 
        /* drop conntrack reference */
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        spkt = &PACKET_SKB_CB(skb)->sa.pkt;
 
@@ -2121,7 +2121,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
        skb_dst_drop(skb);
 
        /* drop conntrack reference */
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        spin_lock(&sk->sk_receive_queue.lock);
        po->stats.stats1.tp_packets++;
index 45acab2..9de2ae2 100644 (file)
@@ -143,6 +143,9 @@ static void rds_ib_add_one(struct ib_device *device)
        refcount_set(&rds_ibdev->refcount, 1);
        INIT_WORK(&rds_ibdev->free_work, rds_ib_dev_free);
 
+       INIT_LIST_HEAD(&rds_ibdev->ipaddr_list);
+       INIT_LIST_HEAD(&rds_ibdev->conn_list);
+
        rds_ibdev->max_wrs = device->attrs.max_qp_wr;
        rds_ibdev->max_sge = min(device->attrs.max_send_sge, RDS_IB_MAX_SGE);
 
@@ -203,9 +206,6 @@ static void rds_ib_add_one(struct ib_device *device)
                device->name,
                rds_ibdev->use_fastreg ? "FRMR" : "FMR");
 
-       INIT_LIST_HEAD(&rds_ibdev->ipaddr_list);
-       INIT_LIST_HEAD(&rds_ibdev->conn_list);
-
        down_write(&rds_ib_devices_lock);
        list_add_tail_rcu(&rds_ibdev->list, &rds_ib_devices);
        up_write(&rds_ib_devices_lock);
index 06c7a2d..39b427d 100644 (file)
@@ -1127,6 +1127,33 @@ static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = {
        [TCA_CBQ_POLICE]        = { .len = sizeof(struct tc_cbq_police) },
 };
 
+static int cbq_opt_parse(struct nlattr *tb[TCA_CBQ_MAX + 1],
+                        struct nlattr *opt,
+                        struct netlink_ext_ack *extack)
+{
+       int err;
+
+       if (!opt) {
+               NL_SET_ERR_MSG(extack, "CBQ options are required for this operation");
+               return -EINVAL;
+       }
+
+       err = nla_parse_nested_deprecated(tb, TCA_CBQ_MAX, opt,
+                                         cbq_policy, extack);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_CBQ_WRROPT]) {
+               const struct tc_cbq_wrropt *wrr = nla_data(tb[TCA_CBQ_WRROPT]);
+
+               if (wrr->priority > TC_CBQ_MAXPRIO) {
+                       NL_SET_ERR_MSG(extack, "priority is bigger than TC_CBQ_MAXPRIO");
+                       err = -EINVAL;
+               }
+       }
+       return err;
+}
+
 static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
                    struct netlink_ext_ack *extack)
 {
@@ -1139,13 +1166,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
        hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
        q->delay_timer.function = cbq_undelay;
 
-       if (!opt) {
-               NL_SET_ERR_MSG(extack, "CBQ options are required for this operation");
-               return -EINVAL;
-       }
-
-       err = nla_parse_nested_deprecated(tb, TCA_CBQ_MAX, opt, cbq_policy,
-                                         extack);
+       err = cbq_opt_parse(tb, opt, extack);
        if (err < 0)
                return err;
 
@@ -1464,13 +1485,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
        struct cbq_class *parent;
        struct qdisc_rate_table *rtab = NULL;
 
-       if (!opt) {
-               NL_SET_ERR_MSG(extack, "Mandatory qdisc options missing");
-               return -EINVAL;
-       }
-
-       err = nla_parse_nested_deprecated(tb, TCA_CBQ_MAX, opt, cbq_policy,
-                                         extack);
+       err = cbq_opt_parse(tb, opt, extack);
        if (err < 0)
                return err;
 
index 1bef152..b2905b0 100644 (file)
@@ -306,7 +306,7 @@ static void cbs_set_port_rate(struct net_device *dev, struct cbs_sched_data *q)
        if (err < 0)
                goto skip;
 
-       if (ecmd.base.speed != SPEED_UNKNOWN)
+       if (ecmd.base.speed && ecmd.base.speed != SPEED_UNKNOWN)
                speed = ecmd.base.speed;
 
 skip:
index bad1cbe..05605b3 100644 (file)
@@ -361,6 +361,8 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt,
                goto errout;
 
        err = -EINVAL;
+       if (!tb[TCA_DSMARK_INDICES])
+               goto errout;
        indices = nla_get_u16(tb[TCA_DSMARK_INDICES]);
 
        if (hweight32(indices) != 1)
index 2f7b342..68b543f 100644 (file)
@@ -1044,12 +1044,11 @@ static void taprio_set_picos_per_byte(struct net_device *dev,
        if (err < 0)
                goto skip;
 
-       if (ecmd.base.speed != SPEED_UNKNOWN)
+       if (ecmd.base.speed && ecmd.base.speed != SPEED_UNKNOWN)
                speed = ecmd.base.speed;
 
 skip:
-       picos_per_byte = div64_s64(NSEC_PER_SEC * 1000LL * 8,
-                                  speed * 1000 * 1000);
+       picos_per_byte = (USEC_PER_SEC * 8) / speed;
 
        atomic64_set(&q->picos_per_byte, picos_per_byte);
        netdev_dbg(dev, "taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
index 1008cdc..5a070fb 100644 (file)
@@ -201,7 +201,7 @@ int sctp_rcv(struct sk_buff *skb)
 
        if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
                goto discard_release;
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        if (sk_filter(sk, skb))
                goto discard_release;
index e41ed2e..48d6395 100644 (file)
@@ -2155,7 +2155,7 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
        case SCTP_PARAM_SET_PRIMARY:
                if (ep->asconf_enable)
                        break;
-               goto fallthrough;
+               goto unhandled;
 
        case SCTP_PARAM_HOST_NAME_ADDRESS:
                /* Tell the peer, we won't support this param.  */
@@ -2166,11 +2166,11 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
        case SCTP_PARAM_FWD_TSN_SUPPORT:
                if (ep->prsctp_enable)
                        break;
-               goto fallthrough;
+               goto unhandled;
 
        case SCTP_PARAM_RANDOM:
                if (!ep->auth_enable)
-                       goto fallthrough;
+                       goto unhandled;
 
                /* SCTP-AUTH: Secion 6.1
                 * If the random number is not 32 byte long the association
@@ -2187,7 +2187,7 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
 
        case SCTP_PARAM_CHUNKS:
                if (!ep->auth_enable)
-                       goto fallthrough;
+                       goto unhandled;
 
                /* SCTP-AUTH: Section 3.2
                 * The CHUNKS parameter MUST be included once in the INIT or
@@ -2203,7 +2203,7 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
 
        case SCTP_PARAM_HMAC_ALGO:
                if (!ep->auth_enable)
-                       goto fallthrough;
+                       goto unhandled;
 
                hmacs = (struct sctp_hmac_algo_param *)param.p;
                n_elt = (ntohs(param.p->length) -
@@ -2226,7 +2226,7 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
                        retval = SCTP_IERROR_ABORT;
                }
                break;
-fallthrough:
+unhandled:
        default:
                pr_debug("%s: unrecognized param:%d for chunk:%d\n",
                         __func__, ntohs(param.p->type), cid);
index 9ac8872..70e52f5 100644 (file)
@@ -1249,19 +1249,21 @@ static void xs_error_report(struct sock *sk)
 {
        struct sock_xprt *transport;
        struct rpc_xprt *xprt;
-       int err;
 
        read_lock_bh(&sk->sk_callback_lock);
        if (!(xprt = xprt_from_sock(sk)))
                goto out;
 
        transport = container_of(xprt, struct sock_xprt, xprt);
-       err = -sk->sk_err;
-       if (err == 0)
+       transport->xprt_err = -sk->sk_err;
+       if (transport->xprt_err == 0)
                goto out;
        dprintk("RPC:       xs_error_report client %p, error=%d...\n",
-                       xprt, -err);
-       trace_rpc_socket_error(xprt, sk->sk_socket, err);
+                       xprt, -transport->xprt_err);
+       trace_rpc_socket_error(xprt, sk->sk_socket, transport->xprt_err);
+
+       /* barrier ensures xprt_err is set before XPRT_SOCK_WAKE_ERROR */
+       smp_mb__before_atomic();
        xs_run_error_worker(transport, XPRT_SOCK_WAKE_ERROR);
  out:
        read_unlock_bh(&sk->sk_callback_lock);
@@ -2476,7 +2478,6 @@ static void xs_wake_write(struct sock_xprt *transport)
 static void xs_wake_error(struct sock_xprt *transport)
 {
        int sockerr;
-       int sockerr_len = sizeof(sockerr);
 
        if (!test_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state))
                return;
@@ -2485,9 +2486,7 @@ static void xs_wake_error(struct sock_xprt *transport)
                goto out;
        if (!test_and_clear_bit(XPRT_SOCK_WAKE_ERROR, &transport->sock_state))
                goto out;
-       if (kernel_getsockopt(transport->sock, SOL_SOCKET, SO_ERROR,
-                               (char *)&sockerr, &sockerr_len) != 0)
-               goto out;
+       sockerr = xchg(&transport->xprt_err, 0);
        if (sockerr < 0)
                xprt_wake_pending_tasks(&transport->xprt, sockerr);
 out:
index 6cc75ff..999eab5 100644 (file)
@@ -160,6 +160,7 @@ struct tipc_link {
        struct {
                u16 len;
                u16 limit;
+               struct sk_buff *target_bskb;
        } backlog[5];
        u16 snd_nxt;
        u16 window;
@@ -880,6 +881,7 @@ static void link_prepare_wakeup(struct tipc_link *l)
 void tipc_link_reset(struct tipc_link *l)
 {
        struct sk_buff_head list;
+       u32 imp;
 
        __skb_queue_head_init(&list);
 
@@ -901,11 +903,10 @@ void tipc_link_reset(struct tipc_link *l)
        __skb_queue_purge(&l->deferdq);
        __skb_queue_purge(&l->backlogq);
        __skb_queue_purge(&l->failover_deferdq);
-       l->backlog[TIPC_LOW_IMPORTANCE].len = 0;
-       l->backlog[TIPC_MEDIUM_IMPORTANCE].len = 0;
-       l->backlog[TIPC_HIGH_IMPORTANCE].len = 0;
-       l->backlog[TIPC_CRITICAL_IMPORTANCE].len = 0;
-       l->backlog[TIPC_SYSTEM_IMPORTANCE].len = 0;
+       for (imp = 0; imp <= TIPC_SYSTEM_IMPORTANCE; imp++) {
+               l->backlog[imp].len = 0;
+               l->backlog[imp].target_bskb = NULL;
+       }
        kfree_skb(l->reasm_buf);
        kfree_skb(l->reasm_tnlmsg);
        kfree_skb(l->failover_reasm_skb);
@@ -947,7 +948,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
        u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1;
        struct sk_buff_head *transmq = &l->transmq;
        struct sk_buff_head *backlogq = &l->backlogq;
-       struct sk_buff *skb, *_skb, *bskb;
+       struct sk_buff *skb, *_skb, **tskb;
        int pkt_cnt = skb_queue_len(list);
        int rc = 0;
 
@@ -999,19 +1000,21 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
                        seqno++;
                        continue;
                }
-               if (tipc_msg_bundle(skb_peek_tail(backlogq), hdr, mtu)) {
+               tskb = &l->backlog[imp].target_bskb;
+               if (tipc_msg_bundle(*tskb, hdr, mtu)) {
                        kfree_skb(__skb_dequeue(list));
                        l->stats.sent_bundled++;
                        continue;
                }
-               if (tipc_msg_make_bundle(&bskb, hdr, mtu, l->addr)) {
+               if (tipc_msg_make_bundle(tskb, hdr, mtu, l->addr)) {
                        kfree_skb(__skb_dequeue(list));
-                       __skb_queue_tail(backlogq, bskb);
-                       l->backlog[msg_importance(buf_msg(bskb))].len++;
+                       __skb_queue_tail(backlogq, *tskb);
+                       l->backlog[imp].len++;
                        l->stats.sent_bundled++;
                        l->stats.sent_bundles++;
                        continue;
                }
+               l->backlog[imp].target_bskb = NULL;
                l->backlog[imp].len += skb_queue_len(list);
                skb_queue_splice_tail_init(list, backlogq);
        }
@@ -1027,6 +1030,7 @@ static void tipc_link_advance_backlog(struct tipc_link *l,
        u16 seqno = l->snd_nxt;
        u16 ack = l->rcv_nxt - 1;
        u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1;
+       u32 imp;
 
        while (skb_queue_len(&l->transmq) < l->window) {
                skb = skb_peek(&l->backlogq);
@@ -1037,7 +1041,10 @@ static void tipc_link_advance_backlog(struct tipc_link *l,
                        break;
                __skb_dequeue(&l->backlogq);
                hdr = buf_msg(skb);
-               l->backlog[msg_importance(hdr)].len--;
+               imp = msg_importance(hdr);
+               l->backlog[imp].len--;
+               if (unlikely(skb == l->backlog[imp].target_bskb))
+                       l->backlog[imp].target_bskb = NULL;
                __skb_queue_tail(&l->transmq, skb);
                /* next retransmit attempt */
                if (link_is_bc_sndlink(l))
index e6d49cd..922d262 100644 (file)
@@ -543,10 +543,7 @@ bool tipc_msg_make_bundle(struct sk_buff **skb,  struct tipc_msg *msg,
        bmsg = buf_msg(_skb);
        tipc_msg_init(msg_prevnode(msg), bmsg, MSG_BUNDLER, 0,
                      INT_H_SIZE, dnode);
-       if (msg_isdata(msg))
-               msg_set_importance(bmsg, TIPC_CRITICAL_IMPORTANCE);
-       else
-               msg_set_importance(bmsg, TIPC_SYSTEM_IMPORTANCE);
+       msg_set_importance(bmsg, msg_importance(msg));
        msg_set_seqno(bmsg, msg_seqno(msg));
        msg_set_ack(bmsg, msg_ack(msg));
        msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
index ab47bf3..2ab43b2 100644 (file)
@@ -638,7 +638,7 @@ struct sock *__vsock_create(struct net *net,
 }
 EXPORT_SYMBOL_GPL(__vsock_create);
 
-static void __vsock_release(struct sock *sk)
+static void __vsock_release(struct sock *sk, int level)
 {
        if (sk) {
                struct sk_buff *skb;
@@ -648,9 +648,17 @@ static void __vsock_release(struct sock *sk)
                vsk = vsock_sk(sk);
                pending = NULL; /* Compiler warning. */
 
+               /* The release call is supposed to use lock_sock_nested()
+                * rather than lock_sock(), if a sock lock should be acquired.
+                */
                transport->release(vsk);
 
-               lock_sock(sk);
+               /* When "level" is SINGLE_DEPTH_NESTING, use the nested
+                * version to avoid the warning "possible recursive locking
+                * detected". When "level" is 0, lock_sock_nested(sk, level)
+                * is the same as lock_sock(sk).
+                */
+               lock_sock_nested(sk, level);
                sock_orphan(sk);
                sk->sk_shutdown = SHUTDOWN_MASK;
 
@@ -659,7 +667,7 @@ static void __vsock_release(struct sock *sk)
 
                /* Clean up any sockets that never were accepted. */
                while ((pending = vsock_dequeue_accept(sk)) != NULL) {
-                       __vsock_release(pending);
+                       __vsock_release(pending, SINGLE_DEPTH_NESTING);
                        sock_put(pending);
                }
 
@@ -708,7 +716,7 @@ EXPORT_SYMBOL_GPL(vsock_stream_has_space);
 
 static int vsock_release(struct socket *sock)
 {
-       __vsock_release(sock->sk);
+       __vsock_release(sock->sk, 0);
        sock->sk = NULL;
        sock->state = SS_FREE;
 
index 261521d..c443db7 100644 (file)
@@ -559,7 +559,7 @@ static void hvs_release(struct vsock_sock *vsk)
        struct sock *sk = sk_vsock(vsk);
        bool remove_sock;
 
-       lock_sock(sk);
+       lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
        remove_sock = hvs_close_lock_held(vsk);
        release_sock(sk);
        if (remove_sock)
index 5bb70c6..a666ef8 100644 (file)
@@ -820,7 +820,7 @@ void virtio_transport_release(struct vsock_sock *vsk)
        struct sock *sk = &vsk->sk;
        bool remove_sock = true;
 
-       lock_sock(sk);
+       lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
        if (sk->sk_type == SOCK_STREAM)
                remove_sock = virtio_transport_close(vsk);
 
index d21b158..141cdb1 100644 (file)
@@ -201,6 +201,38 @@ cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
        return __cfg80211_rdev_from_attrs(netns, info->attrs);
 }
 
+static int validate_beacon_head(const struct nlattr *attr,
+                               struct netlink_ext_ack *extack)
+{
+       const u8 *data = nla_data(attr);
+       unsigned int len = nla_len(attr);
+       const struct element *elem;
+       const struct ieee80211_mgmt *mgmt = (void *)data;
+       unsigned int fixedlen = offsetof(struct ieee80211_mgmt,
+                                        u.beacon.variable);
+
+       if (len < fixedlen)
+               goto err;
+
+       if (ieee80211_hdrlen(mgmt->frame_control) !=
+           offsetof(struct ieee80211_mgmt, u.beacon))
+               goto err;
+
+       data += fixedlen;
+       len -= fixedlen;
+
+       for_each_element(elem, data, len) {
+               /* nothing */
+       }
+
+       if (for_each_element_completed(elem, data, len))
+               return 0;
+
+err:
+       NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
+       return -EINVAL;
+}
+
 static int validate_ie_attr(const struct nlattr *attr,
                            struct netlink_ext_ack *extack)
 {
@@ -338,8 +370,9 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 
        [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
        [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
-       [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
-                                      .len = IEEE80211_MAX_DATA_LEN },
+       [NL80211_ATTR_BEACON_HEAD] =
+               NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
+                                      IEEE80211_MAX_DATA_LEN),
        [NL80211_ATTR_BEACON_TAIL] =
                NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
                                       IEEE80211_MAX_DATA_LEN),
@@ -2636,6 +2669,8 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
 
        control_freq = nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]);
 
+       memset(chandef, 0, sizeof(*chandef));
+
        chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
        chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
        chandef->center_freq1 = control_freq;
@@ -3176,7 +3211,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
 
        if (rdev->ops->get_channel) {
                int ret;
-               struct cfg80211_chan_def chandef;
+               struct cfg80211_chan_def chandef = {};
 
                ret = rdev_get_channel(rdev, wdev, &chandef);
                if (ret == 0) {
@@ -6270,6 +6305,9 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->del_mpath)
                return -EOPNOTSUPP;
 
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
+               return -EOPNOTSUPP;
+
        return rdev_del_mpath(rdev, dev, dst);
 }
 
index 5311d0a..420c420 100644 (file)
@@ -2108,7 +2108,7 @@ static void reg_call_notifier(struct wiphy *wiphy,
 
 static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
-       struct cfg80211_chan_def chandef;
+       struct cfg80211_chan_def chandef = {};
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
        enum nl80211_iftype iftype;
 
index d313c9b..ff10166 100644 (file)
@@ -1723,7 +1723,12 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
                return;
        new_ie_len -= trans_ssid[1];
        mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen);
-       if (!mbssid)
+       /*
+        * It's not valid to have the MBSSID element before SSID
+        * ignore if that happens - the code below assumes it is
+        * after (while copying things inbetween).
+        */
+       if (!mbssid || mbssid < trans_ssid)
                return;
        new_ie_len -= mbssid[1];
        rcu_read_lock();
index 7b6529d..cac9e28 100644 (file)
@@ -798,7 +798,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
-       struct cfg80211_chan_def chandef;
+       struct cfg80211_chan_def chandef = {};
        int ret;
 
        switch (wdev->iftype) {
index 6088bc2..9b599ed 100644 (file)
@@ -706,7 +706,7 @@ resume:
        if (err)
                goto drop;
 
-       nf_reset(skb);
+       nf_reset_ct(skb);
 
        if (decaps) {
                sp = skb_sec_path(skb);
index 2ab4859..0f5131b 100644 (file)
@@ -185,7 +185,7 @@ static void xfrmi_scrub_packet(struct sk_buff *skb, bool xnet)
        skb->skb_iif = 0;
        skb->ignore_df = 0;
        skb_dst_drop(skb);
-       nf_reset(skb);
+       nf_reset_ct(skb);
        nf_reset_trace(skb);
 
        if (!xnet)
index 9499b35..b1db55b 100644 (file)
@@ -502,7 +502,7 @@ int xfrm_output_resume(struct sk_buff *skb, int err)
        struct net *net = xs_net(skb_dst(skb)->xfrm);
 
        while (likely((err = xfrm_output_one(skb, err)) == 0)) {
-               nf_reset(skb);
+               nf_reset_ct(skb);
 
                err = skb_dst(skb)->ops->local_out(net, skb->sk, skb);
                if (unlikely(err != 1))
index 21e9392..f2d1e57 100644 (file)
@@ -2808,7 +2808,7 @@ static void xfrm_policy_queue_process(struct timer_list *t)
                        continue;
                }
 
-               nf_reset(skb);
+               nf_reset_ct(skb);
                skb_dst_drop(skb);
                skb_dst_set(skb, dst);
 
index 4b0432e..10ba926 100644 (file)
@@ -143,11 +143,6 @@ cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || e
 # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
 ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
 
-# ar-option
-# Usage: KBUILD_ARFLAGS := $(call ar-option,D)
-# Important: no spaces around options
-ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2))
-
 # ld-version
 # Note this is mainly for HJ Lu's 3 number binutil versions
 ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
index f72aba6..a9e4795 100644 (file)
@@ -389,7 +389,7 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ;
 ifdef builtin-target
 
 quiet_cmd_ar_builtin = AR      $@
-      cmd_ar_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(real-prereqs)
+      cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
 
 $(builtin-target): $(real-obj-y) FORCE
        $(call if_changed,ar_builtin)
index 4a0cdd6..179d55a 100644 (file)
@@ -232,7 +232,7 @@ quiet_cmd_ld = LD      $@
 # ---------------------------------------------------------------------------
 
 quiet_cmd_ar = AR      $@
-      cmd_ar = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(real-prereqs)
+      cmd_ar = rm -f $@; $(AR) cDPrsT $@ $(real-prereqs)
 
 # Objcopy
 # ---------------------------------------------------------------------------
index c832bb6..99e93a6 100644 (file)
@@ -6,6 +6,8 @@
 /// add a missing namespace tag to a module source file.
 ///
 
+virtual report
+
 @has_ns_import@
 declarer name MODULE_IMPORT_NS;
 identifier virtual.ns;
index 3961941..936d3ad 100644 (file)
@@ -166,7 +166,7 @@ struct symbol {
        struct module *module;
        unsigned int crc;
        int crc_valid;
-       const char *namespace;
+       char *namespace;
        unsigned int weak:1;
        unsigned int vmlinux:1;    /* 1 if symbol is defined in vmlinux */
        unsigned int kernel:1;     /* 1 if symbol is from kernel
@@ -348,20 +348,18 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
                return export_unknown;
 }
 
-static const char *sym_extract_namespace(const char **symname)
+static char *sym_extract_namespace(const char **symname)
 {
-       size_t n;
-       char *dupsymname;
+       char *namespace = NULL;
+       char *ns_separator;
 
-       n = strcspn(*symname, ".");
-       if (n < strlen(*symname) - 1) {
-               dupsymname = NOFAIL(strdup(*symname));
-               dupsymname[n] = '\0';
-               *symname = dupsymname;
-               return dupsymname + n + 1;
+       ns_separator = strchr(*symname, '.');
+       if (ns_separator) {
+               namespace = NOFAIL(strndup(*symname, ns_separator - *symname));
+               *symname = ns_separator + 1;
        }
 
-       return NULL;
+       return namespace;
 }
 
 /**
@@ -375,7 +373,6 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace,
 
        if (!s) {
                s = new_symbol(name, mod, export);
-               s->namespace = namespace;
        } else {
                if (!s->preloaded) {
                        warn("%s: '%s' exported twice. Previous export was in %s%s\n",
@@ -386,6 +383,8 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace,
                        s->module = mod;
                }
        }
+       free(s->namespace);
+       s->namespace = namespace ? strdup(namespace) : NULL;
        s->preloaded = 0;
        s->vmlinux   = is_vmlinux(mod->name);
        s->kernel    = 0;
@@ -672,7 +671,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
        unsigned int crc;
        enum export export;
        bool is_crc = false;
-       const char *name, *namespace;
+       const char *name;
+       char *namespace;
 
        if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
            strstarts(symname, "__ksymtab"))
@@ -747,6 +747,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
                        name = symname + strlen("__ksymtab_");
                        namespace = sym_extract_namespace(&name);
                        sym_add_exported(name, namespace, mod, export);
+                       free(namespace);
                }
                if (strcmp(symname, "init_module") == 0)
                        mod->has_init = 1;
@@ -2195,7 +2196,7 @@ static int check_exports(struct module *mod)
                else
                        basename = mod->name;
 
-               if (exp->namespace) {
+               if (exp->namespace && exp->namespace[0]) {
                        add_namespace(&mod->required_namespaces,
                                      exp->namespace);
 
@@ -2652,15 +2653,20 @@ int main(int argc, char **argv)
                fatal("modpost: Section mismatches detected.\n"
                      "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
        for (n = 0; n < SYMBOL_HASH_SIZE; n++) {
-               struct symbol *s = symbolhash[n];
+               struct symbol *s;
+
+               for (s = symbolhash[n]; s; s = s->next) {
+                       /*
+                        * Do not check "vmlinux". This avoids the same warnings
+                        * shown twice, and false-positives for ARCH=um.
+                        */
+                       if (is_vmlinux(s->module->name) && !s->module->is_dot_o)
+                               continue;
 
-               while (s) {
                        if (s->is_static)
                                warn("\"%s\" [%s] is a static %s\n",
                                     s->name, s->module->name,
                                     export_str(s->export));
-
-                       s = s->next;
                }
        }
 
index 6135574..1da7bca 100755 (executable)
 use warnings;
 use strict;
 use File::Find;
+use File::Spec;
 
 my $nm = ($ENV{'NM'} || "nm") . " -p";
 my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment";
-my $srctree = "";
-my $objtree = "";
-$srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'}));
-$objtree = "$ENV{'objtree'}/" if (exists($ENV{'objtree'}));
+my $srctree = File::Spec->curdir();
+my $objtree = File::Spec->curdir();
+$srctree = File::Spec->rel2abs($ENV{'srctree'}) if (exists($ENV{'srctree'}));
+$objtree = File::Spec->rel2abs($ENV{'objtree'}) if (exists($ENV{'objtree'}));
 
 if ($#ARGV != -1) {
        print STDERR "usage: $0 takes no parameters\n";
@@ -231,9 +232,9 @@ sub do_nm
        }
        ($source = $basename) =~ s/\.o$//;
        if (-e "$source.c" || -e "$source.S") {
-               $source = "$objtree$File::Find::dir/$source";
+               $source = File::Spec->catfile($objtree, $File::Find::dir, $source)
        } else {
-               $source = "$srctree$File::Find::dir/$source";
+               $source = File::Spec->catfile($srctree, $File::Find::dir, $source)
        }
        if (! -e "$source.c" && ! -e "$source.S") {
                # No obvious source, exclude the object if it is conglomerate
index ac2b603..3754dac 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # Linux kernel symbol namespace import generator
 #
@@ -41,7 +41,7 @@ generate_deps() {
                for source_file in $mod_source_files; do
                        sed '/MODULE_IMPORT_NS/Q' $source_file > ${source_file}.tmp
                        offset=$(wc -l ${source_file}.tmp | awk '{print $1;}')
-                       cat $source_file | grep MODULE_IMPORT_NS | sort -u >> ${source_file}.tmp
+                       cat $source_file | grep MODULE_IMPORT_NS | LANG=C sort -u >> ${source_file}.tmp
                        tail -n +$((offset +1)) ${source_file} | grep -v MODULE_IMPORT_NS >> ${source_file}.tmp
                        if ! diff -q ${source_file} ${source_file}.tmp; then
                                mv ${source_file}.tmp ${source_file}
index 365b3c2..220dae0 100755 (executable)
@@ -126,7 +126,7 @@ scm_version()
 
 collect_files()
 {
-       local file res
+       local file res=
 
        for file; do
                case "$file" in
index 19faace..35e6ca7 100644 (file)
@@ -13,9 +13,6 @@ integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyrin
 integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
                                        platform_certs/load_uefi.o
 integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o
-$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
 
-subdir-$(CONFIG_IMA)                   += ima
 obj-$(CONFIG_IMA)                      += ima/
-subdir-$(CONFIG_EVM)                   += evm
 obj-$(CONFIG_EVM)                      += evm/
index 3a29e7c..a5813c7 100644 (file)
@@ -1946,7 +1946,14 @@ static int convert_context(struct context *oldc, struct context *newc, void *p)
                rc = string_to_context_struct(args->newp, NULL, s,
                                              newc, SECSID_NULL);
                if (rc == -EINVAL) {
-                       /* Retain string representation for later mapping. */
+                       /*
+                        * Retain string representation for later mapping.
+                        *
+                        * IMPORTANT: We need to copy the contents of oldc->str
+                        * back into s again because string_to_context_struct()
+                        * may have garbled it.
+                        */
+                       memcpy(s, oldc->str, oldc->len);
                        context_init(newc);
                        newc->str = s;
                        newc->len = oldc->len;
index a4217c1..2769360 100644 (file)
@@ -266,8 +266,10 @@ struct kvm_vcpu_events {
 #define   KVM_DEV_ARM_ITS_CTRL_RESET           4
 
 /* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_VCPU2_SHIFT                28
+#define KVM_ARM_IRQ_VCPU2_MASK         0xf
 #define KVM_ARM_IRQ_TYPE_SHIFT         24
-#define KVM_ARM_IRQ_TYPE_MASK          0xff
+#define KVM_ARM_IRQ_TYPE_MASK          0xf
 #define KVM_ARM_IRQ_VCPU_SHIFT         16
 #define KVM_ARM_IRQ_VCPU_MASK          0xff
 #define KVM_ARM_IRQ_NUM_SHIFT          0
index 9a50771..67c21f9 100644 (file)
@@ -325,8 +325,10 @@ struct kvm_vcpu_events {
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER                1
 
 /* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_VCPU2_SHIFT                28
+#define KVM_ARM_IRQ_VCPU2_MASK         0xf
 #define KVM_ARM_IRQ_TYPE_SHIFT         24
-#define KVM_ARM_IRQ_TYPE_MASK          0xff
+#define KVM_ARM_IRQ_TYPE_MASK          0xf
 #define KVM_ARM_IRQ_VCPU_SHIFT         16
 #define KVM_ARM_IRQ_VCPU_MASK          0xff
 #define KVM_ARM_IRQ_NUM_SHIFT          0
index 47104e5..436ec76 100644 (file)
@@ -231,6 +231,12 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_GSCB   (1UL << 9)
 #define KVM_SYNC_BPBC   (1UL << 10)
 #define KVM_SYNC_ETOKEN (1UL << 11)
+
+#define KVM_SYNC_S390_VALID_FIELDS \
+       (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \
+        KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \
+        KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN)
+
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
 #define SDNXL (1UL << SDNXC)
index f0b0c90..f01950a 100644 (file)
@@ -31,6 +31,7 @@
 #define EXIT_REASON_EXCEPTION_NMI       0
 #define EXIT_REASON_EXTERNAL_INTERRUPT  1
 #define EXIT_REASON_TRIPLE_FAULT        2
+#define EXIT_REASON_INIT_SIGNAL                        3
 
 #define EXIT_REASON_PENDING_INTERRUPT   7
 #define EXIT_REASON_NMI_WINDOW          8
@@ -90,6 +91,7 @@
        { EXIT_REASON_EXCEPTION_NMI,         "EXCEPTION_NMI" }, \
        { EXIT_REASON_EXTERNAL_INTERRUPT,    "EXTERNAL_INTERRUPT" }, \
        { EXIT_REASON_TRIPLE_FAULT,          "TRIPLE_FAULT" }, \
+       { EXIT_REASON_INIT_SIGNAL,           "INIT_SIGNAL" }, \
        { EXIT_REASON_PENDING_INTERRUPT,     "PENDING_INTERRUPT" }, \
        { EXIT_REASON_NMI_WINDOW,            "NMI_WINDOW" }, \
        { EXIT_REASON_TASK_SWITCH,           "TASK_SWITCH" }, \
index 63b1f50..c160a53 100644 (file)
@@ -67,6 +67,9 @@
 #define MADV_WIPEONFORK 18             /* Zero memory on fork, child only */
 #define MADV_KEEPONFORK 19             /* Undo MADV_WIPEONFORK */
 
+#define MADV_COLD      20              /* deactivate these pages */
+#define MADV_PAGEOUT   21              /* reclaim these pages */
+
 /* compatibility flags */
 #define MAP_FILE       0
 
index 328d05e..469dc51 100644 (file)
@@ -521,6 +521,7 @@ typedef struct drm_i915_irq_wait {
 #define   I915_SCHEDULER_CAP_PRIORITY  (1ul << 1)
 #define   I915_SCHEDULER_CAP_PREEMPTION        (1ul << 2)
 #define   I915_SCHEDULER_CAP_SEMAPHORES        (1ul << 3)
+#define   I915_SCHEDULER_CAP_ENGINE_BUSY_STATS (1ul << 4)
 
 #define I915_PARAM_HUC_STATUS           42
 
index 2a616aa..379a612 100644 (file)
@@ -13,6 +13,9 @@
 #include <linux/limits.h>
 #include <linux/ioctl.h>
 #include <linux/types.h>
+#ifndef __KERNEL__
+#include <linux/fscrypt.h>
+#endif
 
 /* Use of MS_* flags within the kernel is restricted to core mount(2) code. */
 #if !defined(__KERNEL__)
@@ -212,57 +215,6 @@ struct fsxattr {
 #define FS_IOC_GETFSLABEL              _IOR(0x94, 49, char[FSLABEL_MAX])
 #define FS_IOC_SETFSLABEL              _IOW(0x94, 50, char[FSLABEL_MAX])
 
-/*
- * File system encryption support
- */
-/* Policy provided via an ioctl on the topmost directory */
-#define FS_KEY_DESCRIPTOR_SIZE 8
-
-#define FS_POLICY_FLAGS_PAD_4          0x00
-#define FS_POLICY_FLAGS_PAD_8          0x01
-#define FS_POLICY_FLAGS_PAD_16         0x02
-#define FS_POLICY_FLAGS_PAD_32         0x03
-#define FS_POLICY_FLAGS_PAD_MASK       0x03
-#define FS_POLICY_FLAG_DIRECT_KEY      0x04    /* use master key directly */
-#define FS_POLICY_FLAGS_VALID          0x07
-
-/* Encryption algorithms */
-#define FS_ENCRYPTION_MODE_INVALID             0
-#define FS_ENCRYPTION_MODE_AES_256_XTS         1
-#define FS_ENCRYPTION_MODE_AES_256_GCM         2
-#define FS_ENCRYPTION_MODE_AES_256_CBC         3
-#define FS_ENCRYPTION_MODE_AES_256_CTS         4
-#define FS_ENCRYPTION_MODE_AES_128_CBC         5
-#define FS_ENCRYPTION_MODE_AES_128_CTS         6
-#define FS_ENCRYPTION_MODE_SPECK128_256_XTS    7 /* Removed, do not use. */
-#define FS_ENCRYPTION_MODE_SPECK128_256_CTS    8 /* Removed, do not use. */
-#define FS_ENCRYPTION_MODE_ADIANTUM            9
-
-struct fscrypt_policy {
-       __u8 version;
-       __u8 contents_encryption_mode;
-       __u8 filenames_encryption_mode;
-       __u8 flags;
-       __u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
-};
-
-#define FS_IOC_SET_ENCRYPTION_POLICY   _IOR('f', 19, struct fscrypt_policy)
-#define FS_IOC_GET_ENCRYPTION_PWSALT   _IOW('f', 20, __u8[16])
-#define FS_IOC_GET_ENCRYPTION_POLICY   _IOW('f', 21, struct fscrypt_policy)
-
-/* Parameters for passing an encryption key into the kernel keyring */
-#define FS_KEY_DESC_PREFIX             "fscrypt:"
-#define FS_KEY_DESC_PREFIX_SIZE                8
-
-/* Structure that userspace passes to the kernel keyring */
-#define FS_MAX_KEY_SIZE                        64
-
-struct fscrypt_key {
-       __u32 mode;
-       __u8 raw[FS_MAX_KEY_SIZE];
-       __u32 size;
-};
-
 /*
  * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
  *
@@ -306,6 +258,7 @@ struct fscrypt_key {
 #define FS_TOPDIR_FL                   0x00020000 /* Top of directory hierarchies*/
 #define FS_HUGE_FILE_FL                        0x00040000 /* Reserved for ext4 */
 #define FS_EXTENT_FL                   0x00080000 /* Extents */
+#define FS_VERITY_FL                   0x00100000 /* Verity protected inode */
 #define FS_EA_INODE_FL                 0x00200000 /* Inode used for large EA */
 #define FS_EOFBLOCKS_FL                        0x00400000 /* Reserved for ext4 */
 #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
diff --git a/tools/include/uapi/linux/fscrypt.h b/tools/include/uapi/linux/fscrypt.h
new file mode 100644 (file)
index 0000000..39ccfe9
--- /dev/null
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * fscrypt user API
+ *
+ * These ioctls can be used on filesystems that support fscrypt.  See the
+ * "User API" section of Documentation/filesystems/fscrypt.rst.
+ */
+#ifndef _UAPI_LINUX_FSCRYPT_H
+#define _UAPI_LINUX_FSCRYPT_H
+
+#include <linux/types.h>
+
+/* Encryption policy flags */
+#define FSCRYPT_POLICY_FLAGS_PAD_4             0x00
+#define FSCRYPT_POLICY_FLAGS_PAD_8             0x01
+#define FSCRYPT_POLICY_FLAGS_PAD_16            0x02
+#define FSCRYPT_POLICY_FLAGS_PAD_32            0x03
+#define FSCRYPT_POLICY_FLAGS_PAD_MASK          0x03
+#define FSCRYPT_POLICY_FLAG_DIRECT_KEY         0x04
+#define FSCRYPT_POLICY_FLAGS_VALID             0x07
+
+/* Encryption algorithms */
+#define FSCRYPT_MODE_AES_256_XTS               1
+#define FSCRYPT_MODE_AES_256_CTS               4
+#define FSCRYPT_MODE_AES_128_CBC               5
+#define FSCRYPT_MODE_AES_128_CTS               6
+#define FSCRYPT_MODE_ADIANTUM                  9
+#define __FSCRYPT_MODE_MAX                     9
+
+/*
+ * Legacy policy version; ad-hoc KDF and no key verification.
+ * For new encrypted directories, use fscrypt_policy_v2 instead.
+ *
+ * Careful: the .version field for this is actually 0, not 1.
+ */
+#define FSCRYPT_POLICY_V1              0
+#define FSCRYPT_KEY_DESCRIPTOR_SIZE    8
+struct fscrypt_policy_v1 {
+       __u8 version;
+       __u8 contents_encryption_mode;
+       __u8 filenames_encryption_mode;
+       __u8 flags;
+       __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
+};
+#define fscrypt_policy fscrypt_policy_v1
+
+/*
+ * Process-subscribed "logon" key description prefix and payload format.
+ * Deprecated; prefer FS_IOC_ADD_ENCRYPTION_KEY instead.
+ */
+#define FSCRYPT_KEY_DESC_PREFIX                "fscrypt:"
+#define FSCRYPT_KEY_DESC_PREFIX_SIZE   8
+#define FSCRYPT_MAX_KEY_SIZE           64
+struct fscrypt_key {
+       __u32 mode;
+       __u8 raw[FSCRYPT_MAX_KEY_SIZE];
+       __u32 size;
+};
+
+/*
+ * New policy version with HKDF and key verification (recommended).
+ */
+#define FSCRYPT_POLICY_V2              2
+#define FSCRYPT_KEY_IDENTIFIER_SIZE    16
+struct fscrypt_policy_v2 {
+       __u8 version;
+       __u8 contents_encryption_mode;
+       __u8 filenames_encryption_mode;
+       __u8 flags;
+       __u8 __reserved[4];
+       __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE];
+};
+
+/* Struct passed to FS_IOC_GET_ENCRYPTION_POLICY_EX */
+struct fscrypt_get_policy_ex_arg {
+       __u64 policy_size; /* input/output */
+       union {
+               __u8 version;
+               struct fscrypt_policy_v1 v1;
+               struct fscrypt_policy_v2 v2;
+       } policy; /* output */
+};
+
+/*
+ * v1 policy keys are specified by an arbitrary 8-byte key "descriptor",
+ * matching fscrypt_policy_v1::master_key_descriptor.
+ */
+#define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR       1
+
+/*
+ * v2 policy keys are specified by a 16-byte key "identifier" which the kernel
+ * calculates as a cryptographic hash of the key itself,
+ * matching fscrypt_policy_v2::master_key_identifier.
+ */
+#define FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER       2
+
+/*
+ * Specifies a key, either for v1 or v2 policies.  This doesn't contain the
+ * actual key itself; this is just the "name" of the key.
+ */
+struct fscrypt_key_specifier {
+       __u32 type;     /* one of FSCRYPT_KEY_SPEC_TYPE_* */
+       __u32 __reserved;
+       union {
+               __u8 __reserved[32]; /* reserve some extra space */
+               __u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
+               __u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE];
+       } u;
+};
+
+/* Struct passed to FS_IOC_ADD_ENCRYPTION_KEY */
+struct fscrypt_add_key_arg {
+       struct fscrypt_key_specifier key_spec;
+       __u32 raw_size;
+       __u32 __reserved[9];
+       __u8 raw[];
+};
+
+/* Struct passed to FS_IOC_REMOVE_ENCRYPTION_KEY */
+struct fscrypt_remove_key_arg {
+       struct fscrypt_key_specifier key_spec;
+#define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY     0x00000001
+#define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS    0x00000002
+       __u32 removal_status_flags;     /* output */
+       __u32 __reserved[5];
+};
+
+/* Struct passed to FS_IOC_GET_ENCRYPTION_KEY_STATUS */
+struct fscrypt_get_key_status_arg {
+       /* input */
+       struct fscrypt_key_specifier key_spec;
+       __u32 __reserved[6];
+
+       /* output */
+#define FSCRYPT_KEY_STATUS_ABSENT              1
+#define FSCRYPT_KEY_STATUS_PRESENT             2
+#define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED        3
+       __u32 status;
+#define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF   0x00000001
+       __u32 status_flags;
+       __u32 user_count;
+       __u32 __out_reserved[13];
+};
+
+#define FS_IOC_SET_ENCRYPTION_POLICY           _IOR('f', 19, struct fscrypt_policy)
+#define FS_IOC_GET_ENCRYPTION_PWSALT           _IOW('f', 20, __u8[16])
+#define FS_IOC_GET_ENCRYPTION_POLICY           _IOW('f', 21, struct fscrypt_policy)
+#define FS_IOC_GET_ENCRYPTION_POLICY_EX                _IOWR('f', 22, __u8[9]) /* size + version */
+#define FS_IOC_ADD_ENCRYPTION_KEY              _IOWR('f', 23, struct fscrypt_add_key_arg)
+#define FS_IOC_REMOVE_ENCRYPTION_KEY           _IOWR('f', 24, struct fscrypt_remove_key_arg)
+#define FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS _IOWR('f', 25, struct fscrypt_remove_key_arg)
+#define FS_IOC_GET_ENCRYPTION_KEY_STATUS       _IOWR('f', 26, struct fscrypt_get_key_status_arg)
+
+/**********************************************************************/
+
+/* old names; don't add anything new here! */
+#ifndef __KERNEL__
+#define FS_KEY_DESCRIPTOR_SIZE         FSCRYPT_KEY_DESCRIPTOR_SIZE
+#define FS_POLICY_FLAGS_PAD_4          FSCRYPT_POLICY_FLAGS_PAD_4
+#define FS_POLICY_FLAGS_PAD_8          FSCRYPT_POLICY_FLAGS_PAD_8
+#define FS_POLICY_FLAGS_PAD_16         FSCRYPT_POLICY_FLAGS_PAD_16
+#define FS_POLICY_FLAGS_PAD_32         FSCRYPT_POLICY_FLAGS_PAD_32
+#define FS_POLICY_FLAGS_PAD_MASK       FSCRYPT_POLICY_FLAGS_PAD_MASK
+#define FS_POLICY_FLAG_DIRECT_KEY      FSCRYPT_POLICY_FLAG_DIRECT_KEY
+#define FS_POLICY_FLAGS_VALID          FSCRYPT_POLICY_FLAGS_VALID
+#define FS_ENCRYPTION_MODE_INVALID     0       /* never used */
+#define FS_ENCRYPTION_MODE_AES_256_XTS FSCRYPT_MODE_AES_256_XTS
+#define FS_ENCRYPTION_MODE_AES_256_GCM 2       /* never used */
+#define FS_ENCRYPTION_MODE_AES_256_CBC 3       /* never used */
+#define FS_ENCRYPTION_MODE_AES_256_CTS FSCRYPT_MODE_AES_256_CTS
+#define FS_ENCRYPTION_MODE_AES_128_CBC FSCRYPT_MODE_AES_128_CBC
+#define FS_ENCRYPTION_MODE_AES_128_CTS FSCRYPT_MODE_AES_128_CTS
+#define FS_ENCRYPTION_MODE_SPECK128_256_XTS    7       /* removed */
+#define FS_ENCRYPTION_MODE_SPECK128_256_CTS    8       /* removed */
+#define FS_ENCRYPTION_MODE_ADIANTUM    FSCRYPT_MODE_ADIANTUM
+#define FS_KEY_DESC_PREFIX             FSCRYPT_KEY_DESC_PREFIX
+#define FS_KEY_DESC_PREFIX_SIZE                FSCRYPT_KEY_DESC_PREFIX_SIZE
+#define FS_MAX_KEY_SIZE                        FSCRYPT_MAX_KEY_SIZE
+#endif /* !__KERNEL__ */
+
+#endif /* _UAPI_LINUX_FSCRYPT_H */
index 5e3f12d..233efbb 100644 (file)
@@ -243,6 +243,8 @@ struct kvm_hyperv_exit {
 #define KVM_INTERNAL_ERROR_SIMUL_EX    2
 /* Encounter unexpected vm-exit due to delivery event. */
 #define KVM_INTERNAL_ERROR_DELIVERY_EV 3
+/* Encounter unexpected vm-exit reason */
+#define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON      4
 
 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
 struct kvm_run {
@@ -996,6 +998,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_ARM_PTRAUTH_ADDRESS 171
 #define KVM_CAP_ARM_PTRAUTH_GENERIC 172
 #define KVM_CAP_PMU_EVENT_FILTER 173
+#define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index 78efe87..cf525cd 100644 (file)
@@ -158,6 +158,7 @@ struct usbdevfs_hub_portinfo {
 #define USBDEVFS_CAP_MMAP                      0x20
 #define USBDEVFS_CAP_DROP_PRIVILEGES           0x40
 #define USBDEVFS_CAP_CONNINFO_EX               0x80
+#define USBDEVFS_CAP_SUSPEND                   0x100
 
 /* USBDEVFS_DISCONNECT_CLAIM flags & struct */
 
@@ -223,5 +224,8 @@ struct usbdevfs_streams {
  * extending size of the data returned.
  */
 #define USBDEVFS_CONNINFO_EX(len)  _IOC(_IOC_READ, 'U', 32, len)
+#define USBDEVFS_FORBID_SUSPEND    _IO('U', 33)
+#define USBDEVFS_ALLOW_SUSPEND     _IO('U', 34)
+#define USBDEVFS_WAIT_FOR_RESUME   _IO('U', 35)
 
 #endif /* _UAPI_LINUX_USBDEVICE_FS_H */
index ed61fb3..5b2cd5e 100644 (file)
@@ -20,7 +20,13 @@ MAKEFLAGS += --no-print-directory
 LIBFILE = $(OUTPUT)libsubcmd.a
 
 CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
-CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
+CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -fPIC
+
+ifeq ($(DEBUG),0)
+  ifeq ($(feature-fortify-source), 1)
+    CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
+  endif
+endif
 
 ifeq ($(CC_NO_CLANG), 0)
   CFLAGS += -O3
index 356b23a..2b62ba1 100644 (file)
@@ -71,6 +71,9 @@ ifdef::backend-docbook[]
 [header]
 template::[header-declarations]
 <refentry>
+ifdef::perf_date[]
+<refentryinfo><date>{perf_date}</date></refentryinfo>
+endif::perf_date[]
 <refmeta>
 <refentrytitle>{mantitle}</refentrytitle>
 <manvolnum>{manvolnum}</manvolnum>
index 4c62b07..52152d1 100644 (file)
@@ -36,8 +36,8 @@ III/ Jitdump file header format
 Each jitdump file starts with a fixed size header containing the following fields in order:
 
 
-* uint32_t magic     : a magic number tagging the file type. The value is 4-byte long and represents the string "JiTD" in ASCII form. It is 0x4A695444 or 0x4454694a depending on the endianness. The field can be used to detect the endianness of the file
-* uint32_t version   : a 4-byte value representing the format version. It is currently set to 2
+* uint32_t magic     : a magic number tagging the file type. The value is 4-byte long and represents the string "JiTD" in ASCII form. It written is as 0x4A695444. The reader will detect an endian mismatch when it reads 0x4454694a.
+* uint32_t version   : a 4-byte value representing the format version. It is currently set to 1
 * uint32_t total_size: size in bytes of file header
 * uint32_t elf_mach  : ELF architecture encoding (ELF e_machine value as specified in /usr/include/elf.h)
 * uint32_t pad1      : padding. Reserved for future use
index e1d4b48..2ff6ced 100644 (file)
@@ -37,7 +37,7 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 
        arm = zalloc(sizeof(*arm));
        if (!arm)
-               return -1;
+               return ENOMEM;
 
 #define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)"
        err = regcomp(&arm->call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED);
@@ -59,5 +59,5 @@ out_free_call:
        regfree(&arm->call_insn);
 out_free_arm:
        free(arm);
-       return -1;
+       return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP;
 }
index 43aa93e..037e292 100644 (file)
@@ -95,7 +95,7 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 
        arm = zalloc(sizeof(*arm));
        if (!arm)
-               return -1;
+               return ENOMEM;
 
        /* bl, blr */
        err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED);
@@ -118,5 +118,5 @@ out_free_call:
        regfree(&arm->call_insn);
 out_free_arm:
        free(arm);
-       return -1;
+       return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP;
 }
index b6b7bc7..3b4cdfc 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <sys/types.h>
+#include <errno.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -30,7 +31,7 @@ get_cpuid(char *buffer, size_t sz)
                buffer[nb-1] = '\0';
                return 0;
        }
-       return -1;
+       return ENOBUFS;
 }
 
 char *
index 89bb8f2..a50e70b 100644 (file)
@@ -164,8 +164,10 @@ static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
        if (!arch->initialized) {
                arch->initialized = true;
                arch->associate_instruction_ops = s390__associate_ins_ops;
-               if (cpuid)
-                       err = s390__cpuid_parse(arch, cpuid);
+               if (cpuid) {
+                       if (s390__cpuid_parse(arch, cpuid))
+                               err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
+               }
        }
 
        return err;
index 8b0b018..7933f68 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <sys/types.h>
+#include <errno.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
@@ -54,7 +55,7 @@ int get_cpuid(char *buffer, size_t sz)
 
        sysinfo = fopen(SYSINFO, "r");
        if (sysinfo == NULL)
-               return -1;
+               return errno;
 
        while ((read = getline(&line, &line_sz, sysinfo)) != -1) {
                if (!strncmp(line, SYSINFO_MANU, strlen(SYSINFO_MANU))) {
@@ -89,7 +90,7 @@ int get_cpuid(char *buffer, size_t sz)
 
        /* Missing manufacturer, type or model information should not happen */
        if (!manufacturer[0] || !type[0] || !model[0])
-               return -1;
+               return EINVAL;
 
        /*
         * Scan /proc/service_levels and return the CPU-MF counter facility
@@ -133,14 +134,14 @@ skip_sysinfo:
        else
                nbytes = snprintf(buffer, sz, "%s,%s,%s", manufacturer, type,
                                  model);
-       return (nbytes >= sz) ? -1 : 0;
+       return (nbytes >= sz) ? ENOBUFS : 0;
 }
 
 char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
 {
        char *buf = malloc(128);
 
-       if (buf && get_cpuid(buf, 128) < 0)
+       if (buf && get_cpuid(buf, 128))
                zfree(&buf);
        return buf;
 }
index 44f5aba..7eb5621 100644 (file)
@@ -196,8 +196,10 @@ static int x86__annotate_init(struct arch *arch, char *cpuid)
        if (arch->initialized)
                return 0;
 
-       if (cpuid)
-               err = x86__cpuid_parse(arch, cpuid);
+       if (cpuid) {
+               if (x86__cpuid_parse(arch, cpuid))
+                       err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
+       }
 
        arch->initialized = true;
        return err;
index 662ecf8..aa6deb4 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <sys/types.h>
+#include <errno.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -58,7 +59,7 @@ __get_cpuid(char *buffer, size_t sz, const char *fmt)
                buffer[nb-1] = '\0';
                return 0;
        }
-       return -1;
+       return ENOBUFS;
 }
 
 int
index 2227e2f..58a9e09 100644 (file)
@@ -705,14 +705,15 @@ static int process_sample_event(struct perf_tool *tool,
 
 static int cpu_isa_config(struct perf_kvm_stat *kvm)
 {
-       char buf[64], *cpuid;
+       char buf[128], *cpuid;
        int err;
 
        if (kvm->live) {
                err = get_cpuid(buf, sizeof(buf));
                if (err != 0) {
-                       pr_err("Failed to look up CPU type\n");
-                       return err;
+                       pr_err("Failed to look up CPU type: %s\n",
+                              str_error_r(err, buf, sizeof(buf)));
+                       return -err;
                }
                cpuid = buf;
        } else
index 286fc70..67be8d3 100644 (file)
@@ -1063,7 +1063,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
                        continue;
 
                insn = 0;
-               for (off = 0;; off += ilen) {
+               for (off = 0; off < (unsigned)len; off += ilen) {
                        uint64_t ip = start + off;
 
                        printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
@@ -1074,6 +1074,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
                                        printed += print_srccode(thread, x.cpumode, ip);
                                break;
                        } else {
+                               ilen = 0;
                                printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
                                                   dump_insn(&x, ip, buffer + off, len - off, &ilen));
                                if (ilen == 0)
@@ -1083,6 +1084,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
                                insn++;
                        }
                }
+               if (off != (unsigned)len)
+                       printed += fprintf(fp, "\tmismatch of LBR data and executable\n");
        }
 
        /*
@@ -1123,6 +1126,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
                goto out;
        }
        for (off = 0; off <= end - start; off += ilen) {
+               ilen = 0;
                printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", start + off,
                                   dump_insn(&x, start + off, buffer + off, len - off, &ilen));
                if (ilen == 0)
index e2e0f06..cea13cb 100755 (executable)
@@ -8,6 +8,7 @@ include/uapi/drm/i915_drm.h
 include/uapi/linux/fadvise.h
 include/uapi/linux/fcntl.h
 include/uapi/linux/fs.h
+include/uapi/linux/fscrypt.h
 include/uapi/linux/kcmp.h
 include/uapi/linux/kvm.h
 include/uapi/linux/in.h
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json b/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json
deleted file mode 100644 (file)
index 17fb524..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-[
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "0",
-               "EventName": "CPU_CYCLES",
-               "BriefDescription": "CPU Cycles",
-               "PublicDescription": "Cycle Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "1",
-               "EventName": "INSTRUCTIONS",
-               "BriefDescription": "Instructions",
-               "PublicDescription": "Instruction Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "2",
-               "EventName": "L1I_DIR_WRITES",
-               "BriefDescription": "L1I Directory Writes",
-               "PublicDescription": "Level-1 I-Cache Directory Write Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "3",
-               "EventName": "L1I_PENALTY_CYCLES",
-               "BriefDescription": "L1I Penalty Cycles",
-               "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "4",
-               "EventName": "L1D_DIR_WRITES",
-               "BriefDescription": "L1D Directory Writes",
-               "PublicDescription": "Level-1 D-Cache Directory Write Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "5",
-               "EventName": "L1D_PENALTY_CYCLES",
-               "BriefDescription": "L1D Penalty Cycles",
-               "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "32",
-               "EventName": "PROBLEM_STATE_CPU_CYCLES",
-               "BriefDescription": "Problem-State CPU Cycles",
-               "PublicDescription": "Problem-State Cycle Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "33",
-               "EventName": "PROBLEM_STATE_INSTRUCTIONS",
-               "BriefDescription": "Problem-State Instructions",
-               "PublicDescription": "Problem-State Instruction Count"
-       },
-]
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json
deleted file mode 100644 (file)
index db286f1..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-[
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "64",
-               "EventName": "PRNG_FUNCTIONS",
-               "BriefDescription": "PRNG Functions",
-               "PublicDescription": "Total number of the PRNG functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "65",
-               "EventName": "PRNG_CYCLES",
-               "BriefDescription": "PRNG Cycles",
-               "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "66",
-               "EventName": "PRNG_BLOCKED_FUNCTIONS",
-               "BriefDescription": "PRNG Blocked Functions",
-               "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "67",
-               "EventName": "PRNG_BLOCKED_CYCLES",
-               "BriefDescription": "PRNG Blocked Cycles",
-               "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "68",
-               "EventName": "SHA_FUNCTIONS",
-               "BriefDescription": "SHA Functions",
-               "PublicDescription": "Total number of SHA functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "69",
-               "EventName": "SHA_CYCLES",
-               "BriefDescription": "SHA Cycles",
-               "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "70",
-               "EventName": "SHA_BLOCKED_FUNCTIONS",
-               "BriefDescription": "SHA Blocked Functions",
-               "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "71",
-               "EventName": "SHA_BLOCKED_CYCLES",
-               "BriefDescription": "SHA Bloced Cycles",
-               "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "72",
-               "EventName": "DEA_FUNCTIONS",
-               "BriefDescription": "DEA Functions",
-               "PublicDescription": "Total number of the DEA functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "73",
-               "EventName": "DEA_CYCLES",
-               "BriefDescription": "DEA Cycles",
-               "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "74",
-               "EventName": "DEA_BLOCKED_FUNCTIONS",
-               "BriefDescription": "DEA Blocked Functions",
-               "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "75",
-               "EventName": "DEA_BLOCKED_CYCLES",
-               "BriefDescription": "DEA Blocked Cycles",
-               "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "76",
-               "EventName": "AES_FUNCTIONS",
-               "BriefDescription": "AES Functions",
-               "PublicDescription": "Total number of AES functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "77",
-               "EventName": "AES_CYCLES",
-               "BriefDescription": "AES Cycles",
-               "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "78",
-               "EventName": "AES_BLOCKED_FUNCTIONS",
-               "BriefDescription": "AES Blocked Functions",
-               "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "79",
-               "EventName": "AES_BLOCKED_CYCLES",
-               "BriefDescription": "AES Blocked Cycles",
-               "PublicDescription": "Total number of CPU cycles blocked for the AES functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
-       },
-]
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json
deleted file mode 100644 (file)
index 5e36bc2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-[
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "80",
-               "EventName": "ECC_FUNCTION_COUNT",
-               "BriefDescription": "ECC Function Count",
-               "PublicDescription": "Long ECC function Count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "81",
-               "EventName": "ECC_CYCLES_COUNT",
-               "BriefDescription": "ECC Cycles Count",
-               "PublicDescription": "Long ECC Function cycles count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "82",
-               "EventName": "ECC_BLOCKED_FUNCTION_COUNT",
-               "BriefDescription": "Ecc Blocked Function Count",
-               "PublicDescription": "Long ECC blocked function count"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "83",
-               "EventName": "ECC_BLOCKED_CYCLES_COUNT",
-               "BriefDescription": "ECC Blocked Cycles Count",
-               "PublicDescription": "Long ECC blocked cycles count"
-       },
-]
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json b/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json
deleted file mode 100644 (file)
index 89e0707..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-[
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "128",
-               "EventName": "L1D_RO_EXCL_WRITES",
-               "BriefDescription": "L1D Read-only Exclusive Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "129",
-               "EventName": "DTLB2_WRITES",
-               "BriefDescription": "DTLB2 Writes",
-               "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "130",
-               "EventName": "DTLB2_MISSES",
-               "BriefDescription": "DTLB2 Misses",
-               "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "131",
-               "EventName": "DTLB2_HPAGE_WRITES",
-               "BriefDescription": "DTLB2 One-Megabyte Page Writes",
-               "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "132",
-               "EventName": "DTLB2_GPAGE_WRITES",
-               "BriefDescription": "DTLB2 Two-Gigabyte Page Writes",
-               "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "133",
-               "EventName": "L1D_L2D_SOURCED_WRITES",
-               "BriefDescription": "L1D L2D Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "134",
-               "EventName": "ITLB2_WRITES",
-               "BriefDescription": "ITLB2 Writes",
-               "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "135",
-               "EventName": "ITLB2_MISSES",
-               "BriefDescription": "ITLB2 Misses",
-               "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "136",
-               "EventName": "L1I_L2I_SOURCED_WRITES",
-               "BriefDescription": "L1I L2I Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "137",
-               "EventName": "TLB2_PTE_WRITES",
-               "BriefDescription": "TLB2 PTE Writes",
-               "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "138",
-               "EventName": "TLB2_CRSTE_WRITES",
-               "BriefDescription": "TLB2 CRSTE Writes",
-               "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "139",
-               "EventName": "TLB2_ENGINES_BUSY",
-               "BriefDescription": "TLB2 Engines Busy",
-               "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "140",
-               "EventName": "TX_C_TEND",
-               "BriefDescription": "Completed TEND instructions in constrained TX mode",
-               "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "141",
-               "EventName": "TX_NC_TEND",
-               "BriefDescription": "Completed TEND instructions in non-constrained TX mode",
-               "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "143",
-               "EventName": "L1C_TLB2_MISSES",
-               "BriefDescription": "L1C TLB2 Misses",
-               "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "144",
-               "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
-               "BriefDescription": "L1D On-Chip L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "145",
-               "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1D On-Chip Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "146",
-               "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "147",
-               "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES",
-               "BriefDescription": "L1D On-Cluster L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "148",
-               "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1D On-Cluster Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "149",
-               "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "150",
-               "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES",
-               "BriefDescription": "L1D Off-Cluster L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "151",
-               "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1D Off-Cluster Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "152",
-               "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "153",
-               "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES",
-               "BriefDescription": "L1D Off-Drawer L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "154",
-               "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1D Off-Drawer Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "155",
-               "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "156",
-               "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES",
-               "BriefDescription": "L1D On-Drawer L4 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "157",
-               "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES",
-               "BriefDescription": "L1D Off-Drawer L4 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "158",
-               "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO",
-               "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only",
-               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "162",
-               "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
-               "BriefDescription": "L1I On-Chip L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "163",
-               "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1I On-Chip Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "164",
-               "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "165",
-               "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES",
-               "BriefDescription": "L1I On-Cluster L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "166",
-               "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1I On-Cluster Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "167",
-               "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "168",
-               "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES",
-               "BriefDescription": "L1I Off-Cluster L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "169",
-               "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1I Off-Cluster Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "170",
-               "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "171",
-               "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES",
-               "BriefDescription": "L1I Off-Drawer L3 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "172",
-               "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES",
-               "BriefDescription": "L1I Off-Drawer Memory Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "173",
-               "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV",
-               "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "174",
-               "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES",
-               "BriefDescription": "L1I On-Drawer L4 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "175",
-               "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES",
-               "BriefDescription": "L1I Off-Drawer L4 Sourced Writes",
-               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "224",
-               "EventName": "BCD_DFP_EXECUTION_SLOTS",
-               "BriefDescription": "BCD DFP Execution Slots",
-               "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "225",
-               "EventName": "VX_BCD_EXECUTION_SLOTS",
-               "BriefDescription": "VX BCD Execution Slots",
-               "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "226",
-               "EventName": "DECIMAL_INSTRUCTIONS",
-               "BriefDescription": "Decimal Instructions",
-               "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "232",
-               "EventName": "LAST_HOST_TRANSLATIONS",
-               "BriefDescription": "Last host translation done",
-               "PublicDescription": "Last Host Translation done"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "243",
-               "EventName": "TX_NC_TABORT",
-               "BriefDescription": "Aborted transactions in non-constrained TX mode",
-               "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "244",
-               "EventName": "TX_C_TABORT_NO_SPECIAL",
-               "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
-               "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "245",
-               "EventName": "TX_C_TABORT_SPECIAL",
-               "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
-               "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "448",
-               "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE",
-               "BriefDescription": "Cycle count with one thread active",
-               "PublicDescription": "Cycle count with one thread active"
-       },
-       {
-               "Unit": "CPU-M-CF",
-               "EventCode": "449",
-               "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE",
-               "BriefDescription": "Cycle count with two threads active",
-               "PublicDescription": "Cycle count with two threads active"
-       },
-]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/basic.json b/tools/perf/pmu-events/arch/s390/cf_z15/basic.json
new file mode 100644 (file)
index 0000000..17fb524
--- /dev/null
@@ -0,0 +1,58 @@
+[
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "0",
+               "EventName": "CPU_CYCLES",
+               "BriefDescription": "CPU Cycles",
+               "PublicDescription": "Cycle Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "1",
+               "EventName": "INSTRUCTIONS",
+               "BriefDescription": "Instructions",
+               "PublicDescription": "Instruction Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "2",
+               "EventName": "L1I_DIR_WRITES",
+               "BriefDescription": "L1I Directory Writes",
+               "PublicDescription": "Level-1 I-Cache Directory Write Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "3",
+               "EventName": "L1I_PENALTY_CYCLES",
+               "BriefDescription": "L1I Penalty Cycles",
+               "PublicDescription": "Level-1 I-Cache Penalty Cycle Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "4",
+               "EventName": "L1D_DIR_WRITES",
+               "BriefDescription": "L1D Directory Writes",
+               "PublicDescription": "Level-1 D-Cache Directory Write Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "5",
+               "EventName": "L1D_PENALTY_CYCLES",
+               "BriefDescription": "L1D Penalty Cycles",
+               "PublicDescription": "Level-1 D-Cache Penalty Cycle Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "32",
+               "EventName": "PROBLEM_STATE_CPU_CYCLES",
+               "BriefDescription": "Problem-State CPU Cycles",
+               "PublicDescription": "Problem-State Cycle Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "33",
+               "EventName": "PROBLEM_STATE_INSTRUCTIONS",
+               "BriefDescription": "Problem-State Instructions",
+               "PublicDescription": "Problem-State Instruction Count"
+       },
+]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z15/crypto.json
new file mode 100644 (file)
index 0000000..db286f1
--- /dev/null
@@ -0,0 +1,114 @@
+[
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "64",
+               "EventName": "PRNG_FUNCTIONS",
+               "BriefDescription": "PRNG Functions",
+               "PublicDescription": "Total number of the PRNG functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "65",
+               "EventName": "PRNG_CYCLES",
+               "BriefDescription": "PRNG Cycles",
+               "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "66",
+               "EventName": "PRNG_BLOCKED_FUNCTIONS",
+               "BriefDescription": "PRNG Blocked Functions",
+               "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "67",
+               "EventName": "PRNG_BLOCKED_CYCLES",
+               "BriefDescription": "PRNG Blocked Cycles",
+               "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "68",
+               "EventName": "SHA_FUNCTIONS",
+               "BriefDescription": "SHA Functions",
+               "PublicDescription": "Total number of SHA functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "69",
+               "EventName": "SHA_CYCLES",
+               "BriefDescription": "SHA Cycles",
+               "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "70",
+               "EventName": "SHA_BLOCKED_FUNCTIONS",
+               "BriefDescription": "SHA Blocked Functions",
+               "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "71",
+               "EventName": "SHA_BLOCKED_CYCLES",
+               "BriefDescription": "SHA Bloced Cycles",
+               "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "72",
+               "EventName": "DEA_FUNCTIONS",
+               "BriefDescription": "DEA Functions",
+               "PublicDescription": "Total number of the DEA functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "73",
+               "EventName": "DEA_CYCLES",
+               "BriefDescription": "DEA Cycles",
+               "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "74",
+               "EventName": "DEA_BLOCKED_FUNCTIONS",
+               "BriefDescription": "DEA Blocked Functions",
+               "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "75",
+               "EventName": "DEA_BLOCKED_CYCLES",
+               "BriefDescription": "DEA Blocked Cycles",
+               "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "76",
+               "EventName": "AES_FUNCTIONS",
+               "BriefDescription": "AES Functions",
+               "PublicDescription": "Total number of AES functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "77",
+               "EventName": "AES_CYCLES",
+               "BriefDescription": "AES Cycles",
+               "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "78",
+               "EventName": "AES_BLOCKED_FUNCTIONS",
+               "BriefDescription": "AES Blocked Functions",
+               "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "79",
+               "EventName": "AES_BLOCKED_CYCLES",
+               "BriefDescription": "AES Blocked Cycles",
+               "PublicDescription": "Total number of CPU cycles blocked for the AES functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU"
+       },
+]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/crypto6.json b/tools/perf/pmu-events/arch/s390/cf_z15/crypto6.json
new file mode 100644 (file)
index 0000000..5e36bc2
--- /dev/null
@@ -0,0 +1,30 @@
+[
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "80",
+               "EventName": "ECC_FUNCTION_COUNT",
+               "BriefDescription": "ECC Function Count",
+               "PublicDescription": "Long ECC function Count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "81",
+               "EventName": "ECC_CYCLES_COUNT",
+               "BriefDescription": "ECC Cycles Count",
+               "PublicDescription": "Long ECC Function cycles count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "82",
+               "EventName": "ECC_BLOCKED_FUNCTION_COUNT",
+               "BriefDescription": "Ecc Blocked Function Count",
+               "PublicDescription": "Long ECC blocked function count"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "83",
+               "EventName": "ECC_BLOCKED_CYCLES_COUNT",
+               "BriefDescription": "ECC Blocked Cycles Count",
+               "PublicDescription": "Long ECC blocked cycles count"
+       },
+]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/extended.json b/tools/perf/pmu-events/arch/s390/cf_z15/extended.json
new file mode 100644 (file)
index 0000000..89e0707
--- /dev/null
@@ -0,0 +1,373 @@
+[
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "128",
+               "EventName": "L1D_RO_EXCL_WRITES",
+               "BriefDescription": "L1D Read-only Exclusive Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "129",
+               "EventName": "DTLB2_WRITES",
+               "BriefDescription": "DTLB2 Writes",
+               "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "130",
+               "EventName": "DTLB2_MISSES",
+               "BriefDescription": "DTLB2 Misses",
+               "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "131",
+               "EventName": "DTLB2_HPAGE_WRITES",
+               "BriefDescription": "DTLB2 One-Megabyte Page Writes",
+               "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "132",
+               "EventName": "DTLB2_GPAGE_WRITES",
+               "BriefDescription": "DTLB2 Two-Gigabyte Page Writes",
+               "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "133",
+               "EventName": "L1D_L2D_SOURCED_WRITES",
+               "BriefDescription": "L1D L2D Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "134",
+               "EventName": "ITLB2_WRITES",
+               "BriefDescription": "ITLB2 Writes",
+               "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "135",
+               "EventName": "ITLB2_MISSES",
+               "BriefDescription": "ITLB2 Misses",
+               "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "136",
+               "EventName": "L1I_L2I_SOURCED_WRITES",
+               "BriefDescription": "L1I L2I Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "137",
+               "EventName": "TLB2_PTE_WRITES",
+               "BriefDescription": "TLB2 PTE Writes",
+               "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "138",
+               "EventName": "TLB2_CRSTE_WRITES",
+               "BriefDescription": "TLB2 CRSTE Writes",
+               "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "139",
+               "EventName": "TLB2_ENGINES_BUSY",
+               "BriefDescription": "TLB2 Engines Busy",
+               "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "140",
+               "EventName": "TX_C_TEND",
+               "BriefDescription": "Completed TEND instructions in constrained TX mode",
+               "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "141",
+               "EventName": "TX_NC_TEND",
+               "BriefDescription": "Completed TEND instructions in non-constrained TX mode",
+               "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "143",
+               "EventName": "L1C_TLB2_MISSES",
+               "BriefDescription": "L1C TLB2 Misses",
+               "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "144",
+               "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES",
+               "BriefDescription": "L1D On-Chip L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "145",
+               "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1D On-Chip Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "146",
+               "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "147",
+               "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES",
+               "BriefDescription": "L1D On-Cluster L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "148",
+               "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1D On-Cluster Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "149",
+               "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "150",
+               "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES",
+               "BriefDescription": "L1D Off-Cluster L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "151",
+               "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1D Off-Cluster Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "152",
+               "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "153",
+               "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES",
+               "BriefDescription": "L1D Off-Drawer L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "154",
+               "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1D Off-Drawer Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "155",
+               "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "156",
+               "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES",
+               "BriefDescription": "L1D On-Drawer L4 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "157",
+               "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES",
+               "BriefDescription": "L1D Off-Drawer L4 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "158",
+               "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO",
+               "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only",
+               "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "162",
+               "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES",
+               "BriefDescription": "L1I On-Chip L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "163",
+               "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1I On-Chip Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "164",
+               "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "165",
+               "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES",
+               "BriefDescription": "L1I On-Cluster L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "166",
+               "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1I On-Cluster Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "167",
+               "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "168",
+               "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES",
+               "BriefDescription": "L1I Off-Cluster L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "169",
+               "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1I Off-Cluster Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "170",
+               "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "171",
+               "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES",
+               "BriefDescription": "L1I Off-Drawer L3 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "172",
+               "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES",
+               "BriefDescription": "L1I Off-Drawer Memory Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "173",
+               "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV",
+               "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "174",
+               "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES",
+               "BriefDescription": "L1I On-Drawer L4 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "175",
+               "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES",
+               "BriefDescription": "L1I Off-Drawer L4 Sourced Writes",
+               "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "224",
+               "EventName": "BCD_DFP_EXECUTION_SLOTS",
+               "BriefDescription": "BCD DFP Execution Slots",
+               "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "225",
+               "EventName": "VX_BCD_EXECUTION_SLOTS",
+               "BriefDescription": "VX BCD Execution Slots",
+               "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "226",
+               "EventName": "DECIMAL_INSTRUCTIONS",
+               "BriefDescription": "Decimal Instructions",
+               "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "232",
+               "EventName": "LAST_HOST_TRANSLATIONS",
+               "BriefDescription": "Last host translation done",
+               "PublicDescription": "Last Host Translation done"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "243",
+               "EventName": "TX_NC_TABORT",
+               "BriefDescription": "Aborted transactions in non-constrained TX mode",
+               "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "244",
+               "EventName": "TX_C_TABORT_NO_SPECIAL",
+               "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic",
+               "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "245",
+               "EventName": "TX_C_TABORT_SPECIAL",
+               "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic",
+               "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "448",
+               "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE",
+               "BriefDescription": "Cycle count with one thread active",
+               "PublicDescription": "Cycle count with one thread active"
+       },
+       {
+               "Unit": "CPU-M-CF",
+               "EventCode": "449",
+               "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE",
+               "BriefDescription": "Cycle count with two threads active",
+               "PublicDescription": "Cycle count with two threads active"
+       },
+]
diff --git a/tools/perf/pmu-events/arch/s390/cf_z15/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z15/transaction.json
new file mode 100644 (file)
index 0000000..1a0034f
--- /dev/null
@@ -0,0 +1,7 @@
+[
+  {
+    "BriefDescription": "Transaction count",
+    "MetricName": "transaction",
+    "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL"
+  }
+]
index bd3fc57..61641a3 100644 (file)
@@ -4,4 +4,4 @@ Family-model,Version,Filename,EventType
 ^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
-^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_m8561,core
+^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_z15,core
index 9e37287..e283726 100644 (file)
@@ -450,12 +450,12 @@ static struct fixed {
        const char *name;
        const char *event;
 } fixed[] = {
-       { "inst_retired.any", "event=0xc0" },
-       { "inst_retired.any_p", "event=0xc0" },
-       { "cpu_clk_unhalted.ref", "event=0x0,umask=0x03" },
-       { "cpu_clk_unhalted.thread", "event=0x3c" },
-       { "cpu_clk_unhalted.core", "event=0x3c" },
-       { "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" },
+       { "inst_retired.any", "event=0xc0,period=2000003" },
+       { "inst_retired.any_p", "event=0xc0,period=2000003" },
+       { "cpu_clk_unhalted.ref", "event=0x0,umask=0x03,period=2000003" },
+       { "cpu_clk_unhalted.thread", "event=0x3c,period=2000003" },
+       { "cpu_clk_unhalted.core", "event=0x3c,period=2000003" },
+       { "cpu_clk_unhalted.thread_any", "event=0x3c,any=1,period=2000003" },
        { NULL, NULL},
 };
 
index dbc2719..dd865e0 100644 (file)
@@ -19,12 +19,11 @@ static void sigsegv_handler(int sig __maybe_unused)
 static void the_hook(void *_hook_flags)
 {
        int *hook_flags = _hook_flags;
-       int *p = NULL;
 
        *hook_flags = 1234;
 
        /* Generate a segfault, test perf_hooks__recover */
-       *p = 0;
+       raise(SIGSEGV);
 }
 
 int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused)
index e830ead..4036c7f 100644 (file)
@@ -1631,6 +1631,19 @@ int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map *
        case SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF:
                scnprintf(buf, buflen, "Please link with binutils's libopcode to enable BPF annotation");
                break;
+       case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP:
+               scnprintf(buf, buflen, "Problems with arch specific instruction name regular expressions.");
+               break;
+       case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING:
+               scnprintf(buf, buflen, "Problems while parsing the CPUID in the arch specific initialization.");
+               break;
+       case SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE:
+               scnprintf(buf, buflen, "Invalid BPF file: %s.", dso->long_name);
+               break;
+       case SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF:
+               scnprintf(buf, buflen, "The %s BPF file has no BTF section, compile with -g or use pahole -J.",
+                         dso->long_name);
+               break;
        default:
                scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum);
                break;
@@ -1662,7 +1675,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
 
        build_id_path = strdup(filename);
        if (!build_id_path)
-               return -1;
+               return ENOMEM;
 
        /*
         * old style build-id cache has name of XX/XXXXXXX.. while
@@ -1713,13 +1726,13 @@ static int symbol__disassemble_bpf(struct symbol *sym,
        char tpath[PATH_MAX];
        size_t buf_size;
        int nr_skip = 0;
-       int ret = -1;
        char *buf;
        bfd *bfdf;
+       int ret;
        FILE *s;
 
        if (dso->binary_type != DSO_BINARY_TYPE__BPF_PROG_INFO)
-               return -1;
+               return SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE;
 
        pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__,
                  sym->name, sym->start, sym->end - sym->start);
@@ -1732,8 +1745,10 @@ static int symbol__disassemble_bpf(struct symbol *sym,
        assert(bfd_check_format(bfdf, bfd_object));
 
        s = open_memstream(&buf, &buf_size);
-       if (!s)
+       if (!s) {
+               ret = errno;
                goto out;
+       }
        init_disassemble_info(&info, s,
                              (fprintf_ftype) fprintf);
 
@@ -1742,8 +1757,10 @@ static int symbol__disassemble_bpf(struct symbol *sym,
 
        info_node = perf_env__find_bpf_prog_info(dso->bpf_prog.env,
                                                 dso->bpf_prog.id);
-       if (!info_node)
+       if (!info_node) {
+               return SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF;
                goto out;
+       }
        info_linear = info_node->info_linear;
        sub_id = dso->bpf_prog.sub_id;
 
@@ -2071,11 +2088,11 @@ int symbol__annotate(struct symbol *sym, struct map *map,
        int err;
 
        if (!arch_name)
-               return -1;
+               return errno;
 
        args.arch = arch = arch__find(arch_name);
        if (arch == NULL)
-               return -ENOTSUP;
+               return ENOTSUP;
 
        if (parch)
                *parch = arch;
@@ -2971,7 +2988,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel,
 
        notes->offsets = zalloc(size * sizeof(struct annotation_line *));
        if (notes->offsets == NULL)
-               return -1;
+               return ENOMEM;
 
        if (perf_evsel__is_group_event(evsel))
                nr_pcnt = evsel->core.nr_members;
@@ -2997,7 +3014,7 @@ int symbol__annotate2(struct symbol *sym, struct map *map, struct evsel *evsel,
 
 out_free_offsets:
        zfree(&notes->offsets);
-       return -1;
+       return err;
 }
 
 #define ANNOTATION__CFG(n) \
index d94be91..d76fd0e 100644 (file)
@@ -370,6 +370,10 @@ enum symbol_disassemble_errno {
 
        SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX       = __SYMBOL_ANNOTATE_ERRNO__START,
        SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF,
+       SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING,
+       SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP,
+       SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE,
+       SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF,
 
        __SYMBOL_ANNOTATE_ERRNO__END,
 };
index 5591af8..abc7fda 100644 (file)
@@ -30,6 +30,7 @@
 #include "counts.h"
 #include "event.h"
 #include "evsel.h"
+#include "util/env.h"
 #include "util/evsel_config.h"
 #include "util/evsel_fprintf.h"
 #include "evlist.h"
@@ -2512,7 +2513,7 @@ struct perf_env *perf_evsel__env(struct evsel *evsel)
 {
        if (evsel && evsel->evlist)
                return evsel->evlist->env;
-       return NULL;
+       return &perf_env;
 }
 
 static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist)
index 1bdf4c6..e3ccb0c 100644 (file)
@@ -395,7 +395,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
        size_t size;
        u16 idr_size;
        const char *sym;
-       uint32_t count;
+       uint64_t count;
        int ret, csize, usize;
        pid_t pid, tid;
        struct {
@@ -418,7 +418,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
                return -1;
 
        filename = event->mmap2.filename;
-       size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%u.so",
+       size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so",
                        jd->dir,
                        pid,
                        count);
@@ -529,7 +529,7 @@ static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr)
                return -1;
 
        filename = event->mmap2.filename;
-       size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%"PRIu64,
+       size = snprintf(filename, PATH_MAX, "%s/jitted-%d-%" PRIu64 ".so",
                 jd->dir,
                 pid,
                 jr->move.code_index);
index 8d04e3d..8b14e4a 100644 (file)
@@ -233,14 +233,14 @@ static int detect_kbuild_dir(char **kbuild_dir)
        const char *prefix_dir = "";
        const char *suffix_dir = "";
 
+       /* _UTSNAME_LENGTH is 65 */
+       char release[128];
+
        char *autoconf_path;
 
        int err;
 
        if (!test_dir) {
-               /* _UTSNAME_LENGTH is 65 */
-               char release[128];
-
                err = fetch_kernel_version(NULL, release,
                                           sizeof(release));
                if (err)
index 5b83ed1..eec9b28 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "symbol.h"
+#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
@@ -850,6 +851,8 @@ static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp
                        }
 
                        after->start = map->end;
+                       after->pgoff += map->end - pos->start;
+                       assert(pos->map_ip(pos, map->end) == after->map_ip(after, map->end));
                        __map_groups__insert(pos->groups, after);
                        if (verbose >= 2 && !use_browser)
                                map__fprintf(after, fp);
index 53f3105..0246036 100644 (file)
@@ -14,6 +14,7 @@
 #include "thread_map.h"
 #include "trace-event.h"
 #include "mmap.h"
+#include "util/env.h"
 #include <internal/lib.h>
 #include "../perf-sys.h"
 
@@ -53,6 +54,11 @@ int parse_callchain_record(const char *arg __maybe_unused,
        return 0;
 }
 
+/*
+ * Add this one here not to drag util/env.c
+ */
+struct perf_env perf_env;
+
 /*
  * Support debug printing even though util/debug.c is not linked.  That means
  * implementing 'verbose' and 'eprintf'.
index c3feccb..4cdbae6 100644 (file)
@@ -63,6 +63,13 @@ TARGETS += zram
 TARGETS_HOTPLUG = cpu-hotplug
 TARGETS_HOTPLUG += memory-hotplug
 
+# User can optionally provide a TARGETS skiplist.
+SKIP_TARGETS ?=
+ifneq ($(SKIP_TARGETS),)
+       TMP := $(filter-out $(SKIP_TARGETS), $(TARGETS))
+       override TARGETS := $(TMP)
+endif
+
 # Clear LDFLAGS and MAKEFLAGS if called from main
 # Makefile to avoid test build failures when test
 # Makefile doesn't have explicit build rules.
@@ -171,9 +178,12 @@ run_pstore_crash:
 # 1. output_dir=kernel_src
 # 2. a separate output directory is specified using O= KBUILD_OUTPUT
 # 3. a separate output directory is specified using KBUILD_OUTPUT
+# Avoid conflict with INSTALL_PATH set by the main Makefile
 #
-INSTALL_PATH ?= $(BUILD)/install
-INSTALL_PATH := $(abspath $(INSTALL_PATH))
+KSFT_INSTALL_PATH ?= $(BUILD)/kselftest_install
+KSFT_INSTALL_PATH := $(abspath $(KSFT_INSTALL_PATH))
+# Avoid changing the rest of the logic here and lib.mk.
+INSTALL_PATH := $(KSFT_INSTALL_PATH)
 ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh
 
 install: all
@@ -198,11 +208,16 @@ ifdef INSTALL_PATH
        echo "  cat /dev/null > \$$logfile" >> $(ALL_SCRIPT)
        echo "fi" >> $(ALL_SCRIPT)
 
+       @# While building run_kselftest.sh skip also non-existent TARGET dirs:
+       @# they could be the result of a build failure and should NOT be
+       @# included in the generated runlist.
        for TARGET in $(TARGETS); do \
                BUILD_TARGET=$$BUILD/$$TARGET;  \
+               [ ! -d $$INSTALL_PATH/$$TARGET ] && echo "Skipping non-existent dir: $$TARGET" && continue; \
                echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \
                echo "cd $$TARGET" >> $(ALL_SCRIPT); \
                echo -n "run_many" >> $(ALL_SCRIPT); \
+               echo -n "Emit Tests for $$TARGET\n"; \
                $(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \
                echo "" >> $(ALL_SCRIPT);           \
                echo "cd \$$ROOT" >> $(ALL_SCRIPT); \
index 00c9020..84de7bc 100644 (file)
@@ -3,9 +3,14 @@
 #
 # Runs a set of tests in a given subdirectory.
 export skip_rc=4
+export timeout_rc=124
 export logfile=/dev/stdout
 export per_test_logging=
 
+# Defaults for "settings" file fields:
+# "timeout" how many seconds to let each test run before failing.
+export kselftest_default_timeout=45
+
 # There isn't a shell-agnostic way to find the path of a sourced file,
 # so we must rely on BASE_DIR being set to find other tools.
 if [ -z "$BASE_DIR" ]; then
@@ -24,6 +29,16 @@ tap_prefix()
        fi
 }
 
+tap_timeout()
+{
+       # Make sure tests will time out if utility is available.
+       if [ -x /usr/bin/timeout ] ; then
+               /usr/bin/timeout "$kselftest_timeout" "$1"
+       else
+               "$1"
+       fi
+}
+
 run_one()
 {
        DIR="$1"
@@ -32,6 +47,18 @@ run_one()
 
        BASENAME_TEST=$(basename $TEST)
 
+       # Reset any "settings"-file variables.
+       export kselftest_timeout="$kselftest_default_timeout"
+       # Load per-test-directory kselftest "settings" file.
+       settings="$BASE_DIR/$DIR/settings"
+       if [ -r "$settings" ] ; then
+               while read line ; do
+                       field=$(echo "$line" | cut -d= -f1)
+                       value=$(echo "$line" | cut -d= -f2-)
+                       eval "kselftest_$field"="$value"
+               done < "$settings"
+       fi
+
        TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"
        echo "# $TEST_HDR_MSG"
        if [ ! -x "$TEST" ]; then
@@ -44,14 +71,17 @@ run_one()
                echo "not ok $test_num $TEST_HDR_MSG"
        else
                cd `dirname $TEST` > /dev/null
-               (((((./$BASENAME_TEST 2>&1; echo $? >&3) |
+               ((((( tap_timeout ./$BASENAME_TEST 2>&1; echo $? >&3) |
                        tap_prefix >&4) 3>&1) |
                        (read xs; exit $xs)) 4>>"$logfile" &&
                echo "ok $test_num $TEST_HDR_MSG") ||
-               (if [ $? -eq $skip_rc ]; then   \
+               (rc=$?; \
+               if [ $rc -eq $skip_rc ]; then   \
                        echo "not ok $test_num $TEST_HDR_MSG # SKIP"
+               elif [ $rc -eq $timeout_rc ]; then \
+                       echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT"
                else
-                       echo "not ok $test_num $TEST_HDR_MSG"
+                       echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
                fi)
                cd - >/dev/null
        fi
index ec30446..e2e1911 100755 (executable)
@@ -24,12 +24,12 @@ main()
                echo "$0: Installing in specified location - $install_loc ..."
        fi
 
-       install_dir=$install_loc/kselftest
+       install_dir=$install_loc/kselftest_install
 
 # Create install directory
        mkdir -p $install_dir
 # Build tests
-       INSTALL_PATH=$install_dir make install
+       KSFT_INSTALL_PATH=$install_dir make install
 }
 
 main "$@"
index 62c591f..c5ec868 100644 (file)
@@ -22,6 +22,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/smm_test
 TEST_GEN_PROGS_x86_64 += x86_64/state_test
 TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
 TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
 TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
 TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
 TEST_GEN_PROGS_x86_64 += clear_dirty_log_test
@@ -48,7 +49,7 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
        -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(UNAME_M) -I..
 
 no-pie-option := $(call try-run, echo 'int main() { return 0; }' | \
-        $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
+        $(CC) -Werror -no-pie -x c - -o "$$TMP", -no-pie)
 
 # On s390, build the testcases KVM-enabled
 pgste-option = $(call try-run, echo 'int main() { return 0; }' | \
index 0c17f2e..ff23401 100644 (file)
@@ -1083,6 +1083,9 @@ void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits);
 #define VMX_BASIC_MEM_TYPE_WB  6LLU
 #define VMX_BASIC_INOUT                0x0040000000000000LLU
 
+/* VMX_EPT_VPID_CAP bits */
+#define VMX_EPT_VPID_CAP_AD_BITS       (1ULL << 21)
+
 /* MSR_IA32_VMX_MISC bits */
 #define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
 #define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE   0x1F
index 69b1705..6ae5a47 100644 (file)
@@ -569,6 +569,10 @@ struct vmx_pages {
        void *enlightened_vmcs_hva;
        uint64_t enlightened_vmcs_gpa;
        void *enlightened_vmcs;
+
+       void *eptp_hva;
+       uint64_t eptp_gpa;
+       void *eptp;
 };
 
 struct vmx_pages *vcpu_alloc_vmx(struct kvm_vm *vm, vm_vaddr_t *p_vmx_gva);
@@ -576,4 +580,14 @@ bool prepare_for_vmx_operation(struct vmx_pages *vmx);
 void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp);
 bool load_vmcs(struct vmx_pages *vmx);
 
+void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+                  uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot);
+void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+                uint64_t nested_paddr, uint64_t paddr, uint64_t size,
+                uint32_t eptp_memslot);
+void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
+                       uint32_t memslot, uint32_t eptp_memslot);
+void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm,
+                 uint32_t eptp_memslot);
+
 #endif /* SELFTEST_KVM_VMX_H */
index 80a338b..41cf454 100644 (file)
@@ -705,7 +705,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
  *   on error (e.g. currently no memory region using memslot as a KVM
  *   memory slot ID).
  */
-static struct userspace_mem_region *
+struct userspace_mem_region *
 memslot2region(struct kvm_vm *vm, uint32_t memslot)
 {
        struct userspace_mem_region *region;
index f36262e..ac50c42 100644 (file)
@@ -68,4 +68,7 @@ void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent);
 void regs_dump(FILE *stream, struct kvm_regs *regs, uint8_t indent);
 void sregs_dump(FILE *stream, struct kvm_sregs *sregs, uint8_t indent);
 
+struct userspace_mem_region *
+memslot2region(struct kvm_vm *vm, uint32_t memslot);
+
 #endif /* SELFTEST_KVM_UTIL_INTERNAL_H */
index c53dbc6..6698cb7 100644 (file)
@@ -1085,7 +1085,7 @@ struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid)
        for (i = 0; i < nmsrs; i++)
                state->msrs.entries[i].index = list->indices[i];
        r = ioctl(vcpu->fd, KVM_GET_MSRS, &state->msrs);
-        TEST_ASSERT(r == nmsrs, "Unexpected result from KVM_GET_MSRS, r: %i (failed at %x)",
+        TEST_ASSERT(r == nmsrs, "Unexpected result from KVM_GET_MSRS, r: %i (failed MSR was 0x%x)",
                 r, r == nmsrs ? -1 : list->indices[r]);
 
        r = ioctl(vcpu->fd, KVM_GET_DEBUGREGS, &state->debugregs);
index 9cef045..fab8f6b 100644 (file)
@@ -7,11 +7,39 @@
 
 #include "test_util.h"
 #include "kvm_util.h"
+#include "../kvm_util_internal.h"
 #include "processor.h"
 #include "vmx.h"
 
+#define PAGE_SHIFT_4K  12
+
+#define KVM_EPT_PAGE_TABLE_MIN_PADDR 0x1c0000
+
 bool enable_evmcs;
 
+struct eptPageTableEntry {
+       uint64_t readable:1;
+       uint64_t writable:1;
+       uint64_t executable:1;
+       uint64_t memory_type:3;
+       uint64_t ignore_pat:1;
+       uint64_t page_size:1;
+       uint64_t accessed:1;
+       uint64_t dirty:1;
+       uint64_t ignored_11_10:2;
+       uint64_t address:40;
+       uint64_t ignored_62_52:11;
+       uint64_t suppress_ve:1;
+};
+
+struct eptPageTablePointer {
+       uint64_t memory_type:3;
+       uint64_t page_walk_length:3;
+       uint64_t ad_enabled:1;
+       uint64_t reserved_11_07:5;
+       uint64_t address:40;
+       uint64_t reserved_63_52:12;
+};
 int vcpu_enable_evmcs(struct kvm_vm *vm, int vcpu_id)
 {
        uint16_t evmcs_ver;
@@ -174,15 +202,35 @@ bool load_vmcs(struct vmx_pages *vmx)
  */
 static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
 {
+       uint32_t sec_exec_ctl = 0;
+
        vmwrite(VIRTUAL_PROCESSOR_ID, 0);
        vmwrite(POSTED_INTR_NV, 0);
 
        vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS));
-       if (!vmwrite(SECONDARY_VM_EXEC_CONTROL, 0))
+
+       if (vmx->eptp_gpa) {
+               uint64_t ept_paddr;
+               struct eptPageTablePointer eptp = {
+                       .memory_type = VMX_BASIC_MEM_TYPE_WB,
+                       .page_walk_length = 3, /* + 1 */
+                       .ad_enabled = !!(rdmsr(MSR_IA32_VMX_EPT_VPID_CAP) & VMX_EPT_VPID_CAP_AD_BITS),
+                       .address = vmx->eptp_gpa >> PAGE_SHIFT_4K,
+               };
+
+               memcpy(&ept_paddr, &eptp, sizeof(ept_paddr));
+               vmwrite(EPT_POINTER, ept_paddr);
+               sec_exec_ctl |= SECONDARY_EXEC_ENABLE_EPT;
+       }
+
+       if (!vmwrite(SECONDARY_VM_EXEC_CONTROL, sec_exec_ctl))
                vmwrite(CPU_BASED_VM_EXEC_CONTROL,
                        rdmsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS) | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS);
-       else
+       else {
                vmwrite(CPU_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS));
+               GUEST_ASSERT(!sec_exec_ctl);
+       }
+
        vmwrite(EXCEPTION_BITMAP, 0);
        vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
        vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, -1); /* Never match */
@@ -327,3 +375,152 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp)
        init_vmcs_host_state();
        init_vmcs_guest_state(guest_rip, guest_rsp);
 }
+
+void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+                  uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot)
+{
+       uint16_t index[4];
+       struct eptPageTableEntry *pml4e;
+
+       TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
+                   "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
+
+       TEST_ASSERT((nested_paddr % vm->page_size) == 0,
+                   "Nested physical address not on page boundary,\n"
+                   "  nested_paddr: 0x%lx vm->page_size: 0x%x",
+                   nested_paddr, vm->page_size);
+       TEST_ASSERT((nested_paddr >> vm->page_shift) <= vm->max_gfn,
+                   "Physical address beyond beyond maximum supported,\n"
+                   "  nested_paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
+                   paddr, vm->max_gfn, vm->page_size);
+       TEST_ASSERT((paddr % vm->page_size) == 0,
+                   "Physical address not on page boundary,\n"
+                   "  paddr: 0x%lx vm->page_size: 0x%x",
+                   paddr, vm->page_size);
+       TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn,
+                   "Physical address beyond beyond maximum supported,\n"
+                   "  paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
+                   paddr, vm->max_gfn, vm->page_size);
+
+       index[0] = (nested_paddr >> 12) & 0x1ffu;
+       index[1] = (nested_paddr >> 21) & 0x1ffu;
+       index[2] = (nested_paddr >> 30) & 0x1ffu;
+       index[3] = (nested_paddr >> 39) & 0x1ffu;
+
+       /* Allocate page directory pointer table if not present. */
+       pml4e = vmx->eptp_hva;
+       if (!pml4e[index[3]].readable) {
+               pml4e[index[3]].address = vm_phy_page_alloc(vm,
+                         KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
+                       >> vm->page_shift;
+               pml4e[index[3]].writable = true;
+               pml4e[index[3]].readable = true;
+               pml4e[index[3]].executable = true;
+       }
+
+       /* Allocate page directory table if not present. */
+       struct eptPageTableEntry *pdpe;
+       pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size);
+       if (!pdpe[index[2]].readable) {
+               pdpe[index[2]].address = vm_phy_page_alloc(vm,
+                         KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
+                       >> vm->page_shift;
+               pdpe[index[2]].writable = true;
+               pdpe[index[2]].readable = true;
+               pdpe[index[2]].executable = true;
+       }
+
+       /* Allocate page table if not present. */
+       struct eptPageTableEntry *pde;
+       pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size);
+       if (!pde[index[1]].readable) {
+               pde[index[1]].address = vm_phy_page_alloc(vm,
+                         KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
+                       >> vm->page_shift;
+               pde[index[1]].writable = true;
+               pde[index[1]].readable = true;
+               pde[index[1]].executable = true;
+       }
+
+       /* Fill in page table entry. */
+       struct eptPageTableEntry *pte;
+       pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size);
+       pte[index[0]].address = paddr >> vm->page_shift;
+       pte[index[0]].writable = true;
+       pte[index[0]].readable = true;
+       pte[index[0]].executable = true;
+
+       /*
+        * For now mark these as accessed and dirty because the only
+        * testcase we have needs that.  Can be reconsidered later.
+        */
+       pte[index[0]].accessed = true;
+       pte[index[0]].dirty = true;
+}
+
+/*
+ * Map a range of EPT guest physical addresses to the VM's physical address
+ *
+ * Input Args:
+ *   vm - Virtual Machine
+ *   nested_paddr - Nested guest physical address to map
+ *   paddr - VM Physical Address
+ *   size - The size of the range to map
+ *   eptp_memslot - Memory region slot for new virtual translation tables
+ *
+ * Output Args: None
+ *
+ * Return: None
+ *
+ * Within the VM given by vm, creates a nested guest translation for the
+ * page range starting at nested_paddr to the page range starting at paddr.
+ */
+void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+               uint64_t nested_paddr, uint64_t paddr, uint64_t size,
+               uint32_t eptp_memslot)
+{
+       size_t page_size = vm->page_size;
+       size_t npages = size / page_size;
+
+       TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow");
+       TEST_ASSERT(paddr + size > paddr, "Paddr overflow");
+
+       while (npages--) {
+               nested_pg_map(vmx, vm, nested_paddr, paddr, eptp_memslot);
+               nested_paddr += page_size;
+               paddr += page_size;
+       }
+}
+
+/* Prepare an identity extended page table that maps all the
+ * physical pages in VM.
+ */
+void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
+                       uint32_t memslot, uint32_t eptp_memslot)
+{
+       sparsebit_idx_t i, last;
+       struct userspace_mem_region *region =
+               memslot2region(vm, memslot);
+
+       i = (region->region.guest_phys_addr >> vm->page_shift) - 1;
+       last = i + (region->region.memory_size >> vm->page_shift);
+       for (;;) {
+               i = sparsebit_next_clear(region->unused_phy_pages, i);
+               if (i > last)
+                       break;
+
+               nested_map(vmx, vm,
+                          (uint64_t)i << vm->page_shift,
+                          (uint64_t)i << vm->page_shift,
+                          1 << vm->page_shift,
+                          eptp_memslot);
+       }
+}
+
+void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm,
+                 uint32_t eptp_memslot)
+{
+       vmx->eptp = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
+       vmx->eptp_hva = addr_gva2hva(vm, (uintptr_t)vmx->eptp);
+       vmx->eptp_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->eptp);
+}
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c b/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c
new file mode 100644 (file)
index 0000000..0bca1cf
--- /dev/null
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KVM dirty page logging test
+ *
+ * Copyright (C) 2018, Red Hat, Inc.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_name */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+#include "vmx.h"
+
+#define VCPU_ID                                1
+
+/* The memory slot index to track dirty pages */
+#define TEST_MEM_SLOT_INDEX            1
+#define TEST_MEM_SIZE                  3
+
+/* L1 guest test virtual memory offset */
+#define GUEST_TEST_MEM                 0xc0000000
+
+/* L2 guest test virtual memory offset */
+#define NESTED_TEST_MEM1               0xc0001000
+#define NESTED_TEST_MEM2               0xc0002000
+
+static void l2_guest_code(void)
+{
+       *(volatile uint64_t *)NESTED_TEST_MEM1;
+       *(volatile uint64_t *)NESTED_TEST_MEM1 = 1;
+       GUEST_SYNC(true);
+       GUEST_SYNC(false);
+
+       *(volatile uint64_t *)NESTED_TEST_MEM2 = 1;
+       GUEST_SYNC(true);
+       *(volatile uint64_t *)NESTED_TEST_MEM2 = 1;
+       GUEST_SYNC(true);
+       GUEST_SYNC(false);
+
+       /* Exit to L1 and never come back.  */
+       vmcall();
+}
+
+void l1_guest_code(struct vmx_pages *vmx)
+{
+#define L2_GUEST_STACK_SIZE 64
+       unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
+
+       GUEST_ASSERT(vmx->vmcs_gpa);
+       GUEST_ASSERT(prepare_for_vmx_operation(vmx));
+       GUEST_ASSERT(load_vmcs(vmx));
+
+       prepare_vmcs(vmx, l2_guest_code,
+                    &l2_guest_stack[L2_GUEST_STACK_SIZE]);
+
+       GUEST_SYNC(false);
+       GUEST_ASSERT(!vmlaunch());
+       GUEST_SYNC(false);
+       GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+       GUEST_DONE();
+}
+
+int main(int argc, char *argv[])
+{
+       vm_vaddr_t vmx_pages_gva = 0;
+       struct vmx_pages *vmx;
+       unsigned long *bmap;
+       uint64_t *host_test_mem;
+
+       struct kvm_vm *vm;
+       struct kvm_run *run;
+       struct ucall uc;
+       bool done = false;
+
+       /* Create VM */
+       vm = vm_create_default(VCPU_ID, 0, l1_guest_code);
+       vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
+       vmx = vcpu_alloc_vmx(vm, &vmx_pages_gva);
+       vcpu_args_set(vm, VCPU_ID, 1, vmx_pages_gva);
+       run = vcpu_state(vm, VCPU_ID);
+
+       /* Add an extra memory slot for testing dirty logging */
+       vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
+                                   GUEST_TEST_MEM,
+                                   TEST_MEM_SLOT_INDEX,
+                                   TEST_MEM_SIZE,
+                                   KVM_MEM_LOG_DIRTY_PAGES);
+
+       /*
+        * Add an identity map for GVA range [0xc0000000, 0xc0002000).  This
+        * affects both L1 and L2.  However...
+        */
+       virt_map(vm, GUEST_TEST_MEM, GUEST_TEST_MEM,
+                TEST_MEM_SIZE * 4096, 0);
+
+       /*
+        * ... pages in the L2 GPA range [0xc0001000, 0xc0003000) will map to
+        * 0xc0000000.
+        *
+        * Note that prepare_eptp should be called only L1's GPA map is done,
+        * meaning after the last call to virt_map.
+        */
+       prepare_eptp(vmx, vm, 0);
+       nested_map_memslot(vmx, vm, 0, 0);
+       nested_map(vmx, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, 4096, 0);
+       nested_map(vmx, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, 4096, 0);
+
+       bmap = bitmap_alloc(TEST_MEM_SIZE);
+       host_test_mem = addr_gpa2hva(vm, GUEST_TEST_MEM);
+
+       while (!done) {
+               memset(host_test_mem, 0xaa, TEST_MEM_SIZE * 4096);
+               _vcpu_run(vm, VCPU_ID);
+               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
+                           "Unexpected exit reason: %u (%s),\n",
+                           run->exit_reason,
+                           exit_reason_str(run->exit_reason));
+
+               switch (get_ucall(vm, VCPU_ID, &uc)) {
+               case UCALL_ABORT:
+                       TEST_ASSERT(false, "%s at %s:%d", (const char *)uc.args[0],
+                                   __FILE__, uc.args[1]);
+                       /* NOT REACHED */
+               case UCALL_SYNC:
+                       /*
+                        * The nested guest wrote at offset 0x1000 in the memslot, but the
+                        * dirty bitmap must be filled in according to L1 GPA, not L2.
+                        */
+                       kvm_vm_get_dirty_log(vm, TEST_MEM_SLOT_INDEX, bmap);
+                       if (uc.args[1]) {
+                               TEST_ASSERT(test_bit(0, bmap), "Page 0 incorrectly reported clean\n");
+                               TEST_ASSERT(host_test_mem[0] == 1, "Page 0 not written by guest\n");
+                       } else {
+                               TEST_ASSERT(!test_bit(0, bmap), "Page 0 incorrectly reported dirty\n");
+                               TEST_ASSERT(host_test_mem[0] == 0xaaaaaaaaaaaaaaaaULL, "Page 0 written by guest\n");
+                       }
+
+                       TEST_ASSERT(!test_bit(1, bmap), "Page 1 incorrectly reported dirty\n");
+                       TEST_ASSERT(host_test_mem[4096 / 8] == 0xaaaaaaaaaaaaaaaaULL, "Page 1 written by guest\n");
+                       TEST_ASSERT(!test_bit(2, bmap), "Page 2 incorrectly reported dirty\n");
+                       TEST_ASSERT(host_test_mem[8192 / 8] == 0xaaaaaaaaaaaaaaaaULL, "Page 2 written by guest\n");
+                       break;
+               case UCALL_DONE:
+                       done = true;
+                       break;
+               default:
+                       TEST_ASSERT(false, "Unknown ucall 0x%x.", uc.cmd);
+               }
+       }
+}
index c7cced7..8aefd81 100644 (file)
@@ -21,3 +21,4 @@ ipv6_flowlabel
 ipv6_flowlabel_mgr
 so_txtime
 tcp_fastopen_backup_key
+nettest
index b8265ee..614b31a 100644 (file)
@@ -89,12 +89,9 @@ struct testcase testcases_v4[] = {
                .tfail = true,
        },
        {
-               /* send a single MSS: will fail with GSO, because the segment
-                * logic in udp4_ufo_fragment demands a gso skb to be > MTU
-                */
+               /* send a single MSS: will fall back to no GSO */
                .tlen = CONST_MSS_V4,
                .gso_len = CONST_MSS_V4,
-               .tfail = true,
                .r_num_mss = 1,
        },
        {
@@ -139,10 +136,9 @@ struct testcase testcases_v4[] = {
                .tfail = true,
        },
        {
-               /* send a single 1B MSS: will fail, see single MSS above */
+               /* send a single 1B MSS: will fall back to no GSO */
                .tlen = 1,
                .gso_len = 1,
-               .tfail = true,
                .r_num_mss = 1,
        },
        {
@@ -196,12 +192,9 @@ struct testcase testcases_v6[] = {
                .tfail = true,
        },
        {
-               /* send a single MSS: will fail with GSO, because the segment
-                * logic in udp4_ufo_fragment demands a gso skb to be > MTU
-                */
+               /* send a single MSS: will fall back to no GSO */
                .tlen = CONST_MSS_V6,
                .gso_len = CONST_MSS_V6,
-               .tfail = true,
                .r_num_mss = 1,
        },
        {
@@ -246,10 +239,9 @@ struct testcase testcases_v6[] = {
                .tfail = true,
        },
        {
-               /* send a single 1B MSS: will fail, see single MSS above */
+               /* send a single 1B MSS: will fall back to no GSO */
                .tlen = 1,
                .gso_len = 1,
-               .tfail = true,
                .r_num_mss = 1,
        },
        {
index 464c9b7..7550f08 100644 (file)
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
-CFLAGS += -g -I../../../../usr/include/ -lpthread
+CFLAGS += -g -I../../../../usr/include/ -pthread
 
 TEST_GEN_PROGS := pidfd_test pidfd_open_test pidfd_poll_test pidfd_wait
 
index 9868a5d..f85a093 100644 (file)
@@ -636,7 +636,7 @@ int main(int argc, char *argv[])
                        nrthreads = strtoul(optarg, NULL, 10);
                        break;
                case 'l':
-                       strncpy(logdir, optarg, LOGDIR_NAME_SIZE);
+                       strncpy(logdir, optarg, LOGDIR_NAME_SIZE - 1);
                        break;
                case 't':
                        run_time = strtoul(optarg, NULL, 10);
diff --git a/tools/testing/selftests/rtc/settings b/tools/testing/selftests/rtc/settings
new file mode 100644 (file)
index 0000000..ba4d85f
--- /dev/null
@@ -0,0 +1 @@
+timeout=90
index afff120..f45e510 100644 (file)
@@ -19,7 +19,7 @@
 
 int fd;
 const char v = 'V';
-static const char sopts[] = "bdehp:t:Tn:NLf:";
+static const char sopts[] = "bdehp:t:Tn:NLf:i";
 static const struct option lopts[] = {
        {"bootstatus",          no_argument, NULL, 'b'},
        {"disable",             no_argument, NULL, 'd'},
@@ -32,6 +32,7 @@ static const struct option lopts[] = {
        {"getpretimeout",       no_argument, NULL, 'N'},
        {"gettimeleft",         no_argument, NULL, 'L'},
        {"file",          required_argument, NULL, 'f'},
+       {"info",                no_argument, NULL, 'i'},
        {NULL,                  no_argument, NULL, 0x0}
 };
 
@@ -72,6 +73,7 @@ static void usage(char *progname)
        printf("Usage: %s [options]\n", progname);
        printf(" -f, --file\t\tOpen watchdog device file\n");
        printf("\t\t\tDefault is /dev/watchdog\n");
+       printf(" -i, --info\t\tShow watchdog_info\n");
        printf(" -b, --bootstatus\tGet last boot status (Watchdog/POR)\n");
        printf(" -d, --disable\t\tTurn off the watchdog timer\n");
        printf(" -e, --enable\t\tTurn on the watchdog timer\n");
@@ -97,6 +99,7 @@ int main(int argc, char *argv[])
        int c;
        int oneshot = 0;
        char *file = "/dev/watchdog";
+       struct watchdog_info info;
 
        setbuf(stdout, NULL);
 
@@ -118,6 +121,16 @@ int main(int argc, char *argv[])
                exit(-1);
        }
 
+       /*
+        * Validate that `file` is a watchdog device
+        */
+       ret = ioctl(fd, WDIOC_GETSUPPORT, &info);
+       if (ret) {
+               printf("WDIOC_GETSUPPORT error '%s'\n", strerror(errno));
+               close(fd);
+               exit(ret);
+       }
+
        optind = 0;
 
        while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
@@ -205,6 +218,18 @@ int main(int argc, char *argv[])
                case 'f':
                        /* Handled above */
                        break;
+               case 'i':
+                       /*
+                        * watchdog_info was obtained as part of file open
+                        * validation. So we just show it here.
+                        */
+                       oneshot = 1;
+                       printf("watchdog_info:\n");
+                       printf(" identity:\t\t%s\n", info.identity);
+                       printf(" firmware_version:\t%u\n",
+                              info.firmware_version);
+                       printf(" options:\t\t%08x\n", info.options);
+                       break;
 
                default:
                        usage(argv[0]);
index c9449aa..57b20f7 100644 (file)
@@ -29,13 +29,11 @@ header-test- += linux/android/binderfs.h
 header-test-$(CONFIG_CPU_BIG_ENDIAN) += linux/byteorder/big_endian.h
 header-test-$(CONFIG_CPU_LITTLE_ENDIAN) += linux/byteorder/little_endian.h
 header-test- += linux/coda.h
-header-test- += linux/coda_psdev.h
 header-test- += linux/elfcore.h
 header-test- += linux/errqueue.h
 header-test- += linux/fsmap.h
 header-test- += linux/hdlc/ioctl.h
 header-test- += linux/ivtv.h
-header-test- += linux/jffs2.h
 header-test- += linux/kexec.h
 header-test- += linux/matroxfb.h
 header-test- += linux/netfilter_ipv4/ipt_LOG.h
@@ -55,20 +53,12 @@ header-test- += linux/v4l2-mediabus.h
 header-test- += linux/v4l2-subdev.h
 header-test- += linux/videodev2.h
 header-test- += linux/vm_sockets.h
-header-test- += scsi/scsi_bsg_fc.h
-header-test- += scsi/scsi_netlink.h
-header-test- += scsi/scsi_netlink_fc.h
 header-test- += sound/asequencer.h
 header-test- += sound/asoc.h
 header-test- += sound/asound.h
 header-test- += sound/compress_offload.h
 header-test- += sound/emu10k1.h
 header-test- += sound/sfnt_info.h
-header-test- += sound/sof/eq.h
-header-test- += sound/sof/fw.h
-header-test- += sound/sof/header.h
-header-test- += sound/sof/manifest.h
-header-test- += sound/sof/trace.h
 header-test- += xen/evtchn.h
 header-test- += xen/gntdev.h
 header-test- += xen/privcmd.h
index 55fed77..4fd4f6d 100644 (file)
@@ -30,7 +30,7 @@ TRACE_EVENT(vgic_update_irq_pending,
 #endif /* _TRACE_VGIC_H */
 
 #undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH ../../../virt/kvm/arm/vgic
+#define TRACE_INCLUDE_PATH ../../virt/kvm/arm/vgic
 #undef TRACE_INCLUDE_FILE
 #define TRACE_INCLUDE_FILE trace
 
index e6de315..fd68fbe 100644 (file)
@@ -617,8 +617,9 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
 
                stat_data->kvm = kvm;
                stat_data->offset = p->offset;
+               stat_data->mode = p->mode ? p->mode : 0644;
                kvm->debugfs_stat_data[p - debugfs_entries] = stat_data;
-               debugfs_create_file(p->name, 0644, kvm->debugfs_dentry,
+               debugfs_create_file(p->name, stat_data->mode, kvm->debugfs_dentry,
                                    stat_data, stat_fops_per_vm[p->kind]);
        }
        return 0;
@@ -3929,7 +3930,9 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file,
        if (!refcount_inc_not_zero(&stat_data->kvm->users_count))
                return -ENOENT;
 
-       if (simple_attr_open(inode, file, get, set, fmt)) {
+       if (simple_attr_open(inode, file, get,
+                            stat_data->mode & S_IWUGO ? set : NULL,
+                            fmt)) {
                kvm_put_kvm(stat_data->kvm);
                return -ENOMEM;
        }
@@ -4177,7 +4180,8 @@ static void kvm_init_debug(void)
 
        kvm_debugfs_num_entries = 0;
        for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) {
-               debugfs_create_file(p->name, 0644, kvm_debugfs_dir,
+               int mode = p->mode ? p->mode : 0644;
+               debugfs_create_file(p->name, mode, kvm_debugfs_dir,
                                    (void *)(long)p->offset,
                                    stat_fops[p->kind]);
        }