Merge tag 'x86_cleanups_for_v5.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 21 Mar 2022 18:49:16 +0000 (11:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 21 Mar 2022 18:49:16 +0000 (11:49 -0700)
Pull x86 cleanups from Borislav Petkov:

 - Remove a misleading message and an unused function

* tag 'x86_cleanups_for_v5.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/nmi: Remove the 'strange power saving mode' hint from unknown NMI handler
  x86/pat: Remove the unused set_pages_array_wt() function

958 files changed:
.mailmap
CREDITS
Documentation/ABI/stable/sysfs-devices-system-cpu
Documentation/ABI/testing/sysfs-devices-system-cpu
Documentation/admin-guide/hw-vuln/spectre.rst
Documentation/admin-guide/kdump/vmcoreinfo.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/admin-guide/mm/pagemap.rst
Documentation/arm64/booting.rst
Documentation/arm64/elf_hwcaps.rst
Documentation/arm64/memory-tagging-extension.rst
Documentation/arm64/silicon-errata.rst
Documentation/asm-annotations.rst
Documentation/cpu-freq/cpu-drivers.rst
Documentation/devicetree/bindings/arm/atmel-at91.yaml
Documentation/devicetree/bindings/arm/freescale/fsl,layerscape-dcfg.txt
Documentation/devicetree/bindings/arm/pmu.yaml
Documentation/devicetree/bindings/arm/qcom.yaml
Documentation/devicetree/bindings/clock/qoriq-clock.txt
Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
Documentation/devicetree/bindings/mfd/brcm,cru.yaml
Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml
Documentation/devicetree/bindings/mfd/ti,j721e-system-controller.yaml
Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml
Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml
Documentation/devicetree/bindings/usb/dwc2.yaml
Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml
Documentation/tools/rtla/common_hist_options.rst
Documentation/tools/rtla/common_osnoise_description.rst
Documentation/tools/rtla/rtla-osnoise-hist.rst
Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst
Documentation/virt/kvm/api.rst
MAINTAINERS
Makefile
arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
arch/arm/boot/dts/bcm2711.dtsi
arch/arm/boot/dts/omap3-devkit8000-common.dtsi
arch/arm/boot/dts/omap3-devkit8000.dts
arch/arm/boot/dts/rk322x.dtsi
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/tegra124-nyan-big-fhd.dts
arch/arm/boot/dts/tegra124-nyan-big.dts
arch/arm/boot/dts/tegra124-nyan-blaze.dts
arch/arm/boot/dts/tegra124-venice2.dts
arch/arm/include/asm/assembler.h
arch/arm/include/asm/spectre.h [new file with mode: 0644]
arch/arm/include/asm/vmlinux.lds.h
arch/arm/kernel/Makefile
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/kgdb.c
arch/arm/kernel/spectre.c [new file with mode: 0644]
arch/arm/kernel/traps.c
arch/arm/mach-mstar/Kconfig
arch/arm/mm/Kconfig
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-v7-bugs.c
arch/arm/vdso/Makefile
arch/arm64/Kconfig
arch/arm64/boot/dts/apple/t8103.dtsi
arch/arm64/boot/dts/arm/juno-base.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
arch/arm64/boot/dts/freescale/imx8mm.dtsi
arch/arm64/boot/dts/freescale/imx8ulp.dtsi
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
arch/arm64/boot/dts/marvell/armada-37xx.dtsi
arch/arm64/boot/dts/nvidia/tegra194.dtsi
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
arch/arm64/boot/dts/qcom/sm8350.dtsi
arch/arm64/boot/dts/qcom/sm8450.dtsi
arch/arm64/boot/dts/rockchip/px30.dtsi
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
arch/arm64/boot/dts/rockchip/rk3568.dtsi
arch/arm64/boot/dts/rockchip/rk356x.dtsi
arch/arm64/include/asm/apple_m1_pmu.h [new file with mode: 0644]
arch/arm64/include/asm/arch_gicv3.h
arch/arm64/include/asm/archrandom.h
arch/arm64/include/asm/asm_pointer_auth.h
arch/arm64/include/asm/assembler.h
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/cputype.h
arch/arm64/include/asm/debug-monitors.h
arch/arm64/include/asm/fixmap.h
arch/arm64/include/asm/hwcap.h
arch/arm64/include/asm/insn-def.h
arch/arm64/include/asm/insn.h
arch/arm64/include/asm/kvm_arm.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/kvm_hyp.h
arch/arm64/include/asm/linkage.h
arch/arm64/include/asm/lse.h
arch/arm64/include/asm/module.lds.h
arch/arm64/include/asm/mte-def.h
arch/arm64/include/asm/mte-kasan.h
arch/arm64/include/asm/mte.h
arch/arm64/include/asm/perf_event.h
arch/arm64/include/asm/pgtable-hwdef.h
arch/arm64/include/asm/pgtable-prot.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/processor.h
arch/arm64/include/asm/rwonce.h
arch/arm64/include/asm/sections.h
arch/arm64/include/asm/spectre.h
arch/arm64/include/asm/string.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/vectors.h [new file with mode: 0644]
arch/arm64/include/uapi/asm/hwcap.h
arch/arm64/include/uapi/asm/kvm.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/cpuinfo.c
arch/arm64/kernel/crash_core.c
arch/arm64/kernel/elfcore.c [new file with mode: 0644]
arch/arm64/kernel/entry-common.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/idreg-override.c
arch/arm64/kernel/image-vars.h
arch/arm64/kernel/mte.c
arch/arm64/kernel/perf_event.c
arch/arm64/kernel/process.c
arch/arm64/kernel/proton-pack.c
arch/arm64/kernel/signal.c
arch/arm64/kernel/sys_compat.c
arch/arm64/kernel/traps.c
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/hyp-entry.S
arch/arm64/kvm/hyp/include/hyp/switch.h
arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
arch/arm64/kvm/hyp/nvhe/cache.S
arch/arm64/kvm/hyp/nvhe/mm.c
arch/arm64/kvm/hyp/nvhe/sys_regs.c
arch/arm64/kvm/hyp/vhe/switch.c
arch/arm64/kvm/hypercalls.c
arch/arm64/kvm/psci.c
arch/arm64/kvm/sys_regs.c
arch/arm64/lib/clear_page.S
arch/arm64/lib/copy_page.S
arch/arm64/lib/insn.c
arch/arm64/lib/memchr.S
arch/arm64/lib/memcmp.S
arch/arm64/lib/memcpy.S
arch/arm64/lib/memset.S
arch/arm64/lib/mte.S
arch/arm64/lib/strchr.S
arch/arm64/lib/strcmp.S
arch/arm64/lib/strlen.S
arch/arm64/lib/strncmp.S
arch/arm64/lib/strnlen.S
arch/arm64/lib/strrchr.S
arch/arm64/mm/cache.S
arch/arm64/mm/flush.c
arch/arm64/mm/hugetlbpage.c
arch/arm64/mm/init.c
arch/arm64/mm/mmap.c
arch/arm64/mm/mmu.c
arch/arm64/mm/mteswap.c
arch/arm64/mm/proc.S
arch/arm64/net/bpf_jit.h
arch/arm64/tools/Makefile
arch/arm64/tools/cpucaps
arch/ia64/Kconfig
arch/m68k/amiga/config.c
arch/m68k/apollo/config.c
arch/m68k/atari/config.c
arch/m68k/bvme6000/config.c
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/hp300/config.c
arch/m68k/include/asm/config.h [new file with mode: 0644]
arch/m68k/kernel/setup_mm.c
arch/m68k/mac/config.c
arch/m68k/mm/fault.c
arch/m68k/mvme147/config.c
arch/m68k/mvme16x/config.c
arch/m68k/q40/config.c
arch/mips/kernel/setup.c
arch/mips/kernel/smp.c
arch/mips/ralink/mt7621.c
arch/parisc/kernel/unaligned.c
arch/powerpc/include/asm/book3s/64/mmu.h
arch/powerpc/include/asm/kexec_ranges.h
arch/powerpc/include/asm/nmi.h
arch/riscv/Kconfig.erratas
arch/riscv/Kconfig.socs
arch/riscv/boot/dts/canaan/k210.dtsi
arch/riscv/configs/nommu_k210_sdcard_defconfig
arch/riscv/include/asm/page.h
arch/riscv/include/asm/pgtable.h
arch/riscv/kernel/Makefile
arch/riscv/kernel/entry.S
arch/riscv/kernel/module.c
arch/riscv/kernel/trace_irq.c [new file with mode: 0644]
arch/riscv/kernel/trace_irq.h [new file with mode: 0644]
arch/riscv/mm/Makefile
arch/riscv/mm/init.c
arch/riscv/mm/kasan_init.c
arch/riscv/mm/physaddr.c
arch/s390/include/asm/extable.h
arch/s390/include/asm/ftrace.h
arch/s390/include/asm/ptrace.h
arch/s390/kernel/ftrace.c
arch/s390/kernel/mcount.S
arch/s390/kernel/setup.c
arch/x86/Kbuild
arch/x86/Kconfig
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/coco/Makefile [new file with mode: 0644]
arch/x86/coco/core.c [new file with mode: 0644]
arch/x86/crypto/aesni-intel_asm.S
arch/x86/include/asm/coco.h [new file with mode: 0644]
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/insn.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/nospec-branch.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/set_memory.h
arch/x86/include/asm/topology.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/Makefile
arch/x86/kernel/alternative.c
arch/x86/kernel/cc_platform.c [deleted file]
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/mce/amd.c
arch/x86/kernel/cpu/mce/core.c
arch/x86/kernel/cpu/mce/intel.c
arch/x86/kernel/cpu/mshyperv.c
arch/x86/kernel/cpu/scattered.c
arch/x86/kernel/cpu/sgx/encl.c
arch/x86/kernel/e820.c
arch/x86/kernel/fpu/xstate.c
arch/x86/kernel/head64.c
arch/x86/kernel/kdebugfs.c
arch/x86/kernel/ksysfs.c
arch/x86/kernel/kvm.c
arch/x86/kernel/kvmclock.c
arch/x86/kernel/module.c
arch/x86/kernel/process.c
arch/x86/kernel/setup.c
arch/x86/kernel/traps.c
arch/x86/kernel/x86_init.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/emulate.c
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/vmx/vmx.h
arch/x86/kvm/x86.c
arch/x86/lib/memcpy_64.S
arch/x86/lib/memmove_64.S
arch/x86/lib/memset_64.S
arch/x86/lib/retpoline.S
arch/x86/lib/x86-opcode-map.txt
arch/x86/mm/ioremap.c
arch/x86/mm/mem_encrypt_amd.c
arch/x86/mm/mem_encrypt_identity.c
arch/x86/mm/pat/set_memory.c
arch/x86/net/bpf_jit_comp.c
arch/x86/um/Kconfig
block/blk-core.c
block/blk-mq.c
block/fops.c
certs/system_keyring.c
crypto/asymmetric_keys/Kconfig
crypto/asymmetric_keys/Makefile
crypto/asymmetric_keys/asym_tpm.c [deleted file]
crypto/asymmetric_keys/pkcs7_verify.c
crypto/asymmetric_keys/public_key.c
crypto/asymmetric_keys/tpm.asn1 [deleted file]
crypto/asymmetric_keys/tpm_parser.c [deleted file]
crypto/asymmetric_keys/x509.asn1
crypto/asymmetric_keys/x509_cert_parser.c
crypto/asymmetric_keys/x509_parser.h
crypto/asymmetric_keys/x509_public_key.c
drivers/acpi/scan.c
drivers/amba/bus.c
drivers/ata/pata_hpt37x.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/auxdisplay/lcd2s.c
drivers/base/dd.c
drivers/base/regmap/regmap-irq.c
drivers/base/topology.c
drivers/block/virtio_blk.c
drivers/block/xen-blkfront.c
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm-dev-common.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm2-space.c
drivers/char/tpm/xen-tpmfront.c
drivers/char/virtio_console.c
drivers/clk/Kconfig
drivers/clk/ingenic/jz4725b-cgu.c
drivers/clk/qcom/dispcc-sc7180.c
drivers/clk/qcom/dispcc-sc7280.c
drivers/clk/qcom/dispcc-sm8250.c
drivers/clk/qcom/gcc-msm8994.c
drivers/clk/qcom/gdsc.c
drivers/clk/qcom/gdsc.h
drivers/clocksource/timer-ti-dm-systimer.c
drivers/counter/counter-sysfs.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/qcom-cpufreq-hw.c
drivers/crypto/qcom-rng.c
drivers/dma/pl330.c
drivers/edac/altera_edac.c
drivers/edac/amd64_edac.c
drivers/edac/amd64_edac.h
drivers/edac/edac_device_sysfs.c
drivers/edac/edac_mc.c
drivers/edac/edac_pci_sysfs.c
drivers/firmware/arm_scmi/driver.c
drivers/firmware/efi/apple-properties.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/libstub/riscv-stub.c
drivers/firmware/efi/mokvar-table.c
drivers/firmware/efi/vars.c
drivers/gpio/gpio-rockchip.c
drivers/gpio/gpio-sim.c
drivers/gpio/gpio-tegra186.c
drivers/gpio/gpio-ts4900.c
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/arm/Kconfig
drivers/gpu/drm/bridge/Kconfig
drivers/gpu/drm/bridge/ti-sn65dsi86.c
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_fimc.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_gsc.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/display/intel_bw.c
drivers/gpu/drm/i915/display/intel_bw.h
drivers/gpu/drm/i915/display/intel_psr.c
drivers/gpu/drm/i915/display/intel_snps_phy.c
drivers/gpu/drm/i915/display/intel_tc.c
drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_pch.c
drivers/gpu/drm/i915/intel_pch.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/imx/dcss/Kconfig
drivers/gpu/drm/imx/parallel-display.c
drivers/gpu/drm/mgag200/mgag200_pll.c
drivers/gpu/drm/panel/Kconfig
drivers/gpu/drm/panel/panel-simple.c
drivers/gpu/drm/radeon/radeon_uvd.c
drivers/gpu/drm/sun4i/sun8i_mixer.h
drivers/gpu/drm/tegra/Kconfig
drivers/gpu/drm/tegra/dpaux.c
drivers/gpu/drm/tegra/falcon.c
drivers/gpu/drm/vc4/vc4_crtc.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/gpu/drm/vc4/vc4_hdmi.h
drivers/gpu/host1x/syncpt.c
drivers/hid/hid-debug.c
drivers/hid/hid-elo.c
drivers/hid/hid-input.c
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-nintendo.c
drivers/hid/hid-thrustmaster.c
drivers/hid/hid-vivaldi.c
drivers/hwmon/hwmon.c
drivers/hwmon/ntc_thermistor.c
drivers/hwmon/pmbus/pmbus_core.c
drivers/iio/accel/bmc150-accel-core.c
drivers/iio/accel/fxls8962af-core.c
drivers/iio/accel/fxls8962af-i2c.c
drivers/iio/accel/fxls8962af-spi.c
drivers/iio/accel/fxls8962af.h
drivers/iio/accel/kxcjk-1013.c
drivers/iio/accel/mma9551.c
drivers/iio/accel/mma9553.c
drivers/iio/adc/ad7124.c
drivers/iio/adc/men_z188_adc.c
drivers/iio/adc/ti-tsc2046.c
drivers/iio/addac/ad74413r.c
drivers/iio/frequency/admv1013.c
drivers/iio/gyro/bmg160_core.c
drivers/iio/imu/adis16480.c
drivers/iio/imu/kmx61.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
drivers/iio/magnetometer/bmc150_magn.c
drivers/infiniband/core/cma.c
drivers/infiniband/hw/qib/qib_sysfs.c
drivers/infiniband/ulp/rtrs/rtrs-clt.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/input/keyboard/Kconfig
drivers/input/mouse/elan_i2c_core.c
drivers/input/tablet/aiptek.c
drivers/input/touchscreen/goodix.c
drivers/input/touchscreen/zinitix.c
drivers/iommu/amd/amd_iommu.h
drivers/iommu/amd/amd_iommu_types.h
drivers/iommu/amd/init.c
drivers/iommu/amd/io_pgtable.c
drivers/iommu/amd/iommu.c
drivers/iommu/intel/iommu.c
drivers/iommu/tegra-smmu.c
drivers/irqchip/irq-apple-aic.c
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/isdn/mISDN/dsp_pipeline.c
drivers/mmc/core/block.c
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/mmc_ops.h
drivers/mmc/core/sd.c
drivers/mmc/host/meson-gx-mmc.c
drivers/mtd/mtdcore.c
drivers/mtd/nand/raw/Kconfig
drivers/net/arcnet/com20020-pci.c
drivers/net/can/rcar/rcar_canfd.c
drivers/net/can/usb/etas_es58x/es58x_core.c
drivers/net/can/usb/etas_es58x/es58x_core.h
drivers/net/can/usb/gs_usb.c
drivers/net/dsa/microchip/ksz8795_spi.c
drivers/net/dsa/microchip/ksz9477_spi.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/mt7530.c
drivers/net/ethernet/8390/mcf8390.c
drivers/net/ethernet/arc/emac_mdio.c
drivers/net/ethernet/atheros/alx/main.c
drivers/net/ethernet/broadcom/bnx2.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
drivers/net/ethernet/faraday/ftgmac100.c
drivers/net/ethernet/freescale/gianfar_ethtool.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/ibm/ibmvnic.h
drivers/net/ethernet/intel/e1000e/hw.h
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/ich8lan.h
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/i40e/i40e_debugfs.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
drivers/net/ethernet/intel/iavf/iavf.h
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_eswitch.c
drivers/net/ethernet/intel/ice/ice_ethtool.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_protocol_type.h
drivers/net/ethernet/intel/ice/ice_ptp.c
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_tc_lib.c
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
drivers/net/ethernet/intel/igc/igc_phy.c
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
drivers/net/ethernet/lantiq_xrx200.c
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/marvell/prestera/prestera_main.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.h
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/ct.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mirred.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mpls.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_mplsoudp.c
drivers/net/ethernet/mellanox/mlx5/core/en/tir.c
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h
drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c
drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h
drivers/net/ethernet/microchip/sparx5/sparx5_main.h
drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
drivers/net/ethernet/mscc/ocelot_flower.c
drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/qlogic/qed/qed_sriov.c
drivers/net/ethernet/qlogic/qed/qed_vf.c
drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
drivers/net/ethernet/sfc/mcdi.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/sun/sunhme.c
drivers/net/ethernet/ti/cpts.c
drivers/net/ethernet/xilinx/ll_temac_main.c
drivers/net/ethernet/xilinx/xilinx_emaclite.c
drivers/net/hamradio/6pack.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/ipa/Kconfig
drivers/net/mdio/mdio-ipq4019.c
drivers/net/mdio/mdio-mscc-miim.c
drivers/net/phy/dp83822.c
drivers/net/phy/marvell.c
drivers/net/phy/meson-gxl.c
drivers/net/phy/mscc/mscc_main.c
drivers/net/usb/smsc95xx.c
drivers/net/usb/sr9700.c
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/intel/Makefile
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c
drivers/net/xen-netback/xenbus.c
drivers/net/xen-netfront.c
drivers/nfc/port100.c
drivers/ntb/hw/intel/ntb_hw_gen4.c
drivers/ntb/hw/intel/ntb_hw_gen4.h
drivers/ntb/msi.c
drivers/nvme/host/core.c
drivers/nvme/host/tcp.c
drivers/nvme/target/configfs.c
drivers/nvme/target/core.c
drivers/nvmem/core.c
drivers/of/fdt.c
drivers/of/unittest.c
drivers/pci/controller/pci-mvebu.c
drivers/pci/controller/vmd.c
drivers/pci/quirks.c
drivers/perf/Kconfig
drivers/perf/Makefile
drivers/perf/apple_m1_cpu_pmu.c [new file with mode: 0644]
drivers/perf/arm-cci.c
drivers/perf/arm-ccn.c
drivers/perf/arm-cmn.c
drivers/perf/arm_pmu.c
drivers/perf/hisilicon/hisi_uncore_pmu.c
drivers/perf/marvell_cn10k_ddr_pmu.c [new file with mode: 0644]
drivers/perf/marvell_cn10k_tad_pmu.c
drivers/perf/thunderx2_pmu.c
drivers/perf/xgene_pmu.c
drivers/pinctrl/intel/pinctrl-tigerlake.c
drivers/pinctrl/pinctrl-k210.c
drivers/pinctrl/pinctrl-starfive.c
drivers/pinctrl/sunxi/pinctrl-sunxi.c
drivers/platform/surface/surface3_power.c
drivers/platform/x86/amd-pmc.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/intel/int3472/tps68470_board_data.c
drivers/platform/x86/thinkpad_acpi.c
drivers/ptp/ptp_ocp.c
drivers/regulator/da9121-regulator.c
drivers/scsi/fnic/fnic_scsi.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/xen-scsifront.c
drivers/soc/fsl/guts.c
drivers/soc/fsl/qe/qe.c
drivers/soc/fsl/qe/qe_io.c
drivers/soc/imx/gpcv2.c
drivers/soc/mediatek/mt8192-mmsys.h
drivers/soc/samsung/exynos-chipid.c
drivers/spi/spi-rockchip.c
drivers/spi/spi-zynq-qspi.c
drivers/spi/spi.c
drivers/staging/fbtft/fb_st7789v.c
drivers/staging/gdm724x/gdm_lte.c
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
drivers/staging/rtl8723bs/core/rtw_recv.c
drivers/staging/rtl8723bs/core/rtw_sta_mgt.c
drivers/staging/rtl8723bs/core/rtw_xmit.c
drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c
drivers/staging/rtl8723bs/include/rtw_mlme.h
drivers/tee/optee/ffa_abi.c
drivers/tee/optee/smc_abi.c
drivers/thermal/intel/int340x_thermal/int3400_thermal.c
drivers/thermal/thermal_netlink.c
drivers/tty/n_gsm.c
drivers/tty/serial/sc16is7xx.c
drivers/usb/class/usbtmc.c
drivers/usb/dwc2/core.h
drivers/usb/dwc2/drd.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/rndis.c
drivers/usb/gadget/function/rndis.h
drivers/usb/gadget/udc/core.c
drivers/usb/gadget/udc/udc-xilinx.c
drivers/usb/host/xen-hcd.c
drivers/usb/host/xhci.c
drivers/usb/musb/omap2430.c
drivers/usb/serial/ch341.c
drivers/usb/serial/option.c
drivers/usb/typec/tipd/core.c
drivers/vdpa/mlx5/net/mlx5_vnet.c
drivers/vdpa/vdpa.c
drivers/vdpa/vdpa_user/iova_domain.c
drivers/vdpa/virtio_pci/vp_vdpa.c
drivers/vhost/iotlb.c
drivers/vhost/vdpa.c
drivers/vhost/vhost.c
drivers/vhost/vsock.c
drivers/virtio/Kconfig
drivers/virtio/virtio.c
drivers/virtio/virtio_vdpa.c
drivers/xen/gntalloc.c
drivers/xen/grant-table.c
drivers/xen/pvcalls-front.c
drivers/xen/xenbus/xenbus_client.c
fs/Kconfig.binfmt
fs/afs/write.c
fs/binfmt_elf.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/lzo.c
fs/btrfs/qgroup.c
fs/btrfs/relocation.c
fs/btrfs/root-tree.c
fs/btrfs/subpage.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/tree-checker.c
fs/btrfs/tree-log.c
fs/cachefiles/interface.c
fs/cachefiles/xattr.c
fs/cifs/connect.c
fs/configfs/dir.c
fs/erofs/internal.h
fs/fuse/dev.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/fuse/ioctl.c
fs/io_uring.c
fs/ocfs2/super.c
fs/pipe.c
fs/proc/task_mmu.c
fs/tracefs/inode.c
fs/userfaultfd.c
fs/xfs/xfs_super.c
include/crypto/asym_tpm_subtype.h [deleted file]
include/dt-bindings/interrupt-controller/apple-aic.h
include/keys/system_keyring.h
include/linux/amba/bus.h
include/linux/arm-smccc.h
include/linux/bpf.h
include/linux/cpufreq.h
include/linux/cpuhotplug.h
include/linux/elfcore.h
include/linux/if_arp.h
include/linux/kasan-enabled.h [new file with mode: 0644]
include/linux/kasan.h
include/linux/linkage.h
include/linux/mlx5/mlx5_ifc.h
include/linux/mm.h
include/linux/mm_inline.h
include/linux/mm_types.h
include/linux/netdevice.h
include/linux/netfilter_netdev.h
include/linux/nvme-tcp.h
include/linux/nvmem-provider.h
include/linux/perf/arm_pmu.h
include/linux/phy.h
include/linux/rfkill.h
include/linux/slab.h
include/linux/topology.h
include/linux/trace_events.h
include/linux/vdpa.h
include/linux/virtio.h
include/linux/virtio_config.h
include/linux/watch_queue.h
include/net/af_vsock.h
include/net/bluetooth/bluetooth.h
include/net/bluetooth/hci_core.h
include/net/checksum.h
include/net/esp.h
include/net/ndisc.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_flow_table.h
include/net/netfilter/nf_queue.h
include/net/netfilter/nf_tables.h
include/net/netfilter/nf_tables_offload.h
include/net/sock.h
include/net/xfrm.h
include/soc/fsl/dpaa2-fd.h
include/soc/fsl/qe/immap_qe.h
include/soc/fsl/qe/qe_tdm.h
include/soc/fsl/qe/ucc_fast.h
include/soc/fsl/qe/ucc_slow.h
include/trace/events/cachefiles.h
include/uapi/linux/elf.h
include/uapi/linux/input-event-codes.h
include/uapi/linux/kvm.h
include/uapi/linux/magic.h
include/uapi/linux/xfrm.h
include/xen/grant_table.h
kernel/bpf/btf.c
kernel/bpf/helpers.c
kernel/bpf/syscall.c
kernel/cgroup/cgroup-v1.c
kernel/cgroup/cgroup.c
kernel/cgroup/cpuset.c
kernel/configs/debug.config
kernel/dma/swiotlb.c
kernel/fork.c
kernel/sys.c
kernel/sysctl.c
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_eprobe.c
kernel/trace/trace_events_hist.c
kernel/trace/trace_events_trigger.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_osnoise.c
kernel/trace/trace_probe.c
kernel/trace/trace_probe.h
kernel/trace/trace_selftest.c
kernel/user_namespace.c
kernel/watch_queue.c
lib/Kconfig
lib/iov_iter.c
lib/test_kasan.c
mm/gup.c
mm/hugetlb.c
mm/madvise.c
mm/memblock.c
mm/memfd.c
mm/mempolicy.c
mm/mlock.c
mm/mmap.c
mm/mprotect.c
mm/swap_state.c
mm/util.c
net/9p/trans_xen.c
net/ax25/af_ax25.c
net/batman-adv/hard-interface.c
net/bluetooth/hci_core.c
net/bluetooth/hci_sync.c
net/bluetooth/mgmt.c
net/bluetooth/mgmt_util.c
net/can/j1939/transport.c
net/core/filter.c
net/core/gro.c
net/core/net-sysfs.c
net/core/skbuff.c
net/core/skmsg.c
net/core/sock.c
net/core/xdp.c
net/dcb/dcbnl.c
net/dsa/dsa2.c
net/dsa/master.c
net/dsa/port.c
net/ipv4/af_inet.c
net/ipv4/esp4.c
net/ipv4/esp4_offload.c
net/ipv4/ip_output.c
net/ipv4/ping.c
net/ipv4/tcp.c
net/ipv4/udp_tunnel_nic.c
net/ipv6/addrconf.c
net/ipv6/esp6.c
net/ipv6/esp6_offload.c
net/ipv6/ip6_offload.c
net/ipv6/ip6_output.c
net/ipv6/mcast.c
net/ipv6/xfrm6_output.c
net/key/af_key.c
net/mac80211/agg-tx.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rx.c
net/mptcp/mib.c
net/mptcp/mib.h
net/mptcp/pm.c
net/mptcp/pm_netlink.c
net/mptcp/protocol.c
net/netfilter/core.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_flow_table_offload.c
net/netfilter/nf_nat_core.c
net/netfilter/nf_queue.c
net/netfilter/nf_tables_api.c
net/netfilter/nf_tables_offload.c
net/netfilter/nfnetlink_queue.c
net/netfilter/nft_dup_netdev.c
net/netfilter/nft_fwd_netdev.c
net/netfilter/nft_immediate.c
net/netfilter/nft_limit.c
net/netfilter/xt_socket.c
net/openvswitch/actions.c
net/packet/af_packet.c
net/sched/act_api.c
net/sched/act_ct.c
net/sctp/diag.c
net/smc/af_smc.c
net/smc/smc_core.c
net/smc/smc_pnet.c
net/smc/smc_pnet.h
net/tipc/bearer.c
net/tipc/link.c
net/tipc/name_table.c
net/tipc/socket.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/virtio_transport.c
net/vmw_vsock/vmci_transport.c
net/wireless/Makefile
net/wireless/nl80211.c
net/xfrm/xfrm_device.c
net/xfrm/xfrm_interface.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/integrity/Kconfig
security/integrity/Makefile
security/integrity/digsig.c
security/integrity/integrity.h
security/integrity/platform_certs/keyring_handler.c
security/integrity/platform_certs/keyring_handler.h
security/integrity/platform_certs/load_uefi.c
security/integrity/platform_certs/machine_keyring.c [new file with mode: 0644]
security/keys/keyctl_pkey.c
security/keys/trusted-keys/trusted_core.c
security/selinux/ima.c
sound/soc/codecs/cs4265.c
sound/soc/soc-ops.c
sound/x86/intel_hdmi_audio.c
tools/arch/arm64/include/uapi/asm/kvm.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/asm/insn.h
tools/arch/x86/include/asm/msr-index.h
tools/arch/x86/lib/memcpy_64.S
tools/arch/x86/lib/memset_64.S
tools/arch/x86/lib/x86-opcode-map.txt
tools/cgroup/memcg_slabinfo.py
tools/include/uapi/linux/kvm.h
tools/perf/arch/x86/tests/insn-x86-dat-32.c
tools/perf/arch/x86/tests/insn-x86-dat-64.c
tools/perf/arch/x86/tests/insn-x86-dat-src.c
tools/perf/arch/x86/util/evlist.c
tools/perf/bench/epoll-ctl.c
tools/perf/builtin-script.c
tools/perf/tests/sigtrap.c
tools/perf/util/data.c
tools/perf/util/evlist-hybrid.c
tools/perf/util/evlist.c
tools/perf/util/include/linux/linkage.h
tools/perf/util/parse-events.c
tools/perf/util/symbol.c
tools/testing/selftests/arm64/abi/syscall-abi.c
tools/testing/selftests/arm64/fp/sve-ptrace.c
tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
tools/testing/selftests/arm64/mte/check_user_mem.c
tools/testing/selftests/arm64/signal/test_signals.h
tools/testing/selftests/arm64/signal/test_signals_utils.c
tools/testing/selftests/arm64/signal/test_signals_utils.h
tools/testing/selftests/bpf/prog_tests/timer_crash.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/test_sockmap_kern.h
tools/testing/selftests/bpf/progs/timer_crash.c [new file with mode: 0644]
tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh
tools/testing/selftests/drivers/net/mlxsw/tc_police_scale.sh
tools/testing/selftests/kvm/aarch64/arch_timer.c
tools/testing/selftests/kvm/aarch64/vgic_irq.c
tools/testing/selftests/kvm/lib/aarch64/vgic.c
tools/testing/selftests/memfd/memfd_test.c
tools/testing/selftests/net/mptcp/diag.sh
tools/testing/selftests/net/mptcp/mptcp_connect.sh
tools/testing/selftests/net/mptcp/mptcp_join.sh
tools/testing/selftests/net/pmtu.sh
tools/testing/selftests/netfilter/.gitignore
tools/testing/selftests/netfilter/Makefile
tools/testing/selftests/netfilter/connect_close.c [new file with mode: 0644]
tools/testing/selftests/netfilter/nft_nat.sh
tools/testing/selftests/netfilter/nft_queue.sh
tools/testing/selftests/sgx/Makefile
tools/testing/selftests/sgx/load.c
tools/testing/selftests/sgx/main.c
tools/testing/selftests/tpm2/tpm2.py
tools/testing/selftests/tpm2/tpm2_tests.py
tools/testing/selftests/vm/Makefile
tools/testing/selftests/vm/hugepage-mremap.c
tools/testing/selftests/vm/map_fixed_noreplace.c
tools/testing/selftests/vm/run_vmtests.sh
tools/testing/selftests/vm/userfaultfd.c
tools/testing/selftests/x86/check_cc.sh
tools/tracing/rtla/src/osnoise.c
tools/tracing/rtla/src/osnoise_hist.c
tools/tracing/rtla/src/osnoise_top.c
tools/tracing/rtla/src/timerlat_hist.c
tools/virtio/linux/mm_types.h [new file with mode: 0644]
tools/virtio/virtio_test.c
virt/kvm/kvm_main.c

index 8cd44b0c657970486f3c3e27f20d36a4fc7bc9b9..97ccdf147111471e6712fa10fad93ce3b1989a02 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -187,6 +187,8 @@ Jiri Slaby <jirislaby@kernel.org> <jslaby@novell.com>
 Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.com>
 Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.cz>
 Jiri Slaby <jirislaby@kernel.org> <xslaby@fi.muni.cz>
+Jisheng Zhang <jszhang@kernel.org> <jszhang@marvell.com>
+Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>
 Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
 Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
 John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
@@ -216,6 +218,7 @@ Koushik <raghavendra.koushik@neterion.com>
 Krishna Manikandan <quic_mkrishn@quicinc.com> <mkrishn@codeaurora.org>
 Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com>
 Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
+Krzysztof Kozlowski <krzk@kernel.org> <krzysztof.kozlowski@canonical.com>
 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 Kuogee Hsieh <quic_khsieh@quicinc.com> <khsieh@codeaurora.org>
 Leonardo Bras <leobras.c@gmail.com> <leonardo@linux.ibm.com>
@@ -333,6 +336,9 @@ Rémi Denis-Courmont <rdenis@simphalempin.com>
 Ricardo Ribalda <ribalda@kernel.org> <ricardo@ribalda.com>
 Ricardo Ribalda <ribalda@kernel.org> Ricardo Ribalda Delgado <ribalda@kernel.org>
 Ricardo Ribalda <ribalda@kernel.org> <ricardo.ribalda@gmail.com>
+Roman Gushchin <roman.gushchin@linux.dev> <guro@fb.com>
+Roman Gushchin <roman.gushchin@linux.dev> <guroan@gmail.com>
+Roman Gushchin <roman.gushchin@linux.dev> <klamm@yandex-team.ru>
 Ross Zwisler <zwisler@kernel.org> <ross.zwisler@linux.intel.com>
 Rudolf Marek <R.Marek@sh.cvut.cz>
 Rui Saraiva <rmps@joel.ist.utl.pt>
diff --git a/CREDITS b/CREDITS
index b97256d5bc2487eeac91a9c9d5d7f12b11887905..7e85a53b6a880942e9379125bae8ad4c9a08f13b 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -895,6 +895,12 @@ S: 3000 FORE Drive
 S: Warrendale, Pennsylvania 15086
 S: USA
 
+N: Ludovic Desroches
+E: ludovic.desroches@microchip.com
+D: Maintainer for ARM/Microchip (AT91) SoC support
+D: Author of ADC, pinctrl, XDMA and SDHCI drivers for this platform
+S: France
+
 N: Martin Devera
 E: devik@cdi.cz
 W: http://luxik.cdi.cz/~devik/qos/
index 3965ce504484a2ef8e2e01fcb1feda008a4699fa..902392d7eddf03e84e1e7cd420e715d2e0239898 100644 (file)
@@ -86,6 +86,10 @@ What:           /sys/devices/system/cpu/cpuX/topology/die_cpus
 Description:    internal kernel map of CPUs within the same die.
 Values:         hexadecimal bitmask.
 
+What:           /sys/devices/system/cpu/cpuX/topology/ppin
+Description:    per-socket protected processor inventory number
+Values:         hexadecimal.
+
 What:           /sys/devices/system/cpu/cpuX/topology/die_cpus_list
 Description:    human-readable list of CPUs within the same die.
                 The format is like 0-3, 8-11, 14,17.
index 61f5676a7429a440dd9bc0d6e919f5750ba2aa12..2ad01cad7f1c8286530a7a959aaf655b990a6c98 100644 (file)
@@ -73,6 +73,7 @@ What:         /sys/devices/system/cpu/cpuX/topology/core_id
                /sys/devices/system/cpu/cpuX/topology/physical_package_id
                /sys/devices/system/cpu/cpuX/topology/thread_siblings
                /sys/devices/system/cpu/cpuX/topology/thread_siblings_list
+               /sys/devices/system/cpu/cpuX/topology/ppin
 Date:          December 2008
 Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
 Description:   CPU topology files that describe a logical CPU's relationship
@@ -103,6 +104,11 @@ Description:       CPU topology files that describe a logical CPU's relationship
                thread_siblings_list: human-readable list of cpuX's hardware
                threads within the same core as cpuX
 
+               ppin: human-readable Protected Processor Identification
+               Number of the socket the cpu# belongs to. There should be
+               one per physical_package_id. File is readable only to
+               admin.
+
                See Documentation/admin-guide/cputopology.rst for more information.
 
 
@@ -662,6 +668,7 @@ Description:        Preferred MTE tag checking mode
 
                ================  ==============================================
                "sync"            Prefer synchronous mode
+               "asymm"           Prefer asymmetric mode
                "async"           Prefer asynchronous mode
                ================  ==============================================
 
index a2b22d5640ec9f9fb2e918f0bdca323fc3b4da88..9e9556826450bee1d881f196aff13f8bd048c276 100644 (file)
@@ -60,8 +60,8 @@ privileged data touched during the speculative execution.
 Spectre variant 1 attacks take advantage of speculative execution of
 conditional branches, while Spectre variant 2 attacks use speculative
 execution of indirect branches to leak privileged memory.
-See :ref:`[1] <spec_ref1>` :ref:`[5] <spec_ref5>` :ref:`[7] <spec_ref7>`
-:ref:`[10] <spec_ref10>` :ref:`[11] <spec_ref11>`.
+See :ref:`[1] <spec_ref1>` :ref:`[5] <spec_ref5>` :ref:`[6] <spec_ref6>`
+:ref:`[7] <spec_ref7>` :ref:`[10] <spec_ref10>` :ref:`[11] <spec_ref11>`.
 
 Spectre variant 1 (Bounds Check Bypass)
 ---------------------------------------
@@ -131,6 +131,19 @@ steer its indirect branch speculations to gadget code, and measure the
 speculative execution's side effects left in level 1 cache to infer the
 victim's data.
 
+Yet another variant 2 attack vector is for the attacker to poison the
+Branch History Buffer (BHB) to speculatively steer an indirect branch
+to a specific Branch Target Buffer (BTB) entry, even if the entry isn't
+associated with the source address of the indirect branch. Specifically,
+the BHB might be shared across privilege levels even in the presence of
+Enhanced IBRS.
+
+Currently the only known real-world BHB attack vector is via
+unprivileged eBPF. Therefore, it's highly recommended to not enable
+unprivileged eBPF, especially when eIBRS is used (without retpolines).
+For a full mitigation against BHB attacks, it's recommended to use
+retpolines (or eIBRS combined with retpolines).
+
 Attack scenarios
 ----------------
 
@@ -364,13 +377,15 @@ The possible values in this file are:
 
   - Kernel status:
 
-  ====================================  =================================
-  'Not affected'                        The processor is not vulnerable
-  'Vulnerable'                          Vulnerable, no mitigation
-  'Mitigation: Full generic retpoline'  Software-focused mitigation
-  'Mitigation: Full AMD retpoline'      AMD-specific software mitigation
-  'Mitigation: Enhanced IBRS'           Hardware-focused mitigation
-  ====================================  =================================
+  ========================================  =================================
+  'Not affected'                            The processor is not vulnerable
+  'Mitigation: None'                        Vulnerable, no mitigation
+  'Mitigation: Retpolines'                  Use Retpoline thunks
+  'Mitigation: LFENCE'                      Use LFENCE instructions
+  'Mitigation: Enhanced IBRS'               Hardware-focused mitigation
+  'Mitigation: Enhanced IBRS + Retpolines'  Hardware-focused + Retpolines
+  'Mitigation: Enhanced IBRS + LFENCE'      Hardware-focused + LFENCE
+  ========================================  =================================
 
   - Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) is
     used to protect against Spectre variant 2 attacks when calling firmware (x86 only).
@@ -583,12 +598,13 @@ kernel command line.
 
                Specific mitigations can also be selected manually:
 
-               retpoline
-                                       replace indirect branches
-               retpoline,generic
-                                       google's original retpoline
-               retpoline,amd
-                                       AMD-specific minimal thunk
+                retpoline               auto pick between generic,lfence
+                retpoline,generic       Retpolines
+                retpoline,lfence        LFENCE; indirect branch
+                retpoline,amd           alias for retpoline,lfence
+                eibrs                   enhanced IBRS
+                eibrs,retpoline         enhanced IBRS + Retpolines
+                eibrs,lfence            enhanced IBRS + LFENCE
 
                Not specifying this option is equivalent to
                spectre_v2=auto.
@@ -599,7 +615,7 @@ kernel command line.
                spectre_v2=off. Spectre variant 1 mitigations
                cannot be disabled.
 
-For spectre_v2_user see :doc:`/admin-guide/kernel-parameters`.
+For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt
 
 Mitigation selection guide
 --------------------------
@@ -681,7 +697,7 @@ AMD white papers:
 
 .. _spec_ref6:
 
-[6] `Software techniques for managing speculation on AMD processors <https://developer.amd.com/wp-content/resources/90343-B_SoftwareTechniquesforManagingSpeculation_WP_7-18Update_FNL.pdf>`_.
+[6] `Software techniques for managing speculation on AMD processors <https://developer.amd.com/wp-content/resources/Managing-Speculation-on-AMD-Processors.pdf>`_.
 
 ARM white papers:
 
index 3861a25faae18e7b44126b21f7c807f1fdd54b07..8419019b6a88f2136904bfb820e6fa0038d97556 100644 (file)
@@ -494,6 +494,14 @@ architecture which is used to lookup the page-tables for the Virtual
 addresses in the higher VA range (refer to ARMv8 ARM document for
 more details).
 
+MODULES_VADDR|MODULES_END|VMALLOC_START|VMALLOC_END|VMEMMAP_START|VMEMMAP_END
+-----------------------------------------------------------------------------
+
+Used to get the correct ranges:
+       MODULES_VADDR ~ MODULES_END-1 : Kernel module space.
+       VMALLOC_START ~ VMALLOC_END-1 : vmalloc() / ioremap() space.
+       VMEMMAP_START ~ VMEMMAP_END-1 : vmemmap region, used for struct page array.
+
 arm
 ===
 
index f5a27f067db9ed97da621036f111f881d3aa3561..7123524a86b8b4b1ed1a996a986db1495fa3f44d 100644 (file)
                        Specific mitigations can also be selected manually:
 
                        retpoline         - replace indirect branches
-                       retpoline,generic - google's original retpoline
-                       retpoline,amd     - AMD-specific minimal thunk
+                       retpoline,generic - Retpolines
+                       retpoline,lfence  - LFENCE; indirect branch
+                       retpoline,amd     - alias for retpoline,lfence
+                       eibrs             - enhanced IBRS
+                       eibrs,retpoline   - enhanced IBRS + Retpolines
+                       eibrs,lfence      - enhanced IBRS + LFENCE
 
                        Not specifying this option is equivalent to
                        spectre_v2=auto.
index bfc28704856c6fa375b29fcd623ab567e891eeb5..6e2e416af78380cea2cdd5d0fa6f9a86d175b49e 100644 (file)
@@ -23,7 +23,7 @@ There are four components to pagemap:
     * Bit  56    page exclusively mapped (since 4.2)
     * Bit  57    pte is uffd-wp write-protected (since 5.13) (see
       :ref:`Documentation/admin-guide/mm/userfaultfd.rst <userfaultfd>`)
-    * Bits 57-60 zero
+    * Bits 58-60 zero
     * Bit  61    page is file-page or shared-anon (since 3.5)
     * Bit  62    page swapped
     * Bit  63    page present
index 52d060caf8bbaceecea4275f35cad92c5218bb7f..29884b261aa9cc40f73dc3cc91fe1d719da835b4 100644 (file)
@@ -10,9 +10,9 @@ This document is based on the ARM booting document by Russell King and
 is relevant to all public releases of the AArch64 Linux kernel.
 
 The AArch64 exception model is made up of a number of exception levels
-(EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
-counterpart.  EL2 is the hypervisor level and exists only in non-secure
-mode. EL3 is the highest priority level and exists only in secure mode.
+(EL0 - EL3), with EL0, EL1 and EL2 having a secure and a non-secure
+counterpart.  EL2 is the hypervisor level, EL3 is the highest priority
+level and exists only in secure mode. Both are architecturally optional.
 
 For the purposes of this document, we will use the term `boot loader`
 simply to define all software that executes on the CPU(s) before control
@@ -167,8 +167,8 @@ Before jumping into the kernel, the following conditions must be met:
 
   All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
   IRQ and FIQ).
-  The CPU must be in either EL2 (RECOMMENDED in order to have access to
-  the virtualisation extensions) or non-secure EL1.
+  The CPU must be in non-secure state, either in EL2 (RECOMMENDED in order
+  to have access to the virtualisation extensions), or in EL1.
 
 - Caches, MMUs
 
index b72ff17d600aee7932157e993e580f41a2a7c426..a8f30963e550d372763b3b1a63a7fb38d733b533 100644 (file)
@@ -259,6 +259,11 @@ HWCAP2_RPRES
 
     Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
 
+HWCAP2_MTE3
+
+    Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0011, as described
+    by Documentation/arm64/memory-tagging-extension.rst.
+
 4. Unused AT_HWCAP bits
 -----------------------
 
index 7b99c8f428eb6e623cdd41734cea9111c88980f7..dd27f78d7608f99fa8e1b8de30127a12ac61a0e0 100644 (file)
@@ -76,6 +76,9 @@ configurable behaviours:
   with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
   address is unknown).
 
+- *Asymmetric* - Reads are handled as for synchronous mode while writes
+  are handled as for asynchronous mode.
+
 The user can select the above modes, per thread, using the
 ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags``
 contains any number of the following values in the ``PR_MTE_TCF_MASK``
@@ -91,8 +94,9 @@ mode is specified, the program will run in that mode. If multiple
 modes are specified, the mode is selected as described in the "Per-CPU
 preferred tag checking modes" section below.
 
-The current tag check fault mode can be read using the
-``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call.
+The current tag check fault configuration can be read using the
+``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call. If
+multiple modes were requested then all will be reported.
 
 Tag checking can also be disabled for a user thread by setting the
 ``PSTATE.TCO`` bit with ``MSR TCO, #1``.
@@ -139,18 +143,25 @@ tag checking mode as the CPU's preferred tag checking mode.
 
 The preferred tag checking mode for each CPU is controlled by
 ``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
-privileged user may write the value ``async`` or ``sync``.  The default
-preferred mode for each CPU is ``async``.
+privileged user may write the value ``async``, ``sync`` or ``asymm``.  The
+default preferred mode for each CPU is ``async``.
 
 To allow a program to potentially run in the CPU's preferred tag
 checking mode, the user program may set multiple tag check fault mode
 bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
-flags, 0, 0, 0)`` system call. If the CPU's preferred tag checking
-mode is in the task's set of provided tag checking modes (this will
-always be the case at present because the kernel only supports two
-tag checking modes, but future kernels may support more modes), that
-mode will be selected. Otherwise, one of the modes in the task's mode
-set will be selected in a currently unspecified manner.
+flags, 0, 0, 0)`` system call. If both synchronous and asynchronous
+modes are requested then asymmetric mode may also be selected by the
+kernel. If the CPU's preferred tag checking mode is in the task's set
+of provided tag checking modes, that mode will be selected. Otherwise,
+one of the modes in the task's mode will be selected by the kernel
+from the task's mode set using the preference order:
+
+       1. Asynchronous
+       2. Asymmetric
+       3. Synchronous
+
+Note that there is no way for userspace to request multiple modes and
+also disable asymmetric mode.
 
 Initial process state
 ---------------------
@@ -213,6 +224,29 @@ address ABI control and MTE configuration of a process as per the
 Documentation/arm64/tagged-address-abi.rst and above. The corresponding
 ``regset`` is 1 element of 8 bytes (``sizeof(long))``).
 
+Core dump support
+-----------------
+
+The allocation tags for user memory mapped with ``PROT_MTE`` are dumped
+in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The
+program header for such segment is defined as:
+
+:``p_type``: ``PT_ARM_MEMTAG_MTE``
+:``p_flags``: 0
+:``p_offset``: segment file offset
+:``p_vaddr``: segment virtual address, same as the corresponding
+  ``PT_LOAD`` segment
+:``p_paddr``: 0
+:``p_filesz``: segment size in file, calculated as ``p_mem_sz / 32``
+  (two 4-bit tags cover 32 bytes of memory)
+:``p_memsz``: segment size in memory, same as the corresponding
+  ``PT_LOAD`` segment
+:``p_align``: 0
+
+The tags are stored in the core file at ``p_offset`` as two 4-bit tags
+in a byte. With the tag granule of 16 bytes, a 4K page requires 128
+bytes in the core file.
+
 Example of correct usage
 ========================
 
index ea281dd755171d5c61a140997839c6846ac52f01..466cb9e89047fb51e5d2308d44cf4b16fd1e1113 100644 (file)
@@ -136,7 +136,7 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | Cavium         | ThunderX ITS    | #23144          | CAVIUM_ERRATUM_23144        |
 +----------------+-----------------+-----------------+-----------------------------+
-| Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154        |
+| Cavium         | ThunderX GICv3  | #23154,38545    | CAVIUM_ERRATUM_23154        |
 +----------------+-----------------+-----------------+-----------------------------+
 | Cavium         | ThunderX GICv3  | #38539          | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
index f4bf0f6395fb97d442d24a9aee02774e7114150e..a64f2ca469d4579eb4d88e46852181be0f53b04d 100644 (file)
@@ -130,14 +130,13 @@ denoting a range of code via ``SYM_*_START/END`` annotations.
   In fact, this kind of annotation corresponds to the now deprecated ``ENTRY``
   and ``ENDPROC`` macros.
 
-* ``SYM_FUNC_START_ALIAS`` and ``SYM_FUNC_START_LOCAL_ALIAS`` serve for those
-  who decided to have two or more names for one function. The typical use is::
+* ``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can
+  be used to define multiple names for a function. The typical use is::
 
-    SYM_FUNC_START_ALIAS(__memset)
-    SYM_FUNC_START(memset)
+    SYM_FUNC_START(__memset)
         ... asm insns ...
-    SYM_FUNC_END(memset)
-    SYM_FUNC_END_ALIAS(__memset)
+    SYN_FUNC_END(__memset)
+    SYM_FUNC_ALIAS(memset, __memset)
 
   In this example, one can call ``__memset`` or ``memset`` with the same
   result, except the debug information for the instructions is generated to
index 3b32336a7803ebc59faab9b908b599dac93b52fc..d84ededb66f92a234395be70f8fcdec1412aaed7 100644 (file)
@@ -75,6 +75,9 @@ And optionally
  .resume - A pointer to a per-policy resume function which is called
  with interrupts disabled and _before_ the governor is started again.
 
+ .ready - A pointer to a per-policy ready function which is called after
+ the policy is fully initialized.
+
  .attr - A pointer to a NULL-terminated list of "struct freq_attr" which
  allow to export values to sysfs.
 
index c612e1f48dbab956da81d30cf0f442fe56e29368..ff91df04f9f46080c283d85ebaf43c0ce8e715b4 100644 (file)
@@ -8,7 +8,8 @@ title: Atmel AT91 device tree bindings.
 
 maintainers:
   - Alexandre Belloni <alexandre.belloni@bootlin.com>
-  - Ludovic Desroches <ludovic.desroches@microchip.com>
+  - Claudiu Beznea <claudiu.beznea@microchip.com>
+  - Nicolas Ferre <nicolas.ferre@microchip.com>
 
 description: |
   Boards with a SoC of the Atmel AT91 or SMART family shall have the following
index b5cb374dc47d068dce8cf6eb23607ce55eb7011a..10a91cc8b9977de621c40c2bacc0aae587d0fe71 100644 (file)
@@ -8,7 +8,7 @@ Required properties:
   - compatible: Should contain a chip-specific compatible string,
        Chip-specific strings are of the form "fsl,<chip>-dcfg",
        The following <chip>s are known to be supported:
-       ls1012a, ls1021a, ls1043a, ls1046a, ls2080a.
+       ls1012a, ls1021a, ls1043a, ls1046a, ls2080a, lx2160a
 
   - reg : should contain base address and length of DCFG memory-mapped registers
 
index 981bac45169881dae1c371ee5df5c15b035f475b..7a04b8aaaec3001387909da0ac13660dcac3a481 100644 (file)
@@ -20,6 +20,8 @@ properties:
     items:
       - enum:
           - apm,potenza-pmu
+          - apple,firestorm-pmu
+          - apple,icestorm-pmu
           - arm,armv8-pmuv3 # Only for s/w models
           - arm,arm1136-pmu
           - arm,arm1176-pmu
index 370aab274cd1396470ae9f7cd98adcd362a0f3f6..04ff0b55bb85c911a9e8e8e7a391313059b083c0 100644 (file)
@@ -48,7 +48,6 @@ description: |
         sdx65
         sm7225
         sm8150
-        sdx65
         sm8250
         sm8350
         sm8450
@@ -228,11 +227,6 @@ properties:
               - qcom,sdx65-mtp
           - const: qcom,sdx65
 
-      - items:
-          - enum:
-              - qcom,sdx65-mtp
-          - const: qcom,sdx65
-
       - items:
           - enum:
               - qcom,ipq6018-cp01
index f7d48f23da444796eb5766129fcc8b4cb3ffb7a0..10119d9ef4b11b63a5b1439521bf11d03ed068b0 100644 (file)
@@ -44,6 +44,7 @@ Required properties:
        * "fsl,ls1046a-clockgen"
        * "fsl,ls1088a-clockgen"
        * "fsl,ls2080a-clockgen"
+       * "fsl,lx2160a-clockgen"
        Chassis-version clock strings include:
        * "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
        * "fsl,qoriq-clockgen-2.0": for chassis 2.0 clocks
index 1d3e88daca041ab204c231167153c982208cc84e..25b5ef3f759cac768e203cd155ca21a475675608 100644 (file)
@@ -91,22 +91,7 @@ properties:
         $ref: /schemas/graph.yaml#/$defs/port-base
         unevaluatedProperties: false
         description:
-          MIPI DSI/DPI input.
-
-        properties:
-          endpoint:
-            $ref: /schemas/media/video-interfaces.yaml#
-            type: object
-            additionalProperties: false
-
-            properties:
-              remote-endpoint: true
-
-              bus-type:
-                enum: [1, 5]
-                default: 1
-
-              data-lanes: true
+          Video port for MIPI DSI input.
 
       port@1:
         $ref: /schemas/graph.yaml#/properties/port
@@ -155,8 +140,6 @@ examples:
                     reg = <0>;
                     anx7625_in: endpoint {
                         remote-endpoint = <&mipi_dsi>;
-                        bus-type = <5>;
-                        data-lanes = <0 1 2 3>;
                     };
                 };
 
index e04349567eebb72c35e4bbd0893bd5acff33a961..427c5873f96a79401947bd69d16a309cc9d7f447 100644 (file)
@@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: SiFive GPIO controller
 
 maintainers:
-  - Yash Shah <yash.shah@sifive.com>
   - Paul Walmsley <paul.walmsley@sifive.com>
 
 properties:
index 97359024709af51f5b5ff8649477bcc80be70bcd..85c85b694217c16d157ee0c68509b95f9baa322c 100644 (file)
@@ -56,6 +56,8 @@ properties:
           - 1: virtual HV timer
           - 2: physical guest timer
           - 3: virtual guest timer
+          - 4: 'efficient' CPU PMU
+          - 5: 'performance' CPU PMU
 
       The 3rd cell contains the interrupt flags. This is normally
       IRQ_TYPE_LEVEL_HIGH (4).
@@ -68,6 +70,35 @@ properties:
   power-domains:
     maxItems: 1
 
+  affinities:
+    type: object
+    additionalProperties: false
+    description:
+      FIQ affinity can be expressed as a single "affinities" node,
+      containing a set of sub-nodes, one per FIQ with a non-default
+      affinity.
+    patternProperties:
+      "^.+-affinity$":
+        type: object
+        additionalProperties: false
+        properties:
+          apple,fiq-index:
+            description:
+              The interrupt number specified as a FIQ, and for which
+              the affinity is not the default.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            maximum: 5
+
+          cpus:
+            $ref: /schemas/types.yaml#/definitions/phandle-array
+            description:
+              Should be a list of phandles to CPU nodes (as described in
+              Documentation/devicetree/bindings/arm/cpus.yaml).
+
+        required:
+          - fiq-index
+          - cpus
+
 required:
   - compatible
   - '#interrupt-cells'
index be4a2df71c25d0d7f508c6510aefc05ecb34458c..b85819fbb07c8d9886bd1ab4289d227fa690f09f 100644 (file)
@@ -39,7 +39,7 @@ patternProperties:
   '^phy@[a-f0-9]+$':
     $ref: ../phy/bcm-ns-usb2-phy.yaml
 
-  '^pin-controller@[a-f0-9]+$':
+  '^pinctrl@[a-f0-9]+$':
     $ref: ../pinctrl/brcm,ns-pinmux.yaml
 
   '^syscon@[a-f0-9]+$':
@@ -94,7 +94,7 @@ examples:
             reg = <0x180 0x4>;
         };
 
-        pin-controller@1c0 {
+        pinctrl@1c0 {
             compatible = "brcm,bcm4708-pinmux";
             reg = <0x1c0 0x24>;
             reg-names = "cru_gpio_control";
index c00ad3e21c21c1c4efc1dfeeae6ec7c6e8f50bec..ad285cb480c9e678e3a098c7740ec47b3dd56050 100644 (file)
@@ -126,7 +126,7 @@ properties:
       clock-frequency:
         const: 12288000
 
-  lochnagar-pinctrl:
+  pinctrl:
     type: object
     $ref: /schemas/pinctrl/cirrus,lochnagar.yaml#
 
@@ -255,7 +255,7 @@ required:
   - reg
   - reset-gpios
   - lochnagar-clk
-  - lochnagar-pinctrl
+  - pinctrl
 
 additionalProperties: false
 
@@ -293,7 +293,7 @@ examples:
                 clock-frequency = <32768>;
             };
 
-            lochnagar-pinctrl {
+            pinctrl {
                 compatible = "cirrus,lochnagar-pinctrl";
 
                 gpio-controller;
index 272832e9f8f288b346b3b1ea316100c4037484ee..fa86691ebf1610306e5b5e9d53fb4bb322e5e235 100644 (file)
@@ -20,7 +20,7 @@ description: |
 
 maintainers:
   - Kishon Vijay Abraham I <kishon@ti.com>
-  - Roger Quadros <rogerq@ti.com
+  - Roger Quadros <rogerq@kernel.org>
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
new file mode 100644 (file)
index 0000000..a18dd0a
--- /dev/null
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/marvell-cn10k-ddr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell CN10K DDR performance monitor
+
+maintainers:
+  - Bharat Bhushan <bbhushan2@marvell.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - marvell,cn10k-ddr-pmu
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pmu@87e1c0000000 {
+            compatible = "marvell,cn10k-ddr-pmu";
+            reg = <0x87e1 0xc0000000 0x0 0x10000>;
+        };
+    };
index cbbf5e8b11973cf98d36f5439b6de8f338408270..f78d3246fbdcab5500c5ce034d254a664321801a 100644 (file)
@@ -8,7 +8,7 @@ title: OMAP USB2 PHY
 
 maintainers:
   - Kishon Vijay Abraham I <kishon@ti.com>
-  - Roger Quadros <rogerq@ti.com>
+  - Roger Quadros <rogerq@kernel.org>
 
 properties:
   compatible:
index 6107880e524629ec0a9a54a82b19370538a8c646..02b76f15e71702316c3b24d6ad8e510aa8ea27f5 100644 (file)
@@ -37,6 +37,12 @@ properties:
       max bit rate supported in bps
     minimum: 1
 
+  mux-states:
+    description:
+      mux controller node to route the signals from controller to
+      transceiver.
+    maxItems: 1
+
 required:
   - compatible
   - '#phy-cells'
@@ -53,4 +59,5 @@ examples:
       max-bitrate = <5000000>;
       standby-gpios = <&wakeup_gpio1 16 GPIO_ACTIVE_LOW>;
       enable-gpios = <&main_gpio1 67 GPIO_ACTIVE_HIGH>;
+      mux-states = <&mux0 1>;
     };
index c85f759ae5a3371408358639abb7214fe74e2721..8a90d82737676c8101259bb7335e5a69f8b4112a 100644 (file)
@@ -107,9 +107,6 @@ properties:
 
     additionalProperties: false
 
-allOf:
-  - $ref: "pinctrl.yaml#"
-
 required:
   - pinctrl-0
   - pinctrl-names
index 84e66913d042ef425d35592782e7dc598afeb752..db41cd7bf1509ffdbac20a18706a8e369c85083e 100644 (file)
@@ -8,7 +8,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: SiFive PWM controller
 
 maintainers:
-  - Yash Shah <yash.shah@sifive.com>
   - Sagar Kadam <sagar.kadam@sifive.com>
   - Paul Walmsley <paul.walmsley@sifive.com>
 
index 2b1f9160389721fdcc9db79d96459fb86ef1df5d..e2d330bd4608ab973b2753c362bebe0e696df5c8 100644 (file)
@@ -9,7 +9,6 @@ title: SiFive L2 Cache Controller
 
 maintainers:
   - Sagar Kadam <sagar.kadam@sifive.com>
-  - Yash Shah <yash.shah@sifive.com>
   - Paul Walmsley  <paul.walmsley@sifive.com>
 
 description:
index f00867ebc147ec2fd238fa7742025096a533bf1b..481aaa09f3f2bbfaa6b112001820fc3dbd328c11 100644 (file)
@@ -53,6 +53,7 @@ properties:
           - const: st,stm32mp15-hsotg
           - const: snps,dwc2
       - const: samsung,s3c6400-hsotg
+      - const: intel,socfpga-agilex-hsotg
 
   reg:
     maxItems: 1
index a634774c537c458ea9710d3246d846ba3a774d54..eedde385d2994982dae00fb2c2fe7cce1249c21f 100644 (file)
@@ -7,7 +7,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 title: Bindings for the TI wrapper module for the Cadence USBSS-DRD controller
 
 maintainers:
-  - Roger Quadros <rogerq@ti.com>
+  - Roger Quadros <rogerq@kernel.org>
 
 properties:
   compatible:
index f6e91a5fd8fe7e7f43f330b3a4f044469be9323f..4f7a212fddd37d33549a7f98c39199e2ee50e50f 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: TI Keystone Soc USB Controller
 
 maintainers:
-  - Roger Quadros <rogerq@ti.com>
+  - Roger Quadros <rogerq@kernel.org>
 
 properties:
   compatible:
index 0266cd08a6c929c379c32dfbc7fa691178d468ce..df53ff835bfb6646e7a6bf8041863da2f1f828f4 100644 (file)
@@ -2,7 +2,7 @@
 
         Set the histogram bucket size (default *1*).
 
-**-e**, **--entries** *N*
+**-E**, **--entries** *N*
 
         Set the number of entries of the histogram (default 256).
 
index 8973c5df888f6360a1f75ff512d43d8ecc2c126f..d5d61615b9670918fcf32ac626b9472dfb63a7c7 100644 (file)
@@ -1,7 +1,7 @@
 The **rtla osnoise** tool is an interface for the *osnoise* tracer. The
 *osnoise* tracer dispatches a kernel thread per-cpu. These threads read the
 time in a loop while with preemption, softirq and IRQs enabled, thus
-allowing all the sources of operating systme noise during its execution.
+allowing all the sources of operating system noise during its execution.
 The *osnoise*'s tracer threads take note of the delta between each time
 read, along with an interference counter of all sources of interference.
 At the end of each period, the *osnoise* tracer displays a summary of
index 52298ddd8701b21c13db3cb523230da46b51c3ef..f2e79d22c4c43f67b7859f1a2f6ab5c3e2482598 100644 (file)
@@ -36,7 +36,7 @@ default). The reason for reducing the runtime is to avoid starving the
 **rtla** tool. The tool is also set to run for *one minute*. The output
 histogram is set to group outputs in buckets of *10us* and *25* entries::
 
-  [root@f34 ~/]# rtla osnoise hist -P F:1 -c 0-11 -r 900000 -d 1M -b 10 -e 25
+  [root@f34 ~/]# rtla osnoise hist -P F:1 -c 0-11 -r 900000 -d 1M -b 10 -E 25
   # RTLA osnoise histogram
   # Time unit is microseconds (us)
   # Duration:   0 00:01:00
index 87a36044f828c9af0bf20a3e0ebb9a94ea638c25..2ca92042767be437a4d23689a75fd87e2c1b4477 100644 (file)
@@ -84,6 +84,8 @@ CPUfreq核心层注册一个cpufreq_driver结构体。
  .resume - 一个指向per-policy恢复函数的指针,该函数在关中断且在调节器再一次启动前被
  调用。
 
+ .ready - 一个指向per-policy准备函数的指针,该函数在策略完全初始化之后被调用。
+
  .attr - 一个指向NULL结尾的"struct freq_attr"列表的指针,该列表允许导出值到
  sysfs。
 
index a4267104db50a490b481729e282017e7f453754c..9f3172376ec3a63969cfae8096256f854ea76717 100644 (file)
@@ -1394,7 +1394,7 @@ documentation when it pops into existence).
 -------------------
 
 :Capability: KVM_CAP_ENABLE_CAP
-:Architectures: mips, ppc, s390
+:Architectures: mips, ppc, s390, x86
 :Type: vcpu ioctl
 :Parameters: struct kvm_enable_cap (in)
 :Returns: 0 on success; -1 on error
@@ -6997,6 +6997,20 @@ indicated by the fd to the VM this is called on.
 This is intended to support intra-host migration of VMs between userspace VMMs,
 upgrading the VMM process without interrupting the guest.
 
+7.30 KVM_CAP_PPC_AIL_MODE_3
+-------------------------------
+
+:Capability: KVM_CAP_PPC_AIL_MODE_3
+:Architectures: ppc
+:Type: vm
+
+This capability indicates that the kernel supports the mode 3 setting for the
+"Address Translation Mode on Interrupt" aka "Alternate Interrupt Location"
+resource that is controlled with the H_SET_MODE hypercall.
+
+This capability allows a guest kernel to use a better-performance mode for
+handling interrupts and system calls.
+
 8. Other capabilities.
 ======================
 
index 777cd6fa2b3d69fcf90c6fa07dff18fe16286f32..f092ad6d5212770240dc57e6b7e1aebf1d8db338 100644 (file)
@@ -2254,7 +2254,7 @@ F:        drivers/phy/mediatek/
 ARM/Microchip (AT91) SoC support
 M:     Nicolas Ferre <nicolas.ferre@microchip.com>
 M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
+M:     Claudiu Beznea <claudiu.beznea@microchip.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 W:     http://www.linux4sam.org
@@ -2572,7 +2572,7 @@ F:        sound/soc/rockchip/
 N:     rockchip
 
 ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 R:     Alim Akhtar <alim.akhtar@samsung.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org
@@ -2739,7 +2739,7 @@ N:        stm32
 N:     stm
 
 ARM/Synaptics SoC support
-M:     Jisheng Zhang <Jisheng.Zhang@synaptics.com>
+M:     Jisheng Zhang <jszhang@kernel.org>
 M:     Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -3905,7 +3905,7 @@ M:        Scott Branden <sbranden@broadcom.com>
 M:     bcm-kernel-feedback-list@broadcom.com
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-T:     git git://github.com/broadcom/cygnus-linux.git
+T:     git git://github.com/broadcom/stblinux.git
 F:     arch/arm64/boot/dts/broadcom/northstar2/*
 F:     arch/arm64/boot/dts/broadcom/stingray/*
 F:     drivers/clk/bcm/clk-ns*
@@ -4913,7 +4913,8 @@ F:        kernel/cgroup/cpuset.c
 CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)
 M:     Johannes Weiner <hannes@cmpxchg.org>
 M:     Michal Hocko <mhocko@kernel.org>
-M:     Vladimir Davydov <vdavydov.dev@gmail.com>
+M:     Roman Gushchin <roman.gushchin@linux.dev>
+M:     Shakeel Butt <shakeelb@google.com>
 L:     cgroups@vger.kernel.org
 L:     linux-mm@kvack.org
 S:     Maintained
@@ -6306,8 +6307,8 @@ T:        git git://anongit.freedesktop.org/drm/drm-misc
 F:     drivers/gpu/drm/vboxvideo/
 
 DRM DRIVER FOR VMWARE VIRTUAL GPU
-M:     "VMware Graphics" <linux-graphics-maintainer@vmware.com>
 M:     Zack Rusin <zackr@vmware.com>
+R:     VMware Graphics Reviewers <linux-graphics-maintainer@vmware.com>
 L:     dri-devel@lists.freedesktop.org
 S:     Supported
 T:     git git://anongit.freedesktop.org/drm/drm-misc
@@ -7011,12 +7012,6 @@ L:       linux-edac@vger.kernel.org
 S:     Maintained
 F:     drivers/edac/sb_edac.c
 
-EDAC-SIFIVE
-M:     Yash Shah <yash.shah@sifive.com>
-L:     linux-edac@vger.kernel.org
-S:     Supported
-F:     drivers/edac/sifive_edac.c
-
 EDAC-SKYLAKE
 M:     Tony Luck <tony.luck@intel.com>
 L:     linux-edac@vger.kernel.org
@@ -7749,8 +7744,7 @@ M:        Qiang Zhao <qiang.zhao@nxp.com>
 L:     linuxppc-dev@lists.ozlabs.org
 S:     Maintained
 F:     drivers/soc/fsl/qe/
-F:     include/soc/fsl/*qe*.h
-F:     include/soc/fsl/*ucc*.h
+F:     include/soc/fsl/qe/
 
 FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
 M:     Li Yang <leoyang.li@nxp.com>
@@ -7781,6 +7775,7 @@ F:        Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml
 F:     Documentation/devicetree/bindings/soc/fsl/
 F:     drivers/soc/fsl/
 F:     include/linux/fsl/
+F:     include/soc/fsl/
 
 FREESCALE SOC FS_ENET DRIVER
 M:     Pantelis Antoniou <pantelis.antoniou@gmail.com>
@@ -11680,7 +11675,7 @@ F:      drivers/iio/proximity/mb1232.c
 
 MAXIM MAX17040 FAMILY FUEL GAUGE DRIVERS
 R:     Iskren Chernev <iskren.chernev@gmail.com>
-R:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+R:     Krzysztof Kozlowski <krzk@kernel.org>
 R:     Marek Szyprowski <m.szyprowski@samsung.com>
 R:     Matheus Castello <matheus@castello.eng.br>
 L:     linux-pm@vger.kernel.org
@@ -11690,7 +11685,7 @@ F:      drivers/power/supply/max17040_battery.c
 
 MAXIM MAX17042 FAMILY FUEL GAUGE DRIVERS
 R:     Hans de Goede <hdegoede@redhat.com>
-R:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+R:     Krzysztof Kozlowski <krzk@kernel.org>
 R:     Marek Szyprowski <m.szyprowski@samsung.com>
 R:     Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
 R:     Purism Kernel Team <kernel@puri.sm>
@@ -11735,7 +11730,7 @@ F:      Documentation/devicetree/bindings/power/supply/maxim,max77976.yaml
 F:     drivers/power/supply/max77976_charger.c
 
 MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
 L:     linux-pm@vger.kernel.org
 S:     Supported
@@ -11744,7 +11739,7 @@ F:      drivers/power/supply/max77693_charger.c
 
 MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
 M:     Chanwoo Choi <cw00.choi@samsung.com>
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
 L:     linux-kernel@vger.kernel.org
 S:     Supported
@@ -12433,7 +12428,7 @@ F:      include/linux/memblock.h
 F:     mm/memblock.c
 
 MEMORY CONTROLLER DRIVERS
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git
@@ -13381,6 +13376,7 @@ F:      net/core/drop_monitor.c
 NETWORKING DRIVERS
 M:     "David S. Miller" <davem@davemloft.net>
 M:     Jakub Kicinski <kuba@kernel.org>
+M:     Paolo Abeni <pabeni@redhat.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 Q:     https://patchwork.kernel.org/project/netdevbpf/list/
@@ -13427,6 +13423,7 @@ F:      tools/testing/selftests/drivers/net/dsa/
 NETWORKING [GENERAL]
 M:     "David S. Miller" <davem@davemloft.net>
 M:     Jakub Kicinski <kuba@kernel.org>
+M:     Paolo Abeni <pabeni@redhat.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 Q:     https://patchwork.kernel.org/project/netdevbpf/list/
@@ -13570,7 +13567,7 @@ F:      include/uapi/linux/nexthop.h
 F:     net/ipv4/nexthop.c
 
 NFC SUBSYSTEM
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 L:     linux-nfc@lists.01.org (subscribers-only)
 L:     netdev@vger.kernel.org
 S:     Maintained
@@ -13704,7 +13701,7 @@ F:      scripts/nsdeps
 NTB AMD DRIVER
 M:     Sanjay R Mehta <sanju.mehta@amd.com>
 M:     Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
-L:     linux-ntb@googlegroups.com
+L:     ntb@lists.linux.dev
 S:     Supported
 F:     drivers/ntb/hw/amd/
 
@@ -13712,7 +13709,7 @@ NTB DRIVER CORE
 M:     Jon Mason <jdmason@kudzu.us>
 M:     Dave Jiang <dave.jiang@intel.com>
 M:     Allen Hubbe <allenbh@gmail.com>
-L:     linux-ntb@googlegroups.com
+L:     ntb@lists.linux.dev
 S:     Supported
 W:     https://github.com/jonmason/ntb/wiki
 T:     git git://github.com/jonmason/ntb.git
@@ -13724,13 +13721,13 @@ F:    tools/testing/selftests/ntb/
 
 NTB IDT DRIVER
 M:     Serge Semin <fancer.lancer@gmail.com>
-L:     linux-ntb@googlegroups.com
+L:     ntb@lists.linux.dev
 S:     Supported
 F:     drivers/ntb/hw/idt/
 
 NTB INTEL DRIVER
 M:     Dave Jiang <dave.jiang@intel.com>
-L:     linux-ntb@googlegroups.com
+L:     ntb@lists.linux.dev
 S:     Supported
 W:     https://github.com/davejiang/linux/wiki
 T:     git https://github.com/davejiang/linux.git
@@ -13884,7 +13881,7 @@ F:      Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml
 F:     drivers/regulator/pf8x00-regulator.c
 
 NXP PTN5150A CC LOGIC AND EXTCON DRIVER
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml
@@ -14608,8 +14605,9 @@ F:      include/uapi/linux/ppdev.h
 
 PARAVIRT_OPS INTERFACE
 M:     Juergen Gross <jgross@suse.com>
-M:     Deep Shah <sdeep@vmware.com>
-M:     "VMware, Inc." <pv-drivers@vmware.com>
+M:     Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
+R:     Alexey Makhalov <amakhalov@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     virtualization@lists.linux-foundation.org
 L:     x86@kernel.org
 S:     Supported
@@ -15310,7 +15308,7 @@ F:      drivers/pinctrl/renesas/
 
 PIN CONTROLLER - SAMSUNG
 M:     Tomasz Figa <tomasz.figa@gmail.com>
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
 R:     Alim Akhtar <alim.akhtar@samsung.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -15573,6 +15571,7 @@ M:      Iurii Zaikin <yzaikin@google.com>
 L:     linux-kernel@vger.kernel.org
 L:     linux-fsdevel@vger.kernel.org
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git sysctl-next
 F:     fs/proc/proc_sysctl.c
 F:     include/linux/sysctl.h
 F:     kernel/sysctl-test.c
@@ -16079,8 +16078,8 @@ F:      Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
 F:     drivers/mtd/nand/raw/qcom_nandc.c
 
 QUALCOMM RMNET DRIVER
-M:     Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
-M:     Sean Tranchetti <stranche@codeaurora.org>
+M:     Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
+M:     Sean Tranchetti <quic_stranche@quicinc.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst
@@ -16372,6 +16371,7 @@ F:      drivers/watchdog/realtek_otto_wdt.c
 
 REALTEK RTL83xx SMI DSA ROUTER CHIPS
 M:     Linus Walleij <linus.walleij@linaro.org>
+M:     Alvin Šipraga <alsi@bang-olufsen.dk>
 S:     Maintained
 F:     Documentation/devicetree/bindings/net/dsa/realtek-smi.txt
 F:     drivers/net/dsa/realtek-smi*
@@ -16950,7 +16950,7 @@ W:      http://www.ibm.com/developerworks/linux/linux390/
 F:     drivers/s390/scsi/zfcp_*
 
 S3C ADC BATTERY DRIVER
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 L:     linux-samsung-soc@vger.kernel.org
 S:     Odd Fixes
 F:     drivers/power/supply/s3c_adc_battery.c
@@ -16995,7 +16995,7 @@ F:      Documentation/admin-guide/LSM/SafeSetID.rst
 F:     security/safesetid/
 
 SAMSUNG AUDIO (ASoC) DRIVERS
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
@@ -17003,7 +17003,7 @@ F:      Documentation/devicetree/bindings/sound/samsung*
 F:     sound/soc/samsung/
 
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 L:     linux-crypto@vger.kernel.org
 L:     linux-samsung-soc@vger.kernel.org
 S:     Maintained
@@ -17038,7 +17038,7 @@ S:      Maintained
 F:     drivers/platform/x86/samsung-laptop.c
 
 SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
 L:     linux-kernel@vger.kernel.org
 L:     linux-samsung-soc@vger.kernel.org
@@ -17064,7 +17064,7 @@ F:      drivers/media/platform/s3c-camif/
 F:     include/media/drv-intf/s3c_camif.h
 
 SAMSUNG S3FWRN5 NFC DRIVER
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Krzysztof Opasiak <k.opasiak@samsung.com>
 L:     linux-nfc@lists.01.org (subscribers-only)
 S:     Maintained
@@ -17086,7 +17086,7 @@ S:      Supported
 F:     drivers/media/i2c/s5k5baf.c
 
 SAMSUNG S5P Security SubSystem (SSS) DRIVER
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Vladimir Zapolskiy <vz@mleia.com>
 L:     linux-crypto@vger.kernel.org
 L:     linux-samsung-soc@vger.kernel.org
@@ -17121,7 +17121,7 @@ F:      include/linux/clk/samsung.h
 F:     include/linux/platform_data/clk-s3c2410.h
 
 SAMSUNG SPI DRIVERS
-M:     Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
 M:     Andi Shyti <andi@etezian.org>
 L:     linux-spi@vger.kernel.org
 L:     linux-samsung-soc@vger.kernel.org
@@ -17765,8 +17765,10 @@ M:     David Rientjes <rientjes@google.com>
 M:     Joonsoo Kim <iamjoonsoo.kim@lge.com>
 M:     Andrew Morton <akpm@linux-foundation.org>
 M:     Vlastimil Babka <vbabka@suse.cz>
+R:     Roman Gushchin <roman.gushchin@linux.dev>
 L:     linux-mm@kvack.org
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git
 F:     include/linux/sl?b*.h
 F:     mm/sl?b*
 
@@ -20639,30 +20641,33 @@ F:    tools/testing/vsock/
 
 VMWARE BALLOON DRIVER
 M:     Nadav Amit <namit@vmware.com>
-M:     "VMware, Inc." <pv-drivers@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 F:     drivers/misc/vmw_balloon.c
 
 VMWARE HYPERVISOR INTERFACE
-M:     Deep Shah <sdeep@vmware.com>
-M:     "VMware, Inc." <pv-drivers@vmware.com>
+M:     Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu>
+M:     Alexey Makhalov <amakhalov@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     virtualization@lists.linux-foundation.org
+L:     x86@kernel.org
 S:     Supported
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/vmware
 F:     arch/x86/include/asm/vmware.h
 F:     arch/x86/kernel/cpu/vmware.c
 
 VMWARE PVRDMA DRIVER
 M:     Bryan Tan <bryantan@vmware.com>
 M:     Vishnu Dasa <vdasa@vmware.com>
-M:     VMware PV-Drivers <pv-drivers@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     linux-rdma@vger.kernel.org
 S:     Maintained
 F:     drivers/infiniband/hw/vmw_pvrdma/
 
 VMware PVSCSI driver
 M:     Vishal Bhakta <vbhakta@vmware.com>
-M:     VMware PV-Drivers <pv-drivers@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     linux-scsi@vger.kernel.org
 S:     Maintained
 F:     drivers/scsi/vmw_pvscsi.c
@@ -20670,7 +20675,7 @@ F:      drivers/scsi/vmw_pvscsi.h
 
 VMWARE VIRTUAL PTP CLOCK DRIVER
 M:     Vivek Thampi <vithampi@vmware.com>
-M:     "VMware, Inc." <pv-drivers@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/ptp/ptp_vmw.c
@@ -20678,14 +20683,15 @@ F:    drivers/ptp/ptp_vmw.c
 VMWARE VMCI DRIVER
 M:     Jorgen Hansen <jhansen@vmware.com>
 M:     Vishnu Dasa <vdasa@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     linux-kernel@vger.kernel.org
-L:     pv-drivers@vmware.com (private)
 S:     Maintained
 F:     drivers/misc/vmw_vmci/
 
 VMWARE VMMOUSE SUBDRIVER
-M:     "VMware Graphics" <linux-graphics-maintainer@vmware.com>
-M:     "VMware, Inc." <pv-drivers@vmware.com>
+M:     Zack Rusin <zackr@vmware.com>
+R:     VMware Graphics Reviewers <linux-graphics-maintainer@vmware.com>
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     linux-input@vger.kernel.org
 S:     Maintained
 F:     drivers/input/mouse/vmmouse.c
@@ -20693,7 +20699,7 @@ F:      drivers/input/mouse/vmmouse.h
 
 VMWARE VMXNET3 ETHERNET DRIVER
 M:     Ronak Doshi <doshir@vmware.com>
-M:     pv-drivers@vmware.com
+R:     VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/vmxnet3/
@@ -21469,7 +21475,6 @@ THE REST
 M:     Linus Torvalds <torvalds@linux-foundation.org>
 L:     linux-kernel@vger.kernel.org
 S:     Buried alive in reporters
-Q:     http://patchwork.kernel.org/project/LKML/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 F:     *
 F:     */
index 289ce2be8032a4a5e91d242fe5623a0acd4e454e..7214f075e1f06445c3a3e7992f8ee8f5f31033a4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 17
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION =
 NAME = Superb Owl
 
 # *DOCUMENTATION*
index 6dde51c2aed3fe48761df586cd0c9d3c213fe336..e4775bbceecc6143927b3954e3c99d44018a55c4 100644 (file)
        };
 
        pinctrl_fwqspid_default: fwqspid_default {
-               function = "FWQSPID";
+               function = "FWSPID";
                groups = "FWQSPID";
        };
 
index dff18fc9a9065c77a1e5477da94e9159e9cc93b6..21294f775a20f2e58bcb9fcfda944fbb72064607 100644 (file)
 
                hvs: hvs@7e400000 {
                        compatible = "brcm,bcm2711-hvs";
+                       reg = <0x7e400000 0x8000>;
                        interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
                };
 
index 5e55198e4576543d3c3dbd08b71e65994faa974b..54cd37336be7a1d8dab5534ed36a7a8d84c87759 100644 (file)
        status = "disabled";
 };
 
+/* Unusable as clockevent because if unreliable oscillator, allow to idle */
+&timer1_target {
+       /delete-property/ti,no-reset-on-init;
+       /delete-property/ti,no-idle;
+       timer@0 {
+               /delete-property/ti,timer-alwon;
+       };
+};
+
+/* Preferred timer for clockevent */
+&timer12_target {
+       ti,no-reset-on-init;
+       ti,no-idle;
+       timer@0 {
+               /* Always clocked by secure_32k_fck */
+       };
+};
+
 &twl_gpio {
        ti,use-leds;
        /*
index c2995a280729d27900eeda63af011ce94d8b995a..162d0726b00801c50f4b029ef011f6d24cced686 100644 (file)
                display2 = &tv0;
        };
 };
-
-/* Unusable as clocksource because of unreliable oscillator */
-&counter32k {
-       status = "disabled";
-};
-
-/* Unusable as clockevent because if unreliable oscillator, allow to idle */
-&timer1_target {
-       /delete-property/ti,no-reset-on-init;
-       /delete-property/ti,no-idle;
-       timer@0 {
-               /delete-property/ti,timer-alwon;
-       };
-};
-
-/* Preferred always-on timer for clocksource */
-&timer12_target {
-       ti,no-reset-on-init;
-       ti,no-idle;
-       timer@0 {
-               /* Always clocked by secure_32k_fck */
-       };
-};
-
-/* Preferred timer for clockevent */
-&timer2_target {
-       ti,no-reset-on-init;
-       ti,no-idle;
-       timer@0 {
-               assigned-clocks = <&gpt2_fck>;
-               assigned-clock-parents = <&sys_ck>;
-       };
-};
index 8eed9e3a92e901b6c2769e38224423de1be950da..5868eb512f69fef83251fcf56138ba125cdfa1b9 100644 (file)
                interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
                assigned-clocks = <&cru SCLK_HDMI_PHY>;
                assigned-clock-parents = <&hdmi_phy>;
-               clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_CEC>;
-               clock-names = "isfr", "iahb", "cec";
+               clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;
+               clock-names = "iahb", "isfr", "cec";
                pinctrl-names = "default";
                pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>;
                resets = <&cru SRST_HDMI_P>;
index aaaa61875701d916bd75ab032c655bf208d3b3df..45a9d9b908d2a1a3ecb15340383f1c744ef62724 100644 (file)
                status = "disabled";
        };
 
-       crypto: cypto-controller@ff8a0000 {
+       crypto: crypto@ff8a0000 {
                compatible = "rockchip,rk3288-crypto";
                reg = <0x0 0xff8a0000 0x0 0x4000>;
                interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
index d35fb79d2f51b36d76fdcbdbf1ed9554455cdee9..4db43324dafa7dad92cab90c0a8c8c0dbd0ca1ff 100644 (file)
@@ -5,7 +5,13 @@
 
 / {
        /* Version of Nyan Big with 1080p panel */
-       panel {
-               compatible = "auo,b133htn01";
+       host1x@50000000 {
+               dpaux@545c0000 {
+                       aux-bus {
+                               panel: panel {
+                                       compatible = "auo,b133htn01";
+                               };
+                       };
+               };
        };
 };
index 1d2aac2cb6d038b50db7e48fbcdc2432e7564d13..fdc1d64dfff9dccbd9d3cc69a90e8c803de56dd1 100644 (file)
                     "google,nyan-big-rev1", "google,nyan-big-rev0",
                     "google,nyan-big", "google,nyan", "nvidia,tegra124";
 
-       panel: panel {
-               compatible = "auo,b133xtn01";
-
-               power-supply = <&vdd_3v3_panel>;
-               backlight = <&backlight>;
-               ddc-i2c-bus = <&dpaux>;
+       host1x@50000000 {
+               dpaux@545c0000 {
+                       aux-bus {
+                               panel: panel {
+                                       compatible = "auo,b133xtn01";
+                                       backlight = <&backlight>;
+                               };
+                       };
+               };
        };
 
        mmc@700b0400 { /* SD Card on this bus */
index 677babde6460ed1eb39a1e5d2db5fc42c896e1f4..abdf4456826f8f7100519e742fadb01b110e04db 100644 (file)
                     "google,nyan-blaze-rev0", "google,nyan-blaze",
                     "google,nyan", "nvidia,tegra124";
 
-       panel: panel {
-               compatible = "samsung,ltn140at29-301";
-
-               power-supply = <&vdd_3v3_panel>;
-               backlight = <&backlight>;
-               ddc-i2c-bus = <&dpaux>;
+       host1x@50000000 {
+               dpaux@545c0000 {
+                       aux-bus {
+                               panel: panel {
+                                       compatible = "samsung,ltn140at29-301";
+                                       backlight = <&backlight>;
+                               };
+                       };
+               };
        };
 
        sound {
index 232c90604df9f2650e747a9d82ff919e95643fc7..6a9592ceb5f2b1bc9e634a2f2ea604847dd594c2 100644 (file)
                dpaux@545c0000 {
                        vdd-supply = <&vdd_3v3_panel>;
                        status = "okay";
+
+                       aux-bus {
+                               panel: panel {
+                                       compatible = "lg,lp129qe";
+                                       backlight = <&backlight>;
+                               };
+                       };
                };
        };
 
                };
        };
 
-       panel: panel {
-               compatible = "lg,lp129qe";
-               power-supply = <&vdd_3v3_panel>;
-               backlight = <&backlight>;
-               ddc-i2c-bus = <&dpaux>;
-       };
-
        vdd_mux: regulator-mux {
                compatible = "regulator-fixed";
                regulator-name = "+VDD_MUX";
index 6fe67963ba5a0885e68165e5ec591fed039dbcb9..aee73ef5b3dc49043d251fb0b9ca0a02fae08a95 100644 (file)
        .endm
 #endif
 
+#if __LINUX_ARM_ARCH__ < 7
+       .macro  dsb, args
+       mcr     p15, 0, r0, c7, c10, 4
+       .endm
+
+       .macro  isb, args
+       mcr     p15, 0, r0, c7, c5, 4
+       .endm
+#endif
+
        .macro asm_trace_hardirqs_off, save=1
 #if defined(CONFIG_TRACE_IRQFLAGS)
        .if \save
diff --git a/arch/arm/include/asm/spectre.h b/arch/arm/include/asm/spectre.h
new file mode 100644 (file)
index 0000000..85f9e53
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ASM_SPECTRE_H
+#define __ASM_SPECTRE_H
+
+enum {
+       SPECTRE_UNAFFECTED,
+       SPECTRE_MITIGATED,
+       SPECTRE_VULNERABLE,
+};
+
+enum {
+       __SPECTRE_V2_METHOD_BPIALL,
+       __SPECTRE_V2_METHOD_ICIALLU,
+       __SPECTRE_V2_METHOD_SMC,
+       __SPECTRE_V2_METHOD_HVC,
+       __SPECTRE_V2_METHOD_LOOP8,
+};
+
+enum {
+       SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL),
+       SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU),
+       SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC),
+       SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC),
+       SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8),
+};
+
+#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
+void spectre_v2_update_state(unsigned int state, unsigned int methods);
+#else
+static inline void spectre_v2_update_state(unsigned int state,
+                                          unsigned int methods)
+{}
+#endif
+
+int spectre_bhb_update_vectors(unsigned int method);
+
+#endif
index 4a91428c324dbd2c68f30dbfb237d832c5dbeb22..fad45c884e98890b4958ec9f71d377d14b0d4173 100644 (file)
 #define ARM_MMU_DISCARD(x)     x
 #endif
 
+/*
+ * ld.lld does not support NOCROSSREFS:
+ * https://github.com/ClangBuiltLinux/linux/issues/1609
+ */
+#ifdef CONFIG_LD_IS_LLD
+#define NOCROSSREFS
+#endif
+
+/* Set start/end symbol names to the LMA for the section */
+#define ARM_LMA(sym, section)                                          \
+       sym##_start = LOADADDR(section);                                \
+       sym##_end = LOADADDR(section) + SIZEOF(section)
+
 #define PROC_INFO                                                      \
                . = ALIGN(4);                                           \
                __proc_info_begin = .;                                  \
  * only thing that matters is their relative offsets
  */
 #define ARM_VECTORS                                                    \
-       __vectors_start = .;                                            \
-       .vectors 0xffff0000 : AT(__vectors_start) {                     \
-               *(.vectors)                                             \
+       __vectors_lma = .;                                              \
+       OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) {            \
+               .vectors {                                              \
+                       *(.vectors)                                     \
+               }                                                       \
+               .vectors.bhb.loop8 {                                    \
+                       *(.vectors.bhb.loop8)                           \
+               }                                                       \
+               .vectors.bhb.bpiall {                                   \
+                       *(.vectors.bhb.bpiall)                          \
+               }                                                       \
        }                                                               \
-       . = __vectors_start + SIZEOF(.vectors);                         \
-       __vectors_end = .;                                              \
+       ARM_LMA(__vectors, .vectors);                                   \
+       ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8);               \
+       ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall);             \
+       . = __vectors_lma + SIZEOF(.vectors) +                          \
+               SIZEOF(.vectors.bhb.loop8) +                            \
+               SIZEOF(.vectors.bhb.bpiall);                            \
                                                                        \
-       __stubs_start = .;                                              \
-       .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {            \
+       __stubs_lma = .;                                                \
+       .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) {              \
                *(.stubs)                                               \
        }                                                               \
-       . = __stubs_start + SIZEOF(.stubs);                             \
-       __stubs_end = .;                                                \
+       ARM_LMA(__stubs, .stubs);                                       \
+       . = __stubs_lma + SIZEOF(.stubs);                               \
                                                                        \
        PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
 
index ae295a3bcfefddad015d56e79a4af37b80d66487..6ef3b535b7bf7764dd7b06816b05007516d0add0 100644 (file)
@@ -106,4 +106,6 @@ endif
 
 obj-$(CONFIG_HAVE_ARM_SMCCC)   += smccc-call.o
 
+obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o
+
 extra-y := $(head-y) vmlinux.lds
index 5cd057859fe909ca573f21980ca1b3585fe6050c..ee3f7a599181e34dd3aa35b016d07d13df37952e 100644 (file)
@@ -1002,12 +1002,11 @@ vector_\name:
        sub     lr, lr, #\correction
        .endif
 
-       @
-       @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
-       @ (parent CPSR)
-       @
+       @ Save r0, lr_<exception> (parent PC)
        stmia   sp, {r0, lr}            @ save r0, lr
-       mrs     lr, spsr
+
+       @ Save spsr_<exception> (parent CPSR)
+2:     mrs     lr, spsr
        str     lr, [sp, #8]            @ save spsr
 
        @
@@ -1028,6 +1027,44 @@ vector_\name:
        movs    pc, lr                  @ branch to handler in SVC mode
 ENDPROC(vector_\name)
 
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+       .subsection 1
+       .align 5
+vector_bhb_loop8_\name:
+       .if \correction
+       sub     lr, lr, #\correction
+       .endif
+
+       @ Save r0, lr_<exception> (parent PC)
+       stmia   sp, {r0, lr}
+
+       @ bhb workaround
+       mov     r0, #8
+3:     b       . + 4
+       subs    r0, r0, #1
+       bne     3b
+       dsb
+       isb
+       b       2b
+ENDPROC(vector_bhb_loop8_\name)
+
+vector_bhb_bpiall_\name:
+       .if \correction
+       sub     lr, lr, #\correction
+       .endif
+
+       @ Save r0, lr_<exception> (parent PC)
+       stmia   sp, {r0, lr}
+
+       @ bhb workaround
+       mcr     p15, 0, r0, c7, c5, 6   @ BPIALL
+       @ isb not needed due to "movs pc, lr" in the vector stub
+       @ which gives a "context synchronisation".
+       b       2b
+ENDPROC(vector_bhb_bpiall_\name)
+       .previous
+#endif
+
        .align  2
        @ handler addresses follow this label
 1:
@@ -1036,6 +1073,10 @@ ENDPROC(vector_\name)
        .section .stubs, "ax", %progbits
        @ This must be the first word
        .word   vector_swi
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+       .word   vector_bhb_loop8_swi
+       .word   vector_bhb_bpiall_swi
+#endif
 
 vector_rst:
  ARM(  swi     SYS_ERROR0      )
@@ -1150,8 +1191,10 @@ vector_addrexcptn:
  * FIQ "NMI" handler
  *-----------------------------------------------------------------------------
  * Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86
- * systems.
+ * systems. This must be the last vector stub, so lets place it in its own
+ * subsection.
  */
+       .subsection 2
        vector_stub     fiq, FIQ_MODE, 4
 
        .long   __fiq_usr                       @  0  (USR_26 / USR_32)
@@ -1184,6 +1227,30 @@ vector_addrexcptn:
        W(b)    vector_irq
        W(b)    vector_fiq
 
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+       .section .vectors.bhb.loop8, "ax", %progbits
+.L__vectors_bhb_loop8_start:
+       W(b)    vector_rst
+       W(b)    vector_bhb_loop8_und
+       W(ldr)  pc, .L__vectors_bhb_loop8_start + 0x1004
+       W(b)    vector_bhb_loop8_pabt
+       W(b)    vector_bhb_loop8_dabt
+       W(b)    vector_addrexcptn
+       W(b)    vector_bhb_loop8_irq
+       W(b)    vector_bhb_loop8_fiq
+
+       .section .vectors.bhb.bpiall, "ax", %progbits
+.L__vectors_bhb_bpiall_start:
+       W(b)    vector_rst
+       W(b)    vector_bhb_bpiall_und
+       W(ldr)  pc, .L__vectors_bhb_bpiall_start + 0x1008
+       W(b)    vector_bhb_bpiall_pabt
+       W(b)    vector_bhb_bpiall_dabt
+       W(b)    vector_addrexcptn
+       W(b)    vector_bhb_bpiall_irq
+       W(b)    vector_bhb_bpiall_fiq
+#endif
+
        .data
        .align  2
 
index ac86c34682bb505094443c043ae92ba2b71b55b4..dbc1913ee30bcb5cb39ad4a606c37f92d946020d 100644 (file)
@@ -153,6 +153,29 @@ ENDPROC(ret_from_fork)
  *-----------------------------------------------------------------------------
  */
 
+       .align  5
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+ENTRY(vector_bhb_loop8_swi)
+       sub     sp, sp, #PT_REGS_SIZE
+       stmia   sp, {r0 - r12}
+       mov     r8, #8
+1:     b       2f
+2:     subs    r8, r8, #1
+       bne     1b
+       dsb
+       isb
+       b       3f
+ENDPROC(vector_bhb_loop8_swi)
+
+       .align  5
+ENTRY(vector_bhb_bpiall_swi)
+       sub     sp, sp, #PT_REGS_SIZE
+       stmia   sp, {r0 - r12}
+       mcr     p15, 0, r8, c7, c5, 6   @ BPIALL
+       isb
+       b       3f
+ENDPROC(vector_bhb_bpiall_swi)
+#endif
        .align  5
 ENTRY(vector_swi)
 #ifdef CONFIG_CPU_V7M
@@ -160,6 +183,7 @@ ENTRY(vector_swi)
 #else
        sub     sp, sp, #PT_REGS_SIZE
        stmia   sp, {r0 - r12}                  @ Calling r0 - r12
+3:
  ARM(  add     r8, sp, #S_PC           )
  ARM(  stmdb   r8, {sp, lr}^           )       @ Calling sp, lr
  THUMB(        mov     r8, sp                  )
index 7bd30c0a4280d9a6e029c05c49e8fb2d9b373b00..22f937e6f3ffb12a7e854179b73ea2a77c0eb06b 100644 (file)
@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
        return 0;
 }
 
-static struct undef_hook kgdb_brkpt_hook = {
+static struct undef_hook kgdb_brkpt_arm_hook = {
        .instr_mask             = 0xffffffff,
        .instr_val              = KGDB_BREAKINST,
-       .cpsr_mask              = MODE_MASK,
+       .cpsr_mask              = PSR_T_BIT | MODE_MASK,
        .cpsr_val               = SVC_MODE,
        .fn                     = kgdb_brk_fn
 };
 
-static struct undef_hook kgdb_compiled_brkpt_hook = {
+static struct undef_hook kgdb_brkpt_thumb_hook = {
+       .instr_mask             = 0xffff,
+       .instr_val              = KGDB_BREAKINST & 0xffff,
+       .cpsr_mask              = PSR_T_BIT | MODE_MASK,
+       .cpsr_val               = PSR_T_BIT | SVC_MODE,
+       .fn                     = kgdb_brk_fn
+};
+
+static struct undef_hook kgdb_compiled_brkpt_arm_hook = {
        .instr_mask             = 0xffffffff,
        .instr_val              = KGDB_COMPILED_BREAK,
-       .cpsr_mask              = MODE_MASK,
+       .cpsr_mask              = PSR_T_BIT | MODE_MASK,
        .cpsr_val               = SVC_MODE,
        .fn                     = kgdb_compiled_brk_fn
 };
 
+static struct undef_hook kgdb_compiled_brkpt_thumb_hook = {
+       .instr_mask             = 0xffff,
+       .instr_val              = KGDB_COMPILED_BREAK & 0xffff,
+       .cpsr_mask              = PSR_T_BIT | MODE_MASK,
+       .cpsr_val               = PSR_T_BIT | SVC_MODE,
+       .fn                     = kgdb_compiled_brk_fn
+};
+
 static int __kgdb_notify(struct die_args *args, unsigned long cmd)
 {
        struct pt_regs *regs = args->regs;
@@ -210,8 +226,10 @@ int kgdb_arch_init(void)
        if (ret != 0)
                return ret;
 
-       register_undef_hook(&kgdb_brkpt_hook);
-       register_undef_hook(&kgdb_compiled_brkpt_hook);
+       register_undef_hook(&kgdb_brkpt_arm_hook);
+       register_undef_hook(&kgdb_brkpt_thumb_hook);
+       register_undef_hook(&kgdb_compiled_brkpt_arm_hook);
+       register_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
 
        return 0;
 }
@@ -224,8 +242,10 @@ int kgdb_arch_init(void)
  */
 void kgdb_arch_exit(void)
 {
-       unregister_undef_hook(&kgdb_brkpt_hook);
-       unregister_undef_hook(&kgdb_compiled_brkpt_hook);
+       unregister_undef_hook(&kgdb_brkpt_arm_hook);
+       unregister_undef_hook(&kgdb_brkpt_thumb_hook);
+       unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook);
+       unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
        unregister_die_notifier(&kgdb_notifier);
 }
 
diff --git a/arch/arm/kernel/spectre.c b/arch/arm/kernel/spectre.c
new file mode 100644 (file)
index 0000000..0dcefc3
--- /dev/null
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/bpf.h>
+#include <linux/cpu.h>
+#include <linux/device.h>
+
+#include <asm/spectre.h>
+
+static bool _unprivileged_ebpf_enabled(void)
+{
+#ifdef CONFIG_BPF_SYSCALL
+       return !sysctl_unprivileged_bpf_disabled;
+#else
+       return false;
+#endif
+}
+
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       return sprintf(buf, "Mitigation: __user pointer sanitization\n");
+}
+
+static unsigned int spectre_v2_state;
+static unsigned int spectre_v2_methods;
+
+void spectre_v2_update_state(unsigned int state, unsigned int method)
+{
+       if (state > spectre_v2_state)
+               spectre_v2_state = state;
+       spectre_v2_methods |= method;
+}
+
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       const char *method;
+
+       if (spectre_v2_state == SPECTRE_UNAFFECTED)
+               return sprintf(buf, "%s\n", "Not affected");
+
+       if (spectre_v2_state != SPECTRE_MITIGATED)
+               return sprintf(buf, "%s\n", "Vulnerable");
+
+       if (_unprivileged_ebpf_enabled())
+               return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
+
+       switch (spectre_v2_methods) {
+       case SPECTRE_V2_METHOD_BPIALL:
+               method = "Branch predictor hardening";
+               break;
+
+       case SPECTRE_V2_METHOD_ICIALLU:
+               method = "I-cache invalidation";
+               break;
+
+       case SPECTRE_V2_METHOD_SMC:
+       case SPECTRE_V2_METHOD_HVC:
+               method = "Firmware call";
+               break;
+
+       case SPECTRE_V2_METHOD_LOOP8:
+               method = "History overwrite";
+               break;
+
+       default:
+               method = "Multiple mitigations";
+               break;
+       }
+
+       return sprintf(buf, "Mitigation: %s\n", method);
+}
index da04ed85855ae44b25670e8e94f9c256c18ece4f..cae4a748811f8312f2f8c40424842932a92d7b08 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/atomic.h>
 #include <asm/cacheflush.h>
 #include <asm/exception.h>
+#include <asm/spectre.h>
 #include <asm/unistd.h>
 #include <asm/traps.h>
 #include <asm/ptrace.h>
@@ -789,10 +790,59 @@ static inline void __init kuser_init(void *vectors)
 }
 #endif
 
+#ifndef CONFIG_CPU_V7M
+static void copy_from_lma(void *vma, void *lma_start, void *lma_end)
+{
+       memcpy(vma, lma_start, lma_end - lma_start);
+}
+
+static void flush_vectors(void *vma, size_t offset, size_t size)
+{
+       unsigned long start = (unsigned long)vma + offset;
+       unsigned long end = start + size;
+
+       flush_icache_range(start, end);
+}
+
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+int spectre_bhb_update_vectors(unsigned int method)
+{
+       extern char __vectors_bhb_bpiall_start[], __vectors_bhb_bpiall_end[];
+       extern char __vectors_bhb_loop8_start[], __vectors_bhb_loop8_end[];
+       void *vec_start, *vec_end;
+
+       if (system_state >= SYSTEM_FREEING_INITMEM) {
+               pr_err("CPU%u: Spectre BHB workaround too late - system vulnerable\n",
+                      smp_processor_id());
+               return SPECTRE_VULNERABLE;
+       }
+
+       switch (method) {
+       case SPECTRE_V2_METHOD_LOOP8:
+               vec_start = __vectors_bhb_loop8_start;
+               vec_end = __vectors_bhb_loop8_end;
+               break;
+
+       case SPECTRE_V2_METHOD_BPIALL:
+               vec_start = __vectors_bhb_bpiall_start;
+               vec_end = __vectors_bhb_bpiall_end;
+               break;
+
+       default:
+               pr_err("CPU%u: unknown Spectre BHB state %d\n",
+                      smp_processor_id(), method);
+               return SPECTRE_VULNERABLE;
+       }
+
+       copy_from_lma(vectors_page, vec_start, vec_end);
+       flush_vectors(vectors_page, 0, vec_end - vec_start);
+
+       return SPECTRE_MITIGATED;
+}
+#endif
+
 void __init early_trap_init(void *vectors_base)
 {
-#ifndef CONFIG_CPU_V7M
-       unsigned long vectors = (unsigned long)vectors_base;
        extern char __stubs_start[], __stubs_end[];
        extern char __vectors_start[], __vectors_end[];
        unsigned i;
@@ -813,17 +863,20 @@ void __init early_trap_init(void *vectors_base)
         * into the vector page, mapped at 0xffff0000, and ensure these
         * are visible to the instruction stream.
         */
-       memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
-       memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
+       copy_from_lma(vectors_base, __vectors_start, __vectors_end);
+       copy_from_lma(vectors_base + 0x1000, __stubs_start, __stubs_end);
 
        kuser_init(vectors_base);
 
-       flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
+       flush_vectors(vectors_base, 0, PAGE_SIZE * 2);
+}
 #else /* ifndef CONFIG_CPU_V7M */
+void __init early_trap_init(void *vectors_base)
+{
        /*
         * on V7-M there is no need to copy the vector table to a dedicated
         * memory area. The address is configurable and so a table in the kernel
         * image can be used.
         */
-#endif
 }
+#endif
index cd300eeedc2067f06e5652e10cb50aecc1cb0f97..0bf4d312bcfd99480b376848f771be84a80138a8 100644 (file)
@@ -3,6 +3,7 @@ menuconfig ARCH_MSTARV7
        depends on ARCH_MULTI_V7
        select ARM_GIC
        select ARM_HEAVY_MB
+       select HAVE_ARM_ARCH_TIMER
        select MST_IRQ
        select MSTAR_MSC313_MPLL
        help
index 58afba346729960e2101f4d26f682f58ce187398..9724c16e907671b83cdb2454cef76a0917a26366 100644 (file)
@@ -830,6 +830,7 @@ config CPU_BPREDICT_DISABLE
 
 config CPU_SPECTRE
        bool
+       select GENERIC_CPU_VULNERABILITIES
 
 config HARDEN_BRANCH_PREDICTOR
        bool "Harden the branch predictor against aliasing attacks" if EXPERT
@@ -850,6 +851,16 @@ config HARDEN_BRANCH_PREDICTOR
 
           If unsure, say Y.
 
+config HARDEN_BRANCH_HISTORY
+       bool "Harden Spectre style attacks against branch history" if EXPERT
+       depends on CPU_SPECTRE
+       default y
+       help
+         Speculation attacks against some high-performance processors can
+         make use of branch history to influence future speculation. When
+         taking an exception, a sequence of branches overwrites the branch
+         history, or branch history is invalidated.
+
 config TLS_REG_EMUL
        bool
        select NEED_KUSER_HELPERS
index 6d0cb0f7bc54bd1c66b7215ae8e2711de3105efb..fe249ea919083f5a918e799fd2006f407674262e 100644 (file)
@@ -164,47 +164,6 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)
        return phys;
 }
 
-static void __init arm_initrd_init(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-       phys_addr_t start;
-       unsigned long size;
-
-       initrd_start = initrd_end = 0;
-
-       if (!phys_initrd_size)
-               return;
-
-       /*
-        * Round the memory region to page boundaries as per free_initrd_mem()
-        * This allows us to detect whether the pages overlapping the initrd
-        * are in use, but more importantly, reserves the entire set of pages
-        * as we don't want these pages allocated for other purposes.
-        */
-       start = round_down(phys_initrd_start, PAGE_SIZE);
-       size = phys_initrd_size + (phys_initrd_start - start);
-       size = round_up(size, PAGE_SIZE);
-
-       if (!memblock_is_region_memory(start, size)) {
-               pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",
-                      (u64)start, size);
-               return;
-       }
-
-       if (memblock_is_region_reserved(start, size)) {
-               pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n",
-                      (u64)start, size);
-               return;
-       }
-
-       memblock_reserve(start, size);
-
-       /* Now convert initrd to virtual addresses */
-       initrd_start = __phys_to_virt(phys_initrd_start);
-       initrd_end = initrd_start + phys_initrd_size;
-#endif
-}
-
 #ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
 void check_cpu_icache_size(int cpuid)
 {
@@ -226,7 +185,7 @@ void __init arm_memblock_init(const struct machine_desc *mdesc)
        /* Register the kernel text, kernel data and initrd with memblock. */
        memblock_reserve(__pa(KERNEL_START), KERNEL_END - KERNEL_START);
 
-       arm_initrd_init();
+       reserve_initrd_mem();
 
        arm_mm_memblock_reserve();
 
index 274e4f73fd33c21c3179d2a5a9090688e6e2c6bf..5e2be37a198e29eefa1b0a3ce6b64296c4d0e2f6 100644 (file)
@@ -212,12 +212,14 @@ early_param("ecc", early_ecc);
 static int __init early_cachepolicy(char *p)
 {
        pr_warn("cachepolicy kernel parameter not supported without cp15\n");
+       return 0;
 }
 early_param("cachepolicy", early_cachepolicy);
 
 static int __init noalign_setup(char *__unused)
 {
        pr_warn("noalign kernel parameter not supported without cp15\n");
+       return 1;
 }
 __setup("noalign", noalign_setup);
 
index 114c05ab4dd919a26064eda1f395f1c8f4119ec1..06dbfb968182de7c585e41308da09eec15360600 100644 (file)
@@ -6,8 +6,35 @@
 #include <asm/cp15.h>
 #include <asm/cputype.h>
 #include <asm/proc-fns.h>
+#include <asm/spectre.h>
 #include <asm/system_misc.h>
 
+#ifdef CONFIG_ARM_PSCI
+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
+{
+       struct arm_smccc_res res;
+
+       arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+                            ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+
+       switch ((int)res.a0) {
+       case SMCCC_RET_SUCCESS:
+               return SPECTRE_MITIGATED;
+
+       case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
+               return SPECTRE_UNAFFECTED;
+
+       default:
+               return SPECTRE_VULNERABLE;
+       }
+}
+#else
+static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
+{
+       return SPECTRE_VULNERABLE;
+}
+#endif
+
 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
 DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn);
 
@@ -36,13 +63,61 @@ static void __maybe_unused call_hvc_arch_workaround_1(void)
        arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
 }
 
-static void cpu_v7_spectre_init(void)
+static unsigned int spectre_v2_install_workaround(unsigned int method)
 {
        const char *spectre_v2_method = NULL;
        int cpu = smp_processor_id();
 
        if (per_cpu(harden_branch_predictor_fn, cpu))
-               return;
+               return SPECTRE_MITIGATED;
+
+       switch (method) {
+       case SPECTRE_V2_METHOD_BPIALL:
+               per_cpu(harden_branch_predictor_fn, cpu) =
+                       harden_branch_predictor_bpiall;
+               spectre_v2_method = "BPIALL";
+               break;
+
+       case SPECTRE_V2_METHOD_ICIALLU:
+               per_cpu(harden_branch_predictor_fn, cpu) =
+                       harden_branch_predictor_iciallu;
+               spectre_v2_method = "ICIALLU";
+               break;
+
+       case SPECTRE_V2_METHOD_HVC:
+               per_cpu(harden_branch_predictor_fn, cpu) =
+                       call_hvc_arch_workaround_1;
+               cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
+               spectre_v2_method = "hypervisor";
+               break;
+
+       case SPECTRE_V2_METHOD_SMC:
+               per_cpu(harden_branch_predictor_fn, cpu) =
+                       call_smc_arch_workaround_1;
+               cpu_do_switch_mm = cpu_v7_smc_switch_mm;
+               spectre_v2_method = "firmware";
+               break;
+       }
+
+       if (spectre_v2_method)
+               pr_info("CPU%u: Spectre v2: using %s workaround\n",
+                       smp_processor_id(), spectre_v2_method);
+
+       return SPECTRE_MITIGATED;
+}
+#else
+static unsigned int spectre_v2_install_workaround(unsigned int method)
+{
+       pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n",
+               smp_processor_id());
+
+       return SPECTRE_VULNERABLE;
+}
+#endif
+
+static void cpu_v7_spectre_v2_init(void)
+{
+       unsigned int state, method = 0;
 
        switch (read_cpuid_part()) {
        case ARM_CPU_PART_CORTEX_A8:
@@ -51,69 +126,133 @@ static void cpu_v7_spectre_init(void)
        case ARM_CPU_PART_CORTEX_A17:
        case ARM_CPU_PART_CORTEX_A73:
        case ARM_CPU_PART_CORTEX_A75:
-               per_cpu(harden_branch_predictor_fn, cpu) =
-                       harden_branch_predictor_bpiall;
-               spectre_v2_method = "BPIALL";
+               state = SPECTRE_MITIGATED;
+               method = SPECTRE_V2_METHOD_BPIALL;
                break;
 
        case ARM_CPU_PART_CORTEX_A15:
        case ARM_CPU_PART_BRAHMA_B15:
-               per_cpu(harden_branch_predictor_fn, cpu) =
-                       harden_branch_predictor_iciallu;
-               spectre_v2_method = "ICIALLU";
+               state = SPECTRE_MITIGATED;
+               method = SPECTRE_V2_METHOD_ICIALLU;
                break;
 
-#ifdef CONFIG_ARM_PSCI
        case ARM_CPU_PART_BRAHMA_B53:
                /* Requires no workaround */
+               state = SPECTRE_UNAFFECTED;
                break;
+
        default:
                /* Other ARM CPUs require no workaround */
-               if (read_cpuid_implementor() == ARM_CPU_IMP_ARM)
+               if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) {
+                       state = SPECTRE_UNAFFECTED;
                        break;
+               }
+
                fallthrough;
-               /* Cortex A57/A72 require firmware workaround */
-       case ARM_CPU_PART_CORTEX_A57:
-       case ARM_CPU_PART_CORTEX_A72: {
-               struct arm_smccc_res res;
 
-               arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
-                                    ARM_SMCCC_ARCH_WORKAROUND_1, &res);
-               if ((int)res.a0 != 0)
-                       return;
+       /* Cortex A57/A72 require firmware workaround */
+       case ARM_CPU_PART_CORTEX_A57:
+       case ARM_CPU_PART_CORTEX_A72:
+               state = spectre_v2_get_cpu_fw_mitigation_state();
+               if (state != SPECTRE_MITIGATED)
+                       break;
 
                switch (arm_smccc_1_1_get_conduit()) {
                case SMCCC_CONDUIT_HVC:
-                       per_cpu(harden_branch_predictor_fn, cpu) =
-                               call_hvc_arch_workaround_1;
-                       cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
-                       spectre_v2_method = "hypervisor";
+                       method = SPECTRE_V2_METHOD_HVC;
                        break;
 
                case SMCCC_CONDUIT_SMC:
-                       per_cpu(harden_branch_predictor_fn, cpu) =
-                               call_smc_arch_workaround_1;
-                       cpu_do_switch_mm = cpu_v7_smc_switch_mm;
-                       spectre_v2_method = "firmware";
+                       method = SPECTRE_V2_METHOD_SMC;
                        break;
 
                default:
+                       state = SPECTRE_VULNERABLE;
                        break;
                }
        }
-#endif
+
+       if (state == SPECTRE_MITIGATED)
+               state = spectre_v2_install_workaround(method);
+
+       spectre_v2_update_state(state, method);
+}
+
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
+static int spectre_bhb_method;
+
+static const char *spectre_bhb_method_name(int method)
+{
+       switch (method) {
+       case SPECTRE_V2_METHOD_LOOP8:
+               return "loop";
+
+       case SPECTRE_V2_METHOD_BPIALL:
+               return "BPIALL";
+
+       default:
+               return "unknown";
        }
+}
 
-       if (spectre_v2_method)
-               pr_info("CPU%u: Spectre v2: using %s workaround\n",
-                       smp_processor_id(), spectre_v2_method);
+static int spectre_bhb_install_workaround(int method)
+{
+       if (spectre_bhb_method != method) {
+               if (spectre_bhb_method) {
+                       pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n",
+                              smp_processor_id());
+
+                       return SPECTRE_VULNERABLE;
+               }
+
+               if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE)
+                       return SPECTRE_VULNERABLE;
+
+               spectre_bhb_method = method;
+       }
+
+       pr_info("CPU%u: Spectre BHB: using %s workaround\n",
+               smp_processor_id(), spectre_bhb_method_name(method));
+
+       return SPECTRE_MITIGATED;
 }
 #else
-static void cpu_v7_spectre_init(void)
+static int spectre_bhb_install_workaround(int method)
 {
+       return SPECTRE_VULNERABLE;
 }
 #endif
 
+static void cpu_v7_spectre_bhb_init(void)
+{
+       unsigned int state, method = 0;
+
+       switch (read_cpuid_part()) {
+       case ARM_CPU_PART_CORTEX_A15:
+       case ARM_CPU_PART_BRAHMA_B15:
+       case ARM_CPU_PART_CORTEX_A57:
+       case ARM_CPU_PART_CORTEX_A72:
+               state = SPECTRE_MITIGATED;
+               method = SPECTRE_V2_METHOD_LOOP8;
+               break;
+
+       case ARM_CPU_PART_CORTEX_A73:
+       case ARM_CPU_PART_CORTEX_A75:
+               state = SPECTRE_MITIGATED;
+               method = SPECTRE_V2_METHOD_BPIALL;
+               break;
+
+       default:
+               state = SPECTRE_UNAFFECTED;
+               break;
+       }
+
+       if (state == SPECTRE_MITIGATED)
+               state = spectre_bhb_install_workaround(method);
+
+       spectre_v2_update_state(state, method);
+}
+
 static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned,
                                                  u32 mask, const char *msg)
 {
@@ -142,16 +281,17 @@ static bool check_spectre_auxcr(bool *warned, u32 bit)
 void cpu_v7_ca8_ibe(void)
 {
        if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6)))
-               cpu_v7_spectre_init();
+               cpu_v7_spectre_v2_init();
 }
 
 void cpu_v7_ca15_ibe(void)
 {
        if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0)))
-               cpu_v7_spectre_init();
+               cpu_v7_spectre_v2_init();
 }
 
 void cpu_v7_bugs_init(void)
 {
-       cpu_v7_spectre_init();
+       cpu_v7_spectre_v2_init();
+       cpu_v7_spectre_bhb_init();
 }
index 7c9e395b77f7cbbab8f72960c79add9f50257b29..ec52b776f9267d1f5c1c3826642db4a991148ce8 100644 (file)
@@ -18,7 +18,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32
 
 ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
 ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
-           -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \
+           -z max-page-size=4096 -shared $(ldflags-y) \
            --hash-style=sysv --build-id=sha1 \
            -T
 
index 09b885cc4db531fd18debbb2d3cd43e5aa5cdd58..a555f409ba95e9c4265b4b7823343aa23fd8ab76 100644 (file)
@@ -10,6 +10,7 @@ config ARM64
        select ACPI_SPCR_TABLE if ACPI
        select ACPI_PPTT if ACPI
        select ARCH_HAS_DEBUG_WX
+       select ARCH_BINFMT_ELF_EXTRA_PHDRS
        select ARCH_BINFMT_ELF_STATE
        select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
        select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
@@ -891,13 +892,17 @@ config CAVIUM_ERRATUM_23144
          If unsure, say Y.
 
 config CAVIUM_ERRATUM_23154
-       bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
+       bool "Cavium errata 23154 and 38545: GICv3 lacks HW synchronisation"
        default y
        help
-         The gicv3 of ThunderX requires a modified version for
+         The ThunderX GICv3 implementation requires a modified version for
          reading the IAR status to ensure data synchronization
          (access to icc_iar1_el1 is not sync'ed before and after).
 
+         It also suffers from erratum 38545 (also present on Marvell's
+         OcteonTX and OcteonTX2), resulting in deactivated interrupts being
+         spuriously presented to the CPU interface.
+
          If unsure, say Y.
 
 config CAVIUM_ERRATUM_27456
@@ -1252,9 +1257,6 @@ config HW_PERF_EVENTS
        def_bool y
        depends on ARM_PMU
 
-config ARCH_HAS_FILTER_PGPROT
-       def_bool y
-
 # Supported by clang >= 7.0
 config CC_HAVE_SHADOW_CALL_STACK
        def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
@@ -1383,6 +1385,15 @@ config UNMAP_KERNEL_AT_EL0
 
          If unsure, say Y.
 
+config MITIGATE_SPECTRE_BRANCH_HISTORY
+       bool "Mitigate Spectre style attacks against branch history" if EXPERT
+       default y
+       help
+         Speculation attacks against some high-performance processors can
+         make use of branch history to influence future speculation.
+         When taking an exception from user-space, a sequence of branches
+         or a firmware call overwrites the branch history.
+
 config RODATA_FULL_DEFAULT_ENABLED
        bool "Apply r/o permissions of VM areas also to their linear aliases"
        default y
index 19afbc91020a25d8f21fed5117adb082950c6165..9f8f4145db8805c42261fa23caf461733692eb60 100644 (file)
                             <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       pmu-e {
+               compatible = "apple,icestorm-pmu";
+               interrupt-parent = <&aic>;
+               interrupts = <AIC_FIQ AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       pmu-p {
+               compatible = "apple,firestorm-pmu";
+               interrupt-parent = <&aic>;
+               interrupts = <AIC_FIQ AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        clkref: clock-ref {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                        interrupt-controller;
                        reg = <0x2 0x3b100000 0x0 0x8000>;
                        power-domains = <&ps_aic>;
+
+                       affinities {
+                               e-core-pmu-affinity {
+                                       apple,fiq-index = <AIC_CPU_PMU_E>;
+                                       cpus = <&cpu0 &cpu1 &cpu2 &cpu3>;
+                               };
+
+                               p-core-pmu-affinity {
+                                       apple,fiq-index = <AIC_CPU_PMU_P>;
+                                       cpus = <&cpu4 &cpu5 &cpu6 &cpu7>;
+                               };
+                       };
                };
 
                pmgr: power-management@23b700000 {
index 6288e104a0893f65377ee70706c95137fe4e63ba..a2635b14da3098c85f41b3010bb7c6038b7d1912 100644 (file)
                         <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
                         <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
                /* Standard AXI Translation entries as programmed by EDK2 */
-               dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>,
-                            <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
+               dma-ranges = <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
                             <0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>;
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 0 7>;
index 3ed1f2c51cadf4b9da2d2521e29b62626e9a7e43..18e529118476af69d4eae25790cc3d92570ad4a8 100644 (file)
                                interrupt-controller;
                                reg = <0x14 4>;
                                interrupt-map =
-                                       <0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-                                       <1 0 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-                                       <2 0 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-                                       <3 0 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-                                       <4 0 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
-                                       <5 0 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
-                                       <6 0 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
-                                       <7 0 &gic 0 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
-                                       <8 0 &gic 0 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-                                       <9 0 &gic 0 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
-                                       <10 0 &gic 0 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
-                                       <11 0 &gic 0 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                                       <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                       <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                                       <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                                       <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                       <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                                       <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                                       <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                                       <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+                                       <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                       <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                                       <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                                       <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                interrupt-map-mask = <0xffffffff 0x0>;
                        };
                };
index 3cb9c21d2775aefe3c870d83890c88999e9e2527..1282b61da8a55e67d65e22ff0862f9992f8cf94d 100644 (file)
                                interrupt-controller;
                                reg = <0x14 4>;
                                interrupt-map =
-                                       <0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-                                       <1 0 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-                                       <2 0 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-                                       <3 0 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-                                       <4 0 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
-                                       <5 0 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
-                                       <6 0 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
-                                       <7 0 &gic 0 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
-                                       <8 0 &gic 0 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-                                       <9 0 &gic 0 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
-                                       <10 0 &gic 0 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
-                                       <11 0 &gic 0 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                                       <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                       <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                                       <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                                       <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                       <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                                       <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                                       <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                                       <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+                                       <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                       <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                                       <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                                       <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                interrupt-map-mask = <0xffffffff 0x0>;
                        };
                };
index 7032505f5ef3a1300c5c40291e5ebcac62104046..3c611cb4f5fef964072fc200d68efa390479efda 100644 (file)
                                interrupt-controller;
                                reg = <0x14 4>;
                                interrupt-map =
-                                       <0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-                                       <1 0 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
-                                       <2 0 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
-                                       <3 0 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-                                       <4 0 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
-                                       <5 0 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
-                                       <6 0 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
-                                       <7 0 &gic 0 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
-                                       <8 0 &gic 0 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-                                       <9 0 &gic 0 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
-                                       <10 0 &gic 0 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
-                                       <11 0 &gic 0 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                                       <0 0 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                       <1 0 &gic GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                                       <2 0 &gic GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                                       <3 0 &gic GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                       <4 0 &gic GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                                       <5 0 &gic GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                                       <6 0 &gic GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                                       <7 0 &gic GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+                                       <8 0 &gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                       <9 0 &gic GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                                       <10 0 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                                       <11 0 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                interrupt-map-mask = <0xffffffff 0x0>;
                        };
                };
index f77f90ed416f9101f58c3be40adc59bb0c9e7082..0c7a72c51a313a172e9fb289092a4bcdf18d420b 100644 (file)
                                                clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
                                                assigned-clocks = <&clk IMX8MM_CLK_VPU_BUS>;
                                                assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>;
-                                               resets = <&src IMX8MQ_RESET_VPU_RESET>;
                                        };
 
                                        pgc_vpu_g1: power-domain@7 {
index a987ff7156bd6b6044539bbabd017f3fe57ff23c..09f7364dd1d05a114d2bc22caa75c63d3dd73f72 100644 (file)
 
                        scmi_sensor: protocol@15 {
                                reg = <0x15>;
-                               #thermal-sensor-cells = <0>;
+                               #thermal-sensor-cells = <1>;
                        };
                };
        };
index 0dd2d2ee765aa566db0d4f10a284b2e56a22f1ac..f4270cf1899624ca4722ac3a412288fa9ee6dfb2 100644 (file)
                };
 
                usb0: usb@ffb00000 {
-                       compatible = "snps,dwc2";
+                       compatible = "intel,socfpga-agilex-hsotg", "snps,dwc2";
                        reg = <0xffb00000 0x40000>;
                        interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
                        phys = <&usbphy0>;
                };
 
                usb1: usb@ffb40000 {
-                       compatible = "snps,dwc2";
+                       compatible = "intel,socfpga-agilex-hsotg", "snps,dwc2";
                        reg = <0xffb40000 0x40000>;
                        interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
                        phys = <&usbphy0>;
index 04da07ae4420846144822a3dab6a901eb97b6384..1cee26479bfecec78480ab73703067ed43d9e20a 100644 (file)
@@ -18,6 +18,7 @@
 
        aliases {
                spi0 = &spi0;
+               ethernet0 = &eth0;
                ethernet1 = &eth1;
                mmc0 = &sdhci0;
                mmc1 = &sdhci1;
        /*
         * U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property
         * contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and
-        * 2 size cells and also expects that the second range starts at 16 MB offset. If these
+        * 2 size cells and also expects that the second range starts at 16 MB offset. Also it
+        * expects that first range uses same address for PCI (child) and CPU (parent) cells (so
+        * no remapping) and that this address is the lowest from all specified ranges. If these
         * conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
         * space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
         * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
         * https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
         * https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
         * https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
+        * Bug related to requirement of same child and parent addresses for first range is fixed
+        * in U-Boot version 2022.04 by following commit:
+        * https://source.denx.de/u-boot/u-boot/-/commit/1fd54253bca7d43d046bba4853fe5fafd034bc17
         */
        #address-cells = <3>;
        #size-cells = <2>;
index 673f4906eef90a4ad2505bf573abef6d8b03b1c8..fb78ef613b29248982176074c58e875710b6a03c 100644 (file)
                         * (totaling 127 MiB) for MEM.
                         */
                        ranges = <0x82000000 0 0xe8000000   0 0xe8000000   0 0x07f00000   /* Port 0 MEM */
-                                 0x81000000 0 0xefff0000   0 0xefff0000   0 0x00010000>; /* Port 0 IO */
+                                 0x81000000 0 0x00000000   0 0xefff0000   0 0x00010000>; /* Port 0 IO */
                        interrupt-map-mask = <0 0 0 7>;
                        interrupt-map = <0 0 0 1 &pcie_intc 0>,
                                        <0 0 0 2 &pcie_intc 1>,
index 2d48c3715fc640e3ff444eaca35944958dd661dd..aaa00da5351dfa71be46801c15a1179e40d0eb34 100644 (file)
                        #iommu-cells = <1>;
 
                        nvidia,memory-controller = <&mc>;
-                       status = "okay";
+                       status = "disabled";
                };
 
                smmu: iommu@12000000 {
index 58845a14805f63cb116205f05bcbd99a15a51618..e2b9ec134cb10ab4274962de2273bd0f6c469efc 100644 (file)
 
        qcom,snoc-host-cap-8bit-quirk;
 };
+
+&crypto {
+       /* FIXME: qce_start triggers an SError */
+       status= "disable";
+};
index 53b39e718fb66b873f27354d4627408b427ebbe7..4b19744bcfb34ecde260460e4e81855518d2a11a 100644 (file)
                        clock-frequency = <32000>;
                        #clock-cells = <0>;
                };
+
+               ufs_phy_rx_symbol_0_clk: ufs-phy-rx-symbol-0 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <1000>;
+                       #clock-cells = <0>;
+               };
+
+               ufs_phy_rx_symbol_1_clk: ufs-phy-rx-symbol-1 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <1000>;
+                       #clock-cells = <0>;
+               };
+
+               ufs_phy_tx_symbol_0_clk: ufs-phy-tx-symbol-0 {
+                       compatible = "fixed-clock";
+                       clock-frequency = <1000>;
+                       #clock-cells = <0>;
+               };
        };
 
        cpus {
                                 <0>,
                                 <0>,
                                 <0>,
-                                <0>,
-                                <0>,
-                                <0>,
+                                <&ufs_phy_rx_symbol_0_clk>,
+                                <&ufs_phy_rx_symbol_1_clk>,
+                                <&ufs_phy_tx_symbol_0_clk>,
                                 <0>,
                                 <0>;
                };
                                <75000000 300000000>,
                                <0 0>,
                                <0 0>,
-                               <75000000 300000000>,
-                               <75000000 300000000>;
+                               <0>,
+                               <0>;
                        status = "disabled";
                };
 
index 10c25ad2d0c7422999c7acf8ba92dbbcd4f04721..02b97e838c4742e3e60fb034b1c51d3460ae033f 100644 (file)
                        compatible = "qcom,sm8450-smmu-500", "arm,mmu-500";
                        reg = <0 0x15000000 0 0x100000>;
                        #iommu-cells = <2>;
-                       #global-interrupts = <2>;
+                       #global-interrupts = <1>;
                        interrupts =    <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
                                        <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
                                 <&gcc GCC_USB30_PRIM_MASTER_CLK>,
                                 <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
                                 <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
-                                <&gcc GCC_USB30_PRIM_SLEEP_CLK>;
+                                <&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+                                <&gcc GCC_USB3_0_CLKREF_EN>;
                        clock-names = "cfg_noc", "core", "iface", "mock_utmi",
-                                     "sleep";
+                                     "sleep", "xo";
 
                        assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
                                          <&gcc GCC_USB30_PRIM_MASTER_CLK>;
index f972704dfe7abf27585bda276194b1875e8569af..56dfbb2e2fa66440af6f57b608e8f19a3e6b7d8d 100644 (file)
                clock-names = "pclk", "timer";
        };
 
-       dmac: dmac@ff240000 {
+       dmac: dma-controller@ff240000 {
                compatible = "arm,pl330", "arm,primecell";
                reg = <0x0 0xff240000 0x0 0x4000>;
                interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
index 39db0b85b4da2a730a9982c47452406886d33f06..b822533dc7f19e73993bbf399e0b8e243755727c 100644 (file)
                status = "disabled";
        };
 
-       dmac: dmac@ff1f0000 {
+       dmac: dma-controller@ff1f0000 {
                compatible = "arm,pl330", "arm,primecell";
                reg = <0x0 0xff1f0000 0x0 0x4000>;
                interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
index 45a5ae5d2027f858f60bb6abb0746c00de82de10..162f08bca0d40618176531eecdff1ad159c085c0 100644 (file)
 
        sound: sound {
                compatible = "rockchip,rk3399-gru-sound";
-               rockchip,cpu = <&i2s0 &i2s2>;
+               rockchip,cpu = <&i2s0 &spdif>;
        };
 };
 
@@ -437,10 +437,6 @@ ap_i2c_audio: &i2c8 {
        status = "okay";
 };
 
-&i2s2 {
-       status = "okay";
-};
-
 &io_domains {
        status = "okay";
 
@@ -537,6 +533,17 @@ ap_i2c_audio: &i2c8 {
        vqmmc-supply = <&ppvar_sd_card_io>;
 };
 
+&spdif {
+       status = "okay";
+
+       /*
+        * SPDIF is routed internally to DP; we either don't use these pins, or
+        * mux them to something else.
+        */
+       /delete-property/ pinctrl-0;
+       /delete-property/ pinctrl-names;
+};
+
 &spi1 {
        status = "okay";
 
index 292bb7e80cf35dab9564fb77d4dee224743ec066..3ae5d727e36745425288311d14073aefe1117f25 100644 (file)
 
 &usbdrd_dwc3_0 {
        dr_mode = "otg";
+       extcon = <&extcon_usb3>;
        status = "okay";
 };
 
index fb67db4619ea07087d55bef9d711bc8c34aa292b..08fa00364b42f0f4a509cf0c5613ebd79fe56a9d 100644 (file)
                };
        };
 
+       extcon_usb3: extcon-usb3 {
+               compatible = "linux,extcon-usb-gpio";
+               id-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb3_id>;
+       };
+
        clkin_gmac: external-gmac-clock {
                compatible = "fixed-clock";
                clock-frequency = <125000000>;
                          <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
+
+       usb3 {
+               usb3_id: usb3-id {
+                       rockchip,pins =
+                         <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
 };
 
 &sdhci {
+       /*
+        * Signal integrity isn't great at 200MHz but 100MHz has proven stable
+        * enough.
+        */
+       max-frequency = <100000000>;
+
        bus-width = <8>;
        mmc-hs400-1_8v;
        mmc-hs400-enhanced-strobe;
index d3cdf6f42a30367d7255cd6ce7907b551a081f70..080457a68e3c70e99a8fc517e3a24290463ba6dc 100644 (file)
                interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
                clocks = <&cru PCLK_HDMI_CTRL>,
                         <&cru SCLK_HDMI_SFR>,
-                        <&cru PLL_VPLL>,
+                        <&cru SCLK_HDMI_CEC>,
                         <&cru PCLK_VIO_GRF>,
-                        <&cru SCLK_HDMI_CEC>;
-               clock-names = "iahb", "isfr", "vpll", "grf", "cec";
+                        <&cru PLL_VPLL>;
+               clock-names = "iahb", "isfr", "cec", "grf", "vpll";
                power-domains = <&power RK3399_PD_HDCP>;
                reg-io-width = <4>;
                rockchip,grf = <&grf>;
index 166399b7f13f05b6d8c04c68bc463fcd2731d501..d9eb92d5909907cc219992f3a21959763b4ba6a6 100644 (file)
                        vcc_ddr: DCDC_REG3 {
                                regulator-always-on;
                                regulator-boot-on;
-                               regulator-min-microvolt = <1100000>;
-                               regulator-max-microvolt = <1100000>;
                                regulator-initial-mode = <0x2>;
                                regulator-name = "vcc_ddr";
                                regulator-state-mem {
index 2fd313a295f8aaa1d5c7a8b1250fc428513baa88..d91df1cde73631947d2ad49b01f31e0ed0229c27 100644 (file)
                clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
                         <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
                         <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
-                        <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
-                        <&cru PCLK_XPCS>;
+                        <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
                clock-names = "stmmaceth", "mac_clk_rx",
                              "mac_clk_tx", "clk_mac_refout",
                              "aclk_mac", "pclk_mac",
-                             "clk_mac_speed", "ptp_ref",
-                             "pclk_xpcs";
+                             "clk_mac_speed", "ptp_ref";
                resets = <&cru SRST_A_GMAC0>;
                reset-names = "stmmaceth";
                rockchip,grf = <&grf>;
index a68033a239750454b554ef2f9be3c8ad23204c68..8ccce54ee8e728e9cef67ed1f85f7d14b54f25cc 100644 (file)
                status = "disabled";
        };
 
-       dmac0: dmac@fe530000 {
+       dmac0: dma-controller@fe530000 {
                compatible = "arm,pl330", "arm,primecell";
                reg = <0x0 0xfe530000 0x0 0x4000>;
                interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
                #dma-cells = <1>;
        };
 
-       dmac1: dmac@fe550000 {
+       dmac1: dma-controller@fe550000 {
                compatible = "arm,pl330", "arm,primecell";
                reg = <0x0 0xfe550000 0x0 0x4000>;
                interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/include/asm/apple_m1_pmu.h b/arch/arm64/include/asm/apple_m1_pmu.h
new file mode 100644 (file)
index 0000000..99483b1
--- /dev/null
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef __ASM_APPLE_M1_PMU_h
+#define __ASM_APPLE_M1_PMU_h
+
+#include <linux/bits.h>
+#include <asm/sysreg.h>
+
+/* Counters */
+#define SYS_IMP_APL_PMC0_EL1   sys_reg(3, 2, 15, 0, 0)
+#define SYS_IMP_APL_PMC1_EL1   sys_reg(3, 2, 15, 1, 0)
+#define SYS_IMP_APL_PMC2_EL1   sys_reg(3, 2, 15, 2, 0)
+#define SYS_IMP_APL_PMC3_EL1   sys_reg(3, 2, 15, 3, 0)
+#define SYS_IMP_APL_PMC4_EL1   sys_reg(3, 2, 15, 4, 0)
+#define SYS_IMP_APL_PMC5_EL1   sys_reg(3, 2, 15, 5, 0)
+#define SYS_IMP_APL_PMC6_EL1   sys_reg(3, 2, 15, 6, 0)
+#define SYS_IMP_APL_PMC7_EL1   sys_reg(3, 2, 15, 7, 0)
+#define SYS_IMP_APL_PMC8_EL1   sys_reg(3, 2, 15, 9, 0)
+#define SYS_IMP_APL_PMC9_EL1   sys_reg(3, 2, 15, 10, 0)
+
+/* Core PMC control register */
+#define SYS_IMP_APL_PMCR0_EL1  sys_reg(3, 1, 15, 0, 0)
+#define PMCR0_CNT_ENABLE_0_7   GENMASK(7, 0)
+#define PMCR0_IMODE            GENMASK(10, 8)
+#define PMCR0_IMODE_OFF                0
+#define PMCR0_IMODE_PMI                1
+#define PMCR0_IMODE_AIC                2
+#define PMCR0_IMODE_HALT       3
+#define PMCR0_IMODE_FIQ                4
+#define PMCR0_IACT             BIT(11)
+#define PMCR0_PMI_ENABLE_0_7   GENMASK(19, 12)
+#define PMCR0_STOP_CNT_ON_PMI  BIT(20)
+#define PMCR0_CNT_GLOB_L2C_EVT BIT(21)
+#define PMCR0_DEFER_PMI_TO_ERET        BIT(22)
+#define PMCR0_ALLOW_CNT_EN_EL0 BIT(30)
+#define PMCR0_CNT_ENABLE_8_9   GENMASK(33, 32)
+#define PMCR0_PMI_ENABLE_8_9   GENMASK(45, 44)
+
+#define SYS_IMP_APL_PMCR1_EL1  sys_reg(3, 1, 15, 1, 0)
+#define PMCR1_COUNT_A64_EL0_0_7        GENMASK(15, 8)
+#define PMCR1_COUNT_A64_EL1_0_7        GENMASK(23, 16)
+#define PMCR1_COUNT_A64_EL0_8_9        GENMASK(41, 40)
+#define PMCR1_COUNT_A64_EL1_8_9        GENMASK(49, 48)
+
+#define SYS_IMP_APL_PMCR2_EL1  sys_reg(3, 1, 15, 2, 0)
+#define SYS_IMP_APL_PMCR3_EL1  sys_reg(3, 1, 15, 3, 0)
+#define SYS_IMP_APL_PMCR4_EL1  sys_reg(3, 1, 15, 4, 0)
+
+#define SYS_IMP_APL_PMESR0_EL1 sys_reg(3, 1, 15, 5, 0)
+#define PMESR0_EVT_CNT_2       GENMASK(7, 0)
+#define PMESR0_EVT_CNT_3       GENMASK(15, 8)
+#define PMESR0_EVT_CNT_4       GENMASK(23, 16)
+#define PMESR0_EVT_CNT_5       GENMASK(31, 24)
+
+#define SYS_IMP_APL_PMESR1_EL1 sys_reg(3, 1, 15, 6, 0)
+#define PMESR1_EVT_CNT_6       GENMASK(7, 0)
+#define PMESR1_EVT_CNT_7       GENMASK(15, 8)
+#define PMESR1_EVT_CNT_8       GENMASK(23, 16)
+#define PMESR1_EVT_CNT_9       GENMASK(31, 24)
+
+#define SYS_IMP_APL_PMSR_EL1   sys_reg(3, 1, 15, 13, 0)
+#define PMSR_OVERFLOW          GENMASK(9, 0)
+
+#endif /* __ASM_APPLE_M1_PMU_h */
index 4ad22c3135dbb916b6e427f517f1ae2038c7da44..8bd5afc7b692ea16df704f6d51cf7cca2f977d6c 100644 (file)
@@ -53,17 +53,36 @@ static inline u64 gic_read_iar_common(void)
  * The gicv3 of ThunderX requires a modified version for reading the
  * IAR status to ensure data synchronization (access to icc_iar1_el1
  * is not sync'ed before and after).
+ *
+ * Erratum 38545
+ *
+ * When a IAR register read races with a GIC interrupt RELEASE event,
+ * GIC-CPU interface could wrongly return a valid INTID to the CPU
+ * for an interrupt that is already released(non activated) instead of 0x3ff.
+ *
+ * To workaround this, return a valid interrupt ID only if there is a change
+ * in the active priority list after the IAR read.
+ *
+ * Common function used for both the workarounds since,
+ * 1. On Thunderx 88xx 1.x both erratas are applicable.
+ * 2. Having extra nops doesn't add any side effects for Silicons where
+ *    erratum 23154 is not applicable.
  */
 static inline u64 gic_read_iar_cavium_thunderx(void)
 {
-       u64 irqstat;
+       u64 irqstat, apr;
 
+       apr = read_sysreg_s(SYS_ICC_AP1R0_EL1);
        nops(8);
        irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1);
        nops(4);
        mb();
 
-       return irqstat;
+       /* Max priority groups implemented is only 32 */
+       if (likely(apr != read_sysreg_s(SYS_ICC_AP1R0_EL1)))
+               return irqstat;
+
+       return 0x3ff;
 }
 
 static inline void gic_write_ctlr(u32 val)
index 09e43272ccb0a2e7924306f210e1f9c04e576c76..d1bb5e71df256ab679b0e275e2ad8e5aa56ae339 100644 (file)
@@ -42,13 +42,47 @@ static inline bool __arm64_rndr(unsigned long *v)
        return ok;
 }
 
+static inline bool __arm64_rndrrs(unsigned long *v)
+{
+       bool ok;
+
+       /*
+        * Reads of RNDRRS set PSTATE.NZCV to 0b0000 on success,
+        * and set PSTATE.NZCV to 0b0100 otherwise.
+        */
+       asm volatile(
+               __mrs_s("%0", SYS_RNDRRS_EL0) "\n"
+       "       cset %w1, ne\n"
+       : "=r" (*v), "=r" (ok)
+       :
+       : "cc");
+
+       return ok;
+}
+
 static inline bool __must_check arch_get_random_long(unsigned long *v)
 {
+       /*
+        * Only support the generic interface after we have detected
+        * the system wide capability, avoiding complexity with the
+        * cpufeature code and with potential scheduling between CPUs
+        * with and without the feature.
+        */
+       if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
+               return true;
        return false;
 }
 
 static inline bool __must_check arch_get_random_int(unsigned int *v)
 {
+       if (cpus_have_const_cap(ARM64_HAS_RNG)) {
+               unsigned long val;
+
+               if (__arm64_rndr(&val)) {
+                       *v = val;
+                       return true;
+               }
+       }
        return false;
 }
 
@@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
        }
 
        /*
-        * Only support the generic interface after we have detected
-        * the system wide capability, avoiding complexity with the
-        * cpufeature code and with potential scheduling between CPUs
-        * with and without the feature.
+        * RNDRRS is not backed by an entropy source but by a DRBG that is
+        * reseeded after each invocation. This is not a 100% fit but good
+        * enough to implement this API if no other entropy source exists.
         */
-       if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
+       if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
                return true;
 
        return false;
@@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
        }
 
        if (cpus_have_const_cap(ARM64_HAS_RNG)) {
-               if (__arm64_rndr(&val)) {
+               if (__arm64_rndrrs(&val)) {
                        *v = val;
                        return true;
                }
index f1bba5fc61c49f326dc42f27485a07988b1f84fc..ead62f7dd2694b9390f9af92f1068a22b50e2201 100644 (file)
@@ -60,6 +60,9 @@ alternative_else_nop_endif
        .macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
        mrs     \tmp1, id_aa64isar1_el1
        ubfx    \tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
+       mrs_s   \tmp2, SYS_ID_AA64ISAR2_EL1
+       ubfx    \tmp2, \tmp2, #ID_AA64ISAR2_APA3_SHIFT, #4
+       orr     \tmp1, \tmp1, \tmp2
        cbz     \tmp1, .Lno_addr_auth\@
        mov_q   \tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
                        SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
index e8bd0af0141c36164170701ca598d8ff6610288b..8c5a61aeaf8e754fe819caac37cdf22f43dce3af 100644 (file)
        hint    #20
        .endm
 
+/*
+ * Clear Branch History instruction
+ */
+       .macro clearbhb
+       hint    #22
+       .endm
+
 /*
  * Speculation barrier
  */
@@ -535,11 +542,6 @@ alternative_endif
 #define EXPORT_SYMBOL_NOKASAN(name)    EXPORT_SYMBOL(name)
 #endif
 
-#ifdef CONFIG_KASAN_HW_TAGS
-#define EXPORT_SYMBOL_NOHWKASAN(name)
-#else
-#define EXPORT_SYMBOL_NOHWKASAN(name)  EXPORT_SYMBOL_NOKASAN(name)
-#endif
        /*
         * Emit a 64-bit absolute little endian symbol reference in a way that
         * ensures that it will be resolved at build time, even when building a
@@ -850,4 +852,50 @@ alternative_endif
 
 #endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */
 
+       .macro __mitigate_spectre_bhb_loop      tmp
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+alternative_cb  spectre_bhb_patch_loop_iter
+       mov     \tmp, #32               // Patched to correct the immediate
+alternative_cb_end
+.Lspectre_bhb_loop\@:
+       b       . + 4
+       subs    \tmp, \tmp, #1
+       b.ne    .Lspectre_bhb_loop\@
+       sb
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+       .endm
+
+       .macro mitigate_spectre_bhb_loop        tmp
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+alternative_cb spectre_bhb_patch_loop_mitigation_enable
+       b       .L_spectre_bhb_loop_done\@      // Patched to NOP
+alternative_cb_end
+       __mitigate_spectre_bhb_loop     \tmp
+.L_spectre_bhb_loop_done\@:
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+       .endm
+
+       /* Save/restores x0-x3 to the stack */
+       .macro __mitigate_spectre_bhb_fw
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+       stp     x0, x1, [sp, #-16]!
+       stp     x2, x3, [sp, #-16]!
+       mov     w0, #ARM_SMCCC_ARCH_WORKAROUND_3
+alternative_cb smccc_patch_fw_mitigation_conduit
+       nop                                     // Patched to SMC/HVC #0
+alternative_cb_end
+       ldp     x2, x3, [sp], #16
+       ldp     x0, x1, [sp], #16
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+       .endm
+
+       .macro mitigate_spectre_bhb_clear_insn
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+alternative_cb spectre_bhb_patch_clearbhb
+       /* Patched to NOP when not supported */
+       clearbhb
+       isb
+alternative_cb_end
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+       .endm
 #endif /* __ASM_ASSEMBLER_H */
index ef6be92b1921aea1d6ccece91a2ddfeced9e5726..c62e7e5e2f0c636fa9255bf47a00df765fe15142 100644 (file)
@@ -356,6 +356,7 @@ struct arm64_cpu_capabilities {
                struct {        /* Feature register checking */
                        u32 sys_reg;
                        u8 field_pos;
+                       u8 field_width;
                        u8 min_field_value;
                        u8 hwcap_type;
                        bool sign;
@@ -576,6 +577,8 @@ static inline u64 arm64_ftr_reg_user_value(const struct arm64_ftr_reg *reg)
 static inline int __attribute_const__
 cpuid_feature_extract_field_width(u64 features, int field, int width, bool sign)
 {
+       if (WARN_ON_ONCE(!width))
+               width = 4;
        return (sign) ?
                cpuid_feature_extract_signed_field_width(features, field, width) :
                cpuid_feature_extract_unsigned_field_width(features, field, width);
@@ -637,6 +640,35 @@ static inline bool cpu_supports_mixed_endian_el0(void)
        return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
 }
 
+
+static inline bool supports_csv2p3(int scope)
+{
+       u64 pfr0;
+       u8 csv2_val;
+
+       if (scope == SCOPE_LOCAL_CPU)
+               pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
+       else
+               pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+
+       csv2_val = cpuid_feature_extract_unsigned_field(pfr0,
+                                                       ID_AA64PFR0_CSV2_SHIFT);
+       return csv2_val == 3;
+}
+
+static inline bool supports_clearbhb(int scope)
+{
+       u64 isar2;
+
+       if (scope == SCOPE_LOCAL_CPU)
+               isar2 = read_sysreg_s(SYS_ID_AA64ISAR2_EL1);
+       else
+               isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
+
+       return cpuid_feature_extract_unsigned_field(isar2,
+                                                   ID_AA64ISAR2_CLEARBHB_SHIFT);
+}
+
 const struct cpumask *system_32bit_el0_cpumask(void);
 DECLARE_STATIC_KEY_FALSE(arm64_mismatched_32bit_el0);
 
@@ -854,6 +886,7 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
 extern struct arm64_ftr_override id_aa64mmfr1_override;
 extern struct arm64_ftr_override id_aa64pfr1_override;
 extern struct arm64_ftr_override id_aa64isar1_override;
+extern struct arm64_ftr_override id_aa64isar2_override;
 
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
index 999b9149f85681e014d7fa6ab539edcfc621cdcb..232b439cbaf3d8511199fa69399ce27d47c336c6 100644 (file)
 #define ARM_CPU_PART_CORTEX_A76                0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1       0xD0C
 #define ARM_CPU_PART_CORTEX_A77                0xD0D
+#define ARM_CPU_PART_NEOVERSE_V1       0xD40
+#define ARM_CPU_PART_CORTEX_A78                0xD41
+#define ARM_CPU_PART_CORTEX_X1         0xD44
 #define ARM_CPU_PART_CORTEX_A510       0xD46
 #define ARM_CPU_PART_CORTEX_A710       0xD47
 #define ARM_CPU_PART_CORTEX_X2         0xD48
 #define ARM_CPU_PART_NEOVERSE_N2       0xD49
+#define ARM_CPU_PART_CORTEX_A78C       0xD4B
 
 #define APM_CPU_PART_POTENZA           0x000
 
 #define CAVIUM_CPU_PART_THUNDERX_81XX  0x0A2
 #define CAVIUM_CPU_PART_THUNDERX_83XX  0x0A3
 #define CAVIUM_CPU_PART_THUNDERX2      0x0AF
+/* OcteonTx2 series */
+#define CAVIUM_CPU_PART_OCTX2_98XX     0x0B1
+#define CAVIUM_CPU_PART_OCTX2_96XX     0x0B2
+#define CAVIUM_CPU_PART_OCTX2_95XX     0x0B3
+#define CAVIUM_CPU_PART_OCTX2_95XXN    0x0B4
+#define CAVIUM_CPU_PART_OCTX2_95XXMM   0x0B5
+#define CAVIUM_CPU_PART_OCTX2_95XXO    0x0B6
 
 #define BRCM_CPU_PART_BRAHMA_B53       0x100
 #define BRCM_CPU_PART_VULCAN           0x516
 #define MIDR_CORTEX_A76        MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77        MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_NEOVERSE_V1       MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
+#define MIDR_CORTEX_A78        MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
+#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
 #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
+#define MIDR_CORTEX_A78C       MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
 #define MIDR_THUNDERX  MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
 #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
+#define MIDR_OCTX2_98XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_98XX)
+#define MIDR_OCTX2_96XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_96XX)
+#define MIDR_OCTX2_95XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XX)
+#define MIDR_OCTX2_95XXN MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXN)
+#define MIDR_OCTX2_95XXMM MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXMM)
+#define MIDR_OCTX2_95XXO MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXO)
 #define MIDR_CAVIUM_THUNDERX2 MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX2)
 #define MIDR_BRAHMA_B53 MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_BRAHMA_B53)
 #define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN)
index 657c921fd784a7c12a0e45d814c6bc089f9ca0ec..00c291067e57d0e06a7431a3c3af8e905aa49c00 100644 (file)
  */
 #define BREAK_INSTR_SIZE               AARCH64_INSN_SIZE
 
-/*
- * BRK instruction encoding
- * The #imm16 value should be placed at bits[20:5] within BRK ins
- */
-#define AARCH64_BREAK_MON      0xd4200000
-
-/*
- * BRK instruction for provoking a fault on purpose
- * Unlike kgdb, #imm16 value with unallocated handler is used for faulting.
- */
-#define AARCH64_BREAK_FAULT    (AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5))
-
 #define AARCH64_BREAK_KGDB_DYN_DBG     \
        (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5))
 
index 4335800201c97ad1d22bc61ec2a3b12f498f2377..daff882883f92c956775b3a8cf15f560f2de2d56 100644 (file)
@@ -62,9 +62,11 @@ enum fixed_addresses {
 #endif /* CONFIG_ACPI_APEI_GHES */
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+       FIX_ENTRY_TRAMP_TEXT3,
+       FIX_ENTRY_TRAMP_TEXT2,
+       FIX_ENTRY_TRAMP_TEXT1,
        FIX_ENTRY_TRAMP_DATA,
-       FIX_ENTRY_TRAMP_TEXT,
-#define TRAMP_VALIAS           (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT))
+#define TRAMP_VALIAS           (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1))
 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
        __end_of_permanent_fixed_addresses,
 
index f68fbb207473047d7756cb2cc1b2bc29e4c4da03..8db5ec0089dbd3d476da432faa316102860b1bde 100644 (file)
 #define KERNEL_HWCAP_ECV               __khwcap2_feature(ECV)
 #define KERNEL_HWCAP_AFP               __khwcap2_feature(AFP)
 #define KERNEL_HWCAP_RPRES             __khwcap2_feature(RPRES)
+#define KERNEL_HWCAP_MTE3              __khwcap2_feature(MTE3)
 
 /*
  * This yields a mask that user programs can use to figure out what
index 2c075f615c6ac1389ec519b68d6a30eb1b958f38..1a7d0d483698e204a741e5644612bbefab2eaa62 100644 (file)
@@ -3,7 +3,21 @@
 #ifndef __ASM_INSN_DEF_H
 #define __ASM_INSN_DEF_H
 
+#include <asm/brk-imm.h>
+
 /* A64 instructions are always 32 bits. */
 #define        AARCH64_INSN_SIZE               4
 
+/*
+ * BRK instruction encoding
+ * The #imm16 value should be placed at bits[20:5] within BRK ins
+ */
+#define AARCH64_BREAK_MON      0xd4200000
+
+/*
+ * BRK instruction for provoking a fault on purpose
+ * Unlike kgdb, #imm16 value with unallocated handler is used for faulting.
+ */
+#define AARCH64_BREAK_FAULT    (AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5))
+
 #endif /* __ASM_INSN_DEF_H */
index 6b776c8667b2029ac9af4552033892b8fd24d464..1e5760d567aeae1d1057443b46194f90c8c59d2a 100644 (file)
@@ -65,6 +65,7 @@ enum aarch64_insn_hint_cr_op {
        AARCH64_INSN_HINT_PSB  = 0x11 << 5,
        AARCH64_INSN_HINT_TSB  = 0x12 << 5,
        AARCH64_INSN_HINT_CSDB = 0x14 << 5,
+       AARCH64_INSN_HINT_CLEARBHB = 0x16 << 5,
 
        AARCH64_INSN_HINT_BTI   = 0x20 << 5,
        AARCH64_INSN_HINT_BTIC  = 0x22 << 5,
@@ -205,7 +206,9 @@ enum aarch64_insn_ldst_type {
        AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX,
        AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX,
        AARCH64_INSN_LDST_LOAD_EX,
+       AARCH64_INSN_LDST_LOAD_ACQ_EX,
        AARCH64_INSN_LDST_STORE_EX,
+       AARCH64_INSN_LDST_STORE_REL_EX,
 };
 
 enum aarch64_insn_adsb_type {
@@ -280,6 +283,36 @@ enum aarch64_insn_adr_type {
        AARCH64_INSN_ADR_TYPE_ADR,
 };
 
+enum aarch64_insn_mem_atomic_op {
+       AARCH64_INSN_MEM_ATOMIC_ADD,
+       AARCH64_INSN_MEM_ATOMIC_CLR,
+       AARCH64_INSN_MEM_ATOMIC_EOR,
+       AARCH64_INSN_MEM_ATOMIC_SET,
+       AARCH64_INSN_MEM_ATOMIC_SWP,
+};
+
+enum aarch64_insn_mem_order_type {
+       AARCH64_INSN_MEM_ORDER_NONE,
+       AARCH64_INSN_MEM_ORDER_ACQ,
+       AARCH64_INSN_MEM_ORDER_REL,
+       AARCH64_INSN_MEM_ORDER_ACQREL,
+};
+
+enum aarch64_insn_mb_type {
+       AARCH64_INSN_MB_SY,
+       AARCH64_INSN_MB_ST,
+       AARCH64_INSN_MB_LD,
+       AARCH64_INSN_MB_ISH,
+       AARCH64_INSN_MB_ISHST,
+       AARCH64_INSN_MB_ISHLD,
+       AARCH64_INSN_MB_NSH,
+       AARCH64_INSN_MB_NSHST,
+       AARCH64_INSN_MB_NSHLD,
+       AARCH64_INSN_MB_OSH,
+       AARCH64_INSN_MB_OSHST,
+       AARCH64_INSN_MB_OSHLD,
+};
+
 #define        __AARCH64_INSN_FUNCS(abbr, mask, val)                           \
 static __always_inline bool aarch64_insn_is_##abbr(u32 code)           \
 {                                                                      \
@@ -303,6 +336,11 @@ __AARCH64_INSN_FUNCS(store_post,   0x3FE00C00, 0x38000400)
 __AARCH64_INSN_FUNCS(load_post,        0x3FE00C00, 0x38400400)
 __AARCH64_INSN_FUNCS(str_reg,  0x3FE0EC00, 0x38206800)
 __AARCH64_INSN_FUNCS(ldadd,    0x3F20FC00, 0x38200000)
+__AARCH64_INSN_FUNCS(ldclr,    0x3F20FC00, 0x38201000)
+__AARCH64_INSN_FUNCS(ldeor,    0x3F20FC00, 0x38202000)
+__AARCH64_INSN_FUNCS(ldset,    0x3F20FC00, 0x38203000)
+__AARCH64_INSN_FUNCS(swp,      0x3F20FC00, 0x38208000)
+__AARCH64_INSN_FUNCS(cas,      0x3FA07C00, 0x08A07C00)
 __AARCH64_INSN_FUNCS(ldr_reg,  0x3FE0EC00, 0x38606800)
 __AARCH64_INSN_FUNCS(ldr_lit,  0xBF000000, 0x18000000)
 __AARCH64_INSN_FUNCS(ldrsw_lit,        0xFF000000, 0x98000000)
@@ -474,13 +512,6 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
                                   enum aarch64_insn_register state,
                                   enum aarch64_insn_size_type size,
                                   enum aarch64_insn_ldst_type type);
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
-                          enum aarch64_insn_register address,
-                          enum aarch64_insn_register value,
-                          enum aarch64_insn_size_type size);
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
-                          enum aarch64_insn_register value,
-                          enum aarch64_insn_size_type size);
 u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
                                 enum aarch64_insn_register src,
                                 int imm, enum aarch64_insn_variant variant,
@@ -541,6 +572,42 @@ u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
                              enum aarch64_insn_prfm_type type,
                              enum aarch64_insn_prfm_target target,
                              enum aarch64_insn_prfm_policy policy);
+#ifdef CONFIG_ARM64_LSE_ATOMICS
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+                                 enum aarch64_insn_register address,
+                                 enum aarch64_insn_register value,
+                                 enum aarch64_insn_size_type size,
+                                 enum aarch64_insn_mem_atomic_op op,
+                                 enum aarch64_insn_mem_order_type order);
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+                        enum aarch64_insn_register address,
+                        enum aarch64_insn_register value,
+                        enum aarch64_insn_size_type size,
+                        enum aarch64_insn_mem_order_type order);
+#else
+static inline
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+                                 enum aarch64_insn_register address,
+                                 enum aarch64_insn_register value,
+                                 enum aarch64_insn_size_type size,
+                                 enum aarch64_insn_mem_atomic_op op,
+                                 enum aarch64_insn_mem_order_type order)
+{
+       return AARCH64_BREAK_FAULT;
+}
+
+static inline
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+                        enum aarch64_insn_register address,
+                        enum aarch64_insn_register value,
+                        enum aarch64_insn_size_type size,
+                        enum aarch64_insn_mem_order_type order)
+{
+       return AARCH64_BREAK_FAULT;
+}
+#endif
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
+
 s32 aarch64_get_branch_offset(u32 insn);
 u32 aarch64_set_branch_offset(u32 insn, s32 offset);
 
index 01d47c5886dc43a6925116e3ba38c0a52aaf5657..1767ded8388802bfc94a444e1bb28129dd993bc3 100644 (file)
        ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
        ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
 
-#define CPACR_EL1_FPEN         (3 << 20)
 #define CPACR_EL1_TTA          (1 << 28)
-#define CPACR_EL1_DEFAULT      (CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
+#define CPACR_EL1_DEFAULT      (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN |\
+                                CPACR_EL1_ZEN_EL1EN)
 
 #endif /* __ARM64_KVM_ARM_H__ */
index 5bc01e62c08a03d55f12d1bafa9f6fc9ead49f10..031e3a2537fc8632bf23325a5c13f6d8f7a79644 100644 (file)
@@ -714,6 +714,11 @@ static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
        ctxt_sys_reg(cpu_ctxt, MPIDR_EL1) = read_cpuid_mpidr();
 }
 
+static inline bool kvm_system_needs_idmapped_vectors(void)
+{
+       return cpus_have_const_cap(ARM64_SPECTRE_V3A);
+}
+
 void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu);
 
 static inline void kvm_arch_hardware_unsetup(void) {}
index 462882f356c775d1e364dce108b7c6769ed0a8f4..aa7fa2a08f0604af5b25f2eb0f334f4a716b4431 100644 (file)
@@ -118,6 +118,7 @@ extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64isar0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64isar1_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64isar2_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
index b77e9b3f5371c9f38def6f6b4d3f66eb3557a875..43f8c25b3fda655577859cf7a8ce59c1a049ed6b 100644 (file)
        SYM_START(name, SYM_L_WEAK, SYM_A_NONE)         \
        bti c ;
 
-/*
- * Annotate a function as position independent, i.e., safe to be called before
- * the kernel virtual mapping is activated.
- */
-#define SYM_FUNC_START_PI(x)                   \
-               SYM_FUNC_START_ALIAS(__pi_##x); \
-               SYM_FUNC_START(x)
-
-#define SYM_FUNC_START_WEAK_PI(x)              \
-               SYM_FUNC_START_ALIAS(__pi_##x); \
-               SYM_FUNC_START_WEAK(x)
-
-#define SYM_FUNC_START_WEAK_ALIAS_PI(x)                \
-               SYM_FUNC_START_ALIAS(__pi_##x); \
-               SYM_START(x, SYM_L_WEAK, SYM_A_ALIGN)
-
-#define SYM_FUNC_END_PI(x)                     \
-               SYM_FUNC_END(x);                \
-               SYM_FUNC_END_ALIAS(__pi_##x)
-
-#define SYM_FUNC_END_ALIAS_PI(x)               \
-               SYM_FUNC_END_ALIAS(x);          \
-               SYM_FUNC_END_ALIAS(__pi_##x)
-
 #endif
index 5d10051c3e62e839808d9ee0a56e0274d934589a..29c85810ae69052e3198e79ff4770b5f05d97177 100644 (file)
 #include <asm/cpucaps.h>
 
 extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
-extern struct static_key_false arm64_const_caps_ready;
 
-static inline bool system_uses_lse_atomics(void)
+static __always_inline bool system_uses_lse_atomics(void)
 {
-       return (static_branch_likely(&arm64_const_caps_ready)) &&
-               static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]);
+       return static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]);
 }
 
 #define __lse_ll_sc_body(op, ...)                                      \
index a11ccadd47d299975cd6eb2a4fa75bf603e6e7df..094701ec5500b431094b9a6fafcae4bbdb6e2e10 100644 (file)
@@ -1,8 +1,8 @@
 SECTIONS {
 #ifdef CONFIG_ARM64_MODULE_PLTS
-       .plt 0 (NOLOAD) : { BYTE(0) }
-       .init.plt 0 (NOLOAD) : { BYTE(0) }
-       .text.ftrace_trampoline 0 (NOLOAD) : { BYTE(0) }
+       .plt 0 : { BYTE(0) }
+       .init.plt 0 : { BYTE(0) }
+       .text.ftrace_trampoline 0 : { BYTE(0) }
 #endif
 
 #ifdef CONFIG_KASAN_SW_TAGS
index 626d359b396e58e8f1d8ee4fcb149d6a16c77868..14ee86b019c2e50f9430c9fa374937209b8d63ed 100644 (file)
@@ -11,6 +11,7 @@
 #define MTE_TAG_SHIFT          56
 #define MTE_TAG_SIZE           4
 #define MTE_TAG_MASK           GENMASK((MTE_TAG_SHIFT + (MTE_TAG_SIZE - 1)), MTE_TAG_SHIFT)
+#define MTE_PAGE_TAG_STORAGE   (MTE_GRANULES_PER_PAGE * MTE_TAG_SIZE / 8)
 
 #define __MTE_PREAMBLE         ARM64_ASM_PREAMBLE ".arch_extension memtag\n"
 
index e4704a403237e2f0d6b253e09964caf47b4101cd..a857bcacf0fe16dede870491d13ff34c712eee31 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef __ASM_MTE_KASAN_H
 #define __ASM_MTE_KASAN_H
 
+#include <asm/compiler.h>
 #include <asm/mte-def.h>
 
 #ifndef __ASSEMBLY__
index 075539f5f1c88f42298ae4c6b824cb34a9728a7e..adcb937342f14d2d431eab7bff46e90a19f9a026 100644 (file)
@@ -11,7 +11,9 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/bitfield.h>
+#include <linux/kasan-enabled.h>
 #include <linux/page-flags.h>
+#include <linux/sched.h>
 #include <linux/types.h>
 
 #include <asm/pgtable-types.h>
@@ -86,6 +88,26 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child,
 
 #endif /* CONFIG_ARM64_MTE */
 
+static inline void mte_disable_tco_entry(struct task_struct *task)
+{
+       if (!system_supports_mte())
+               return;
+
+       /*
+        * Re-enable tag checking (TCO set on exception entry). This is only
+        * necessary if MTE is enabled in either the kernel or the userspace
+        * task in synchronous or asymmetric mode (SCTLR_EL1.TCF0 bit 0 is set
+        * for both). With MTE disabled in the kernel and disabled or
+        * asynchronous in userspace, tag check faults (including in uaccesses)
+        * are not reported, therefore there is no need to re-enable checking.
+        * This is beneficial on microarchitectures where re-enabling TCO is
+        * expensive.
+        */
+       if (kasan_hw_tags_enabled() ||
+           (task->thread.sctlr_user & (1UL << SCTLR_EL1_TCF0_SHIFT)))
+               asm volatile(SET_PSTATE_TCO(0));
+}
+
 #ifdef CONFIG_KASAN_HW_TAGS
 /* Whether the MTE asynchronous mode is enabled. */
 DECLARE_STATIC_KEY_FALSE(mte_async_or_asymm_mode);
index 4ef6f19331f981dc7ddd9c49ca93a8a4222a9902..3eaf462f5752ccffe4c15e54345de34249704415 100644 (file)
 /*
  * Common architectural and microarchitectural event numbers.
  */
-#define ARMV8_PMUV3_PERFCTR_SW_INCR                            0x00
-#define ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL                   0x01
-#define ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL                     0x02
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL                   0x03
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE                          0x04
-#define ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL                     0x05
-#define ARMV8_PMUV3_PERFCTR_LD_RETIRED                         0x06
-#define ARMV8_PMUV3_PERFCTR_ST_RETIRED                         0x07
-#define ARMV8_PMUV3_PERFCTR_INST_RETIRED                       0x08
-#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN                          0x09
-#define ARMV8_PMUV3_PERFCTR_EXC_RETURN                         0x0A
-#define ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED                  0x0B
-#define ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED                   0x0C
-#define ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED                   0x0D
-#define ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED                  0x0E
-#define ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED             0x0F
-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED                                0x10
-#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES                         0x11
-#define ARMV8_PMUV3_PERFCTR_BR_PRED                            0x12
-#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS                         0x13
-#define ARMV8_PMUV3_PERFCTR_L1I_CACHE                          0x14
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB                       0x15
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE                          0x16
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL                   0x17
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB                       0x18
-#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS                         0x19
-#define ARMV8_PMUV3_PERFCTR_MEMORY_ERROR                       0x1A
-#define ARMV8_PMUV3_PERFCTR_INST_SPEC                          0x1B
-#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED                 0x1C
-#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES                         0x1D
-#define ARMV8_PMUV3_PERFCTR_CHAIN                              0x1E
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE                 0x1F
-#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE                 0x20
-#define ARMV8_PMUV3_PERFCTR_BR_RETIRED                         0x21
-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED                        0x22
-#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND                     0x23
-#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND                      0x24
-#define ARMV8_PMUV3_PERFCTR_L1D_TLB                            0x25
-#define ARMV8_PMUV3_PERFCTR_L1I_TLB                            0x26
-#define ARMV8_PMUV3_PERFCTR_L2I_CACHE                          0x27
-#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL                   0x28
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE                 0x29
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL                   0x2A
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE                          0x2B
-#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB                       0x2C
-#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL                     0x2D
-#define ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL                     0x2E
-#define ARMV8_PMUV3_PERFCTR_L2D_TLB                            0x2F
-#define ARMV8_PMUV3_PERFCTR_L2I_TLB                            0x30
-#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS                      0x31
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE                           0x32
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS                      0x33
-#define ARMV8_PMUV3_PERFCTR_DTLB_WALK                          0x34
-#define ARMV8_PMUV3_PERFCTR_ITLB_WALK                          0x35
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE_RD                                0x36
-#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD                   0x37
-#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD                   0x38
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_LMISS_RD                 0x39
-#define ARMV8_PMUV3_PERFCTR_OP_RETIRED                         0x3A
-#define ARMV8_PMUV3_PERFCTR_OP_SPEC                            0x3B
-#define ARMV8_PMUV3_PERFCTR_STALL                              0x3C
-#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND                 0x3D
-#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND                        0x3E
-#define ARMV8_PMUV3_PERFCTR_STALL_SLOT                         0x3F
+#define ARMV8_PMUV3_PERFCTR_SW_INCR                            0x0000
+#define ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL                   0x0001
+#define ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL                     0x0002
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL                   0x0003
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE                          0x0004
+#define ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL                     0x0005
+#define ARMV8_PMUV3_PERFCTR_LD_RETIRED                         0x0006
+#define ARMV8_PMUV3_PERFCTR_ST_RETIRED                         0x0007
+#define ARMV8_PMUV3_PERFCTR_INST_RETIRED                       0x0008
+#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN                          0x0009
+#define ARMV8_PMUV3_PERFCTR_EXC_RETURN                         0x000A
+#define ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED                  0x000B
+#define ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED                   0x000C
+#define ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED                   0x000D
+#define ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED                  0x000E
+#define ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED             0x000F
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED                                0x0010
+#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES                         0x0011
+#define ARMV8_PMUV3_PERFCTR_BR_PRED                            0x0012
+#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS                         0x0013
+#define ARMV8_PMUV3_PERFCTR_L1I_CACHE                          0x0014
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB                       0x0015
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE                          0x0016
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL                   0x0017
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB                       0x0018
+#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS                         0x0019
+#define ARMV8_PMUV3_PERFCTR_MEMORY_ERROR                       0x001A
+#define ARMV8_PMUV3_PERFCTR_INST_SPEC                          0x001B
+#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED                 0x001C
+#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES                         0x001D
+#define ARMV8_PMUV3_PERFCTR_CHAIN                              0x001E
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE                 0x001F
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE                 0x0020
+#define ARMV8_PMUV3_PERFCTR_BR_RETIRED                         0x0021
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED                        0x0022
+#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND                     0x0023
+#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND                      0x0024
+#define ARMV8_PMUV3_PERFCTR_L1D_TLB                            0x0025
+#define ARMV8_PMUV3_PERFCTR_L1I_TLB                            0x0026
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE                          0x0027
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL                   0x0028
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE                 0x0029
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL                   0x002A
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE                          0x002B
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB                       0x002C
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL                     0x002D
+#define ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL                     0x002E
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB                            0x002F
+#define ARMV8_PMUV3_PERFCTR_L2I_TLB                            0x0030
+#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS                      0x0031
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE                           0x0032
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS                      0x0033
+#define ARMV8_PMUV3_PERFCTR_DTLB_WALK                          0x0034
+#define ARMV8_PMUV3_PERFCTR_ITLB_WALK                          0x0035
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE_RD                                0x0036
+#define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD                   0x0037
+#define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD                   0x0038
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_LMISS_RD                 0x0039
+#define ARMV8_PMUV3_PERFCTR_OP_RETIRED                         0x003A
+#define ARMV8_PMUV3_PERFCTR_OP_SPEC                            0x003B
+#define ARMV8_PMUV3_PERFCTR_STALL                              0x003C
+#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND                 0x003D
+#define ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND                        0x003E
+#define ARMV8_PMUV3_PERFCTR_STALL_SLOT                         0x003F
 
 /* Statistical profiling extension microarchitectural events */
 #define        ARMV8_SPE_PERFCTR_SAMPLE_POP                            0x4000
 #define        ARMV8_PMUV3_PERFCTR_L2I_CACHE_LMISS                     0x400A
 #define        ARMV8_PMUV3_PERFCTR_L3D_CACHE_LMISS_RD                  0x400B
 
+/* Trace buffer events */
+#define ARMV8_PMUV3_PERFCTR_TRB_WRAP                           0x400C
+#define ARMV8_PMUV3_PERFCTR_TRB_TRIG                           0x400E
+
+/* Trace unit events */
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT0                         0x4010
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT1                         0x4011
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT2                         0x4012
+#define ARMV8_PMUV3_PERFCTR_TRCEXTOUT3                         0x4013
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT4                       0x4018
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT5                       0x4019
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT6                       0x401A
+#define ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT7                       0x401B
+
 /* additional latency from alignment events */
 #define        ARMV8_PMUV3_PERFCTR_LDST_ALIGN_LAT                      0x4020
 #define        ARMV8_PMUV3_PERFCTR_LD_ALIGN_LAT                        0x4021
 #define        ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED_WR                 0x4026
 
 /* ARMv8 recommended implementation defined event types */
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD                      0x40
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR                      0x41
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_RD               0x42
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR               0x43
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_INNER            0x44
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_OUTER            0x45
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_VICTIM               0x46
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_CLEAN                        0x47
-#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_INVAL                   0x48
-
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD                 0x4C
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR                 0x4D
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD                                0x4E
-#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR                                0x4F
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_RD                      0x50
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WR                      0x51
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_RD               0x52
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_WR               0x53
-
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_VICTIM               0x56
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_CLEAN                        0x57
-#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_INVAL                   0x58
-
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_RD                 0x5C
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_WR                 0x5D
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_RD                                0x5E
-#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_WR                                0x5F
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD                     0x60
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR                     0x61
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_SHARED                 0x62
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NOT_SHARED             0x63
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NORMAL                 0x64
-#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_PERIPH                 0x65
-#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_RD                     0x66
-#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_WR                     0x67
-#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LD_SPEC                 0x68
-#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_ST_SPEC                 0x69
-#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LDST_SPEC               0x6A
-
-#define ARMV8_IMPDEF_PERFCTR_LDREX_SPEC                                0x6C
-#define ARMV8_IMPDEF_PERFCTR_STREX_PASS_SPEC                   0x6D
-#define ARMV8_IMPDEF_PERFCTR_STREX_FAIL_SPEC                   0x6E
-#define ARMV8_IMPDEF_PERFCTR_STREX_SPEC                                0x6F
-#define ARMV8_IMPDEF_PERFCTR_LD_SPEC                           0x70
-#define ARMV8_IMPDEF_PERFCTR_ST_SPEC                           0x71
-#define ARMV8_IMPDEF_PERFCTR_LDST_SPEC                         0x72
-#define ARMV8_IMPDEF_PERFCTR_DP_SPEC                           0x73
-#define ARMV8_IMPDEF_PERFCTR_ASE_SPEC                          0x74
-#define ARMV8_IMPDEF_PERFCTR_VFP_SPEC                          0x75
-#define ARMV8_IMPDEF_PERFCTR_PC_WRITE_SPEC                     0x76
-#define ARMV8_IMPDEF_PERFCTR_CRYPTO_SPEC                       0x77
-#define ARMV8_IMPDEF_PERFCTR_BR_IMMED_SPEC                     0x78
-#define ARMV8_IMPDEF_PERFCTR_BR_RETURN_SPEC                    0x79
-#define ARMV8_IMPDEF_PERFCTR_BR_INDIRECT_SPEC                  0x7A
-
-#define ARMV8_IMPDEF_PERFCTR_ISB_SPEC                          0x7C
-#define ARMV8_IMPDEF_PERFCTR_DSB_SPEC                          0x7D
-#define ARMV8_IMPDEF_PERFCTR_DMB_SPEC                          0x7E
-
-#define ARMV8_IMPDEF_PERFCTR_EXC_UNDEF                         0x81
-#define ARMV8_IMPDEF_PERFCTR_EXC_SVC                           0x82
-#define ARMV8_IMPDEF_PERFCTR_EXC_PABORT                                0x83
-#define ARMV8_IMPDEF_PERFCTR_EXC_DABORT                                0x84
-
-#define ARMV8_IMPDEF_PERFCTR_EXC_IRQ                           0x86
-#define ARMV8_IMPDEF_PERFCTR_EXC_FIQ                           0x87
-#define ARMV8_IMPDEF_PERFCTR_EXC_SMC                           0x88
-
-#define ARMV8_IMPDEF_PERFCTR_EXC_HVC                           0x8A
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_PABORT                   0x8B
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_DABORT                   0x8C
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_OTHER                    0x8D
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_IRQ                      0x8E
-#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_FIQ                      0x8F
-#define ARMV8_IMPDEF_PERFCTR_RC_LD_SPEC                                0x90
-#define ARMV8_IMPDEF_PERFCTR_RC_ST_SPEC                                0x91
-
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_RD                      0xA0
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WR                      0xA1
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_RD               0xA2
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_WR               0xA3
-
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_VICTIM               0xA6
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_CLEAN                        0xA7
-#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_INVAL                   0xA8
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD                      0x0040
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR                      0x0041
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_RD               0x0042
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR               0x0043
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_INNER            0x0044
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_OUTER            0x0045
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_VICTIM               0x0046
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WB_CLEAN                        0x0047
+#define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_INVAL                   0x0048
+
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD                 0x004C
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR                 0x004D
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD                                0x004E
+#define ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR                                0x004F
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_RD                      0x0050
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WR                      0x0051
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_RD               0x0052
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_REFILL_WR               0x0053
+
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_VICTIM               0x0056
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_WB_CLEAN                        0x0057
+#define ARMV8_IMPDEF_PERFCTR_L2D_CACHE_INVAL                   0x0058
+
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_RD                 0x005C
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_REFILL_WR                 0x005D
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_RD                                0x005E
+#define ARMV8_IMPDEF_PERFCTR_L2D_TLB_WR                                0x005F
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD                     0x0060
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR                     0x0061
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_SHARED                 0x0062
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NOT_SHARED             0x0063
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_NORMAL                 0x0064
+#define ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_PERIPH                 0x0065
+#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_RD                     0x0066
+#define ARMV8_IMPDEF_PERFCTR_MEM_ACCESS_WR                     0x0067
+#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LD_SPEC                 0x0068
+#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_ST_SPEC                 0x0069
+#define ARMV8_IMPDEF_PERFCTR_UNALIGNED_LDST_SPEC               0x006A
+
+#define ARMV8_IMPDEF_PERFCTR_LDREX_SPEC                                0x006C
+#define ARMV8_IMPDEF_PERFCTR_STREX_PASS_SPEC                   0x006D
+#define ARMV8_IMPDEF_PERFCTR_STREX_FAIL_SPEC                   0x006E
+#define ARMV8_IMPDEF_PERFCTR_STREX_SPEC                                0x006F
+#define ARMV8_IMPDEF_PERFCTR_LD_SPEC                           0x0070
+#define ARMV8_IMPDEF_PERFCTR_ST_SPEC                           0x0071
+#define ARMV8_IMPDEF_PERFCTR_LDST_SPEC                         0x0072
+#define ARMV8_IMPDEF_PERFCTR_DP_SPEC                           0x0073
+#define ARMV8_IMPDEF_PERFCTR_ASE_SPEC                          0x0074
+#define ARMV8_IMPDEF_PERFCTR_VFP_SPEC                          0x0075
+#define ARMV8_IMPDEF_PERFCTR_PC_WRITE_SPEC                     0x0076
+#define ARMV8_IMPDEF_PERFCTR_CRYPTO_SPEC                       0x0077
+#define ARMV8_IMPDEF_PERFCTR_BR_IMMED_SPEC                     0x0078
+#define ARMV8_IMPDEF_PERFCTR_BR_RETURN_SPEC                    0x0079
+#define ARMV8_IMPDEF_PERFCTR_BR_INDIRECT_SPEC                  0x007A
+
+#define ARMV8_IMPDEF_PERFCTR_ISB_SPEC                          0x007C
+#define ARMV8_IMPDEF_PERFCTR_DSB_SPEC                          0x007D
+#define ARMV8_IMPDEF_PERFCTR_DMB_SPEC                          0x007E
+
+#define ARMV8_IMPDEF_PERFCTR_EXC_UNDEF                         0x0081
+#define ARMV8_IMPDEF_PERFCTR_EXC_SVC                           0x0082
+#define ARMV8_IMPDEF_PERFCTR_EXC_PABORT                                0x0083
+#define ARMV8_IMPDEF_PERFCTR_EXC_DABORT                                0x0084
+
+#define ARMV8_IMPDEF_PERFCTR_EXC_IRQ                           0x0086
+#define ARMV8_IMPDEF_PERFCTR_EXC_FIQ                           0x0087
+#define ARMV8_IMPDEF_PERFCTR_EXC_SMC                           0x0088
+
+#define ARMV8_IMPDEF_PERFCTR_EXC_HVC                           0x008A
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_PABORT                   0x008B
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_DABORT                   0x008C
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_OTHER                    0x008D
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_IRQ                      0x008E
+#define ARMV8_IMPDEF_PERFCTR_EXC_TRAP_FIQ                      0x008F
+#define ARMV8_IMPDEF_PERFCTR_RC_LD_SPEC                                0x0090
+#define ARMV8_IMPDEF_PERFCTR_RC_ST_SPEC                                0x0091
+
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_RD                      0x00A0
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WR                      0x00A1
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_RD               0x00A2
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_REFILL_WR               0x00A3
+
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_VICTIM               0x00A6
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_WB_CLEAN                        0x00A7
+#define ARMV8_IMPDEF_PERFCTR_L3D_CACHE_INVAL                   0x00A8
 
 /*
  * Per-CPU PMCR: config reg
index 40085e53f573dd27c4828d58d76e2c707682f74e..66671ff051835bbbacdfbcf69372f32c9fa98af8 100644 (file)
 #define TCR_NFD1               (UL(1) << 54)
 #define TCR_E0PD0              (UL(1) << 55)
 #define TCR_E0PD1              (UL(1) << 56)
+#define TCR_TCMA0              (UL(1) << 57)
+#define TCR_TCMA1              (UL(1) << 58)
 
 /*
  * TTBR.
index 7032f04c8ac6ef6f8a6294c399e2f338546b1aad..b1e1b74d993c3d1c462171134936e2c22e900b5b 100644 (file)
@@ -92,7 +92,7 @@ extern bool arm64_use_ng_mappings;
 #define __P001  PAGE_READONLY
 #define __P010  PAGE_READONLY
 #define __P011  PAGE_READONLY
-#define __P100  PAGE_EXECONLY
+#define __P100  PAGE_READONLY_EXEC     /* PAGE_EXECONLY if Enhanced PAN */
 #define __P101  PAGE_READONLY_EXEC
 #define __P110  PAGE_READONLY_EXEC
 #define __P111  PAGE_READONLY_EXEC
@@ -101,7 +101,7 @@ extern bool arm64_use_ng_mappings;
 #define __S001  PAGE_READONLY
 #define __S010  PAGE_SHARED
 #define __S011  PAGE_SHARED
-#define __S100  PAGE_EXECONLY
+#define __S100  PAGE_READONLY_EXEC     /* PAGE_EXECONLY if Enhanced PAN */
 #define __S101  PAGE_READONLY_EXEC
 #define __S110  PAGE_SHARED_EXEC
 #define __S111  PAGE_SHARED_EXEC
index c4ba047a82d2605ffcf8f985284693e29b8ceecb..94e147e5456ca9998ede2aa20d580c2f4431b9fa 100644 (file)
@@ -1017,17 +1017,6 @@ static inline bool arch_wants_old_prefaulted_pte(void)
 }
 #define arch_wants_old_prefaulted_pte  arch_wants_old_prefaulted_pte
 
-static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
-{
-       if (cpus_have_const_cap(ARM64_HAS_EPAN))
-               return prot;
-
-       if (pgprot_val(prot) != pgprot_val(PAGE_EXECONLY))
-               return prot;
-
-       return PAGE_READONLY_EXEC;
-}
-
 static inline bool pud_sect_supported(void)
 {
        return PAGE_SIZE == SZ_4K;
index 6f41b65f9962806a99567a8485f175258ff9b6cd..73e38d9a540ce94451849f22161fc673c91638d5 100644 (file)
@@ -21,6 +21,7 @@
 
 #define MTE_CTRL_TCF_SYNC              (1UL << 16)
 #define MTE_CTRL_TCF_ASYNC             (1UL << 17)
+#define MTE_CTRL_TCF_ASYMM             (1UL << 18)
 
 #ifndef __ASSEMBLY__
 
index 1bce62fa908a37f4f204524635e9422d79ee8255..56f7b1d4d54b9a2d2784926de576fa6caa28306b 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef __ASM_RWONCE_H
 #define __ASM_RWONCE_H
 
-#ifdef CONFIG_LTO
+#if defined(CONFIG_LTO) && !defined(__ASSEMBLY__)
 
 #include <linux/compiler_types.h>
 #include <asm/alternative-macros.h>
@@ -66,7 +66,7 @@
 })
 
 #endif /* !BUILD_VDSO */
-#endif /* CONFIG_LTO */
+#endif /* CONFIG_LTO && !__ASSEMBLY__ */
 
 #include <asm-generic/rwonce.h>
 
index 152cb35bf9df71421d73b20e94c52fb6ad59d692..40971ac1303f9aa0067d9e860b81e01a444a4b54 100644 (file)
@@ -23,4 +23,9 @@ extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
 extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
 
+static inline size_t entry_tramp_text_size(void)
+{
+       return __entry_tramp_text_end - __entry_tramp_text_start;
+}
+
 #endif /* __ASM_SECTIONS_H */
index f62ca39da6c5a70fef556c1b62fc72e0a10b0739..aa3d3607d5c8de457f95829a57816dc21280a576 100644 (file)
@@ -67,7 +67,8 @@ struct bp_hardening_data {
 
 DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
 
-static inline void arm64_apply_bp_hardening(void)
+/* Called during entry so must be __always_inline */
+static __always_inline void arm64_apply_bp_hardening(void)
 {
        struct bp_hardening_data *d;
 
@@ -93,5 +94,9 @@ void spectre_v4_enable_task_mitigation(struct task_struct *tsk);
 
 enum mitigation_state arm64_get_meltdown_state(void);
 
+enum mitigation_state arm64_get_spectre_bhb_state(void);
+bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
+u8 spectre_bhb_loop_affected(int scope);
+void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_SPECTRE_H */
index 95f7686b728d7e5689f46ce6ae37fe7724779be2..3a3264ff47b9709df741eaece1c8eae995a5ffb3 100644 (file)
@@ -12,13 +12,11 @@ extern char *strrchr(const char *, int c);
 #define __HAVE_ARCH_STRCHR
 extern char *strchr(const char *, int c);
 
-#ifndef CONFIG_KASAN_HW_TAGS
 #define __HAVE_ARCH_STRCMP
 extern int strcmp(const char *, const char *);
 
 #define __HAVE_ARCH_STRNCMP
 extern int strncmp(const char *, const char *, __kernel_size_t);
-#endif
 
 #define __HAVE_ARCH_STRLEN
 extern __kernel_size_t strlen(const char *);
index 898bee0004aee603d7e51717bbb4643dbd0e6d2b..c7ca3a105528858a0481650e0d6134475333c2db 100644 (file)
 #define ID_AA64ISAR1_GPI_IMP_DEF               0x1
 
 /* id_aa64isar2 */
+#define ID_AA64ISAR2_CLEARBHB_SHIFT    28
+#define ID_AA64ISAR2_APA3_SHIFT                12
+#define ID_AA64ISAR2_GPA3_SHIFT                8
 #define ID_AA64ISAR2_RPRES_SHIFT       4
 #define ID_AA64ISAR2_WFXT_SHIFT                0
 
 #define ID_AA64ISAR2_WFXT_NI           0x0
 #define ID_AA64ISAR2_WFXT_SUPPORTED    0x2
 
+#define ID_AA64ISAR2_APA3_NI                   0x0
+#define ID_AA64ISAR2_APA3_ARCHITECTED          0x1
+#define ID_AA64ISAR2_APA3_ARCH_EPAC            0x2
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2           0x3
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2_FPAC      0x4
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2_FPAC_CMB  0x5
+
+#define ID_AA64ISAR2_GPA3_NI                   0x0
+#define ID_AA64ISAR2_GPA3_ARCHITECTED          0x1
+
 /* id_aa64pfr0 */
 #define ID_AA64PFR0_CSV3_SHIFT         60
 #define ID_AA64PFR0_CSV2_SHIFT         56
 #endif
 
 /* id_aa64mmfr1 */
+#define ID_AA64MMFR1_ECBHB_SHIFT       60
 #define ID_AA64MMFR1_AFP_SHIFT         44
 #define ID_AA64MMFR1_ETS_SHIFT         36
 #define ID_AA64MMFR1_TWED_SHIFT                32
 #define ZCR_ELx_LEN_SIZE       9
 #define ZCR_ELx_LEN_MASK       0x1ff
 
+#define CPACR_EL1_FPEN_EL1EN   (BIT(20)) /* enable EL1 access */
+#define CPACR_EL1_FPEN_EL0EN   (BIT(21)) /* enable EL0 access, if EL1EN set */
+
 #define CPACR_EL1_ZEN_EL1EN    (BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN    (BIT(17)) /* enable EL0 access, if EL1EN set */
-#define CPACR_EL1_ZEN          (CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
-
-/* TCR EL1 Bit Definitions */
-#define SYS_TCR_EL1_TCMA1      (BIT(58))
-#define SYS_TCR_EL1_TCMA0      (BIT(57))
 
 /* GCR_EL1 Definitions */
 #define SYS_GCR_EL1_RRND       (BIT(16))
diff --git a/arch/arm64/include/asm/vectors.h b/arch/arm64/include/asm/vectors.h
new file mode 100644 (file)
index 0000000..bc9a214
--- /dev/null
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 ARM Ltd.
+ */
+#ifndef __ASM_VECTORS_H
+#define __ASM_VECTORS_H
+
+#include <linux/bug.h>
+#include <linux/percpu.h>
+
+#include <asm/fixmap.h>
+
+extern char vectors[];
+extern char tramp_vectors[];
+extern char __bp_harden_el1_vectors[];
+
+/*
+ * Note: the order of this enum corresponds to two arrays in entry.S:
+ * tramp_vecs and __bp_harden_el1_vectors. By default the canonical
+ * 'full fat' vectors are used directly.
+ */
+enum arm64_bp_harden_el1_vectors {
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+       /*
+        * Perform the BHB loop mitigation, before branching to the canonical
+        * vectors.
+        */
+       EL1_VECTOR_BHB_LOOP,
+
+       /*
+        * Make the SMC call for firmware mitigation, before branching to the
+        * canonical vectors.
+        */
+       EL1_VECTOR_BHB_FW,
+
+       /*
+        * Use the ClearBHB instruction, before branching to the canonical
+        * vectors.
+        */
+       EL1_VECTOR_BHB_CLEAR_INSN,
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+
+       /*
+        * Remap the kernel before branching to the canonical vectors.
+        */
+       EL1_VECTOR_KPTI,
+};
+
+#ifndef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+#define EL1_VECTOR_BHB_LOOP            -1
+#define EL1_VECTOR_BHB_FW              -1
+#define EL1_VECTOR_BHB_CLEAR_INSN      -1
+#endif /* !CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+
+/* The vectors to use on return from EL0. e.g. to remap the kernel */
+DECLARE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector);
+
+#ifndef CONFIG_UNMAP_KERNEL_AT_EL0
+#define TRAMP_VALIAS   0ul
+#endif
+
+static inline const char *
+arm64_get_bp_hardening_vector(enum arm64_bp_harden_el1_vectors slot)
+{
+       if (arm64_kernel_unmapped_at_el0())
+               return (char *)(TRAMP_VALIAS + SZ_2K * slot);
+
+       WARN_ON_ONCE(slot == EL1_VECTOR_KPTI);
+
+       return __bp_harden_el1_vectors + SZ_2K * slot;
+}
+
+#endif /* __ASM_VECTORS_H */
index f03731847d9dfdbed849baceafb61f91745bd1cc..99cb5d383048dd8dedb08f51be0d3951dc6b0f4f 100644 (file)
@@ -78,5 +78,6 @@
 #define HWCAP2_ECV             (1 << 19)
 #define HWCAP2_AFP             (1 << 20)
 #define HWCAP2_RPRES           (1 << 21)
+#define HWCAP2_MTE3            (1 << 22)
 
 #endif /* _UAPI__ASM_HWCAP_H */
index b3edde68bc3e013c66d3272e8848a090800362d3..323e251ed37bc0f6bc2fc4f8de8143a1872ed8f2 100644 (file)
@@ -281,6 +281,11 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED       3
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED            (1U << 4)
 
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3    KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL          0
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL              1
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED       2
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE              (0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
index 88b3e2a214084522f079a7928f44abdac2c2ba40..986837d7ec82dc1863f06b0906575674d32a628e 100644 (file)
@@ -61,6 +61,7 @@ obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)     += acpi_parking_protocol.o
 obj-$(CONFIG_PARAVIRT)                 += paravirt.o
 obj-$(CONFIG_RANDOMIZE_BASE)           += kaslr.o
 obj-$(CONFIG_HIBERNATION)              += hibernate.o hibernate-asm.o
+obj-$(CONFIG_ELF_CORE)                 += elfcore.o
 obj-$(CONFIG_KEXEC_CORE)               += machine_kexec.o relocate_kernel.o    \
                                           cpu-reset.o
 obj-$(CONFIG_KEXEC_FILE)               += machine_kexec_file.o kexec_image.o
index b217941713a8d652a710795af632e2ed8ab5576d..4c9b5b4b7a0bc036f3d8a92e4378b1d622e9dbef 100644 (file)
@@ -214,6 +214,21 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
 };
 #endif
 
+#ifdef CONFIG_CAVIUM_ERRATUM_23154
+const struct midr_range cavium_erratum_23154_cpus[] = {
+       MIDR_ALL_VERSIONS(MIDR_THUNDERX),
+       MIDR_ALL_VERSIONS(MIDR_THUNDERX_81XX),
+       MIDR_ALL_VERSIONS(MIDR_THUNDERX_83XX),
+       MIDR_ALL_VERSIONS(MIDR_OCTX2_98XX),
+       MIDR_ALL_VERSIONS(MIDR_OCTX2_96XX),
+       MIDR_ALL_VERSIONS(MIDR_OCTX2_95XX),
+       MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXN),
+       MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXMM),
+       MIDR_ALL_VERSIONS(MIDR_OCTX2_95XXO),
+       {},
+};
+#endif
+
 #ifdef CONFIG_CAVIUM_ERRATUM_27456
 const struct midr_range cavium_erratum_27456_cpus[] = {
        /* Cavium ThunderX, T88 pass 1.x - 2.1 */
@@ -425,10 +440,10 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 #endif
 #ifdef CONFIG_CAVIUM_ERRATUM_23154
        {
-       /* Cavium ThunderX, pass 1.x */
-               .desc = "Cavium erratum 23154",
+               .desc = "Cavium errata 23154 and 38545",
                .capability = ARM64_WORKAROUND_CAVIUM_23154,
-               ERRATA_MIDR_REV_RANGE(MIDR_THUNDERX, 0, 0, 1),
+               .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+               ERRATA_MIDR_RANGE_LIST(cavium_erratum_23154_cpus),
        },
 #endif
 #ifdef CONFIG_CAVIUM_ERRATUM_27456
@@ -502,6 +517,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
                .matches = has_spectre_v4,
                .cpu_enable = spectre_v4_enable_mitigation,
        },
+       {
+               .desc = "Spectre-BHB",
+               .capability = ARM64_SPECTRE_BHB,
+               .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+               .matches = is_spectre_bhb_affected,
+               .cpu_enable = spectre_bhb_enable_mitigation,
+       },
 #ifdef CONFIG_ARM64_ERRATUM_1418040
        {
                .desc = "ARM erratum 1418040",
@@ -604,7 +626,6 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
        {
                .desc = "ARM erratum 2077057",
                .capability = ARM64_WORKAROUND_2077057,
-               .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
                ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
        },
 #endif
index e5f23dab1c8df8acc56a64d982cb065984167ecb..d72c4b4d389c4130741e5a56df1159a9049d063d 100644 (file)
@@ -73,6 +73,8 @@
 #include <linux/mm.h>
 #include <linux/cpu.h>
 #include <linux/kasan.h>
+#include <linux/percpu.h>
+
 #include <asm/cpu.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
@@ -85,6 +87,7 @@
 #include <asm/smp.h>
 #include <asm/sysreg.h>
 #include <asm/traps.h>
+#include <asm/vectors.h>
 #include <asm/virt.h>
 
 /* Kernel representation of AT_HWCAP and AT_HWCAP2 */
@@ -110,6 +113,8 @@ DECLARE_BITMAP(boot_capabilities, ARM64_NPATCHABLE);
 bool arm64_use_ng_mappings = false;
 EXPORT_SYMBOL(arm64_use_ng_mappings);
 
+DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors;
+
 /*
  * Permit PER_LINUX32 and execve() of 32-bit binaries even if not all CPUs
  * support it?
@@ -226,6 +231,11 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_CLEARBHB_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+                      FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_APA3_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+                      FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_GPA3_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_RPRES_SHIFT, 4, 0),
        ARM64_FTR_END,
 };
@@ -596,6 +606,7 @@ static const struct arm64_ftr_bits ftr_raz[] = {
 struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
 struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
 struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
+struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
 
 static const struct __ftr_reg_entry {
        u32                     sys_id;
@@ -644,6 +655,8 @@ static const struct __ftr_reg_entry {
        ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1,
                               &id_aa64isar1_override),
        ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2),
+       ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2,
+                              &id_aa64isar2_override),
 
        /* Op1 = 0, CRn = 0, CRm = 7 */
        ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
@@ -1307,7 +1320,9 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
 static bool
 feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
 {
-       int val = cpuid_feature_extract_field(reg, entry->field_pos, entry->sign);
+       int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
+                                                   entry->field_width,
+                                                   entry->sign);
 
        return val >= entry->min_field_value;
 }
@@ -1590,6 +1605,12 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
 
        int cpu = smp_processor_id();
 
+       if (__this_cpu_read(this_cpu_vector) == vectors) {
+               const char *v = arm64_get_bp_hardening_vector(EL1_VECTOR_KPTI);
+
+               __this_cpu_write(this_cpu_vector, v);
+       }
+
        /*
         * We don't need to rewrite the page-tables if either we've done
         * it already or we have KASLR enabled and therefore have not
@@ -1775,14 +1796,6 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
                write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
 }
 
-static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)
-{
-       u64 val = read_sysreg_s(SYS_CLIDR_EL1);
-
-       /* Check that CLIDR_EL1.LOU{U,IS} are both 0 */
-       WARN_ON(CLIDR_LOUU(val) || CLIDR_LOUIS(val));
-}
-
 #ifdef CONFIG_ARM64_PAN
 static void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused)
 {
@@ -1829,21 +1842,27 @@ static bool has_address_auth_cpucap(const struct arm64_cpu_capabilities *entry,
        /* Now check for the secondary CPUs with SCOPE_LOCAL_CPU scope */
        sec_val = cpuid_feature_extract_field(__read_sysreg_by_encoding(entry->sys_reg),
                                              entry->field_pos, entry->sign);
-       return sec_val == boot_val;
+       return (sec_val >= entry->min_field_value) && (sec_val == boot_val);
 }
 
 static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry,
                                     int scope)
 {
-       return has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH], scope) ||
-              has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
+       bool api = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
+       bool apa = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA5], scope);
+       bool apa3 = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA3], scope);
+
+       return apa || apa3 || api;
 }
 
 static bool has_generic_auth(const struct arm64_cpu_capabilities *entry,
                             int __unused)
 {
-       return __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH) ||
-              __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
+       bool gpi = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
+       bool gpa = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH_QARMA5);
+       bool gpa3 = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH_QARMA3);
+
+       return gpa || gpa3 || gpi;
 }
 #endif /* CONFIG_ARM64_PTR_AUTH */
 
@@ -1945,6 +1964,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_useable_gicv3_cpuif,
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .field_pos = ID_AA64PFR0_GIC_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 1,
        },
@@ -1955,6 +1975,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64MMFR0_EL1,
                .field_pos = ID_AA64MMFR0_ECV_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 1,
        },
@@ -1966,6 +1987,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64MMFR1_EL1,
                .field_pos = ID_AA64MMFR1_PAN_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 1,
                .cpu_enable = cpu_enable_pan,
@@ -1979,6 +2001,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64MMFR1_EL1,
                .field_pos = ID_AA64MMFR1_PAN_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 3,
        },
@@ -1991,6 +2014,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64ISAR0_EL1,
                .field_pos = ID_AA64ISAR0_ATOMICS_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 2,
        },
@@ -2015,6 +2039,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64PFR0_EL0_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
        },
 #ifdef CONFIG_KVM
@@ -2026,6 +2051,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64PFR0_EL1_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
        },
        {
@@ -2046,6 +2072,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                 */
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .field_pos = ID_AA64PFR0_CSV3_SHIFT,
+               .field_width = 4,
                .min_field_value = 1,
                .matches = unmap_kernel_at_el0,
                .cpu_enable = kpti_install_ng_mappings,
@@ -2065,6 +2092,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .field_pos = ID_AA64ISAR1_DPB_SHIFT,
+               .field_width = 4,
                .min_field_value = 1,
        },
        {
@@ -2075,6 +2103,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64ISAR1_DPB_SHIFT,
+               .field_width = 4,
                .min_field_value = 2,
        },
 #endif
@@ -2086,6 +2115,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64PFR0_SVE_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR0_SVE,
                .matches = has_cpuid_feature,
                .cpu_enable = sve_kernel_enable,
@@ -2100,6 +2130,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64PFR0_RAS_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR0_RAS_V1,
                .cpu_enable = cpu_clear_disr,
        },
@@ -2118,6 +2149,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64PFR0_AMU_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR0_AMU,
                .cpu_enable = cpu_amu_enable,
        },
@@ -2142,9 +2174,9 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64MMFR2_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64MMFR2_FWB_SHIFT,
+               .field_width = 4,
                .min_field_value = 1,
                .matches = has_cpuid_feature,
-               .cpu_enable = cpu_has_fwb,
        },
        {
                .desc = "ARMv8.4 Translation Table Level",
@@ -2153,6 +2185,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64MMFR2_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64MMFR2_TTL_SHIFT,
+               .field_width = 4,
                .min_field_value = 1,
                .matches = has_cpuid_feature,
        },
@@ -2163,6 +2196,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64ISAR0_EL1,
                .field_pos = ID_AA64ISAR0_TLB_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = ID_AA64ISAR0_TLB_RANGE,
        },
@@ -2181,6 +2215,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64MMFR1_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64MMFR1_HADBS_SHIFT,
+               .field_width = 4,
                .min_field_value = 2,
                .matches = has_hw_dbm,
                .cpu_enable = cpu_enable_hw_dbm,
@@ -2193,6 +2228,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64ISAR0_EL1,
                .field_pos = ID_AA64ISAR0_CRC32_SHIFT,
+               .field_width = 4,
                .min_field_value = 1,
        },
        {
@@ -2202,6 +2238,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64PFR1_EL1,
                .field_pos = ID_AA64PFR1_SSBS_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
        },
@@ -2214,6 +2251,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64MMFR2_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64MMFR2_CNP_SHIFT,
+               .field_width = 4,
                .min_field_value = 1,
                .cpu_enable = cpu_enable_cnp,
        },
@@ -2225,20 +2263,33 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .field_pos = ID_AA64ISAR1_SB_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 1,
        },
 #ifdef CONFIG_ARM64_PTR_AUTH
        {
-               .desc = "Address authentication (architected algorithm)",
-               .capability = ARM64_HAS_ADDRESS_AUTH_ARCH,
+               .desc = "Address authentication (architected QARMA5 algorithm)",
+               .capability = ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA5,
                .type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64ISAR1_APA_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64ISAR1_APA_ARCHITECTED,
                .matches = has_address_auth_cpucap,
        },
+       {
+               .desc = "Address authentication (architected QARMA3 algorithm)",
+               .capability = ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA3,
+               .type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
+               .sys_reg = SYS_ID_AA64ISAR2_EL1,
+               .sign = FTR_UNSIGNED,
+               .field_pos = ID_AA64ISAR2_APA3_SHIFT,
+               .field_width = 4,
+               .min_field_value = ID_AA64ISAR2_APA3_ARCHITECTED,
+               .matches = has_address_auth_cpucap,
+       },
        {
                .desc = "Address authentication (IMP DEF algorithm)",
                .capability = ARM64_HAS_ADDRESS_AUTH_IMP_DEF,
@@ -2246,6 +2297,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64ISAR1_API_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64ISAR1_API_IMP_DEF,
                .matches = has_address_auth_cpucap,
        },
@@ -2255,15 +2307,27 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_address_auth_metacap,
        },
        {
-               .desc = "Generic authentication (architected algorithm)",
-               .capability = ARM64_HAS_GENERIC_AUTH_ARCH,
+               .desc = "Generic authentication (architected QARMA5 algorithm)",
+               .capability = ARM64_HAS_GENERIC_AUTH_ARCH_QARMA5,
                .type = ARM64_CPUCAP_SYSTEM_FEATURE,
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64ISAR1_GPA_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED,
                .matches = has_cpuid_feature,
        },
+       {
+               .desc = "Generic authentication (architected QARMA3 algorithm)",
+               .capability = ARM64_HAS_GENERIC_AUTH_ARCH_QARMA3,
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .sys_reg = SYS_ID_AA64ISAR2_EL1,
+               .sign = FTR_UNSIGNED,
+               .field_pos = ID_AA64ISAR2_GPA3_SHIFT,
+               .field_width = 4,
+               .min_field_value = ID_AA64ISAR2_GPA3_ARCHITECTED,
+               .matches = has_cpuid_feature,
+       },
        {
                .desc = "Generic authentication (IMP DEF algorithm)",
                .capability = ARM64_HAS_GENERIC_AUTH_IMP_DEF,
@@ -2271,6 +2335,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64ISAR1_GPI_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64ISAR1_GPI_IMP_DEF,
                .matches = has_cpuid_feature,
        },
@@ -2291,6 +2356,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = can_use_gic_priorities,
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .field_pos = ID_AA64PFR0_GIC_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 1,
        },
@@ -2302,6 +2368,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .type = ARM64_CPUCAP_SYSTEM_FEATURE,
                .sys_reg = SYS_ID_AA64MMFR2_EL1,
                .sign = FTR_UNSIGNED,
+               .field_width = 4,
                .field_pos = ID_AA64MMFR2_E0PD_SHIFT,
                .matches = has_cpuid_feature,
                .min_field_value = 1,
@@ -2316,6 +2383,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64ISAR0_EL1,
                .field_pos = ID_AA64ISAR0_RNDR_SHIFT,
+               .field_width = 4,
                .sign = FTR_UNSIGNED,
                .min_field_value = 1,
        },
@@ -2333,6 +2401,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .cpu_enable = bti_enable,
                .sys_reg = SYS_ID_AA64PFR1_EL1,
                .field_pos = ID_AA64PFR1_BT_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR1_BT_BTI,
                .sign = FTR_UNSIGNED,
        },
@@ -2345,6 +2414,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64PFR1_EL1,
                .field_pos = ID_AA64PFR1_MTE_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR1_MTE,
                .sign = FTR_UNSIGNED,
                .cpu_enable = cpu_enable_mte,
@@ -2356,6 +2426,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
                .sys_reg = SYS_ID_AA64PFR1_EL1,
                .field_pos = ID_AA64PFR1_MTE_SHIFT,
+               .field_width = 4,
                .min_field_value = ID_AA64PFR1_MTE_ASYMM,
                .sign = FTR_UNSIGNED,
        },
@@ -2367,16 +2438,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .sys_reg = SYS_ID_AA64ISAR1_EL1,
                .sign = FTR_UNSIGNED,
                .field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
+               .field_width = 4,
                .matches = has_cpuid_feature,
                .min_field_value = 1,
        },
        {},
 };
 
-#define HWCAP_CPUID_MATCH(reg, field, s, min_value)                            \
+#define HWCAP_CPUID_MATCH(reg, field, width, s, min_value)                     \
                .matches = has_cpuid_feature,                                   \
                .sys_reg = reg,                                                 \
                .field_pos = field,                                             \
+               .field_width = width,                                           \
                .sign = s,                                                      \
                .min_field_value = min_value,
 
@@ -2386,10 +2459,10 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .hwcap_type = cap_type,                                         \
                .hwcap = cap,                                                   \
 
-#define HWCAP_CAP(reg, field, s, min_value, cap_type, cap)                     \
+#define HWCAP_CAP(reg, field, width, s, min_value, cap_type, cap)              \
        {                                                                       \
                __HWCAP_CAP(#cap, cap_type, cap)                                \
-               HWCAP_CPUID_MATCH(reg, field, s, min_value)                     \
+               HWCAP_CPUID_MATCH(reg, field, width, s, min_value)              \
        }
 
 #define HWCAP_MULTI_CAP(list, cap_type, cap)                                   \
@@ -2409,11 +2482,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
        {
                HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT,
-                                 FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED)
+                                 4, FTR_UNSIGNED,
+                                 ID_AA64ISAR1_APA_ARCHITECTED)
+       },
+       {
+               HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_APA3_SHIFT,
+                                 4, FTR_UNSIGNED, ID_AA64ISAR2_APA3_ARCHITECTED)
        },
        {
                HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT,
-                                 FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
+                                 4, FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
        },
        {},
 };
@@ -2421,77 +2499,82 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = {
        {
                HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT,
-                                 FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
+                                 4, FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
+       },
+       {
+               HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_GPA3_SHIFT,
+                                 4, FTR_UNSIGNED, ID_AA64ISAR2_GPA3_ARCHITECTED)
        },
        {
                HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT,
-                                 FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
+                                 4, FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
        },
        {},
 };
 #endif
 
 static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
-       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
-       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
-       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
-       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
-       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
-       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
-       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
-       HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
+       HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
-       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
-       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
+       HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
 #endif
-       HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
+       HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
 #ifdef CONFIG_ARM64_BTI
-       HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
+       HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
        HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA),
        HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG),
 #endif
 #ifdef CONFIG_ARM64_MTE
-       HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+       HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+       HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_MTE_ASYMM, CAP_HWCAP, KERNEL_HWCAP_MTE3),
 #endif /* CONFIG_ARM64_MTE */
-       HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
-       HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
-       HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+       HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
+       HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
+       HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
        {},
 };
 
@@ -2520,15 +2603,15 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope)
 static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = {
 #ifdef CONFIG_COMPAT
        HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON),
-       HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
+       HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
        /* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */
-       HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
-       HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
-       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
-       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
-       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
-       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
-       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
+       HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
+       HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
+       HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
 #endif
        {},
 };
index 591c18a889a56fee002fecce7f686c598bb92244..330b92ea863aad3e61e7559ebc8a37de215497b5 100644 (file)
@@ -97,6 +97,7 @@ static const char *const hwcap_str[] = {
        [KERNEL_HWCAP_ECV]              = "ecv",
        [KERNEL_HWCAP_AFP]              = "afp",
        [KERNEL_HWCAP_RPRES]            = "rpres",
+       [KERNEL_HWCAP_MTE3]             = "mte3",
 };
 
 #ifdef CONFIG_COMPAT
index 314391a156ee6a6b9f4e28413dd4e4c89cf866cf..2b65aae332ce9862f2f5ef0676587f5356f7aff5 100644 (file)
@@ -20,6 +20,12 @@ void arch_crash_save_vmcoreinfo(void)
 {
        VMCOREINFO_NUMBER(VA_BITS);
        /* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
+       vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR);
+       vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END);
+       vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START);
+       vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END);
+       vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START);
+       vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END);
        vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
                                                kimage_voffset);
        vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n",
diff --git a/arch/arm64/kernel/elfcore.c b/arch/arm64/kernel/elfcore.c
new file mode 100644 (file)
index 0000000..3ed39c6
--- /dev/null
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/coredump.h>
+#include <linux/elfcore.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/cpufeature.h>
+#include <asm/mte.h>
+
+#ifndef VMA_ITERATOR
+#define VMA_ITERATOR(name, mm, addr)   \
+       struct mm_struct *name = mm
+#define for_each_vma(vmi, vma)         \
+       for (vma = vmi->mmap; vma; vma = vma->vm_next)
+#endif
+
+#define for_each_mte_vma(vmi, vma)                                     \
+       if (system_supports_mte())                                      \
+               for_each_vma(vmi, vma)                                  \
+                       if (vma->vm_flags & VM_MTE)
+
+static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma)
+{
+       if (vma->vm_flags & VM_DONTDUMP)
+               return 0;
+
+       return vma_pages(vma) * MTE_PAGE_TAG_STORAGE;
+}
+
+/* Derived from dump_user_range(); start/end must be page-aligned */
+static int mte_dump_tag_range(struct coredump_params *cprm,
+                             unsigned long start, unsigned long end)
+{
+       unsigned long addr;
+
+       for (addr = start; addr < end; addr += PAGE_SIZE) {
+               char tags[MTE_PAGE_TAG_STORAGE];
+               struct page *page = get_dump_page(addr);
+
+               /*
+                * get_dump_page() returns NULL when encountering an empty
+                * page table entry that would otherwise have been filled with
+                * the zero page. Skip the equivalent tag dump which would
+                * have been all zeros.
+                */
+               if (!page) {
+                       dump_skip(cprm, MTE_PAGE_TAG_STORAGE);
+                       continue;
+               }
+
+               /*
+                * Pages mapped in user space as !pte_access_permitted() (e.g.
+                * PROT_EXEC only) may not have the PG_mte_tagged flag set.
+                */
+               if (!test_bit(PG_mte_tagged, &page->flags)) {
+                       put_page(page);
+                       dump_skip(cprm, MTE_PAGE_TAG_STORAGE);
+                       continue;
+               }
+
+               mte_save_page_tags(page_address(page), tags);
+               put_page(page);
+               if (!dump_emit(cprm, tags, MTE_PAGE_TAG_STORAGE))
+                       return 0;
+       }
+
+       return 1;
+}
+
+Elf_Half elf_core_extra_phdrs(void)
+{
+       struct vm_area_struct *vma;
+       int vma_count = 0;
+       VMA_ITERATOR(vmi, current->mm, 0);
+
+       for_each_mte_vma(vmi, vma)
+               vma_count++;
+
+       return vma_count;
+}
+
+int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
+{
+       struct vm_area_struct *vma;
+       VMA_ITERATOR(vmi, current->mm, 0);
+
+       for_each_mte_vma(vmi, vma) {
+               struct elf_phdr phdr;
+
+               phdr.p_type = PT_ARM_MEMTAG_MTE;
+               phdr.p_offset = offset;
+               phdr.p_vaddr = vma->vm_start;
+               phdr.p_paddr = 0;
+               phdr.p_filesz = mte_vma_tag_dump_size(vma);
+               phdr.p_memsz = vma->vm_end - vma->vm_start;
+               offset += phdr.p_filesz;
+               phdr.p_flags = 0;
+               phdr.p_align = 0;
+
+               if (!dump_emit(cprm, &phdr, sizeof(phdr)))
+                       return 0;
+       }
+
+       return 1;
+}
+
+size_t elf_core_extra_data_size(void)
+{
+       struct vm_area_struct *vma;
+       size_t data_size = 0;
+       VMA_ITERATOR(vmi, current->mm, 0);
+
+       for_each_mte_vma(vmi, vma)
+               data_size += mte_vma_tag_dump_size(vma);
+
+       return data_size;
+}
+
+int elf_core_write_extra_data(struct coredump_params *cprm)
+{
+       struct vm_area_struct *vma;
+       VMA_ITERATOR(vmi, current->mm, 0);
+
+       for_each_mte_vma(vmi, vma) {
+               if (vma->vm_flags & VM_DONTDUMP)
+                       continue;
+
+               if (!mte_dump_tag_range(cprm, vma->vm_start, vma->vm_end))
+                       return 0;
+       }
+
+       return 1;
+}
index ef7fcefb96bd1acfb178c72afee7d15727948c55..7093b578e32502acf38401d8d5c1e52a10e50e08 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/context_tracking.h>
+#include <linux/kasan.h>
 #include <linux/linkage.h>
 #include <linux/lockdep.h>
 #include <linux/ptrace.h>
@@ -56,6 +57,7 @@ static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
 {
        __enter_from_kernel_mode(regs);
        mte_check_tfsr_entry();
+       mte_disable_tco_entry(current);
 }
 
 /*
@@ -103,6 +105,7 @@ static __always_inline void __enter_from_user_mode(void)
        CT_WARN_ON(ct_state() != CONTEXT_USER);
        user_exit_irqoff();
        trace_hardirqs_off_finish();
+       mte_disable_tco_entry(current);
 }
 
 static __always_inline void enter_from_user_mode(struct pt_regs *regs)
index 772ec2ecf48884f24148772ab854497b5eada522..ede028dee81b09a0b07d91c99123605b3ebc3a0e 100644 (file)
 
        .macro kernel_ventry, el:req, ht:req, regsize:req, label:req
        .align 7
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+.Lventry_start\@:
        .if     \el == 0
-alternative_if ARM64_UNMAP_KERNEL_AT_EL0
+       /*
+        * This must be the first instruction of the EL0 vector entries. It is
+        * skipped by the trampoline vectors, to trigger the cleanup.
+        */
+       b       .Lskip_tramp_vectors_cleanup\@
        .if     \regsize == 64
        mrs     x30, tpidrro_el0
        msr     tpidrro_el0, xzr
        .else
        mov     x30, xzr
        .endif
-alternative_else_nop_endif
+.Lskip_tramp_vectors_cleanup\@:
        .endif
-#endif
 
        sub     sp, sp, #PT_REGS_SIZE
 #ifdef CONFIG_VMAP_STACK
@@ -95,11 +98,15 @@ alternative_else_nop_endif
        mrs     x0, tpidrro_el0
 #endif
        b       el\el\ht\()_\regsize\()_\label
+.org .Lventry_start\@ + 128    // Did we overflow the ventry slot?
        .endm
 
-       .macro tramp_alias, dst, sym
+       .macro tramp_alias, dst, sym, tmp
        mov_q   \dst, TRAMP_VALIAS
-       add     \dst, \dst, #(\sym - .entry.tramp.text)
+       adr_l   \tmp, \sym
+       add     \dst, \dst, \tmp
+       adr_l   \tmp, .entry.tramp.text
+       sub     \dst, \dst, \tmp
        .endm
 
        /*
@@ -116,7 +123,7 @@ alternative_cb_end
        tbnz    \tmp2, #TIF_SSBD, .L__asm_ssbd_skip\@
        mov     w0, #ARM_SMCCC_ARCH_WORKAROUND_2
        mov     w1, #\state
-alternative_cb spectre_v4_patch_fw_mitigation_conduit
+alternative_cb smccc_patch_fw_mitigation_conduit
        nop                                     // Patched to SMC/HVC #0
 alternative_cb_end
 .L__asm_ssbd_skip\@:
@@ -300,6 +307,7 @@ alternative_else_nop_endif
        str     w21, [sp, #S_SYSCALLNO]
        .endif
 
+#ifdef CONFIG_ARM64_PSEUDO_NMI
        /* Save pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
        mrs_s   x20, SYS_ICC_PMR_EL1
@@ -307,12 +315,6 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
        mov     x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
        msr_s   SYS_ICC_PMR_EL1, x20
 alternative_else_nop_endif
-
-       /* Re-enable tag checking (TCO set on exception entry) */
-#ifdef CONFIG_ARM64_MTE
-alternative_if ARM64_MTE
-       SET_PSTATE_TCO(0)
-alternative_else_nop_endif
 #endif
 
        /*
@@ -330,6 +332,7 @@ alternative_else_nop_endif
        disable_daif
        .endif
 
+#ifdef CONFIG_ARM64_PSEUDO_NMI
        /* Restore pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
        ldr     x20, [sp, #S_PMR_SAVE]
@@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
        dsb     sy                              // Ensure priority change is seen by redistributor
 .L__skip_pmr_sync\@:
 alternative_else_nop_endif
+#endif
 
        ldp     x21, x22, [sp, #S_PC]           // load ELR, SPSR
 
@@ -413,21 +417,26 @@ alternative_else_nop_endif
        ldp     x24, x25, [sp, #16 * 12]
        ldp     x26, x27, [sp, #16 * 13]
        ldp     x28, x29, [sp, #16 * 14]
-       ldr     lr, [sp, #S_LR]
-       add     sp, sp, #PT_REGS_SIZE           // restore sp
 
        .if     \el == 0
-alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
+alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
+       ldr     lr, [sp, #S_LR]
+       add     sp, sp, #PT_REGS_SIZE           // restore sp
+       eret
+alternative_else_nop_endif
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
        bne     4f
-       msr     far_el1, x30
-       tramp_alias     x30, tramp_exit_native
+       msr     far_el1, x29
+       tramp_alias     x30, tramp_exit_native, x29
        br      x30
 4:
-       tramp_alias     x30, tramp_exit_compat
+       tramp_alias     x30, tramp_exit_compat, x29
        br      x30
 #endif
        .else
+       ldr     lr, [sp, #S_LR]
+       add     sp, sp, #PT_REGS_SIZE           // restore sp
+
        /* Ensure any device/NC reads complete */
        alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412
 
@@ -594,12 +603,6 @@ SYM_CODE_END(ret_to_user)
 
        .popsection                             // .entry.text
 
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-/*
- * Exception vectors trampoline.
- */
-       .pushsection ".entry.tramp.text", "ax"
-
        // Move from tramp_pg_dir to swapper_pg_dir
        .macro tramp_map_kernel, tmp
        mrs     \tmp, ttbr1_el1
@@ -633,12 +636,47 @@ alternative_else_nop_endif
         */
        .endm
 
-       .macro tramp_ventry, regsize = 64
+       .macro tramp_data_page  dst
+       adr_l   \dst, .entry.tramp.text
+       sub     \dst, \dst, PAGE_SIZE
+       .endm
+
+       .macro tramp_data_read_var      dst, var
+#ifdef CONFIG_RANDOMIZE_BASE
+       tramp_data_page         \dst
+       add     \dst, \dst, #:lo12:__entry_tramp_data_\var
+       ldr     \dst, [\dst]
+#else
+       ldr     \dst, =\var
+#endif
+       .endm
+
+#define BHB_MITIGATION_NONE    0
+#define BHB_MITIGATION_LOOP    1
+#define BHB_MITIGATION_FW      2
+#define BHB_MITIGATION_INSN    3
+
+       .macro tramp_ventry, vector_start, regsize, kpti, bhb
        .align  7
 1:
        .if     \regsize == 64
        msr     tpidrro_el0, x30        // Restored in kernel_ventry
        .endif
+
+       .if     \bhb == BHB_MITIGATION_LOOP
+       /*
+        * This sequence must appear before the first indirect branch. i.e. the
+        * ret out of tramp_ventry. It appears here because x30 is free.
+        */
+       __mitigate_spectre_bhb_loop     x30
+       .endif // \bhb == BHB_MITIGATION_LOOP
+
+       .if     \bhb == BHB_MITIGATION_INSN
+       clearbhb
+       isb
+       .endif // \bhb == BHB_MITIGATION_INSN
+
+       .if     \kpti == 1
        /*
         * Defend against branch aliasing attacks by pushing a dummy
         * entry onto the return stack and using a RET instruction to
@@ -648,46 +686,75 @@ alternative_else_nop_endif
        b       .
 2:
        tramp_map_kernel        x30
-#ifdef CONFIG_RANDOMIZE_BASE
-       adr     x30, tramp_vectors + PAGE_SIZE
 alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
-       ldr     x30, [x30]
-#else
-       ldr     x30, =vectors
-#endif
+       tramp_data_read_var     x30, vectors
 alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM
-       prfm    plil1strm, [x30, #(1b - tramp_vectors)]
+       prfm    plil1strm, [x30, #(1b - \vector_start)]
 alternative_else_nop_endif
+
        msr     vbar_el1, x30
-       add     x30, x30, #(1b - tramp_vectors)
        isb
+       .else
+       ldr     x30, =vectors
+       .endif // \kpti == 1
+
+       .if     \bhb == BHB_MITIGATION_FW
+       /*
+        * The firmware sequence must appear before the first indirect branch.
+        * i.e. the ret out of tramp_ventry. But it also needs the stack to be
+        * mapped to save/restore the registers the SMC clobbers.
+        */
+       __mitigate_spectre_bhb_fw
+       .endif // \bhb == BHB_MITIGATION_FW
+
+       add     x30, x30, #(1b - \vector_start + 4)
        ret
+.org 1b + 128  // Did we overflow the ventry slot?
        .endm
 
        .macro tramp_exit, regsize = 64
-       adr     x30, tramp_vectors
+       tramp_data_read_var     x30, this_cpu_vector
+       get_this_cpu_offset x29
+       ldr     x30, [x30, x29]
+
        msr     vbar_el1, x30
-       tramp_unmap_kernel      x30
+       ldr     lr, [sp, #S_LR]
+       tramp_unmap_kernel      x29
        .if     \regsize == 64
-       mrs     x30, far_el1
+       mrs     x29, far_el1
        .endif
+       add     sp, sp, #PT_REGS_SIZE           // restore sp
        eret
        sb
        .endm
 
-       .align  11
-SYM_CODE_START_NOALIGN(tramp_vectors)
+       .macro  generate_tramp_vector,  kpti, bhb
+.Lvector_start\@:
        .space  0x400
 
-       tramp_ventry
-       tramp_ventry
-       tramp_ventry
-       tramp_ventry
+       .rept   4
+       tramp_ventry    .Lvector_start\@, 64, \kpti, \bhb
+       .endr
+       .rept   4
+       tramp_ventry    .Lvector_start\@, 32, \kpti, \bhb
+       .endr
+       .endm
 
-       tramp_ventry    32
-       tramp_ventry    32
-       tramp_ventry    32
-       tramp_ventry    32
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+/*
+ * Exception vectors trampoline.
+ * The order must match __bp_harden_el1_vectors and the
+ * arm64_bp_harden_el1_vectors enum.
+ */
+       .pushsection ".entry.tramp.text", "ax"
+       .align  11
+SYM_CODE_START_NOALIGN(tramp_vectors)
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+       generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_LOOP
+       generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_FW
+       generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_INSN
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+       generate_tramp_vector   kpti=1, bhb=BHB_MITIGATION_NONE
 SYM_CODE_END(tramp_vectors)
 
 SYM_CODE_START(tramp_exit_native)
@@ -704,12 +771,56 @@ SYM_CODE_END(tramp_exit_compat)
        .pushsection ".rodata", "a"
        .align PAGE_SHIFT
 SYM_DATA_START(__entry_tramp_data_start)
+__entry_tramp_data_vectors:
        .quad   vectors
+#ifdef CONFIG_ARM_SDE_INTERFACE
+__entry_tramp_data___sdei_asm_handler:
+       .quad   __sdei_asm_handler
+#endif /* CONFIG_ARM_SDE_INTERFACE */
+__entry_tramp_data_this_cpu_vector:
+       .quad   this_cpu_vector
 SYM_DATA_END(__entry_tramp_data_start)
        .popsection                             // .rodata
 #endif /* CONFIG_RANDOMIZE_BASE */
 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
 
+/*
+ * Exception vectors for spectre mitigations on entry from EL1 when
+ * kpti is not in use.
+ */
+       .macro generate_el1_vector, bhb
+.Lvector_start\@:
+       kernel_ventry   1, t, 64, sync          // Synchronous EL1t
+       kernel_ventry   1, t, 64, irq           // IRQ EL1t
+       kernel_ventry   1, t, 64, fiq           // FIQ EL1h
+       kernel_ventry   1, t, 64, error         // Error EL1t
+
+       kernel_ventry   1, h, 64, sync          // Synchronous EL1h
+       kernel_ventry   1, h, 64, irq           // IRQ EL1h
+       kernel_ventry   1, h, 64, fiq           // FIQ EL1h
+       kernel_ventry   1, h, 64, error         // Error EL1h
+
+       .rept   4
+       tramp_ventry    .Lvector_start\@, 64, 0, \bhb
+       .endr
+       .rept 4
+       tramp_ventry    .Lvector_start\@, 32, 0, \bhb
+       .endr
+       .endm
+
+/* The order must match tramp_vecs and the arm64_bp_harden_el1_vectors enum. */
+       .pushsection ".entry.text", "ax"
+       .align  11
+SYM_CODE_START(__bp_harden_el1_vectors)
+#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
+       generate_el1_vector     bhb=BHB_MITIGATION_LOOP
+       generate_el1_vector     bhb=BHB_MITIGATION_FW
+       generate_el1_vector     bhb=BHB_MITIGATION_INSN
+#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
+SYM_CODE_END(__bp_harden_el1_vectors)
+       .popsection
+
+
 /*
  * Register switch for AArch64. The callee-saved registers need to be saved
  * and restored. On entry:
@@ -835,14 +946,7 @@ SYM_CODE_START(__sdei_asm_entry_trampoline)
         * Remember whether to unmap the kernel on exit.
         */
 1:     str     x4, [x1, #(SDEI_EVENT_INTREGS + S_SDEI_TTBR1)]
-
-#ifdef CONFIG_RANDOMIZE_BASE
-       adr     x4, tramp_vectors + PAGE_SIZE
-       add     x4, x4, #:lo12:__sdei_asm_trampoline_next_handler
-       ldr     x4, [x4]
-#else
-       ldr     x4, =__sdei_asm_handler
-#endif
+       tramp_data_read_var     x4, __sdei_asm_handler
        br      x4
 SYM_CODE_END(__sdei_asm_entry_trampoline)
 NOKPROBE(__sdei_asm_entry_trampoline)
@@ -865,13 +969,6 @@ SYM_CODE_END(__sdei_asm_exit_trampoline)
 NOKPROBE(__sdei_asm_exit_trampoline)
        .ltorg
 .popsection            // .entry.tramp.text
-#ifdef CONFIG_RANDOMIZE_BASE
-.pushsection ".rodata", "a"
-SYM_DATA_START(__sdei_asm_trampoline_next_handler)
-       .quad   __sdei_asm_handler
-SYM_DATA_END(__sdei_asm_trampoline_next_handler)
-.popsection            // .rodata
-#endif /* CONFIG_RANDOMIZE_BASE */
 #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
 
 /*
@@ -981,7 +1078,7 @@ alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
 alternative_else_nop_endif
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-       tramp_alias     dst=x5, sym=__sdei_asm_exit_trampoline
+       tramp_alias     dst=x5, sym=__sdei_asm_exit_trampoline, tmp=x3
        br      x5
 #endif
 SYM_CODE_END(__sdei_asm_handler)
index d8e606fe3c21bcae2927a448214201cdc25b01d5..8a2ceb591686398f78ce4d3ff6331be820514bb8 100644 (file)
@@ -17,7 +17,7 @@
 #define FTR_DESC_NAME_LEN      20
 #define FTR_DESC_FIELD_LEN     10
 #define FTR_ALIAS_NAME_LEN     30
-#define FTR_ALIAS_OPTION_LEN   80
+#define FTR_ALIAS_OPTION_LEN   116
 
 struct ftr_set_desc {
        char                            name[FTR_DESC_NAME_LEN];
@@ -71,6 +71,16 @@ static const struct ftr_set_desc isar1 __initconst = {
        },
 };
 
+static const struct ftr_set_desc isar2 __initconst = {
+       .name           = "id_aa64isar2",
+       .override       = &id_aa64isar2_override,
+       .fields         = {
+               { "gpa3", ID_AA64ISAR2_GPA3_SHIFT },
+               { "apa3", ID_AA64ISAR2_APA3_SHIFT },
+               {}
+       },
+};
+
 extern struct arm64_ftr_override kaslr_feature_override;
 
 static const struct ftr_set_desc kaslr __initconst = {
@@ -88,6 +98,7 @@ static const struct ftr_set_desc * const regs[] __initconst = {
        &mmfr1,
        &pfr1,
        &isar1,
+       &isar2,
        &kaslr,
 };
 
@@ -100,7 +111,8 @@ static const struct {
        { "arm64.nobti",                "id_aa64pfr1.bt=0" },
        { "arm64.nopauth",
          "id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
-         "id_aa64isar1.api=0 id_aa64isar1.apa=0"          },
+         "id_aa64isar1.api=0 id_aa64isar1.apa=0 "
+         "id_aa64isar2.gpa3=0 id_aa64isar2.apa3=0"        },
        { "arm64.nomte",                "id_aa64pfr1.mte=0" },
        { "nokaslr",                    "kaslr.disabled=1" },
 };
index 7eaf1f7c4168dbd394f4b01e1000e5e3703a3bad..55a1ced8eb77d87c322e43946f38cc4016ef5d56 100644 (file)
@@ -66,6 +66,10 @@ KVM_NVHE_ALIAS(kvm_patch_vector_branch);
 KVM_NVHE_ALIAS(kvm_update_va_mask);
 KVM_NVHE_ALIAS(kvm_get_kimage_voffset);
 KVM_NVHE_ALIAS(kvm_compute_final_ctr_el0);
+KVM_NVHE_ALIAS(spectre_bhb_patch_loop_iter);
+KVM_NVHE_ALIAS(spectre_bhb_patch_loop_mitigation_enable);
+KVM_NVHE_ALIAS(spectre_bhb_patch_wa3);
+KVM_NVHE_ALIAS(spectre_bhb_patch_clearbhb);
 
 /* Global kernel state accessed by nVHE hyp code. */
 KVM_NVHE_ALIAS(kvm_vgic_global_state);
index f418ebc65f9509f079dff585c2ac714019fffbe9..78b3e0f8e997cab99b70bffe181949d8d29610dc 100644 (file)
@@ -186,6 +186,11 @@ void mte_check_tfsr_el1(void)
 }
 #endif
 
+/*
+ * This is where we actually resolve the system and process MTE mode
+ * configuration into an actual value in SCTLR_EL1 that affects
+ * userspace.
+ */
 static void mte_update_sctlr_user(struct task_struct *task)
 {
        /*
@@ -199,9 +204,20 @@ static void mte_update_sctlr_user(struct task_struct *task)
        unsigned long pref, resolved_mte_tcf;
 
        pref = __this_cpu_read(mte_tcf_preferred);
+       /*
+        * If there is no overlap between the system preferred and
+        * program requested values go with what was requested.
+        */
        resolved_mte_tcf = (mte_ctrl & pref) ? pref : mte_ctrl;
        sctlr &= ~SCTLR_EL1_TCF0_MASK;
-       if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
+       /*
+        * Pick an actual setting. The order in which we check for
+        * set bits and map into register values determines our
+        * default order.
+        */
+       if (resolved_mte_tcf & MTE_CTRL_TCF_ASYMM)
+               sctlr |= SCTLR_EL1_TCF0_ASYMM;
+       else if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
                sctlr |= SCTLR_EL1_TCF0_ASYNC;
        else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
                sctlr |= SCTLR_EL1_TCF0_SYNC;
@@ -253,6 +269,9 @@ void mte_thread_switch(struct task_struct *next)
        mte_update_sctlr_user(next);
        mte_update_gcr_excl(next);
 
+       /* TCO may not have been disabled on exception entry for the current task. */
+       mte_disable_tco_entry(next);
+
        /*
         * Check if an async tag exception occurred at EL1.
         *
@@ -293,6 +312,17 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
        if (arg & PR_MTE_TCF_SYNC)
                mte_ctrl |= MTE_CTRL_TCF_SYNC;
 
+       /*
+        * If the system supports it and both sync and async modes are
+        * specified then implicitly enable asymmetric mode.
+        * Userspace could see a mix of both sync and async anyway due
+        * to differing or changing defaults on CPUs.
+        */
+       if (cpus_have_cap(ARM64_MTE_ASYMM) &&
+           (arg & PR_MTE_TCF_ASYNC) &&
+           (arg & PR_MTE_TCF_SYNC))
+               mte_ctrl |= MTE_CTRL_TCF_ASYMM;
+
        task->thread.mte_ctrl = mte_ctrl;
        if (task == current) {
                preempt_disable();
@@ -467,6 +497,8 @@ static ssize_t mte_tcf_preferred_show(struct device *dev,
                return sysfs_emit(buf, "async\n");
        case MTE_CTRL_TCF_SYNC:
                return sysfs_emit(buf, "sync\n");
+       case MTE_CTRL_TCF_ASYMM:
+               return sysfs_emit(buf, "asymm\n");
        default:
                return sysfs_emit(buf, "???\n");
        }
@@ -482,6 +514,8 @@ static ssize_t mte_tcf_preferred_store(struct device *dev,
                tcf = MTE_CTRL_TCF_ASYNC;
        else if (sysfs_streq(buf, "sync"))
                tcf = MTE_CTRL_TCF_SYNC;
+       else if (cpus_have_cap(ARM64_MTE_ASYMM) && sysfs_streq(buf, "asymm"))
+               tcf = MTE_CTRL_TCF_ASYMM;
        else
                return -EINVAL;
 
index cab678ed661839a0392bce1777a05be8d967cb96..cb69ff1e61380b7f5371b6dde6436dd09f672c74 100644 (file)
@@ -242,6 +242,16 @@ static struct attribute *armv8_pmuv3_event_attrs[] = {
        ARMV8_EVENT_ATTR(l2d_cache_lmiss_rd, ARMV8_PMUV3_PERFCTR_L2D_CACHE_LMISS_RD),
        ARMV8_EVENT_ATTR(l2i_cache_lmiss, ARMV8_PMUV3_PERFCTR_L2I_CACHE_LMISS),
        ARMV8_EVENT_ATTR(l3d_cache_lmiss_rd, ARMV8_PMUV3_PERFCTR_L3D_CACHE_LMISS_RD),
+       ARMV8_EVENT_ATTR(trb_wrap, ARMV8_PMUV3_PERFCTR_TRB_WRAP),
+       ARMV8_EVENT_ATTR(trb_trig, ARMV8_PMUV3_PERFCTR_TRB_TRIG),
+       ARMV8_EVENT_ATTR(trcextout0, ARMV8_PMUV3_PERFCTR_TRCEXTOUT0),
+       ARMV8_EVENT_ATTR(trcextout1, ARMV8_PMUV3_PERFCTR_TRCEXTOUT1),
+       ARMV8_EVENT_ATTR(trcextout2, ARMV8_PMUV3_PERFCTR_TRCEXTOUT2),
+       ARMV8_EVENT_ATTR(trcextout3, ARMV8_PMUV3_PERFCTR_TRCEXTOUT3),
+       ARMV8_EVENT_ATTR(cti_trigout4, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT4),
+       ARMV8_EVENT_ATTR(cti_trigout5, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT5),
+       ARMV8_EVENT_ATTR(cti_trigout6, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT6),
+       ARMV8_EVENT_ATTR(cti_trigout7, ARMV8_PMUV3_PERFCTR_CTI_TRIGOUT7),
        ARMV8_EVENT_ATTR(ldst_align_lat, ARMV8_PMUV3_PERFCTR_LDST_ALIGN_LAT),
        ARMV8_EVENT_ATTR(ld_align_lat, ARMV8_PMUV3_PERFCTR_LD_ALIGN_LAT),
        ARMV8_EVENT_ATTR(st_align_lat, ARMV8_PMUV3_PERFCTR_ST_ALIGN_LAT),
index 5369e649fa79ff8e547d18ee3e74c236161f60e6..7fa97df55e3ad3f24443cf6ec49318d1e64f8e53 100644 (file)
@@ -635,7 +635,8 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
                return -EINVAL;
 
        if (system_supports_mte())
-               valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK;
+               valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \
+                       | PR_MTE_TAG_MASK;
 
        if (arg & ~valid_mask)
                return -EINVAL;
index 902e4084c4775251fa77a4aecdb6617969b31784..5777929d35bf47664ec9f8efd6598fb9bb17cf7e 100644 (file)
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/bpf.h>
 #include <linux/cpu.h>
 #include <linux/device.h>
 #include <linux/nospec.h>
 #include <linux/prctl.h>
 #include <linux/sched/task_stack.h>
 
+#include <asm/debug-monitors.h>
 #include <asm/insn.h>
 #include <asm/spectre.h>
 #include <asm/traps.h>
+#include <asm/vectors.h>
 #include <asm/virt.h>
 
 /*
@@ -96,14 +99,51 @@ static bool spectre_v2_mitigations_off(void)
        return ret;
 }
 
+static const char *get_bhb_affected_string(enum mitigation_state bhb_state)
+{
+       switch (bhb_state) {
+       case SPECTRE_UNAFFECTED:
+               return "";
+       default:
+       case SPECTRE_VULNERABLE:
+               return ", but not BHB";
+       case SPECTRE_MITIGATED:
+               return ", BHB";
+       }
+}
+
+static bool _unprivileged_ebpf_enabled(void)
+{
+#ifdef CONFIG_BPF_SYSCALL
+       return !sysctl_unprivileged_bpf_disabled;
+#else
+       return false;
+#endif
+}
+
 ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
                            char *buf)
 {
+       enum mitigation_state bhb_state = arm64_get_spectre_bhb_state();
+       const char *bhb_str = get_bhb_affected_string(bhb_state);
+       const char *v2_str = "Branch predictor hardening";
+
        switch (spectre_v2_state) {
        case SPECTRE_UNAFFECTED:
-               return sprintf(buf, "Not affected\n");
+               if (bhb_state == SPECTRE_UNAFFECTED)
+                       return sprintf(buf, "Not affected\n");
+
+               /*
+                * Platforms affected by Spectre-BHB can't report
+                * "Not affected" for Spectre-v2.
+                */
+               v2_str = "CSV2";
+               fallthrough;
        case SPECTRE_MITIGATED:
-               return sprintf(buf, "Mitigation: Branch predictor hardening\n");
+               if (bhb_state == SPECTRE_MITIGATED && _unprivileged_ebpf_enabled())
+                       return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
+
+               return sprintf(buf, "Mitigation: %s%s\n", v2_str, bhb_str);
        case SPECTRE_VULNERABLE:
                fallthrough;
        default:
@@ -193,17 +233,20 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn)
        __this_cpu_write(bp_hardening_data.slot, HYP_VECTOR_SPECTRE_DIRECT);
 }
 
-static void call_smc_arch_workaround_1(void)
+/* Called during entry so must be noinstr */
+static noinstr void call_smc_arch_workaround_1(void)
 {
        arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
 }
 
-static void call_hvc_arch_workaround_1(void)
+/* Called during entry so must be noinstr */
+static noinstr void call_hvc_arch_workaround_1(void)
 {
        arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
 }
 
-static void qcom_link_stack_sanitisation(void)
+/* Called during entry so must be noinstr */
+static noinstr void qcom_link_stack_sanitisation(void)
 {
        u64 tmp;
 
@@ -554,9 +597,9 @@ void __init spectre_v4_patch_fw_mitigation_enable(struct alt_instr *alt,
  * Patch a NOP in the Spectre-v4 mitigation code with an SMC/HVC instruction
  * to call into firmware to adjust the mitigation state.
  */
-void __init spectre_v4_patch_fw_mitigation_conduit(struct alt_instr *alt,
-                                                  __le32 *origptr,
-                                                  __le32 *updptr, int nr_inst)
+void __init smccc_patch_fw_mitigation_conduit(struct alt_instr *alt,
+                                              __le32 *origptr,
+                                              __le32 *updptr, int nr_inst)
 {
        u32 insn;
 
@@ -770,3 +813,344 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
                return -ENODEV;
        }
 }
+
+/*
+ * Spectre BHB.
+ *
+ * A CPU is either:
+ * - Mitigated by a branchy loop a CPU specific number of times, and listed
+ *   in our "loop mitigated list".
+ * - Mitigated in software by the firmware Spectre v2 call.
+ * - Has the ClearBHB instruction to perform the mitigation.
+ * - Has the 'Exception Clears Branch History Buffer' (ECBHB) feature, so no
+ *   software mitigation in the vectors is needed.
+ * - Has CSV2.3, so is unaffected.
+ */
+static enum mitigation_state spectre_bhb_state;
+
+enum mitigation_state arm64_get_spectre_bhb_state(void)
+{
+       return spectre_bhb_state;
+}
+
+enum bhb_mitigation_bits {
+       BHB_LOOP,
+       BHB_FW,
+       BHB_HW,
+       BHB_INSN,
+};
+static unsigned long system_bhb_mitigations;
+
+/*
+ * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
+ * SCOPE_SYSTEM call will give the right answer.
+ */
+u8 spectre_bhb_loop_affected(int scope)
+{
+       u8 k = 0;
+       static u8 max_bhb_k;
+
+       if (scope == SCOPE_LOCAL_CPU) {
+               static const struct midr_range spectre_bhb_k32_list[] = {
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+                       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+                       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+                       {},
+               };
+               static const struct midr_range spectre_bhb_k24_list[] = {
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+                       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+                       {},
+               };
+               static const struct midr_range spectre_bhb_k8_list[] = {
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+                       MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
+                       {},
+               };
+
+               if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+                       k = 32;
+               else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+                       k = 24;
+               else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+                       k =  8;
+
+               max_bhb_k = max(max_bhb_k, k);
+       } else {
+               k = max_bhb_k;
+       }
+
+       return k;
+}
+
+static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void)
+{
+       int ret;
+       struct arm_smccc_res res;
+
+       arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+                            ARM_SMCCC_ARCH_WORKAROUND_3, &res);
+
+       ret = res.a0;
+       switch (ret) {
+       case SMCCC_RET_SUCCESS:
+               return SPECTRE_MITIGATED;
+       case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
+               return SPECTRE_UNAFFECTED;
+       default:
+               fallthrough;
+       case SMCCC_RET_NOT_SUPPORTED:
+               return SPECTRE_VULNERABLE;
+       }
+}
+
+static bool is_spectre_bhb_fw_affected(int scope)
+{
+       static bool system_affected;
+       enum mitigation_state fw_state;
+       bool has_smccc = arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_NONE;
+       static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
+               MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
+               MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
+               {},
+       };
+       bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
+                                        spectre_bhb_firmware_mitigated_list);
+
+       if (scope != SCOPE_LOCAL_CPU)
+               return system_affected;
+
+       fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
+       if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
+               system_affected = true;
+               return true;
+       }
+
+       return false;
+}
+
+static bool supports_ecbhb(int scope)
+{
+       u64 mmfr1;
+
+       if (scope == SCOPE_LOCAL_CPU)
+               mmfr1 = read_sysreg_s(SYS_ID_AA64MMFR1_EL1);
+       else
+               mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+
+       return cpuid_feature_extract_unsigned_field(mmfr1,
+                                                   ID_AA64MMFR1_ECBHB_SHIFT);
+}
+
+bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
+                            int scope)
+{
+       WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+
+       if (supports_csv2p3(scope))
+               return false;
+
+       if (supports_clearbhb(scope))
+               return true;
+
+       if (spectre_bhb_loop_affected(scope))
+               return true;
+
+       if (is_spectre_bhb_fw_affected(scope))
+               return true;
+
+       return false;
+}
+
+static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
+{
+       const char *v = arm64_get_bp_hardening_vector(slot);
+
+       if (slot < 0)
+               return;
+
+       __this_cpu_write(this_cpu_vector, v);
+
+       /*
+        * When KPTI is in use, the vectors are switched when exiting to
+        * user-space.
+        */
+       if (arm64_kernel_unmapped_at_el0())
+               return;
+
+       write_sysreg(v, vbar_el1);
+       isb();
+}
+
+void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
+{
+       bp_hardening_cb_t cpu_cb;
+       enum mitigation_state fw_state, state = SPECTRE_VULNERABLE;
+       struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data);
+
+       if (!is_spectre_bhb_affected(entry, SCOPE_LOCAL_CPU))
+               return;
+
+       if (arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) {
+               /* No point mitigating Spectre-BHB alone. */
+       } else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) {
+               pr_info_once("spectre-bhb mitigation disabled by compile time option\n");
+       } else if (cpu_mitigations_off()) {
+               pr_info_once("spectre-bhb mitigation disabled by command line option\n");
+       } else if (supports_ecbhb(SCOPE_LOCAL_CPU)) {
+               state = SPECTRE_MITIGATED;
+               set_bit(BHB_HW, &system_bhb_mitigations);
+       } else if (supports_clearbhb(SCOPE_LOCAL_CPU)) {
+               /*
+                * Ensure KVM uses the indirect vector which will have ClearBHB
+                * added.
+                */
+               if (!data->slot)
+                       data->slot = HYP_VECTOR_INDIRECT;
+
+               this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN);
+               state = SPECTRE_MITIGATED;
+               set_bit(BHB_INSN, &system_bhb_mitigations);
+       } else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) {
+               /*
+                * Ensure KVM uses the indirect vector which will have the
+                * branchy-loop added. A57/A72-r0 will already have selected
+                * the spectre-indirect vector, which is sufficient for BHB
+                * too.
+                */
+               if (!data->slot)
+                       data->slot = HYP_VECTOR_INDIRECT;
+
+               this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP);
+               state = SPECTRE_MITIGATED;
+               set_bit(BHB_LOOP, &system_bhb_mitigations);
+       } else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) {
+               fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
+               if (fw_state == SPECTRE_MITIGATED) {
+                       /*
+                        * Ensure KVM uses one of the spectre bp_hardening
+                        * vectors. The indirect vector doesn't include the EL3
+                        * call, so needs upgrading to
+                        * HYP_VECTOR_SPECTRE_INDIRECT.
+                        */
+                       if (!data->slot || data->slot == HYP_VECTOR_INDIRECT)
+                               data->slot += 1;
+
+                       this_cpu_set_vectors(EL1_VECTOR_BHB_FW);
+
+                       /*
+                        * The WA3 call in the vectors supersedes the WA1 call
+                        * made during context-switch. Uninstall any firmware
+                        * bp_hardening callback.
+                        */
+                       cpu_cb = spectre_v2_get_sw_mitigation_cb();
+                       if (__this_cpu_read(bp_hardening_data.fn) != cpu_cb)
+                               __this_cpu_write(bp_hardening_data.fn, NULL);
+
+                       state = SPECTRE_MITIGATED;
+                       set_bit(BHB_FW, &system_bhb_mitigations);
+               }
+       }
+
+       update_mitigation_state(&spectre_bhb_state, state);
+}
+
+/* Patched to NOP when enabled */
+void noinstr spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt,
+                                                    __le32 *origptr,
+                                                     __le32 *updptr, int nr_inst)
+{
+       BUG_ON(nr_inst != 1);
+
+       if (test_bit(BHB_LOOP, &system_bhb_mitigations))
+               *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
+/* Patched to NOP when enabled */
+void noinstr spectre_bhb_patch_fw_mitigation_enabled(struct alt_instr *alt,
+                                                  __le32 *origptr,
+                                                  __le32 *updptr, int nr_inst)
+{
+       BUG_ON(nr_inst != 1);
+
+       if (test_bit(BHB_FW, &system_bhb_mitigations))
+               *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
+/* Patched to correct the immediate */
+void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt,
+                                  __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+       u8 rd;
+       u32 insn;
+       u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM);
+
+       BUG_ON(nr_inst != 1); /* MOV -> MOV */
+
+       if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY))
+               return;
+
+       insn = le32_to_cpu(*origptr);
+       rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
+       insn = aarch64_insn_gen_movewide(rd, loop_count, 0,
+                                        AARCH64_INSN_VARIANT_64BIT,
+                                        AARCH64_INSN_MOVEWIDE_ZERO);
+       *updptr++ = cpu_to_le32(insn);
+}
+
+/* Patched to mov WA3 when supported */
+void noinstr spectre_bhb_patch_wa3(struct alt_instr *alt,
+                                  __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+       u8 rd;
+       u32 insn;
+
+       BUG_ON(nr_inst != 1); /* MOV -> MOV */
+
+       if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY) ||
+           !test_bit(BHB_FW, &system_bhb_mitigations))
+               return;
+
+       insn = le32_to_cpu(*origptr);
+       rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
+
+       insn = aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_ORR,
+                                                 AARCH64_INSN_VARIANT_32BIT,
+                                                 AARCH64_INSN_REG_ZR, rd,
+                                                 ARM_SMCCC_ARCH_WORKAROUND_3);
+       if (WARN_ON_ONCE(insn == AARCH64_BREAK_FAULT))
+               return;
+
+       *updptr++ = cpu_to_le32(insn);
+}
+
+/* Patched to NOP when not supported */
+void __init spectre_bhb_patch_clearbhb(struct alt_instr *alt,
+                                  __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+       BUG_ON(nr_inst != 2);
+
+       if (test_bit(BHB_INSN, &system_bhb_mitigations))
+               return;
+
+       *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+       *updptr++ = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
+#ifdef CONFIG_BPF_SYSCALL
+#define EBPF_WARN "Unprivileged eBPF is enabled, data leaks possible via Spectre v2 BHB attacks!\n"
+void unpriv_ebpf_notify(int new_state)
+{
+       if (spectre_v2_state == SPECTRE_VULNERABLE ||
+           spectre_bhb_state != SPECTRE_MITIGATED)
+               return;
+
+       if (!new_state)
+               pr_err("WARNING: %s", EBPF_WARN);
+}
+#endif
index d8aaf4b6f432080d226c9c1185bafe08b5da6ae0..50fe8eaf7df000a9eabb01d7f0a1e5f363b9b35b 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
-#include <linux/personality.h>
 #include <linux/freezer.h>
 #include <linux/stddef.h>
 #include <linux/uaccess.h>
@@ -577,10 +576,12 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 {
        int err;
 
-       err = sigframe_alloc(user, &user->fpsimd_offset,
-                            sizeof(struct fpsimd_context));
-       if (err)
-               return err;
+       if (system_supports_fpsimd()) {
+               err = sigframe_alloc(user, &user->fpsimd_offset,
+                                    sizeof(struct fpsimd_context));
+               if (err)
+                       return err;
+       }
 
        /* fault information, if valid */
        if (add_all || current->thread.fault_code) {
index db5159a3055fc3d9863210db32a75e8b95e845ca..12c6864e51e13b1da5930d2482f51b78075cd605 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/compat.h>
 #include <linux/cpufeature.h>
-#include <linux/personality.h>
 #include <linux/sched.h>
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
index 70fc42470f1383f337fd7a497ac5e8e838a1e31e..bb878f52ca0ae515617b5ebeaac8c26b0b8d55ab 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/bug.h>
 #include <linux/context_tracking.h>
 #include <linux/signal.h>
-#include <linux/personality.h>
 #include <linux/kallsyms.h>
 #include <linux/kprobes.h>
 #include <linux/spinlock.h>
index 50bab186c49b5133a28c06bf1d270039d5e2c75b..edaf0faf766f0023e99ee8c11f1b5b9ac9742fed 100644 (file)
@@ -341,7 +341,7 @@ ASSERT(__hibernate_exit_text_end - (__hibernate_exit_text_start & ~(SZ_4K - 1))
        <= SZ_4K, "Hibernate exit text too big or misaligned")
 #endif
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE,
+ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE,
        "Entry trampoline text too big")
 #endif
 #ifdef CONFIG_KVM
index ecc5958e27fe2b3fc69b9b1121a626495cb13c46..946e401ef6b014c99530e312bff35f72ee2d6661 100644 (file)
@@ -1491,10 +1491,7 @@ static int kvm_init_vector_slots(void)
        base = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs));
        kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_DIRECT);
 
-       if (!cpus_have_const_cap(ARM64_SPECTRE_V3A))
-               return 0;
-
-       if (!has_vhe()) {
+       if (kvm_system_needs_idmapped_vectors() && !has_vhe()) {
                err = create_hyp_exec_mappings(__pa_symbol(__bp_harden_hyp_vecs),
                                               __BP_HARDEN_HYP_VECS_SZ, &base);
                if (err)
@@ -1870,6 +1867,7 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
        kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
        kvm_nvhe_sym(id_aa64isar0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1);
        kvm_nvhe_sym(id_aa64isar1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);
+       kvm_nvhe_sym(id_aa64isar2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
        kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
        kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
        kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
index b6b6801d96d5a9d48b7636c04976b2e4569d71dd..7839d075729b1601f28fad70443f405e98ea9498 100644 (file)
@@ -62,6 +62,10 @@ el1_sync:                            // Guest trapped into EL2
        /* ARM_SMCCC_ARCH_WORKAROUND_2 handling */
        eor     w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \
                          ARM_SMCCC_ARCH_WORKAROUND_2)
+       cbz     w1, wa_epilogue
+
+       eor     w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_2 ^ \
+                         ARM_SMCCC_ARCH_WORKAROUND_3)
        cbnz    w1, el1_trap
 
 wa_epilogue:
@@ -192,7 +196,10 @@ SYM_CODE_END(__kvm_hyp_vector)
        sub     sp, sp, #(8 * 4)
        stp     x2, x3, [sp, #(8 * 0)]
        stp     x0, x1, [sp, #(8 * 2)]
+       alternative_cb spectre_bhb_patch_wa3
+       /* Patched to mov WA3 when supported */
        mov     w0, #ARM_SMCCC_ARCH_WORKAROUND_1
+       alternative_cb_end
        smc     #0
        ldp     x2, x3, [sp, #(8 * 0)]
        add     sp, sp, #(8 * 2)
@@ -205,6 +212,8 @@ SYM_CODE_END(__kvm_hyp_vector)
        spectrev2_smccc_wa1_smc
        .else
        stp     x0, x1, [sp, #-16]!
+       mitigate_spectre_bhb_loop       x0
+       mitigate_spectre_bhb_clear_insn
        .endif
        .if \indirect != 0
        alternative_cb  kvm_patch_vector_branch
index 701cfb964905df6384168380505408b0fc4be0a1..6379a1e3e6e51a376fe7a9a3171443f2be303bf6 100644 (file)
@@ -174,9 +174,9 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 
        /* Valid trap.  Switch the context: */
        if (has_vhe()) {
-               reg = CPACR_EL1_FPEN;
+               reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN;
                if (sve_guest)
-                       reg |= CPACR_EL1_ZEN;
+                       reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
 
                sysreg_clear_set(cpacr_el1, 0, reg);
        } else {
index eea1f6a53723038b015454513dc7d22261ae97e0..5ad626527d4119d011fb1001d3e10a192f65be63 100644 (file)
        ARM64_FEATURE_MASK(ID_AA64ISAR1_I8MM) \
        )
 
+#define PVM_ID_AA64ISAR2_ALLOW (\
+       ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3) | \
+       ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) \
+       )
+
 u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
 bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
 bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
index 958734f4d6b0ed820ee7fc006d2fd38d2cf0a105..0c367eb5f4e28dce0dcd0986c10413b5361f5faf 100644 (file)
@@ -7,7 +7,8 @@
 #include <asm/assembler.h>
 #include <asm/alternative.h>
 
-SYM_FUNC_START_PI(dcache_clean_inval_poc)
+SYM_FUNC_START(__pi_dcache_clean_inval_poc)
        dcache_by_line_op civac, sy, x0, x1, x2, x3
        ret
-SYM_FUNC_END_PI(dcache_clean_inval_poc)
+SYM_FUNC_END(__pi_dcache_clean_inval_poc)
+SYM_FUNC_ALIAS(dcache_clean_inval_poc, __pi_dcache_clean_inval_poc)
index 526a7d6fa86fbb70cd2ce5a1707fbf7a8791bf4a..cdbe8e24641838401820027b0d8e521cf216d9d8 100644 (file)
@@ -148,8 +148,10 @@ int hyp_map_vectors(void)
        phys_addr_t phys;
        void *bp_base;
 
-       if (!cpus_have_const_cap(ARM64_SPECTRE_V3A))
+       if (!kvm_system_needs_idmapped_vectors()) {
+               __hyp_bp_vect_base = __bp_harden_hyp_vecs;
                return 0;
+       }
 
        phys = __hyp_pa(__bp_harden_hyp_vecs);
        bp_base = (void *)__pkvm_create_private_mapping(phys,
index 792cf6e6ac9205ca0558c279f7c2aba5717a9700..33f5181af330d07dcd12e08ed7907aa640b8a12a 100644 (file)
@@ -22,6 +22,7 @@ u64 id_aa64pfr0_el1_sys_val;
 u64 id_aa64pfr1_el1_sys_val;
 u64 id_aa64isar0_el1_sys_val;
 u64 id_aa64isar1_el1_sys_val;
+u64 id_aa64isar2_el1_sys_val;
 u64 id_aa64mmfr0_el1_sys_val;
 u64 id_aa64mmfr1_el1_sys_val;
 u64 id_aa64mmfr2_el1_sys_val;
@@ -183,6 +184,17 @@ static u64 get_pvm_id_aa64isar1(const struct kvm_vcpu *vcpu)
        return id_aa64isar1_el1_sys_val & allow_mask;
 }
 
+static u64 get_pvm_id_aa64isar2(const struct kvm_vcpu *vcpu)
+{
+       u64 allow_mask = PVM_ID_AA64ISAR2_ALLOW;
+
+       if (!vcpu_has_ptrauth(vcpu))
+               allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) |
+                               ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3));
+
+       return id_aa64isar2_el1_sys_val & allow_mask;
+}
+
 static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
 {
        u64 set_mask;
@@ -225,6 +237,8 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
                return get_pvm_id_aa64isar0(vcpu);
        case SYS_ID_AA64ISAR1_EL1:
                return get_pvm_id_aa64isar1(vcpu);
+       case SYS_ID_AA64ISAR2_EL1:
+               return get_pvm_id_aa64isar2(vcpu);
        case SYS_ID_AA64MMFR0_EL1:
                return get_pvm_id_aa64mmfr0(vcpu);
        case SYS_ID_AA64MMFR1_EL1:
index 11d053fdd604b9dcbf0f91f2db53313f658513e5..262dfe03134daba2f7c9669b115ae792cd5b15e1 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kvm_host.h>
 #include <linux/types.h>
 #include <linux/jump_label.h>
+#include <linux/percpu.h>
 #include <uapi/linux/psci.h>
 
 #include <kvm/arm_psci.h>
@@ -24,6 +25,8 @@
 #include <asm/fpsimd.h>
 #include <asm/debug-monitors.h>
 #include <asm/processor.h>
+#include <asm/thread_info.h>
+#include <asm/vectors.h>
 
 /* VHE specific context */
 DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
@@ -38,7 +41,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
        val = read_sysreg(cpacr_el1);
        val |= CPACR_EL1_TTA;
-       val &= ~CPACR_EL1_ZEN;
+       val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN);
 
        /*
         * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
@@ -53,9 +56,9 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
        if (update_fp_enabled(vcpu)) {
                if (vcpu_has_sve(vcpu))
-                       val |= CPACR_EL1_ZEN;
+                       val |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
        } else {
-               val &= ~CPACR_EL1_FPEN;
+               val &= ~(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN);
                __activate_traps_fpsimd32(vcpu);
        }
 
@@ -67,7 +70,7 @@ NOKPROBE_SYMBOL(__activate_traps);
 
 static void __deactivate_traps(struct kvm_vcpu *vcpu)
 {
-       extern char vectors[];  /* kernel exception vectors */
+       const char *host_vectors = vectors;
 
        ___deactivate_traps(vcpu);
 
@@ -81,7 +84,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
        asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 
        write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
-       write_sysreg(vectors, vbar_el1);
+
+       if (!arm64_kernel_unmapped_at_el0())
+               host_vectors = __this_cpu_read(this_cpu_vector);
+       write_sysreg(host_vectors, vbar_el1);
 }
 NOKPROBE_SYMBOL(__deactivate_traps);
 
index 30da78f72b3b38f6abb427d9b2581b552bfd6f2c..202b8c455724bb0090b9d0f68e683bec0d696bfe 100644 (file)
@@ -107,6 +107,18 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
                                break;
                        }
                        break;
+               case ARM_SMCCC_ARCH_WORKAROUND_3:
+                       switch (arm64_get_spectre_bhb_state()) {
+                       case SPECTRE_VULNERABLE:
+                               break;
+                       case SPECTRE_MITIGATED:
+                               val[0] = SMCCC_RET_SUCCESS;
+                               break;
+                       case SPECTRE_UNAFFECTED:
+                               val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED;
+                               break;
+                       }
+                       break;
                case ARM_SMCCC_HV_PV_TIME_FEATURES:
                        val[0] = SMCCC_RET_SUCCESS;
                        break;
index 3eae32876897cd5a349eaceee93f5caac3b6b7ec..5918095c90a566dfc9881f6781a2e016bd2b1598 100644 (file)
@@ -46,8 +46,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
         * specification (ARM DEN 0022A). This means all suspend states
         * for KVM will preserve the register state.
         */
-       kvm_vcpu_halt(vcpu);
-       kvm_clear_request(KVM_REQ_UNHALT, vcpu);
+       kvm_vcpu_wfi(vcpu);
 
        return PSCI_RET_SUCCESS;
 }
@@ -406,7 +405,7 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)
 
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
 {
-       return 3;               /* PSCI version and two workaround registers */
+       return 4;               /* PSCI version and three workaround registers */
 }
 
 int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
@@ -420,6 +419,9 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
        if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))
                return -EFAULT;
 
+       if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, uindices++))
+               return -EFAULT;
+
        return 0;
 }
 
@@ -459,6 +461,17 @@ static int get_kernel_wa_level(u64 regid)
                case SPECTRE_VULNERABLE:
                        return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
                }
+               break;
+       case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
+               switch (arm64_get_spectre_bhb_state()) {
+               case SPECTRE_VULNERABLE:
+                       return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
+               case SPECTRE_MITIGATED:
+                       return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL;
+               case SPECTRE_UNAFFECTED:
+                       return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED;
+               }
+               return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
        }
 
        return -EINVAL;
@@ -475,6 +488,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
                break;
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
+       case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
                val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
                break;
        default:
@@ -520,6 +534,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        }
 
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
+       case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
                if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
                        return -EINVAL;
 
index 4dc2fba316fffa1298e4af3af9ce5a40c9fbf53e..baa65292bbc2ab57b38e74474d628c7ad3ef93f4 100644 (file)
@@ -1097,6 +1097,11 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
                                 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) |
                                 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI));
                break;
+       case SYS_ID_AA64ISAR2_EL1:
+               if (!vcpu_has_ptrauth(vcpu))
+                       val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) |
+                                ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3));
+               break;
        case SYS_ID_AA64DFR0_EL1:
                /* Limit debug to ARMv8.0 */
                val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER);
index 1fd5d790ab800321786324dbc4ea8804920e07f1..ebde40e7fa2b2f3a6f7b2e604f3c0b9bb572457c 100644 (file)
@@ -14,7 +14,7 @@
  * Parameters:
  *     x0 - dest
  */
-SYM_FUNC_START_PI(clear_page)
+SYM_FUNC_START(__pi_clear_page)
        mrs     x1, dczid_el0
        tbnz    x1, #4, 2f      /* Branch if DC ZVA is prohibited */
        and     w1, w1, #0xf
@@ -35,5 +35,6 @@ SYM_FUNC_START_PI(clear_page)
        tst     x0, #(PAGE_SIZE - 1)
        b.ne    2b
        ret
-SYM_FUNC_END_PI(clear_page)
+SYM_FUNC_END(__pi_clear_page)
+SYM_FUNC_ALIAS(clear_page, __pi_clear_page)
 EXPORT_SYMBOL(clear_page)
index 29144f4cd4492741729f7189f17e8edb86f7e39f..c336d2ffdec55975d8beb31fe36c2b815cfa764e 100644 (file)
@@ -17,7 +17,7 @@
  *     x0 - dest
  *     x1 - src
  */
-SYM_FUNC_START_PI(copy_page)
+SYM_FUNC_START(__pi_copy_page)
 alternative_if ARM64_HAS_NO_HW_PREFETCH
        // Prefetch three cache lines ahead.
        prfm    pldl1strm, [x1, #128]
@@ -75,5 +75,6 @@ alternative_else_nop_endif
        stnp    x16, x17, [x0, #112 - 256]
 
        ret
-SYM_FUNC_END_PI(copy_page)
+SYM_FUNC_END(__pi_copy_page)
+SYM_FUNC_ALIAS(copy_page, __pi_copy_page)
 EXPORT_SYMBOL(copy_page)
index fccfe363e56791eda4433883a595d0d44ee26d22..5e90887deec4a16e4592265c60721d8f46ac8841 100644 (file)
@@ -578,10 +578,16 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
 
        switch (type) {
        case AARCH64_INSN_LDST_LOAD_EX:
+       case AARCH64_INSN_LDST_LOAD_ACQ_EX:
                insn = aarch64_insn_get_load_ex_value();
+               if (type == AARCH64_INSN_LDST_LOAD_ACQ_EX)
+                       insn |= BIT(15);
                break;
        case AARCH64_INSN_LDST_STORE_EX:
+       case AARCH64_INSN_LDST_STORE_REL_EX:
                insn = aarch64_insn_get_store_ex_value();
+               if (type == AARCH64_INSN_LDST_STORE_REL_EX)
+                       insn |= BIT(15);
                break;
        default:
                pr_err("%s: unknown load/store exclusive encoding %d\n", __func__, type);
@@ -603,12 +609,65 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
                                            state);
 }
 
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
-                          enum aarch64_insn_register address,
-                          enum aarch64_insn_register value,
-                          enum aarch64_insn_size_type size)
+#ifdef CONFIG_ARM64_LSE_ATOMICS
+static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
+                                         u32 insn)
 {
-       u32 insn = aarch64_insn_get_ldadd_value();
+       u32 order;
+
+       switch (type) {
+       case AARCH64_INSN_MEM_ORDER_NONE:
+               order = 0;
+               break;
+       case AARCH64_INSN_MEM_ORDER_ACQ:
+               order = 2;
+               break;
+       case AARCH64_INSN_MEM_ORDER_REL:
+               order = 1;
+               break;
+       case AARCH64_INSN_MEM_ORDER_ACQREL:
+               order = 3;
+               break;
+       default:
+               pr_err("%s: unknown mem order %d\n", __func__, type);
+               return AARCH64_BREAK_FAULT;
+       }
+
+       insn &= ~GENMASK(23, 22);
+       insn |= order << 22;
+
+       return insn;
+}
+
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+                                 enum aarch64_insn_register address,
+                                 enum aarch64_insn_register value,
+                                 enum aarch64_insn_size_type size,
+                                 enum aarch64_insn_mem_atomic_op op,
+                                 enum aarch64_insn_mem_order_type order)
+{
+       u32 insn;
+
+       switch (op) {
+       case AARCH64_INSN_MEM_ATOMIC_ADD:
+               insn = aarch64_insn_get_ldadd_value();
+               break;
+       case AARCH64_INSN_MEM_ATOMIC_CLR:
+               insn = aarch64_insn_get_ldclr_value();
+               break;
+       case AARCH64_INSN_MEM_ATOMIC_EOR:
+               insn = aarch64_insn_get_ldeor_value();
+               break;
+       case AARCH64_INSN_MEM_ATOMIC_SET:
+               insn = aarch64_insn_get_ldset_value();
+               break;
+       case AARCH64_INSN_MEM_ATOMIC_SWP:
+               insn = aarch64_insn_get_swp_value();
+               break;
+       default:
+               pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
+               return AARCH64_BREAK_FAULT;
+       }
 
        switch (size) {
        case AARCH64_INSN_SIZE_32:
@@ -621,6 +680,8 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
 
        insn = aarch64_insn_encode_ldst_size(size, insn);
 
+       insn = aarch64_insn_encode_ldst_order(order, insn);
+
        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
                                            result);
 
@@ -631,17 +692,68 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
                                            value);
 }
 
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
-                          enum aarch64_insn_register value,
-                          enum aarch64_insn_size_type size)
+static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
+                                        u32 insn)
 {
-       /*
-        * STADD is simply encoded as an alias for LDADD with XZR as
-        * the destination register.
-        */
-       return aarch64_insn_gen_ldadd(AARCH64_INSN_REG_ZR, address,
-                                     value, size);
+       u32 order;
+
+       switch (type) {
+       case AARCH64_INSN_MEM_ORDER_NONE:
+               order = 0;
+               break;
+       case AARCH64_INSN_MEM_ORDER_ACQ:
+               order = BIT(22);
+               break;
+       case AARCH64_INSN_MEM_ORDER_REL:
+               order = BIT(15);
+               break;
+       case AARCH64_INSN_MEM_ORDER_ACQREL:
+               order = BIT(15) | BIT(22);
+               break;
+       default:
+               pr_err("%s: unknown mem order %d\n", __func__, type);
+               return AARCH64_BREAK_FAULT;
+       }
+
+       insn &= ~(BIT(15) | BIT(22));
+       insn |= order;
+
+       return insn;
+}
+
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+                        enum aarch64_insn_register address,
+                        enum aarch64_insn_register value,
+                        enum aarch64_insn_size_type size,
+                        enum aarch64_insn_mem_order_type order)
+{
+       u32 insn;
+
+       switch (size) {
+       case AARCH64_INSN_SIZE_32:
+       case AARCH64_INSN_SIZE_64:
+               break;
+       default:
+               pr_err("%s: unimplemented size encoding %d\n", __func__, size);
+               return AARCH64_BREAK_FAULT;
+       }
+
+       insn = aarch64_insn_get_cas_value();
+
+       insn = aarch64_insn_encode_ldst_size(size, insn);
+
+       insn = aarch64_insn_encode_cas_order(order, insn);
+
+       insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
+                                           result);
+
+       insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
+                                           address);
+
+       return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
+                                           value);
 }
+#endif
 
 static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type,
                                        enum aarch64_insn_prfm_target target,
@@ -1379,7 +1491,7 @@ static u32 aarch64_encode_immediate(u64 imm,
                 * Compute the rotation to get a continuous set of
                 * ones, with the first bit set at position 0
                 */
-               ror = fls(~imm);
+               ror = fls64(~imm);
        }
 
        /*
@@ -1456,3 +1568,48 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
        return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
 }
+
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
+{
+       u32 opt;
+       u32 insn;
+
+       switch (type) {
+       case AARCH64_INSN_MB_SY:
+               opt = 0xf;
+               break;
+       case AARCH64_INSN_MB_ST:
+               opt = 0xe;
+               break;
+       case AARCH64_INSN_MB_LD:
+               opt = 0xd;
+               break;
+       case AARCH64_INSN_MB_ISH:
+               opt = 0xb;
+               break;
+       case AARCH64_INSN_MB_ISHST:
+               opt = 0xa;
+               break;
+       case AARCH64_INSN_MB_ISHLD:
+               opt = 0x9;
+               break;
+       case AARCH64_INSN_MB_NSH:
+               opt = 0x7;
+               break;
+       case AARCH64_INSN_MB_NSHST:
+               opt = 0x6;
+               break;
+       case AARCH64_INSN_MB_NSHLD:
+               opt = 0x5;
+               break;
+       default:
+               pr_err("%s: unknown dmb type %d\n", __func__, type);
+               return AARCH64_BREAK_FAULT;
+       }
+
+       insn = aarch64_insn_get_dmb_value();
+       insn &= ~GENMASK(11, 8);
+       insn |= (opt << 8);
+
+       return insn;
+}
index 7c2276fdab543231568751b44c732faf0fa007fd..37a9f2a4f7f4b5fb1170e2b78353f6e020818444 100644 (file)
@@ -38,7 +38,7 @@
 
        .p2align 4
        nop
-SYM_FUNC_START_WEAK_PI(memchr)
+SYM_FUNC_START(__pi_memchr)
        and     chrin, chrin, #0xff
        lsr     wordcnt, cntin, #3
        cbz     wordcnt, L(byte_loop)
@@ -71,5 +71,6 @@ CPU_LE(       rev     tmp, tmp)
 L(not_found):
        mov     result, #0
        ret
-SYM_FUNC_END_PI(memchr)
+SYM_FUNC_END(__pi_memchr)
+SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr)
 EXPORT_SYMBOL_NOKASAN(memchr)
index 7d956384222ff24c344dcb6857024ff6a861fde4..a5ccf2c55f911954eb9a340eb499d12e2742d215 100644 (file)
@@ -32,7 +32,7 @@
 #define tmp1           x7
 #define tmp2           x8
 
-SYM_FUNC_START_WEAK_PI(memcmp)
+SYM_FUNC_START(__pi_memcmp)
        subs    limit, limit, 8
        b.lo    L(less8)
 
@@ -134,6 +134,6 @@ L(byte_loop):
        b.eq    L(byte_loop)
        sub     result, data1w, data2w
        ret
-
-SYM_FUNC_END_PI(memcmp)
+SYM_FUNC_END(__pi_memcmp)
+SYM_FUNC_ALIAS_WEAK(memcmp, __pi_memcmp)
 EXPORT_SYMBOL_NOKASAN(memcmp)
index b82fd64ee1e1c01391187997345c82f08dc58f15..4ab48d49c451564a4edb24b5a4ff2d158b85be5c 100644 (file)
    The loop tail is handled by always copying 64 bytes from the end.
 */
 
-SYM_FUNC_START_ALIAS(__memmove)
-SYM_FUNC_START_WEAK_ALIAS_PI(memmove)
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK_PI(memcpy)
+SYM_FUNC_START(__pi_memcpy)
        add     srcend, src, count
        add     dstend, dstin, count
        cmp     count, 128
@@ -241,12 +238,16 @@ L(copy64_from_start):
        stp     B_l, B_h, [dstin, 16]
        stp     C_l, C_h, [dstin]
        ret
+SYM_FUNC_END(__pi_memcpy)
 
-SYM_FUNC_END_PI(memcpy)
-EXPORT_SYMBOL(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
+SYM_FUNC_ALIAS(__memcpy, __pi_memcpy)
 EXPORT_SYMBOL(__memcpy)
-SYM_FUNC_END_ALIAS_PI(memmove)
-EXPORT_SYMBOL(memmove)
-SYM_FUNC_END_ALIAS(__memmove)
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
+SYM_FUNC_ALIAS(__pi_memmove, __pi_memcpy)
+
+SYM_FUNC_ALIAS(__memmove, __pi_memmove)
 EXPORT_SYMBOL(__memmove)
+SYM_FUNC_ALIAS_WEAK(memmove, __memmove)
+EXPORT_SYMBOL(memmove)
index a9c1c9a01ea906954953c6dce74d4c3e482328da..a5aebe82ad73b963d0afd331d68b13e87b5a7f40 100644 (file)
@@ -42,8 +42,7 @@ dst           .req    x8
 tmp3w          .req    w9
 tmp3           .req    x9
 
-SYM_FUNC_START_ALIAS(__memset)
-SYM_FUNC_START_WEAK_PI(memset)
+SYM_FUNC_START(__pi_memset)
        mov     dst, dstin      /* Preserve return value.  */
        and     A_lw, val, #255
        orr     A_lw, A_lw, A_lw, lsl #8
@@ -202,7 +201,10 @@ SYM_FUNC_START_WEAK_PI(memset)
        ands    count, count, zva_bits_x
        b.ne    .Ltail_maybe_long
        ret
-SYM_FUNC_END_PI(memset)
-EXPORT_SYMBOL(memset)
-SYM_FUNC_END_ALIAS(__memset)
+SYM_FUNC_END(__pi_memset)
+
+SYM_FUNC_ALIAS(__memset, __pi_memset)
 EXPORT_SYMBOL(__memset)
+
+SYM_FUNC_ALIAS_WEAK(memset, __pi_memset)
+EXPORT_SYMBOL(memset)
index f531dcb95174a9365f92a3d479d1e106b1364763..8590af3c98c0ba3eb516d994decd845dcf0e278f 100644 (file)
@@ -134,7 +134,7 @@ SYM_FUNC_END(mte_copy_tags_to_user)
 /*
  * Save the tags in a page
  *   x0 - page address
- *   x1 - tag storage
+ *   x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
  */
 SYM_FUNC_START(mte_save_page_tags)
        multitag_transfer_size x7, x5
@@ -158,7 +158,7 @@ SYM_FUNC_END(mte_save_page_tags)
 /*
  * Restore the tags in a page
  *   x0 - page address
- *   x1 - tag storage
+ *   x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
  */
 SYM_FUNC_START(mte_restore_page_tags)
        multitag_transfer_size x7, x5
index 1f47eae3b0d6d618d24c347db7c2da9ffce98068..94ee67a6b212c1f2ad6e582b1a5ac91c84e1eca9 100644 (file)
@@ -18,7 +18,7 @@
  * Returns:
  *     x0 - address of first occurrence of 'c' or 0
  */
-SYM_FUNC_START_WEAK(strchr)
+SYM_FUNC_START(__pi_strchr)
        and     w1, w1, #0xff
 1:     ldrb    w2, [x0], #1
        cmp     w2, w1
@@ -28,5 +28,7 @@ SYM_FUNC_START_WEAK(strchr)
        cmp     w2, w1
        csel    x0, x0, xzr, eq
        ret
-SYM_FUNC_END(strchr)
+SYM_FUNC_END(__pi_strchr)
+
+SYM_FUNC_ALIAS_WEAK(strchr, __pi_strchr)
 EXPORT_SYMBOL_NOKASAN(strchr)
index 83bcad72ec97205f4e7dfd04d5d92ee304d81c13..9b89b453360746e1775e1726bb3ac68595f1b32e 100644 (file)
@@ -1,9 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2012-2021, Arm Limited.
+ * Copyright (c) 2012-2022, Arm Limited.
  *
  * Adapted from the original at:
- * https://github.com/ARM-software/optimized-routines/blob/afd6244a1f8d9229/string/aarch64/strcmp.S
+ * https://github.com/ARM-software/optimized-routines/blob/189dfefe37d54c5b/string/aarch64/strcmp.S
  */
 
 #include <linux/linkage.h>
 
 /* Assumptions:
  *
- * ARMv8-a, AArch64
+ * ARMv8-a, AArch64.
+ * MTE compatible.
  */
 
 #define L(label) .L ## label
 
 #define REP8_01 0x0101010101010101
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
 
-/* Parameters and result.  */
 #define src1           x0
 #define src2           x1
 #define result         x0
 
-/* Internal variables.  */
 #define data1          x2
 #define data1w         w2
 #define data2          x3
 #define data2w         w3
 #define has_nul                x4
 #define diff           x5
+#define off1           x5
 #define syndrome       x6
-#define tmp1           x7
-#define tmp2           x8
-#define tmp3           x9
-#define zeroones       x10
-#define pos            x11
-
-       /* Start of performance-critical section  -- one 64B cache line.  */
-       .align 6
-SYM_FUNC_START_WEAK_PI(strcmp)
-       eor     tmp1, src1, src2
-       mov     zeroones, #REP8_01
-       tst     tmp1, #7
+#define tmp            x6
+#define data3          x7
+#define zeroones       x8
+#define shift          x9
+#define off2           x10
+
+/* On big-endian early bytes are at MSB and on little-endian LSB.
+   LS_FW means shifting towards early bytes.  */
+#ifdef __AARCH64EB__
+# define LS_FW lsl
+#else
+# define LS_FW lsr
+#endif
+
+/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
+   (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
+   can be done in parallel across the entire word.
+   Since carry propagation makes 0x1 bytes before a NUL byte appear
+   NUL too in big-endian, byte-reverse the data before the NUL check.  */
+
+
+SYM_FUNC_START(__pi_strcmp)
+       sub     off2, src2, src1
+       mov     zeroones, REP8_01
+       and     tmp, src1, 7
+       tst     off2, 7
        b.ne    L(misaligned8)
-       ands    tmp1, src1, #7
-       b.ne    L(mutual_align)
-       /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
-          (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
-          can be done in parallel across the entire word.  */
+       cbnz    tmp, L(mutual_align)
+
+       .p2align 4
+
 L(loop_aligned):
-       ldr     data1, [src1], #8
-       ldr     data2, [src2], #8
+       ldr     data2, [src1, off2]
+       ldr     data1, [src1], 8
 L(start_realigned):
-       sub     tmp1, data1, zeroones
-       orr     tmp2, data1, #REP8_7f
-       eor     diff, data1, data2      /* Non-zero if differences found.  */
-       bic     has_nul, tmp1, tmp2     /* Non-zero if NUL terminator.  */
+#ifdef __AARCH64EB__
+       rev     tmp, data1
+       sub     has_nul, tmp, zeroones
+       orr     tmp, tmp, REP8_7f
+#else
+       sub     has_nul, data1, zeroones
+       orr     tmp, data1, REP8_7f
+#endif
+       bics    has_nul, has_nul, tmp   /* Non-zero if NUL terminator.  */
+       ccmp    data1, data2, 0, eq
+       b.eq    L(loop_aligned)
+#ifdef __AARCH64EB__
+       rev     has_nul, has_nul
+#endif
+       eor     diff, data1, data2
        orr     syndrome, diff, has_nul
-       cbz     syndrome, L(loop_aligned)
-       /* End of performance-critical section  -- one 64B cache line.  */
-
 L(end):
-#ifndef        __AARCH64EB__
+#ifndef __AARCH64EB__
        rev     syndrome, syndrome
        rev     data1, data1
-       /* The MS-non-zero bit of the syndrome marks either the first bit
-          that is different, or the top bit of the first zero byte.
-          Shifting left now will bring the critical information into the
-          top bits.  */
-       clz     pos, syndrome
        rev     data2, data2
-       lsl     data1, data1, pos
-       lsl     data2, data2, pos
-       /* But we need to zero-extend (char is unsigned) the value and then
-          perform a signed 32-bit subtraction.  */
-       lsr     data1, data1, #56
-       sub     result, data1, data2, lsr #56
-       ret
-#else
-       /* For big-endian we cannot use the trick with the syndrome value
-          as carry-propagation can corrupt the upper bits if the trailing
-          bytes in the string contain 0x01.  */
-       /* However, if there is no NUL byte in the dword, we can generate
-          the result directly.  We can't just subtract the bytes as the
-          MSB might be significant.  */
-       cbnz    has_nul, 1f
-       cmp     data1, data2
-       cset    result, ne
-       cneg    result, result, lo
-       ret
-1:
-       /* Re-compute the NUL-byte detection, using a byte-reversed value.  */
-       rev     tmp3, data1
-       sub     tmp1, tmp3, zeroones
-       orr     tmp2, tmp3, #REP8_7f
-       bic     has_nul, tmp1, tmp2
-       rev     has_nul, has_nul
-       orr     syndrome, diff, has_nul
-       clz     pos, syndrome
-       /* The MS-non-zero bit of the syndrome marks either the first bit
-          that is different, or the top bit of the first zero byte.
+#endif
+       clz     shift, syndrome
+       /* The most-significant-non-zero bit of the syndrome marks either the
+          first bit that is different, or the top bit of the first zero byte.
           Shifting left now will bring the critical information into the
           top bits.  */
-       lsl     data1, data1, pos
-       lsl     data2, data2, pos
+       lsl     data1, data1, shift
+       lsl     data2, data2, shift
        /* But we need to zero-extend (char is unsigned) the value and then
           perform a signed 32-bit subtraction.  */
-       lsr     data1, data1, #56
-       sub     result, data1, data2, lsr #56
+       lsr     data1, data1, 56
+       sub     result, data1, data2, lsr 56
        ret
-#endif
+
+       .p2align 4
 
 L(mutual_align):
        /* Sources are mutually aligned, but are not currently at an
           alignment boundary.  Round down the addresses and then mask off
-          the bytes that preceed the start point.  */
-       bic     src1, src1, #7
-       bic     src2, src2, #7
-       lsl     tmp1, tmp1, #3          /* Bytes beyond alignment -> bits.  */
-       ldr     data1, [src1], #8
-       neg     tmp1, tmp1              /* Bits to alignment -64.  */
-       ldr     data2, [src2], #8
-       mov     tmp2, #~0
-#ifdef __AARCH64EB__
-       /* Big-endian.  Early bytes are at MSB.  */
-       lsl     tmp2, tmp2, tmp1        /* Shift (tmp1 & 63).  */
-#else
-       /* Little-endian.  Early bytes are at LSB.  */
-       lsr     tmp2, tmp2, tmp1        /* Shift (tmp1 & 63).  */
-#endif
-       orr     data1, data1, tmp2
-       orr     data2, data2, tmp2
+          the bytes that precede the start point.  */
+       bic     src1, src1, 7
+       ldr     data2, [src1, off2]
+       ldr     data1, [src1], 8
+       neg     shift, src2, lsl 3      /* Bits to alignment -64.  */
+       mov     tmp, -1
+       LS_FW   tmp, tmp, shift
+       orr     data1, data1, tmp
+       orr     data2, data2, tmp
        b       L(start_realigned)
 
 L(misaligned8):
        /* Align SRC1 to 8 bytes and then compare 8 bytes at a time, always
-          checking to make sure that we don't access beyond page boundary in
-          SRC2.  */
-       tst     src1, #7
-       b.eq    L(loop_misaligned)
+          checking to make sure that we don't access beyond the end of SRC2.  */
+       cbz     tmp, L(src1_aligned)
 L(do_misaligned):
-       ldrb    data1w, [src1], #1
-       ldrb    data2w, [src2], #1
-       cmp     data1w, #1
-       ccmp    data1w, data2w, #0, cs  /* NZCV = 0b0000.  */
+       ldrb    data1w, [src1], 1
+       ldrb    data2w, [src2], 1
+       cmp     data1w, 0
+       ccmp    data1w, data2w, 0, ne   /* NZCV = 0b0000.  */
        b.ne    L(done)
-       tst     src1, #7
+       tst     src1, 7
        b.ne    L(do_misaligned)
 
-L(loop_misaligned):
-       /* Test if we are within the last dword of the end of a 4K page.  If
-          yes then jump back to the misaligned loop to copy a byte at a time.  */
-       and     tmp1, src2, #0xff8
-       eor     tmp1, tmp1, #0xff8
-       cbz     tmp1, L(do_misaligned)
-       ldr     data1, [src1], #8
-       ldr     data2, [src2], #8
-
-       sub     tmp1, data1, zeroones
-       orr     tmp2, data1, #REP8_7f
-       eor     diff, data1, data2      /* Non-zero if differences found.  */
-       bic     has_nul, tmp1, tmp2     /* Non-zero if NUL terminator.  */
+L(src1_aligned):
+       neg     shift, src2, lsl 3
+       bic     src2, src2, 7
+       ldr     data3, [src2], 8
+#ifdef __AARCH64EB__
+       rev     data3, data3
+#endif
+       lsr     tmp, zeroones, shift
+       orr     data3, data3, tmp
+       sub     has_nul, data3, zeroones
+       orr     tmp, data3, REP8_7f
+       bics    has_nul, has_nul, tmp
+       b.ne    L(tail)
+
+       sub     off1, src2, src1
+
+       .p2align 4
+
+L(loop_unaligned):
+       ldr     data3, [src1, off1]
+       ldr     data2, [src1, off2]
+#ifdef __AARCH64EB__
+       rev     data3, data3
+#endif
+       sub     has_nul, data3, zeroones
+       orr     tmp, data3, REP8_7f
+       ldr     data1, [src1], 8
+       bics    has_nul, has_nul, tmp
+       ccmp    data1, data2, 0, eq
+       b.eq    L(loop_unaligned)
+
+       lsl     tmp, has_nul, shift
+#ifdef __AARCH64EB__
+       rev     tmp, tmp
+#endif
+       eor     diff, data1, data2
+       orr     syndrome, diff, tmp
+       cbnz    syndrome, L(end)
+L(tail):
+       ldr     data1, [src1]
+       neg     shift, shift
+       lsr     data2, data3, shift
+       lsr     has_nul, has_nul, shift
+#ifdef __AARCH64EB__
+       rev     data2, data2
+       rev     has_nul, has_nul
+#endif
+       eor     diff, data1, data2
        orr     syndrome, diff, has_nul
-       cbz     syndrome, L(loop_misaligned)
        b       L(end)
 
 L(done):
        sub     result, data1, data2
        ret
-
-SYM_FUNC_END_PI(strcmp)
-EXPORT_SYMBOL_NOHWKASAN(strcmp)
+SYM_FUNC_END(__pi_strcmp)
+SYM_FUNC_ALIAS_WEAK(strcmp, __pi_strcmp)
+EXPORT_SYMBOL_NOKASAN(strcmp)
index 1648790e91b3ce5b8db6e7627ed73a43b7f5c39d..4919fe81ae540edcee6c9abc459f420e00f378c8 100644 (file)
@@ -79,7 +79,7 @@
           whether the first fetch, which may be misaligned, crosses a page
           boundary.  */
 
-SYM_FUNC_START_WEAK_PI(strlen)
+SYM_FUNC_START(__pi_strlen)
        and     tmp1, srcin, MIN_PAGE_SIZE - 1
        mov     zeroones, REP8_01
        cmp     tmp1, MIN_PAGE_SIZE - 16
@@ -208,6 +208,6 @@ L(page_cross):
        csel    data1, data1, tmp4, eq
        csel    data2, data2, tmp2, eq
        b       L(page_cross_entry)
-
-SYM_FUNC_END_PI(strlen)
+SYM_FUNC_END(__pi_strlen)
+SYM_FUNC_ALIAS_WEAK(strlen, __pi_strlen)
 EXPORT_SYMBOL_NOKASAN(strlen)
index e42bcfcd37e6f691a8b78e3c17a6330272cbefd0..fe7bbc0b42a787414e2a300d8bc66b129084e6fc 100644 (file)
@@ -1,9 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2013-2021, Arm Limited.
+ * Copyright (c) 2013-2022, Arm Limited.
  *
  * Adapted from the original at:
- * https://github.com/ARM-software/optimized-routines/blob/e823e3abf5f89ecb/string/aarch64/strncmp.S
+ * https://github.com/ARM-software/optimized-routines/blob/189dfefe37d54c5b/string/aarch64/strncmp.S
  */
 
 #include <linux/linkage.h>
 
 /* Assumptions:
  *
- * ARMv8-a, AArch64
+ * ARMv8-a, AArch64.
+ * MTE compatible.
  */
 
 #define L(label) .L ## label
 
 #define REP8_01 0x0101010101010101
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
 
 /* Parameters and result.  */
 #define src1           x0
 #define tmp3           x10
 #define zeroones       x11
 #define pos            x12
-#define limit_wd       x13
-#define mask           x14
-#define endloop                x15
+#define mask           x13
+#define endloop                x14
 #define count          mask
+#define offset         pos
+#define neg_offset     x15
 
-SYM_FUNC_START_WEAK_PI(strncmp)
+/* Define endian dependent shift operations.
+   On big-endian early bytes are at MSB and on little-endian LSB.
+   LS_FW means shifting towards early bytes.
+   LS_BK means shifting towards later bytes.
+   */
+#ifdef __AARCH64EB__
+#define LS_FW lsl
+#define LS_BK lsr
+#else
+#define LS_FW lsr
+#define LS_BK lsl
+#endif
+
+SYM_FUNC_START(__pi_strncmp)
        cbz     limit, L(ret0)
        eor     tmp1, src1, src2
        mov     zeroones, #REP8_01
@@ -52,9 +66,6 @@ SYM_FUNC_START_WEAK_PI(strncmp)
        and     count, src1, #7
        b.ne    L(misaligned8)
        cbnz    count, L(mutual_align)
-       /* Calculate the number of full and partial words -1.  */
-       sub     limit_wd, limit, #1     /* limit != 0, so no underflow.  */
-       lsr     limit_wd, limit_wd, #3  /* Convert to Dwords.  */
 
        /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
           (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
@@ -64,56 +75,52 @@ L(loop_aligned):
        ldr     data1, [src1], #8
        ldr     data2, [src2], #8
 L(start_realigned):
-       subs    limit_wd, limit_wd, #1
+       subs    limit, limit, #8
        sub     tmp1, data1, zeroones
        orr     tmp2, data1, #REP8_7f
        eor     diff, data1, data2      /* Non-zero if differences found.  */
-       csinv   endloop, diff, xzr, pl  /* Last Dword or differences.  */
+       csinv   endloop, diff, xzr, hi  /* Last Dword or differences.  */
        bics    has_nul, tmp1, tmp2     /* Non-zero if NUL terminator.  */
        ccmp    endloop, #0, #0, eq
        b.eq    L(loop_aligned)
        /* End of main loop */
 
-       /* Not reached the limit, must have found the end or a diff.  */
-       tbz     limit_wd, #63, L(not_limit)
-
-       /* Limit % 8 == 0 => all bytes significant.  */
-       ands    limit, limit, #7
-       b.eq    L(not_limit)
-
-       lsl     limit, limit, #3        /* Bits -> bytes.  */
-       mov     mask, #~0
-#ifdef __AARCH64EB__
-       lsr     mask, mask, limit
-#else
-       lsl     mask, mask, limit
-#endif
-       bic     data1, data1, mask
-       bic     data2, data2, mask
-
-       /* Make sure that the NUL byte is marked in the syndrome.  */
-       orr     has_nul, has_nul, mask
-
-L(not_limit):
+L(full_check):
+#ifndef __AARCH64EB__
        orr     syndrome, diff, has_nul
-
-#ifndef        __AARCH64EB__
+       add     limit, limit, 8 /* Rewind limit to before last subs. */
+L(syndrome_check):
+       /* Limit was reached. Check if the NUL byte or the difference
+          is before the limit. */
        rev     syndrome, syndrome
        rev     data1, data1
-       /* The MS-non-zero bit of the syndrome marks either the first bit
-          that is different, or the top bit of the first zero byte.
-          Shifting left now will bring the critical information into the
-          top bits.  */
        clz     pos, syndrome
        rev     data2, data2
        lsl     data1, data1, pos
+       cmp     limit, pos, lsr #3
        lsl     data2, data2, pos
        /* But we need to zero-extend (char is unsigned) the value and then
           perform a signed 32-bit subtraction.  */
        lsr     data1, data1, #56
        sub     result, data1, data2, lsr #56
+       csel result, result, xzr, hi
        ret
 #else
+       /* Not reached the limit, must have found the end or a diff.  */
+       tbz     limit, #63, L(not_limit)
+       add     tmp1, limit, 8
+       cbz     limit, L(not_limit)
+
+       lsl     limit, tmp1, #3 /* Bits -> bytes.  */
+       mov     mask, #~0
+       lsr     mask, mask, limit
+       bic     data1, data1, mask
+       bic     data2, data2, mask
+
+       /* Make sure that the NUL byte is marked in the syndrome.  */
+       orr     has_nul, has_nul, mask
+
+L(not_limit):
        /* For big-endian we cannot use the trick with the syndrome value
           as carry-propagation can corrupt the upper bits if the trailing
           bytes in the string contain 0x01.  */
@@ -134,10 +141,11 @@ L(not_limit):
        rev     has_nul, has_nul
        orr     syndrome, diff, has_nul
        clz     pos, syndrome
-       /* The MS-non-zero bit of the syndrome marks either the first bit
-          that is different, or the top bit of the first zero byte.
+       /* The most-significant-non-zero bit of the syndrome marks either the
+          first bit that is different, or the top bit of the first zero byte.
           Shifting left now will bring the critical information into the
           top bits.  */
+L(end_quick):
        lsl     data1, data1, pos
        lsl     data2, data2, pos
        /* But we need to zero-extend (char is unsigned) the value and then
@@ -159,22 +167,12 @@ L(mutual_align):
        neg     tmp3, count, lsl #3     /* 64 - bits(bytes beyond align). */
        ldr     data2, [src2], #8
        mov     tmp2, #~0
-       sub     limit_wd, limit, #1     /* limit != 0, so no underflow.  */
-#ifdef __AARCH64EB__
-       /* Big-endian.  Early bytes are at MSB.  */
-       lsl     tmp2, tmp2, tmp3        /* Shift (count & 63).  */
-#else
-       /* Little-endian.  Early bytes are at LSB.  */
-       lsr     tmp2, tmp2, tmp3        /* Shift (count & 63).  */
-#endif
-       and     tmp3, limit_wd, #7
-       lsr     limit_wd, limit_wd, #3
-       /* Adjust the limit. Only low 3 bits used, so overflow irrelevant.  */
-       add     limit, limit, count
-       add     tmp3, tmp3, count
+       LS_FW   tmp2, tmp2, tmp3        /* Shift (count & 63).  */
+       /* Adjust the limit and ensure it doesn't overflow.  */
+       adds    limit, limit, count
+       csinv   limit, limit, xzr, lo
        orr     data1, data1, tmp2
        orr     data2, data2, tmp2
-       add     limit_wd, limit_wd, tmp3, lsr #3
        b       L(start_realigned)
 
        .p2align 4
@@ -197,13 +195,11 @@ L(done):
        /* Align the SRC1 to a dword by doing a bytewise compare and then do
           the dword loop.  */
 L(try_misaligned_words):
-       lsr     limit_wd, limit, #3
-       cbz     count, L(do_misaligned)
+       cbz     count, L(src1_aligned)
 
        neg     count, count
        and     count, count, #7
        sub     limit, limit, count
-       lsr     limit_wd, limit, #3
 
 L(page_end_loop):
        ldrb    data1w, [src1], #1
@@ -214,48 +210,101 @@ L(page_end_loop):
        subs    count, count, #1
        b.hi    L(page_end_loop)
 
-L(do_misaligned):
-       /* Prepare ourselves for the next page crossing.  Unlike the aligned
-          loop, we fetch 1 less dword because we risk crossing bounds on
-          SRC2.  */
-       mov     count, #8
-       subs    limit_wd, limit_wd, #1
-       b.lo    L(done_loop)
-L(loop_misaligned):
-       and     tmp2, src2, #0xff8
-       eor     tmp2, tmp2, #0xff8
-       cbz     tmp2, L(page_end_loop)
+       /* The following diagram explains the comparison of misaligned strings.
+          The bytes are shown in natural order. For little-endian, it is
+          reversed in the registers. The "x" bytes are before the string.
+          The "|" separates data that is loaded at one time.
+          src1     | a a a a a a a a | b b b c c c c c | . . .
+          src2     | x x x x x a a a   a a a a a b b b | c c c c c . . .
+
+          After shifting in each step, the data looks like this:
+                       STEP_A              STEP_B              STEP_C
+          data1    a a a a a a a a     b b b c c c c c     b b b c c c c c
+          data2    a a a a a a a a     b b b 0 0 0 0 0     0 0 0 c c c c c
 
+          The bytes with "0" are eliminated from the syndrome via mask.
+
+          Align SRC2 down to 16 bytes. This way we can read 16 bytes at a
+          time from SRC2. The comparison happens in 3 steps. After each step
+          the loop can exit, or read from SRC1 or SRC2. */
+L(src1_aligned):
+       /* Calculate offset from 8 byte alignment to string start in bits. No
+          need to mask offset since shifts are ignoring upper bits. */
+       lsl     offset, src2, #3
+       bic     src2, src2, #0xf
+       mov     mask, -1
+       neg     neg_offset, offset
        ldr     data1, [src1], #8
-       ldr     data2, [src2], #8
-       sub     tmp1, data1, zeroones
-       orr     tmp2, data1, #REP8_7f
-       eor     diff, data1, data2      /* Non-zero if differences found.  */
-       bics    has_nul, tmp1, tmp2     /* Non-zero if NUL terminator.  */
-       ccmp    diff, #0, #0, eq
-       b.ne    L(not_limit)
-       subs    limit_wd, limit_wd, #1
-       b.pl    L(loop_misaligned)
+       ldp     tmp1, tmp2, [src2], #16
+       LS_BK   mask, mask, neg_offset
+       and     neg_offset, neg_offset, #63     /* Need actual value for cmp later. */
+       /* Skip the first compare if data in tmp1 is irrelevant. */
+       tbnz    offset, 6, L(misaligned_mid_loop)
 
-L(done_loop):
-       /* We found a difference or a NULL before the limit was reached.  */
-       and     limit, limit, #7
-       cbz     limit, L(not_limit)
-       /* Read the last word.  */
-       sub     src1, src1, 8
-       sub     src2, src2, 8
-       ldr     data1, [src1, limit]
-       ldr     data2, [src2, limit]
-       sub     tmp1, data1, zeroones
-       orr     tmp2, data1, #REP8_7f
+L(loop_misaligned):
+       /* STEP_A: Compare full 8 bytes when there is enough data from SRC2.*/
+       LS_FW   data2, tmp1, offset
+       LS_BK   tmp1, tmp2, neg_offset
+       subs    limit, limit, #8
+       orr     data2, data2, tmp1      /* 8 bytes from SRC2 combined from two regs.*/
+       sub     has_nul, data1, zeroones
        eor     diff, data1, data2      /* Non-zero if differences found.  */
-       bics    has_nul, tmp1, tmp2     /* Non-zero if NUL terminator.  */
-       ccmp    diff, #0, #0, eq
-       b.ne    L(not_limit)
+       orr     tmp3, data1, #REP8_7f
+       csinv   endloop, diff, xzr, hi  /* If limit, set to all ones. */
+       bic     has_nul, has_nul, tmp3  /* Non-zero if NUL byte found in SRC1. */
+       orr     tmp3, endloop, has_nul
+       cbnz    tmp3, L(full_check)
+
+       ldr     data1, [src1], #8
+L(misaligned_mid_loop):
+       /* STEP_B: Compare first part of data1 to second part of tmp2. */
+       LS_FW   data2, tmp2, offset
+#ifdef __AARCH64EB__
+       /* For big-endian we do a byte reverse to avoid carry-propagation
+       problem described above. This way we can reuse the has_nul in the
+       next step and also use syndrome value trick at the end. */
+       rev     tmp3, data1
+       #define data1_fixed tmp3
+#else
+       #define data1_fixed data1
+#endif
+       sub     has_nul, data1_fixed, zeroones
+       orr     tmp3, data1_fixed, #REP8_7f
+       eor     diff, data2, data1      /* Non-zero if differences found.  */
+       bic     has_nul, has_nul, tmp3  /* Non-zero if NUL terminator.  */
+#ifdef __AARCH64EB__
+       rev     has_nul, has_nul
+#endif
+       cmp     limit, neg_offset, lsr #3
+       orr     syndrome, diff, has_nul
+       bic     syndrome, syndrome, mask        /* Ignore later bytes. */
+       csinv   tmp3, syndrome, xzr, hi /* If limit, set to all ones. */
+       cbnz    tmp3, L(syndrome_check)
+
+       /* STEP_C: Compare second part of data1 to first part of tmp1. */
+       ldp     tmp1, tmp2, [src2], #16
+       cmp     limit, #8
+       LS_BK   data2, tmp1, neg_offset
+       eor     diff, data2, data1      /* Non-zero if differences found.  */
+       orr     syndrome, diff, has_nul
+       and     syndrome, syndrome, mask        /* Ignore earlier bytes. */
+       csinv   tmp3, syndrome, xzr, hi /* If limit, set to all ones. */
+       cbnz    tmp3, L(syndrome_check)
+
+       ldr     data1, [src1], #8
+       sub     limit, limit, #8
+       b       L(loop_misaligned)
+
+#ifdef __AARCH64EB__
+L(syndrome_check):
+       clz     pos, syndrome
+       cmp     pos, limit, lsl #3
+       b.lo    L(end_quick)
+#endif
 
 L(ret0):
        mov     result, #0
        ret
-
-SYM_FUNC_END_PI(strncmp)
-EXPORT_SYMBOL_NOHWKASAN(strncmp)
+SYM_FUNC_END(__pi_strncmp)
+SYM_FUNC_ALIAS_WEAK(strncmp, __pi_strncmp)
+EXPORT_SYMBOL_NOKASAN(strncmp)
index b72913a990389a22be61fc981a730816e9a427b6..d5ac0e10a01db79d040ad653b8fa7fb4daa5b555 100644 (file)
@@ -47,7 +47,7 @@ limit_wd      .req    x14
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
 #define REP8_80 0x8080808080808080
 
-SYM_FUNC_START_WEAK_PI(strnlen)
+SYM_FUNC_START(__pi_strnlen)
        cbz     limit, .Lhit_limit
        mov     zeroones, #REP8_01
        bic     src, srcin, #15
@@ -156,5 +156,7 @@ CPU_LE( lsr tmp2, tmp2, tmp4 )      /* Shift (tmp1 & 63).  */
 .Lhit_limit:
        mov     len, limit
        ret
-SYM_FUNC_END_PI(strnlen)
+SYM_FUNC_END(__pi_strnlen)
+
+SYM_FUNC_ALIAS_WEAK(strnlen, __pi_strnlen)
 EXPORT_SYMBOL_NOKASAN(strnlen)
index 13132d1ed6d127913883f3215a3c0819cbb5598e..a5123cf0ce125aa3b9842ba638eb9a3bc3987b92 100644 (file)
@@ -18,7 +18,7 @@
  * Returns:
  *     x0 - address of last occurrence of 'c' or 0
  */
-SYM_FUNC_START_WEAK_PI(strrchr)
+SYM_FUNC_START(__pi_strrchr)
        mov     x3, #0
        and     w1, w1, #0xff
 1:     ldrb    w2, [x0], #1
@@ -29,5 +29,6 @@ SYM_FUNC_START_WEAK_PI(strrchr)
        b       1b
 2:     mov     x0, x3
        ret
-SYM_FUNC_END_PI(strrchr)
+SYM_FUNC_END(__pi_strrchr)
+SYM_FUNC_ALIAS_WEAK(strrchr, __pi_strrchr)
 EXPORT_SYMBOL_NOKASAN(strrchr)
index 7d0563db42014b40185fa94c62ae99fadd403916..0ea6cc25dc66356de86d262cc3d48bb993ec3cd0 100644 (file)
@@ -107,10 +107,11 @@ SYM_FUNC_END(icache_inval_pou)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-SYM_FUNC_START_PI(dcache_clean_inval_poc)
+SYM_FUNC_START(__pi_dcache_clean_inval_poc)
        dcache_by_line_op civac, sy, x0, x1, x2, x3
        ret
-SYM_FUNC_END_PI(dcache_clean_inval_poc)
+SYM_FUNC_END(__pi_dcache_clean_inval_poc)
+SYM_FUNC_ALIAS(dcache_clean_inval_poc, __pi_dcache_clean_inval_poc)
 
 /*
  *     dcache_clean_pou(start, end)
@@ -140,7 +141,7 @@ SYM_FUNC_END(dcache_clean_pou)
  *     - start   - kernel start address of region
  *     - end     - kernel end address of region
  */
-SYM_FUNC_START_PI(dcache_inval_poc)
+SYM_FUNC_START(__pi_dcache_inval_poc)
        dcache_line_size x2, x3
        sub     x3, x2, #1
        tst     x1, x3                          // end cache line aligned?
@@ -158,7 +159,8 @@ SYM_FUNC_START_PI(dcache_inval_poc)
        b.lo    2b
        dsb     sy
        ret
-SYM_FUNC_END_PI(dcache_inval_poc)
+SYM_FUNC_END(__pi_dcache_inval_poc)
+SYM_FUNC_ALIAS(dcache_inval_poc, __pi_dcache_inval_poc)
 
 /*
  *     dcache_clean_poc(start, end)
@@ -169,10 +171,11 @@ SYM_FUNC_END_PI(dcache_inval_poc)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-SYM_FUNC_START_PI(dcache_clean_poc)
+SYM_FUNC_START(__pi_dcache_clean_poc)
        dcache_by_line_op cvac, sy, x0, x1, x2, x3
        ret
-SYM_FUNC_END_PI(dcache_clean_poc)
+SYM_FUNC_END(__pi_dcache_clean_poc)
+SYM_FUNC_ALIAS(dcache_clean_poc, __pi_dcache_clean_poc)
 
 /*
  *     dcache_clean_pop(start, end)
@@ -183,13 +186,14 @@ SYM_FUNC_END_PI(dcache_clean_poc)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-SYM_FUNC_START_PI(dcache_clean_pop)
+SYM_FUNC_START(__pi_dcache_clean_pop)
        alternative_if_not ARM64_HAS_DCPOP
        b       dcache_clean_poc
        alternative_else_nop_endif
        dcache_by_line_op cvap, sy, x0, x1, x2, x3
        ret
-SYM_FUNC_END_PI(dcache_clean_pop)
+SYM_FUNC_END(__pi_dcache_clean_pop)
+SYM_FUNC_ALIAS(dcache_clean_pop, __pi_dcache_clean_pop)
 
 /*
  *     __dma_flush_area(start, size)
@@ -199,11 +203,12 @@ SYM_FUNC_END_PI(dcache_clean_pop)
  *     - start   - virtual start address of region
  *     - size    - size in question
  */
-SYM_FUNC_START_PI(__dma_flush_area)
+SYM_FUNC_START(__pi___dma_flush_area)
        add     x1, x0, x1
        dcache_by_line_op civac, sy, x0, x1, x2, x3
        ret
-SYM_FUNC_END_PI(__dma_flush_area)
+SYM_FUNC_END(__pi___dma_flush_area)
+SYM_FUNC_ALIAS(__dma_flush_area, __pi___dma_flush_area)
 
 /*
  *     __dma_map_area(start, size, dir)
@@ -211,12 +216,13 @@ SYM_FUNC_END_PI(__dma_flush_area)
  *     - size  - size of region
  *     - dir   - DMA direction
  */
-SYM_FUNC_START_PI(__dma_map_area)
+SYM_FUNC_START(__pi___dma_map_area)
        add     x1, x0, x1
        cmp     w2, #DMA_FROM_DEVICE
        b.eq    __pi_dcache_inval_poc
        b       __pi_dcache_clean_poc
-SYM_FUNC_END_PI(__dma_map_area)
+SYM_FUNC_END(__pi___dma_map_area)
+SYM_FUNC_ALIAS(__dma_map_area, __pi___dma_map_area)
 
 /*
  *     __dma_unmap_area(start, size, dir)
@@ -224,9 +230,10 @@ SYM_FUNC_END_PI(__dma_map_area)
  *     - size  - size of region
  *     - dir   - DMA direction
  */
-SYM_FUNC_START_PI(__dma_unmap_area)
+SYM_FUNC_START(__pi___dma_unmap_area)
        add     x1, x0, x1
        cmp     w2, #DMA_TO_DEVICE
        b.ne    __pi_dcache_inval_poc
        ret
-SYM_FUNC_END_PI(__dma_unmap_area)
+SYM_FUNC_END(__pi___dma_unmap_area)
+SYM_FUNC_ALIAS(__dma_unmap_area, __pi___dma_unmap_area)
index 2aaf950b906cbabac1f145555dcc1b37b0271631..a06c6ac770d4554d20ac4d617e063d44da42d611 100644 (file)
@@ -52,6 +52,13 @@ void __sync_icache_dcache(pte_t pte)
 {
        struct page *page = pte_page(pte);
 
+       /*
+        * HugeTLB pages are always fully mapped, so only setting head page's
+        * PG_dcache_clean flag is enough.
+        */
+       if (PageHuge(page))
+               page = compound_head(page);
+
        if (!test_bit(PG_dcache_clean, &page->flags)) {
                sync_icache_aliases((unsigned long)page_address(page),
                                    (unsigned long)page_address(page) +
index ffb9c229610ab5ee0825f1c604f72799bd7296e1..a33aba91ad8917dafa1d86d5dac22045c81f3761 100644 (file)
@@ -56,25 +56,34 @@ void __init arm64_hugetlb_cma_reserve(void)
 }
 #endif /* CONFIG_CMA */
 
-#ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
-bool arch_hugetlb_migration_supported(struct hstate *h)
+static bool __hugetlb_valid_size(unsigned long size)
 {
-       size_t pagesize = huge_page_size(h);
-
-       switch (pagesize) {
+       switch (size) {
 #ifndef __PAGETABLE_PMD_FOLDED
        case PUD_SIZE:
                return pud_sect_supported();
 #endif
-       case PMD_SIZE:
        case CONT_PMD_SIZE:
+       case PMD_SIZE:
        case CONT_PTE_SIZE:
                return true;
        }
-       pr_warn("%s: unrecognized huge page size 0x%lx\n",
-                       __func__, pagesize);
+
        return false;
 }
+
+#ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
+bool arch_hugetlb_migration_supported(struct hstate *h)
+{
+       size_t pagesize = huge_page_size(h);
+
+       if (!__hugetlb_valid_size(pagesize)) {
+               pr_warn("%s: unrecognized huge page size 0x%lx\n",
+                       __func__, pagesize);
+               return false;
+       }
+       return true;
+}
 #endif
 
 int pmd_huge(pmd_t pmd)
@@ -506,16 +515,5 @@ arch_initcall(hugetlbpage_init);
 
 bool __init arch_hugetlb_valid_size(unsigned long size)
 {
-       switch (size) {
-#ifndef __PAGETABLE_PMD_FOLDED
-       case PUD_SIZE:
-               return pud_sect_supported();
-#endif
-       case CONT_PMD_SIZE:
-       case PMD_SIZE:
-       case CONT_PTE_SIZE:
-               return true;
-       }
-
-       return false;
+       return __hugetlb_valid_size(size);
 }
index db63cc885771a527b37f91e1eff0bf1f9432dbee..9e26ec80d317501986c13c668d323e6957f5302e 100644 (file)
@@ -61,8 +61,34 @@ EXPORT_SYMBOL(memstart_addr);
  * unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4).
  * In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory,
  * otherwise it is empty.
+ *
+ * Memory reservation for crash kernel either done early or deferred
+ * depending on DMA memory zones configs (ZONE_DMA) --
+ *
+ * In absence of ZONE_DMA configs arm64_dma_phys_limit initialized
+ * here instead of max_zone_phys().  This lets early reservation of
+ * crash kernel memory which has a dependency on arm64_dma_phys_limit.
+ * Reserving memory early for crash kernel allows linear creation of block
+ * mappings (greater than page-granularity) for all the memory bank rangs.
+ * In this scheme a comparatively quicker boot is observed.
+ *
+ * If ZONE_DMA configs are defined, crash kernel memory reservation
+ * is delayed until DMA zone memory range size initilazation performed in
+ * zone_sizes_init().  The defer is necessary to steer clear of DMA zone
+ * memory range to avoid overlap allocation.  So crash kernel memory boundaries
+ * are not known when mapping all bank memory ranges, which otherwise means
+ * not possible to exclude crash kernel range from creating block mappings
+ * so page-granularity mappings are created for the entire memory range.
+ * Hence a slightly slower boot is observed.
+ *
+ * Note: Page-granularity mapppings are necessary for crash kernel memory
+ * range for shrinking its size via /sys/kernel/kexec_crash_size interface.
  */
-phys_addr_t arm64_dma_phys_limit __ro_after_init;
+#if IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32)
+phys_addr_t __ro_after_init arm64_dma_phys_limit;
+#else
+phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
+#endif
 
 #ifdef CONFIG_KEXEC_CORE
 /*
@@ -153,8 +179,6 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
        if (!arm64_dma_phys_limit)
                arm64_dma_phys_limit = dma32_phys_limit;
 #endif
-       if (!arm64_dma_phys_limit)
-               arm64_dma_phys_limit = PHYS_MASK + 1;
        max_zone_pfns[ZONE_NORMAL] = max;
 
        free_area_init(max_zone_pfns);
@@ -315,6 +339,9 @@ void __init arm64_memblock_init(void)
 
        early_init_fdt_scan_reserved_mem();
 
+       if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32))
+               reserve_crashkernel();
+
        high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
 }
 
@@ -361,7 +388,8 @@ void __init bootmem_init(void)
         * request_standard_resources() depends on crashkernel's memory being
         * reserved, so do it here.
         */
-       reserve_crashkernel();
+       if (IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32))
+               reserve_crashkernel();
 
        memblock_dump_all();
 }
index a38f54cd638c265da6f42ff53cc76b879de99312..77ada00280d9319e2ef6c04c47b5fc415cdcef90 100644 (file)
@@ -7,8 +7,10 @@
 
 #include <linux/io.h>
 #include <linux/memblock.h>
+#include <linux/mm.h>
 #include <linux/types.h>
 
+#include <asm/cpufeature.h>
 #include <asm/page.h>
 
 /*
@@ -38,3 +40,18 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
 {
        return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK);
 }
+
+static int __init adjust_protection_map(void)
+{
+       /*
+        * With Enhanced PAN we can honour the execute-only permissions as
+        * there is no PAN override with such mappings.
+        */
+       if (cpus_have_const_cap(ARM64_HAS_EPAN)) {
+               protection_map[VM_EXEC] = PAGE_EXECONLY;
+               protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY;
+       }
+
+       return 0;
+}
+arch_initcall(adjust_protection_map);
index acfae9b41cc8c983ae6c4a5bc639a5f6d03a139a..0b7d25887ec37cef524da7234c2f4d1746860944 100644 (file)
@@ -63,6 +63,7 @@ static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused;
 static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused;
 
 static DEFINE_SPINLOCK(swapper_pgdir_lock);
+static DEFINE_MUTEX(fixmap_lock);
 
 void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
 {
@@ -294,18 +295,6 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
        } while (addr = next, addr != end);
 }
 
-static inline bool use_1G_block(unsigned long addr, unsigned long next,
-                       unsigned long phys)
-{
-       if (PAGE_SHIFT != 12)
-               return false;
-
-       if (((addr | next | phys) & ~PUD_MASK) != 0)
-               return false;
-
-       return true;
-}
-
 static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
                           phys_addr_t phys, pgprot_t prot,
                           phys_addr_t (*pgtable_alloc)(int),
@@ -329,6 +318,12 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
        }
        BUG_ON(p4d_bad(p4d));
 
+       /*
+        * No need for locking during early boot. And it doesn't work as
+        * expected with KASLR enabled.
+        */
+       if (system_state != SYSTEM_BOOTING)
+               mutex_lock(&fixmap_lock);
        pudp = pud_set_fixmap_offset(p4dp, addr);
        do {
                pud_t old_pud = READ_ONCE(*pudp);
@@ -338,7 +333,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
                /*
                 * For 4K granule only, attempt to put down a 1GB block
                 */
-               if (use_1G_block(addr, next, phys) &&
+               if (pud_sect_supported() &&
+                  ((addr | next | phys) & ~PUD_MASK) == 0 &&
                    (flags & NO_BLOCK_MAPPINGS) == 0) {
                        pud_set_huge(pudp, phys, prot);
 
@@ -359,6 +355,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
        } while (pudp++, addr = next, addr != end);
 
        pud_clear_fixmap();
+       if (system_state != SYSTEM_BOOTING)
+               mutex_unlock(&fixmap_lock);
 }
 
 static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
@@ -517,7 +515,7 @@ static void __init map_mem(pgd_t *pgdp)
         */
        BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end));
 
-       if (can_set_direct_map() || crash_mem_map || IS_ENABLED(CONFIG_KFENCE))
+       if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE))
                flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
 
        /*
@@ -528,6 +526,17 @@ static void __init map_mem(pgd_t *pgdp)
         */
        memblock_mark_nomap(kernel_start, kernel_end - kernel_start);
 
+#ifdef CONFIG_KEXEC_CORE
+       if (crash_mem_map) {
+               if (IS_ENABLED(CONFIG_ZONE_DMA) ||
+                   IS_ENABLED(CONFIG_ZONE_DMA32))
+                       flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
+               else if (crashk_res.end)
+                       memblock_mark_nomap(crashk_res.start,
+                           resource_size(&crashk_res));
+       }
+#endif
+
        /* map all the memory banks */
        for_each_mem_range(i, &start, &end) {
                if (start >= end)
@@ -554,6 +563,25 @@ static void __init map_mem(pgd_t *pgdp)
        __map_memblock(pgdp, kernel_start, kernel_end,
                       PAGE_KERNEL, NO_CONT_MAPPINGS);
        memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
+
+       /*
+        * Use page-level mappings here so that we can shrink the region
+        * in page granularity and put back unused memory to buddy system
+        * through /sys/kernel/kexec_crash_size interface.
+        */
+#ifdef CONFIG_KEXEC_CORE
+       if (crash_mem_map &&
+           !IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32)) {
+               if (crashk_res.end) {
+                       __map_memblock(pgdp, crashk_res.start,
+                                      crashk_res.end + 1,
+                                      PAGE_KERNEL,
+                                      NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
+                       memblock_clear_nomap(crashk_res.start,
+                                            resource_size(&crashk_res));
+               }
+       }
+#endif
 }
 
 void mark_rodata_ro(void)
@@ -617,6 +645,8 @@ early_param("rodata", parse_rodata);
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 static int __init map_entry_trampoline(void)
 {
+       int i;
+
        pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
        phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start);
 
@@ -625,11 +655,15 @@ static int __init map_entry_trampoline(void)
 
        /* Map only the text into the trampoline page table */
        memset(tramp_pg_dir, 0, PGD_SIZE);
-       __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
-                            prot, __pgd_pgtable_alloc, 0);
+       __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS,
+                            entry_tramp_text_size(), prot,
+                            __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS);
 
        /* Map both the text and data into the kernel page table */
-       __set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
+       for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++)
+               __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i,
+                            pa_start + i * PAGE_SIZE, prot);
+
        if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
                extern char __entry_tramp_data_start[];
 
index 7c4ef56265ee1e7a861579416ea9a34221f5def4..a9e50e930484aa3ce7e09f3d9344f7a72b08de6a 100644 (file)
@@ -12,7 +12,7 @@ static DEFINE_XARRAY(mte_pages);
 void *mte_allocate_tag_storage(void)
 {
        /* tags granule is 16 bytes, 2 tags stored per byte */
-       return kmalloc(PAGE_SIZE / 16 / 2, GFP_KERNEL);
+       return kmalloc(MTE_PAGE_TAG_STORAGE, GFP_KERNEL);
 }
 
 void mte_free_tag_storage(char *storage)
index d35c90d2e47ad698b899094eb4b8c99bea721753..50bbed947bec7e0521da145e0e878201ec89d9ec 100644 (file)
@@ -46,7 +46,7 @@
 #endif
 
 #ifdef CONFIG_KASAN_HW_TAGS
-#define TCR_MTE_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1
+#define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1
 #else
 /*
  * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on
index cc0cf0f5c7c3b8d1a15d6296462282b5e8ccc8c2..9d9250c7cc729eb3c84ec136ce2e88e8ed946aae 100644 (file)
 #define A64_STXR(sf, Rt, Rn, Rs) \
        A64_LSX(sf, Rt, Rn, Rs, STORE_EX)
 
-/* LSE atomics */
+/*
+ * LSE atomics
+ *
+ * STADD is simply encoded as an alias for LDADD with XZR as
+ * the destination register.
+ */
 #define A64_STADD(sf, Rn, Rs) \
-       aarch64_insn_gen_stadd(Rn, Rs, A64_SIZE(sf))
+       aarch64_insn_gen_atomic_ld_op(A64_ZR, Rn, Rs, \
+               A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_ADD, \
+               AARCH64_INSN_MEM_ORDER_NONE)
 
 /* Add/subtract (immediate) */
 #define A64_ADDSUB_IMM(sf, Rd, Rn, imm12, type) \
index 932b4fe5c7684341c3c075e1ad024e7e729e3f56..cf1307188150f5130be2fd2c829ee8d0bf9d87f0 100644 (file)
@@ -5,18 +5,14 @@ kapi := $(gen)/asm
 
 kapi-hdrs-y := $(kapi)/cpucaps.h
 
-targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y))
+targets += $(addprefix ../../../, $(kapi-hdrs-y))
 
 PHONY += kapi
 
-kapi:   $(kapi-hdrs-y) $(gen-y)
-
-# Create output directory if not already present
-_dummy := $(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)')
+kapi:   $(kapi-hdrs-y)
 
 quiet_cmd_gen_cpucaps = GEN     $@
-      cmd_gen_cpucaps = mkdir -p $(dir $@) && \
-                     $(AWK) -f $(filter-out $(PHONY),$^) > $@
+      cmd_gen_cpucaps = mkdir -p $(dir $@); $(AWK) -f $(real-prereqs) > $@
 
 $(kapi)/cpucaps.h: $(src)/gen-cpucaps.awk $(src)/cpucaps FORCE
        $(call if_changed,gen_cpucaps)
index 9c65b1e25a96506a874e578ece7bdce6ec52c309..3ed418f70e3bd2f65283dd5fa7c3098c0ac435dd 100644 (file)
@@ -7,7 +7,8 @@ BTI
 HAS_32BIT_EL0_DO_NOT_USE
 HAS_32BIT_EL1
 HAS_ADDRESS_AUTH
-HAS_ADDRESS_AUTH_ARCH
+HAS_ADDRESS_AUTH_ARCH_QARMA3
+HAS_ADDRESS_AUTH_ARCH_QARMA5
 HAS_ADDRESS_AUTH_IMP_DEF
 HAS_AMU_EXTN
 HAS_ARMv8_4_TTL
@@ -21,7 +22,8 @@ HAS_E0PD
 HAS_ECV
 HAS_EPAN
 HAS_GENERIC_AUTH
-HAS_GENERIC_AUTH_ARCH
+HAS_GENERIC_AUTH_ARCH_QARMA3
+HAS_GENERIC_AUTH_ARCH_QARMA5
 HAS_GENERIC_AUTH_IMP_DEF
 HAS_IRQ_PRIO_MASKING
 HAS_LDAPR
@@ -44,6 +46,7 @@ MTE_ASYMM
 SPECTRE_V2
 SPECTRE_V3A
 SPECTRE_V4
+SPECTRE_BHB
 SSBS
 SVE
 UNMAP_KERNEL_AT_EL0
index a7e01573abd831c89f065a1ad522ecddab9a9af0..e003b2473c64dfd48fc4f01272f68a7f75c01602 100644 (file)
@@ -8,6 +8,7 @@ menu "Processor type and features"
 
 config IA64
        bool
+       select ARCH_BINFMT_ELF_EXTRA_PHDRS
        select ARCH_HAS_DMA_MARK_CLEAN
        select ARCH_HAS_STRNCPY_FROM_USER
        select ARCH_HAS_STRNLEN_USER
index be2dfab48fd429c05981f20d3106b268949036b8..3137b45750dfcea79f3997d84400f7167debeec2 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
+#include <asm/config.h>
 
 static unsigned long amiga_model;
 
index 581a5f68d10292de3e57a6df49ecef2c72d24c72..42a8b8e2b664226ac9ab5a0cbae70a714c3d9087 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/apollohw.h>
 #include <asm/irq.h>
 #include <asm/machdep.h>
+#include <asm/config.h>
 
 u_long sio01_physaddr;
 u_long sio23_physaddr;
index 261a0f57cc9acbdc4f624ee9a388d14e0cc9c68f..38a7c05781059840743dfecfc686fc01f648a3d9 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/machdep.h>
 #include <asm/hwtest.h>
 #include <asm/io.h>
+#include <asm/config.h>
 
 u_long atari_mch_cookie;
 EXPORT_SYMBOL(atari_mch_cookie);
index 0c6feafbbd110e1943e34980f3f4cefe00264b8f..9b060d466e036e7301f4073715e788dbcfbf7afa 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/bvme6000hw.h>
+#include <asm/config.h>
 
 static void bvme6000_get_model(char *model);
 extern void bvme6000_sched_init(void);
index bc9952f8be6675d7e18b1eb6bf3c669f069f8bfb..49f301c57df5fb0678c3a55a2c87732f262ac468 100644 (file)
@@ -104,7 +104,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -204,7 +203,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -229,7 +227,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -435,6 +432,7 @@ CONFIG_FB_AMIGA_ECS=y
 CONFIG_FB_AMIGA_AGA=y
 CONFIG_FB_FM2=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_DMASOUND_PAULA=m
@@ -643,7 +641,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index a77269c6e5bacfc10258ca0201b20db46d7ef06f..405997b614472b8031523d6f6f00b467422d3537 100644 (file)
@@ -100,7 +100,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -200,7 +199,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -225,7 +223,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -393,6 +390,7 @@ CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
@@ -599,7 +597,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index 7a74efa6b9a1a0d4126e4667194f3ebf8a864626..eb342a33b73e8fc7657beec0b30a9efd935e931c 100644 (file)
@@ -107,7 +107,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -207,7 +206,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -232,7 +230,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -621,7 +618,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index a5323bf2eb3336a89b909b0c3f57446f1f50ba71..e6de6b4dff86eddb9201d97cae540bdaf386891f 100644 (file)
@@ -97,7 +97,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -197,7 +196,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -222,7 +220,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -592,7 +589,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index 5e80aa0869d541092e75cc913a5da846599f3c95..048d9b114eb4348951e2b9fe53fdfe79dbba98ae 100644 (file)
@@ -99,7 +99,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -199,7 +198,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -224,7 +222,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -395,6 +392,7 @@ CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
@@ -601,7 +599,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index e84326a3f62db53c0d889b114cf044dbe46d1b58..4e5b32ba00dfcedcae7d7a04e9ec4ac7aab0b6c5 100644 (file)
@@ -98,7 +98,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -198,7 +197,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -223,7 +221,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -623,7 +620,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index 337552f433390aaee3df02c6a2d717b89eecd0ac..7df61e743591a028c061c318cd4e340100061103 100644 (file)
@@ -118,7 +118,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -218,7 +217,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -243,7 +241,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -497,6 +494,7 @@ CONFIG_FB_ATARI=y
 CONFIG_FB_VALKYRIE=y
 CONFIG_FB_MAC=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_DMASOUND_ATARI=m
@@ -708,7 +706,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index 7b688f7d272a2980e50879628d4445046d6152e1..80922fe80d9dec663584428fe15c2982fdd00250 100644 (file)
@@ -96,7 +96,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -196,7 +195,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -221,7 +219,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -591,7 +588,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index 7c2cb31d63dd8ebba7b303c3087f7898b94137bb..530c4cf7c59ba6d9a9fc2775836526055b109b87 100644 (file)
@@ -97,7 +97,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -197,7 +196,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -222,7 +220,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -592,7 +589,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index ca43897af26de2c8357e302e3ea17f2015353de7..d3f371e490ec058a12e06528a323a17e9d4e76a2 100644 (file)
@@ -98,7 +98,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -198,7 +197,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -223,7 +221,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -610,7 +607,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index e3d515f37144aa33e1d1c59e0f0d8892bbbbf778..db6769790bdb600ccbbc300d3356c272a061c282 100644 (file)
@@ -94,7 +94,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -194,7 +193,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -219,7 +217,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -388,9 +385,6 @@ CONFIG_NTP_PPS=y
 CONFIG_PPS_CLIENT_LDISC=m
 CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
 CONFIG_HID=m
 CONFIG_HIDRAW=y
 CONFIG_UHID=m
@@ -593,7 +587,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index d601606c969b894e72b70bacfa22763c9e1d0fcc..e9c362683666ab48635a27bf533f6ad84db3e759 100644 (file)
@@ -94,7 +94,6 @@ CONFIG_NF_TABLES_NETDEV=y
 CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_FLOW_OFFLOAD=m
-CONFIG_NFT_COUNTER=m
 CONFIG_NFT_CONNLIMIT=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -194,7 +193,6 @@ CONFIG_IP_SET_LIST_SET=m
 CONFIG_NFT_DUP_IPV4=m
 CONFIG_NFT_FIB_IPV4=m
 CONFIG_NF_TABLES_ARP=y
-CONFIG_NF_FLOW_TABLE_IPV4=m
 CONFIG_NF_LOG_ARP=m
 CONFIG_NF_LOG_IPV4=m
 CONFIG_IP_NF_IPTABLES=m
@@ -219,7 +217,6 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NFT_DUP_IPV6=m
 CONFIG_NFT_FIB_IPV6=m
-CONFIG_NF_FLOW_TABLE_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -387,9 +384,6 @@ CONFIG_NTP_PPS=y
 CONFIG_PPS_CLIENT_LDISC=m
 CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
 CONFIG_HID=m
 CONFIG_HIDRAW=y
 CONFIG_UHID=m
@@ -593,7 +587,7 @@ CONFIG_TEST_UUID=m
 CONFIG_TEST_XARRAY=m
 CONFIG_TEST_OVERFLOW=m
 CONFIG_TEST_RHASHTABLE=m
-CONFIG_TEST_HASH=m
+CONFIG_TEST_SIPHASH=m
 CONFIG_TEST_IDA=m
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_VMALLOC=m
index ce1eb3d3d55d2f72e5d22286794d76c22b7740d1..2c92843397c3476f790b2b7d753e9de31ef2b4d7 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/blinken.h>
 #include <asm/io.h>                               /* readb() and writeb() */
 #include <asm/hp300hw.h>
+#include <asm/config.h>
 
 #include "time.h"
 
diff --git a/arch/m68k/include/asm/config.h b/arch/m68k/include/asm/config.h
new file mode 100644 (file)
index 0000000..e73ffa2
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file contains prototypes provided by each m68k machine
+ * to parse bootinfo data structures and to configure the machine
+ */
+
+#ifndef _M68K_CONFIG_H
+#define _M68K_CONFIG_H
+
+extern int amiga_parse_bootinfo(const struct bi_record *record);
+extern int apollo_parse_bootinfo(const struct bi_record *record);
+extern int atari_parse_bootinfo(const struct bi_record *record);
+extern int bvme6000_parse_bootinfo(const struct bi_record *record);
+extern int hp300_parse_bootinfo(const struct bi_record *record);
+extern int mac_parse_bootinfo(const struct bi_record *record);
+extern int mvme147_parse_bootinfo(const struct bi_record *record);
+extern int mvme16x_parse_bootinfo(const struct bi_record *record);
+extern int q40_parse_bootinfo(const struct bi_record *record);
+
+extern void config_amiga(void);
+extern void config_apollo(void);
+extern void config_atari(void);
+extern void config_bvme6000(void);
+extern void config_hp300(void);
+extern void config_mac(void);
+extern void config_mvme147(void);
+extern void config_mvme16x(void);
+extern void config_q40(void);
+extern void config_sun3(void);
+extern void config_sun3x(void);
+
+#endif /* _M68K_CONFIG_H */
index 49e573b9432682f74c2f3324e2163b2fdea479e5..8228275aae3e89b5ca30b646a8aac1ca04428dc4 100644 (file)
@@ -47,6 +47,7 @@
 #endif
 #include <asm/macintosh.h>
 #include <asm/natfeat.h>
+#include <asm/config.h>
 
 #if !FPSTATESIZE || !NR_IRQS
 #warning No CPU/platform type selected, your kernel will not work!
@@ -113,28 +114,6 @@ EXPORT_SYMBOL(isa_type);
 EXPORT_SYMBOL(isa_sex);
 #endif
 
-extern int amiga_parse_bootinfo(const struct bi_record *);
-extern int atari_parse_bootinfo(const struct bi_record *);
-extern int mac_parse_bootinfo(const struct bi_record *);
-extern int q40_parse_bootinfo(const struct bi_record *);
-extern int bvme6000_parse_bootinfo(const struct bi_record *);
-extern int mvme16x_parse_bootinfo(const struct bi_record *);
-extern int mvme147_parse_bootinfo(const struct bi_record *);
-extern int hp300_parse_bootinfo(const struct bi_record *);
-extern int apollo_parse_bootinfo(const struct bi_record *);
-
-extern void config_amiga(void);
-extern void config_atari(void);
-extern void config_mac(void);
-extern void config_sun3(void);
-extern void config_apollo(void);
-extern void config_mvme147(void);
-extern void config_mvme16x(void);
-extern void config_bvme6000(void);
-extern void config_hp300(void);
-extern void config_q40(void);
-extern void config_sun3x(void);
-
 #define MASK_256K 0xfffc0000
 
 extern void paging_init(void);
index 5d16f9b47aa90c9b5bdddb867be0cd82f2e13e55..65d124ec80bb6ec28fa1a5103f5b24f2315d5870 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/mac_via.h>
 #include <asm/mac_oss.h>
 #include <asm/mac_psc.h>
+#include <asm/config.h>
 
 /* Mac bootinfo struct */
 struct mac_booter_data mac_bi_data;
index 1493cf5eac1e7a3931c068ed6b42bdc8b0b249d4..71aa9f6315dc8028dcb17243d6e63df0068119ec 100644 (file)
@@ -93,8 +93,6 @@ retry:
        vma = find_vma(mm, address);
        if (!vma)
                goto map_err;
-       if (vma->vm_flags & VM_IO)
-               goto acc_err;
        if (vma->vm_start <= address)
                goto good_area;
        if (!(vma->vm_flags & VM_GROWSDOWN))
index dfd6202fd403e92b208f5c8ba15c37be2912a298..b96ea7c76a197f9ea40baeedad3bd0c2ce65279c 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/mvme147hw.h>
+#include <asm/config.h>
 
 
 static void mvme147_get_model(char *model);
index b4422c2dfbbf4f7c0a1131dd0dab5413e7cc50f0..88cbdc10925b98b52f79f59716691cea30a422ed 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/mvme16xhw.h>
+#include <asm/config.h>
 
 extern t_bdid mvme_bdid;
 
index 5caf1e5be1c2b48ad6371c0dd60d14b1d16ba8d8..9237243077ceea3cbf8e2548f1ef291f0a1a8d2b 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/q40_master.h>
+#include <asm/config.h>
 
 extern void q40_init_IRQ(void);
 static void q40_get_model(char *model);
index f979adfd4fc202b31527890f086d8b4c11d7fc64..ef73ba1e0ec10474dd108c89445608039a4043ab 100644 (file)
@@ -803,7 +803,7 @@ early_param("coherentio", setcoherentio);
 
 static int __init setnocoherentio(char *str)
 {
-       dma_default_coherent = true;
+       dma_default_coherent = false;
        pr_info("Software DMA cache coherency (command line)\n");
        return 0;
 }
index d542fb7af3ba2e2221c9e05468928c1775450f41..1986d13094100be081563323e4ab2cb0f82c800a 100644 (file)
@@ -351,6 +351,9 @@ asmlinkage void start_secondary(void)
        cpu = smp_processor_id();
        cpu_data[cpu].udelay_val = loops_per_jiffy;
 
+       set_cpu_sibling_map(cpu);
+       set_cpu_core_map(cpu);
+
        cpumask_set_cpu(cpu, &cpu_coherent_mask);
        notify_cpu_starting(cpu);
 
@@ -362,9 +365,6 @@ asmlinkage void start_secondary(void)
        /* The CPU is running and counters synchronised, now mark it online */
        set_cpu_online(cpu, true);
 
-       set_cpu_sibling_map(cpu);
-       set_cpu_core_map(cpu);
-
        calculate_cpu_foreign_map();
 
        /*
index d6efffd4dd2044be81a770e7522c0238f748ac60..fb0565bc34fda33de75f7dd922074431a1dd8d3f 100644 (file)
@@ -22,7 +22,9 @@
 
 #include "common.h"
 
-static void *detect_magic __initdata = detect_memory_region;
+#define MT7621_MEM_TEST_PATTERN         0xaa5555aa
+
+static u32 detect_magic __initdata;
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
@@ -58,24 +60,32 @@ phys_addr_t mips_cpc_default_phys_base(void)
        panic("Cannot detect cpc address");
 }
 
+static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
+{
+       void *dm = (void *)KSEG1ADDR(&detect_magic);
+
+       if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE)
+               return true;
+       __raw_writel(MT7621_MEM_TEST_PATTERN, dm);
+       if (__raw_readl(dm) != __raw_readl(dm + size))
+               return false;
+       __raw_writel(~MT7621_MEM_TEST_PATTERN, dm);
+       return __raw_readl(dm) == __raw_readl(dm + size);
+}
+
 static void __init mt7621_memory_detect(void)
 {
-       void *dm = &detect_magic;
        phys_addr_t size;
 
-       for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
-               if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
-                       break;
+       for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) {
+               if (mt7621_addr_wraparound_test(size)) {
+                       memblock_add(MT7621_LOWMEM_BASE, size);
+                       return;
+               }
        }
 
-       if ((size == 256 * SZ_1M) &&
-           (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
-           __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
-               memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
-               memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
-       } else {
-               memblock_add(MT7621_LOWMEM_BASE, size);
-       }
+       memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
+       memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
 }
 
 void __init ralink_of_remap(void)
index 237d20dd5622de53fb207ec5888f972c7237a9e3..286cec4d86d7b0165a7b81ffcfdc48512a568acf 100644 (file)
@@ -340,7 +340,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
        : "r" (val), "r" (regs->ior), "r" (regs->isr)
        : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
 
-       return 0;
+       return ret;
 }
 static int emulate_std(struct pt_regs *regs, int frreg, int flop)
 {
@@ -397,7 +397,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
        __asm__ __volatile__ (
 "      mtsp    %4, %%sr1\n"
 "      zdep    %2, 29, 2, %%r19\n"
-"      dep     %%r0, 31, 2, %2\n"
+"      dep     %%r0, 31, 2, %3\n"
 "      mtsar   %%r19\n"
 "      zvdepi  -2, 32, %%r19\n"
 "1:    ldw     0(%%sr1,%3),%%r20\n"
@@ -409,7 +409,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
 "      andcm   %%r21, %%r19, %%r21\n"
 "      or      %1, %%r20, %1\n"
 "      or      %2, %%r21, %2\n"
-"3:    stw     %1,0(%%sr1,%1)\n"
+"3:    stw     %1,0(%%sr1,%3)\n"
 "4:    stw     %%r1,4(%%sr1,%3)\n"
 "5:    stw     %2,8(%%sr1,%3)\n"
 "      copy    %%r0, %0\n"
@@ -596,7 +596,6 @@ void handle_unaligned(struct pt_regs *regs)
                ret = ERR_NOTHANDLED;   /* "undefined", but lets kill them. */
                break;
        }
-#ifdef CONFIG_PA20
        switch (regs->iir & OPCODE2_MASK)
        {
        case OPCODE_FLDD_L:
@@ -607,22 +606,23 @@ void handle_unaligned(struct pt_regs *regs)
                flop=1;
                ret = emulate_std(regs, R2(regs->iir),1);
                break;
+#ifdef CONFIG_PA20
        case OPCODE_LDD_L:
                ret = emulate_ldd(regs, R2(regs->iir),0);
                break;
        case OPCODE_STD_L:
                ret = emulate_std(regs, R2(regs->iir),0);
                break;
-       }
 #endif
+       }
        switch (regs->iir & OPCODE3_MASK)
        {
        case OPCODE_FLDW_L:
                flop=1;
-               ret = emulate_ldw(regs, R2(regs->iir),0);
+               ret = emulate_ldw(regs, R2(regs->iir), 1);
                break;
        case OPCODE_LDW_M:
-               ret = emulate_ldw(regs, R2(regs->iir),1);
+               ret = emulate_ldw(regs, R2(regs->iir), 0);
                break;
 
        case OPCODE_FSTW_L:
index ba5b1becf518372696650d62ccab764b98d133a9..006cbec70ffe5d3c553586b805a64d33ae25bb22 100644 (file)
@@ -202,7 +202,6 @@ static inline struct subpage_prot_table *mm_ctx_subpage_prot(mm_context_t *ctx)
 /*
  * The current system page and segment sizes
  */
-extern int mmu_linear_psize;
 extern int mmu_virtual_psize;
 extern int mmu_vmalloc_psize;
 extern int mmu_io_psize;
@@ -213,6 +212,7 @@ extern int mmu_io_psize;
 #define mmu_virtual_psize MMU_PAGE_4K
 #endif
 #endif
+extern int mmu_linear_psize;
 extern int mmu_vmemmap_psize;
 
 /* MMU initialization */
index 7a90000f8d15298dbee9280254ec39f30680a1d6..f83866a19e870f9462cd5e707bcb03651a0847bd 100644 (file)
@@ -9,7 +9,7 @@ struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges);
 int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
 int add_tce_mem_ranges(struct crash_mem **mem_ranges);
 int add_initrd_mem_range(struct crash_mem **mem_ranges);
-#ifdef CONFIG_PPC_BOOK3S_64
+#ifdef CONFIG_PPC_64S_HASH_MMU
 int add_htab_mem_range(struct crash_mem **mem_ranges);
 #else
 static inline int add_htab_mem_range(struct crash_mem **mem_ranges)
index 160abcb8e9fab22c22c4bf0b6269b1098afe9901..ea0e487f87b1f8629e5ee2d35d9f15f98d935be8 100644 (file)
@@ -9,7 +9,7 @@ long soft_nmi_interrupt(struct pt_regs *regs);
 static inline void arch_touch_nmi_watchdog(void) {}
 #endif
 
-#if defined(CONFIG_NMI_IPI) && defined(CONFIG_STACKTRACE)
+#ifdef CONFIG_NMI_IPI
 extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask,
                                           bool exclude_self);
 #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
index b44d6ecdb46e5c5241ccb70bd293c031f3abb07d..0aacd7052585b5e2820bbcc633a5e8126cbef923 100644 (file)
@@ -2,6 +2,7 @@ menu "CPU errata selection"
 
 config RISCV_ERRATA_ALTERNATIVE
        bool "RISC-V alternative scheme"
+       depends on !XIP_KERNEL
        default y
        help
          This Kconfig allows the kernel to automatically patch the
index 6ec44a22278a419132ece3b12436010a52b7d1b3..c112ab2a90520a0b8e6923f3c32900f0cda40020 100644 (file)
@@ -14,8 +14,8 @@ config SOC_SIFIVE
        select CLK_SIFIVE
        select CLK_SIFIVE_PRCI
        select SIFIVE_PLIC
-       select RISCV_ERRATA_ALTERNATIVE
-       select ERRATA_SIFIVE
+       select RISCV_ERRATA_ALTERNATIVE if !XIP_KERNEL
+       select ERRATA_SIFIVE if !XIP_KERNEL
        help
          This enables support for SiFive SoC platform hardware.
 
index 56f57118c633b91a7c0cd54cc2df05584da29f0b..44d33851476125cb7721dea068558abd1b872981 100644 (file)
                        compatible = "canaan,k210-plic", "sifive,plic-1.0.0";
                        reg = <0xC000000 0x4000000>;
                        interrupt-controller;
-                       interrupts-extended = <&cpu0_intc 11>, <&cpu1_intc 11>;
+                       interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
+                                             <&cpu1_intc 11>, <&cpu1_intc 9>;
                        riscv,ndev = <65>;
                };
 
index 2a82a3b2992b2824c29efd1cd1902b6c9d3b2659..af64b95e88cc636e8369306a7203023623066343 100644 (file)
@@ -23,7 +23,7 @@ CONFIG_SLOB=y
 CONFIG_SOC_CANAAN=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
-CONFIG_CMDLINE="earlycon console=ttySIF0 rootdelay=2 root=/dev/mmcblk0p1 ro"
+CONFIG_CMDLINE="earlycon console=ttySIF0 root=/dev/mmcblk0p1 rootwait ro"
 CONFIG_CMDLINE_FORCE=y
 # CONFIG_SECCOMP is not set
 # CONFIG_STACKPROTECTOR is not set
index 160e3a1e8f8be72f0a12b9d24c0a9dab45b0e60d..004372f8da544fccb8519ec6591067181c18eea0 100644 (file)
@@ -119,7 +119,7 @@ extern phys_addr_t phys_ram_base;
        ((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
 
 #define is_linear_mapping(x)   \
-       ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < kernel_map.virt_addr))
+       ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < PAGE_OFFSET + KERN_VIRT_SIZE))
 
 #define linear_mapping_pa_to_va(x)     ((void *)((unsigned long)(x) + kernel_map.va_pa_offset))
 #define kernel_mapping_pa_to_va(y)     ({                                              \
index 7e949f25c93347728a6f87761d4f1396a483c7b7..e3549e50de95c1e76d20a7dc58a008d8c2b3d64a 100644 (file)
@@ -13,6 +13,7 @@
 
 #ifndef CONFIG_MMU
 #define KERNEL_LINK_ADDR       PAGE_OFFSET
+#define KERN_VIRT_SIZE         (UL(-1))
 #else
 
 #define ADDRESS_SPACE_END      (UL(-1))
index 612556faa527f583cf6fc3bc9a737adcaa18a105..ffc87e76b1ddf093bd11274a4e08be197e04a34c 100644 (file)
@@ -51,6 +51,8 @@ obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o
 obj-$(CONFIG_FUNCTION_TRACER)  += mcount.o ftrace.o
 obj-$(CONFIG_DYNAMIC_FTRACE)   += mcount-dyn.o
 
+obj-$(CONFIG_TRACE_IRQFLAGS)   += trace_irq.o
+
 obj-$(CONFIG_RISCV_BASE_PMU)   += perf_event.o
 obj-$(CONFIG_PERF_EVENTS)      += perf_callchain.o
 obj-$(CONFIG_HAVE_PERF_REGS)   += perf_regs.o
index ed29e9c8f660c6ee79f2fbe3bd67cdf537007a85..d6a46ed0bf051bcb2f541461fdca64f23303fcaf 100644 (file)
@@ -108,7 +108,7 @@ _save_context:
 .option pop
 
 #ifdef CONFIG_TRACE_IRQFLAGS
-       call trace_hardirqs_off
+       call __trace_hardirqs_off
 #endif
 
 #ifdef CONFIG_CONTEXT_TRACKING
@@ -143,7 +143,7 @@ skip_context_tracking:
        li t0, EXC_BREAKPOINT
        beq s4, t0, 1f
 #ifdef CONFIG_TRACE_IRQFLAGS
-       call trace_hardirqs_on
+       call __trace_hardirqs_on
 #endif
        csrs CSR_STATUS, SR_IE
 
@@ -234,7 +234,7 @@ ret_from_exception:
        REG_L s0, PT_STATUS(sp)
        csrc CSR_STATUS, SR_IE
 #ifdef CONFIG_TRACE_IRQFLAGS
-       call trace_hardirqs_off
+       call __trace_hardirqs_off
 #endif
 #ifdef CONFIG_RISCV_M_MODE
        /* the MPP value is too large to be used as an immediate arg for addi */
@@ -270,10 +270,10 @@ restore_all:
        REG_L s1, PT_STATUS(sp)
        andi t0, s1, SR_PIE
        beqz t0, 1f
-       call trace_hardirqs_on
+       call __trace_hardirqs_on
        j 2f
 1:
-       call trace_hardirqs_off
+       call __trace_hardirqs_off
 2:
 #endif
        REG_L a0, PT_STATUS(sp)
index 68a9e3d1fe16a04393bb2adfa334f20138362ee7..4a48287513c375b5f5c5016bd8d09666b3dbcec7 100644 (file)
 #include <linux/pgtable.h>
 #include <asm/sections.h>
 
+/*
+ * The auipc+jalr instruction pair can reach any PC-relative offset
+ * in the range [-2^31 - 2^11, 2^31 - 2^11)
+ */
+static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
+{
+#ifdef CONFIG_32BIT
+       return true;
+#else
+       return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11));
+#endif
+}
+
 static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
 {
        if (v != (u32)v) {
@@ -95,7 +108,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
        ptrdiff_t offset = (void *)v - (void *)location;
        s32 hi20;
 
-       if (offset != (s32)offset) {
+       if (!riscv_insn_valid_32bit_offset(offset)) {
                pr_err(
                  "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
                  me->name, (long long)v, location);
@@ -197,10 +210,9 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
                                       Elf_Addr v)
 {
        ptrdiff_t offset = (void *)v - (void *)location;
-       s32 fill_v = offset;
        u32 hi20, lo12;
 
-       if (offset != fill_v) {
+       if (!riscv_insn_valid_32bit_offset(offset)) {
                /* Only emit the plt entry if offset over 32-bit range */
                if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
                        offset = module_emit_plt_entry(me, v);
@@ -224,10 +236,9 @@ static int apply_r_riscv_call_rela(struct module *me, u32 *location,
                                   Elf_Addr v)
 {
        ptrdiff_t offset = (void *)v - (void *)location;
-       s32 fill_v = offset;
        u32 hi20, lo12;
 
-       if (offset != fill_v) {
+       if (!riscv_insn_valid_32bit_offset(offset)) {
                pr_err(
                  "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
                  me->name, (long long)v, location);
diff --git a/arch/riscv/kernel/trace_irq.c b/arch/riscv/kernel/trace_irq.c
new file mode 100644 (file)
index 0000000..095ac97
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Changbin Du <changbin.du@gmail.com>
+ */
+
+#include <linux/irqflags.h>
+#include <linux/kprobes.h>
+#include "trace_irq.h"
+
+/*
+ * trace_hardirqs_on/off require the caller to setup frame pointer properly.
+ * Otherwise, CALLER_ADDR1 might trigger an pagging exception in kernel.
+ * Here we add one extra level so they can be safely called by low
+ * level entry code which $fp is used for other purpose.
+ */
+
+void __trace_hardirqs_on(void)
+{
+       trace_hardirqs_on();
+}
+NOKPROBE_SYMBOL(__trace_hardirqs_on);
+
+void __trace_hardirqs_off(void)
+{
+       trace_hardirqs_off();
+}
+NOKPROBE_SYMBOL(__trace_hardirqs_off);
diff --git a/arch/riscv/kernel/trace_irq.h b/arch/riscv/kernel/trace_irq.h
new file mode 100644 (file)
index 0000000..99fe673
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 Changbin Du <changbin.du@gmail.com>
+ */
+#ifndef __TRACE_IRQ_H
+#define __TRACE_IRQ_H
+
+void __trace_hardirqs_on(void);
+void __trace_hardirqs_off(void);
+
+#endif /* __TRACE_IRQ_H */
index 7ebaef10ea1b69e1557c9d08fec4d288ac31e842..ac7a25298a04af665ff0552d99a95e1671013ddd 100644 (file)
@@ -24,6 +24,9 @@ obj-$(CONFIG_KASAN)   += kasan_init.o
 ifdef CONFIG_KASAN
 KASAN_SANITIZE_kasan_init.o := n
 KASAN_SANITIZE_init.o := n
+ifdef CONFIG_DEBUG_VIRTUAL
+KASAN_SANITIZE_physaddr.o := n
+endif
 endif
 
 obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
index c27294128e182d77d8f0b7e29ac35b4549069943..0d588032d6e69e3c8513c353d7b0d77da947fa4e 100644 (file)
@@ -125,7 +125,6 @@ void __init mem_init(void)
        else
                swiotlb_force = SWIOTLB_NO_FORCE;
 #endif
-       high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
        memblock_free_all();
 
        print_vm_layout();
@@ -195,6 +194,7 @@ static void __init setup_bootmem(void)
 
        min_low_pfn = PFN_UP(phys_ram_base);
        max_low_pfn = max_pfn = PFN_DOWN(phys_ram_end);
+       high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
 
        dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
        set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
index f61f7ca6fe0fde512c6909eeec795f424123c0f6..cd1a145257b7cd9f2a4ad8d225925772bf2151d3 100644 (file)
@@ -113,8 +113,11 @@ static void __init kasan_populate_pud(pgd_t *pgd,
                base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd)));
        } else {
                base_pud = (pud_t *)pgd_page_vaddr(*pgd);
-               if (base_pud == lm_alias(kasan_early_shadow_pud))
+               if (base_pud == lm_alias(kasan_early_shadow_pud)) {
                        base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE);
+                       memcpy(base_pud, (void *)kasan_early_shadow_pud,
+                              sizeof(pud_t) * PTRS_PER_PUD);
+               }
        }
 
        pudp = base_pud + pud_index(vaddr);
@@ -202,8 +205,7 @@ asmlinkage void __init kasan_early_init(void)
 
        for (i = 0; i < PTRS_PER_PTE; ++i)
                set_pte(kasan_early_shadow_pte + i,
-                       mk_pte(virt_to_page(kasan_early_shadow_page),
-                              PAGE_KERNEL));
+                       pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL));
 
        for (i = 0; i < PTRS_PER_PMD; ++i)
                set_pmd(kasan_early_shadow_pmd + i,
index e7fd0c253c7b29c3006bf5c29b9de5d3a7c72f52..19cf25a74ee29dc4fafb31fa1ef5eda17255906c 100644 (file)
@@ -8,12 +8,10 @@
 
 phys_addr_t __virt_to_phys(unsigned long x)
 {
-       phys_addr_t y = x - PAGE_OFFSET;
-
        /*
         * Boundary checking aginst the kernel linear mapping space.
         */
-       WARN(y >= KERN_VIRT_SIZE,
+       WARN(!is_linear_mapping(x) && !is_kernel_mapping(x),
             "virt_to_phys used for non-linear address: %pK (%pS)\n",
             (void *)x, (void *)x);
 
index 16dc57dd90b303bdc6a89809915cdbbc807c3905..8511f0e59290fa1045f8f2c1195720e1fbb7b4d6 100644 (file)
@@ -69,8 +69,13 @@ static inline void swap_ex_entry_fixup(struct exception_table_entry *a,
 {
        a->fixup = b->fixup + delta;
        b->fixup = tmp.fixup - delta;
-       a->handler = b->handler + delta;
-       b->handler = tmp.handler - delta;
+       a->handler = b->handler;
+       if (a->handler)
+               a->handler += delta;
+       b->handler = tmp.handler;
+       if (b->handler)
+               b->handler -= delta;
 }
+#define swap_ex_entry_fixup swap_ex_entry_fixup
 
 #endif
index 267f70f4393f7650abb919831c4e32dd0610d1ad..6f80ec9c04be9bf4ffc4db69b9ba0a76eb1672df 100644 (file)
@@ -47,15 +47,17 @@ struct ftrace_regs {
 
 static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
 {
-       return &fregs->regs;
+       struct pt_regs *regs = &fregs->regs;
+
+       if (test_pt_regs_flag(regs, PIF_FTRACE_FULL_REGS))
+               return regs;
+       return NULL;
 }
 
 static __always_inline void ftrace_instruction_pointer_set(struct ftrace_regs *fregs,
                                                           unsigned long ip)
 {
-       struct pt_regs *regs = arch_ftrace_get_regs(fregs);
-
-       regs->psw.addr = ip;
+       fregs->regs.psw.addr = ip;
 }
 
 /*
index 4ffa8e7f0ed3acb439cad08f5ff46e051335e561..ddb70fb13fbc99a0c374c2a455f57dbb43675013 100644 (file)
 #define PIF_EXECVE_PGSTE_RESTART       1       /* restart execve for PGSTE binaries */
 #define PIF_SYSCALL_RET_SET            2       /* return value was set via ptrace */
 #define PIF_GUEST_FAULT                        3       /* indicates program check in sie64a */
+#define PIF_FTRACE_FULL_REGS           4       /* all register contents valid (ftrace) */
 
 #define _PIF_SYSCALL                   BIT(PIF_SYSCALL)
 #define _PIF_EXECVE_PGSTE_RESTART      BIT(PIF_EXECVE_PGSTE_RESTART)
 #define _PIF_SYSCALL_RET_SET           BIT(PIF_SYSCALL_RET_SET)
 #define _PIF_GUEST_FAULT               BIT(PIF_GUEST_FAULT)
+#define _PIF_FTRACE_FULL_REGS          BIT(PIF_FTRACE_FULL_REGS)
 
 #ifndef __ASSEMBLY__
 
index 21d62d8b6b9afe7f8698a5d2e796a7fdef0d1639..89c0870d56792ccfe681aaa68fde7ab2a74045ac 100644 (file)
@@ -159,9 +159,38 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
        return 0;
 }
 
+static struct ftrace_hotpatch_trampoline *ftrace_get_trampoline(struct dyn_ftrace *rec)
+{
+       struct ftrace_hotpatch_trampoline *trampoline;
+       struct ftrace_insn insn;
+       s64 disp;
+       u16 opc;
+
+       if (copy_from_kernel_nofault(&insn, (void *)rec->ip, sizeof(insn)))
+               return ERR_PTR(-EFAULT);
+       disp = (s64)insn.disp * 2;
+       trampoline = (void *)(rec->ip + disp);
+       if (get_kernel_nofault(opc, &trampoline->brasl_opc))
+               return ERR_PTR(-EFAULT);
+       if (opc != 0xc015)
+               return ERR_PTR(-EINVAL);
+       return trampoline;
+}
+
 int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
                       unsigned long addr)
 {
+       struct ftrace_hotpatch_trampoline *trampoline;
+       u64 old;
+
+       trampoline = ftrace_get_trampoline(rec);
+       if (IS_ERR(trampoline))
+               return PTR_ERR(trampoline);
+       if (get_kernel_nofault(old, &trampoline->interceptor))
+               return -EFAULT;
+       if (old != old_addr)
+               return -EINVAL;
+       s390_kernel_write(&trampoline->interceptor, &addr, sizeof(addr));
        return 0;
 }
 
@@ -188,6 +217,12 @@ static void brcl_enable(void *brcl)
 
 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
+       struct ftrace_hotpatch_trampoline *trampoline;
+
+       trampoline = ftrace_get_trampoline(rec);
+       if (IS_ERR(trampoline))
+               return PTR_ERR(trampoline);
+       s390_kernel_write(&trampoline->interceptor, &addr, sizeof(addr));
        brcl_enable((void *)rec->ip);
        return 0;
 }
@@ -291,7 +326,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
 
        regs = ftrace_get_regs(fregs);
        p = get_kprobe((kprobe_opcode_t *)ip);
-       if (unlikely(!p) || kprobe_disabled(p))
+       if (!regs || unlikely(!p) || kprobe_disabled(p))
                goto out;
 
        if (kprobe_running()) {
index 39bcc0e39a10d7d0e63ec3a5dd0921a9d8fd9941..a24177dcd12a85a335c2c974b4f9fdad5d94fe59 100644 (file)
@@ -27,6 +27,7 @@ ENDPROC(ftrace_stub)
 #define STACK_PTREGS_GPRS      (STACK_PTREGS + __PT_GPRS)
 #define STACK_PTREGS_PSW       (STACK_PTREGS + __PT_PSW)
 #define STACK_PTREGS_ORIG_GPR2 (STACK_PTREGS + __PT_ORIG_GPR2)
+#define STACK_PTREGS_FLAGS     (STACK_PTREGS + __PT_FLAGS)
 #ifdef __PACK_STACK
 /* allocate just enough for r14, r15 and backchain */
 #define TRACED_FUNC_FRAME_SIZE 24
@@ -57,6 +58,14 @@ ENDPROC(ftrace_stub)
        .if \allregs == 1
        stg     %r14,(STACK_PTREGS_PSW)(%r15)
        stosm   (STACK_PTREGS_PSW)(%r15),0
+#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
+       mvghi   STACK_PTREGS_FLAGS(%r15),_PIF_FTRACE_FULL_REGS
+#else
+       lghi    %r14,_PIF_FTRACE_FULL_REGS
+       stg     %r14,STACK_PTREGS_FLAGS(%r15)
+#endif
+       .else
+       xc      STACK_PTREGS_FLAGS(8,%r15),STACK_PTREGS_FLAGS(%r15)
        .endif
 
        lg      %r14,(__SF_GPRS+8*8)(%r1)       # restore original return address
index f2c25d113e7bef1766f393935d326fd4be50136c..05327be3a982a663013109699c881100e05094a8 100644 (file)
@@ -800,6 +800,8 @@ static void __init check_initrd(void)
 static void __init reserve_kernel(void)
 {
        memblock_reserve(0, STARTUP_NORMAL_OFFSET);
+       memblock_reserve(OLDMEM_BASE, sizeof(unsigned long));
+       memblock_reserve(OLDMEM_SIZE, sizeof(unsigned long));
        memblock_reserve(__amode31_base, __eamode31 - __samode31);
        memblock_reserve(__pa(sclp_early_sccb), EXT_SCCB_READ_SCP);
        memblock_reserve(__pa(_stext), _end - _stext);
index f384cb1a4f7a8ddca2f73e2cdf4b80bdb3445464..5a83da703e8766199f3123f0c915f8743a5e1847 100644 (file)
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += coco/
+
 obj-y += entry/
 
 obj-$(CONFIG_PERF_EVENTS) += events/
index 9f5bd41bf660c7b024e6cf0838e6b7a3cf31b54e..391c4cac8958f8a4677278b9097c423d85107f0d 100644 (file)
@@ -1638,7 +1638,7 @@ config ARCH_SPARSEMEM_DEFAULT
 
 config ARCH_SELECT_MEMORY_MODEL
        def_bool y
-       depends on ARCH_SPARSEMEM_ENABLE
+       depends on ARCH_SPARSEMEM_ENABLE && ARCH_FLATMEM_ENABLE
 
 config ARCH_MEMORY_PROBE
        bool "Enable sysfs memory/probe interface"
index 659fad53ca82342b9b31be4d334659b0c6c73ebe..3b354eb9516df416e8e2a595044c016fabf6f98f 100644 (file)
@@ -152,14 +152,13 @@ SYM_FUNC_END(startup_32)
 
 #ifdef CONFIG_EFI_STUB
 SYM_FUNC_START(efi32_stub_entry)
-SYM_FUNC_START_ALIAS(efi_stub_entry)
        add     $0x4, %esp
        movl    8(%esp), %esi   /* save boot_params pointer */
        call    efi_main
        /* efi_main returns the possibly relocated address of startup_32 */
        jmp     *%eax
 SYM_FUNC_END(efi32_stub_entry)
-SYM_FUNC_END_ALIAS(efi_stub_entry)
+SYM_FUNC_ALIAS(efi_stub_entry, efi32_stub_entry)
 #endif
 
        .text
index fd9441f404570986ccc8338221bf2b877509e07f..dea95301196b8550fdd3faa81355bb20eeba93c8 100644 (file)
@@ -535,7 +535,6 @@ SYM_CODE_END(startup_64)
 #ifdef CONFIG_EFI_STUB
        .org 0x390
 SYM_FUNC_START(efi64_stub_entry)
-SYM_FUNC_START_ALIAS(efi_stub_entry)
        and     $~0xf, %rsp                     /* realign the stack */
        movq    %rdx, %rbx                      /* save boot_params pointer */
        call    efi_main
@@ -543,7 +542,7 @@ SYM_FUNC_START_ALIAS(efi_stub_entry)
        leaq    rva(startup_64)(%rax), %rax
        jmp     *%rax
 SYM_FUNC_END(efi64_stub_entry)
-SYM_FUNC_END_ALIAS(efi_stub_entry)
+SYM_FUNC_ALIAS(efi_stub_entry, efi64_stub_entry)
 #endif
 
        .text
diff --git a/arch/x86/coco/Makefile b/arch/x86/coco/Makefile
new file mode 100644 (file)
index 0000000..c1ead00
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+CFLAGS_REMOVE_core.o   = -pg
+KASAN_SANITIZE_core.o  := n
+CFLAGS_core.o          += -fno-stack-protector
+
+obj-y += core.o
diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
new file mode 100644 (file)
index 0000000..fc1365d
--- /dev/null
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Confidential Computing Platform Capability checks
+ *
+ * Copyright (C) 2021 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky <thomas.lendacky@amd.com>
+ */
+
+#include <linux/export.h>
+#include <linux/cc_platform.h>
+
+#include <asm/coco.h>
+#include <asm/processor.h>
+
+static enum cc_vendor vendor __ro_after_init;
+static u64 cc_mask __ro_after_init;
+
+static bool intel_cc_platform_has(enum cc_attr attr)
+{
+       return false;
+}
+
+/*
+ * SME and SEV are very similar but they are not the same, so there are
+ * times that the kernel will need to distinguish between SME and SEV. The
+ * cc_platform_has() function is used for this.  When a distinction isn't
+ * needed, the CC_ATTR_MEM_ENCRYPT attribute can be used.
+ *
+ * The trampoline code is a good example for this requirement.  Before
+ * paging is activated, SME will access all memory as decrypted, but SEV
+ * will access all memory as encrypted.  So, when APs are being brought
+ * up under SME the trampoline area cannot be encrypted, whereas under SEV
+ * the trampoline area must be encrypted.
+ */
+static bool amd_cc_platform_has(enum cc_attr attr)
+{
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+       switch (attr) {
+       case CC_ATTR_MEM_ENCRYPT:
+               return sme_me_mask;
+
+       case CC_ATTR_HOST_MEM_ENCRYPT:
+               return sme_me_mask && !(sev_status & MSR_AMD64_SEV_ENABLED);
+
+       case CC_ATTR_GUEST_MEM_ENCRYPT:
+               return sev_status & MSR_AMD64_SEV_ENABLED;
+
+       case CC_ATTR_GUEST_STATE_ENCRYPT:
+               return sev_status & MSR_AMD64_SEV_ES_ENABLED;
+
+       /*
+        * With SEV, the rep string I/O instructions need to be unrolled
+        * but SEV-ES supports them through the #VC handler.
+        */
+       case CC_ATTR_GUEST_UNROLL_STRING_IO:
+               return (sev_status & MSR_AMD64_SEV_ENABLED) &&
+                       !(sev_status & MSR_AMD64_SEV_ES_ENABLED);
+
+       default:
+               return false;
+       }
+#else
+       return false;
+#endif
+}
+
+static bool hyperv_cc_platform_has(enum cc_attr attr)
+{
+       return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
+}
+
+bool cc_platform_has(enum cc_attr attr)
+{
+       switch (vendor) {
+       case CC_VENDOR_AMD:
+               return amd_cc_platform_has(attr);
+       case CC_VENDOR_INTEL:
+               return intel_cc_platform_has(attr);
+       case CC_VENDOR_HYPERV:
+               return hyperv_cc_platform_has(attr);
+       default:
+               return false;
+       }
+}
+EXPORT_SYMBOL_GPL(cc_platform_has);
+
+u64 cc_mkenc(u64 val)
+{
+       switch (vendor) {
+       case CC_VENDOR_AMD:
+               return val | cc_mask;
+       default:
+               return val;
+       }
+}
+
+u64 cc_mkdec(u64 val)
+{
+       switch (vendor) {
+       case CC_VENDOR_AMD:
+               return val & ~cc_mask;
+       default:
+               return val;
+       }
+}
+EXPORT_SYMBOL_GPL(cc_mkdec);
+
+__init void cc_set_vendor(enum cc_vendor v)
+{
+       vendor = v;
+}
+
+__init void cc_set_mask(u64 mask)
+{
+       cc_mask = mask;
+}
index 363699dd72206e67d15ea757a76c6858eee9e0c0..837c1e0aa0217783896dfd45b66f761e103cf8a6 100644 (file)
@@ -1751,8 +1751,6 @@ SYM_FUNC_END(aesni_gcm_finalize)
 
 #endif
 
-
-SYM_FUNC_START_LOCAL_ALIAS(_key_expansion_128)
 SYM_FUNC_START_LOCAL(_key_expansion_256a)
        pshufd $0b11111111, %xmm1, %xmm1
        shufps $0b00010000, %xmm0, %xmm4
@@ -1764,7 +1762,7 @@ SYM_FUNC_START_LOCAL(_key_expansion_256a)
        add $0x10, TKEYP
        RET
 SYM_FUNC_END(_key_expansion_256a)
-SYM_FUNC_END_ALIAS(_key_expansion_128)
+SYM_FUNC_ALIAS_LOCAL(_key_expansion_128, _key_expansion_256a)
 
 SYM_FUNC_START_LOCAL(_key_expansion_192a)
        pshufd $0b01010101, %xmm1, %xmm1
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
new file mode 100644 (file)
index 0000000..3d98c3a
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_COCO_H
+#define _ASM_X86_COCO_H
+
+#include <asm/types.h>
+
+enum cc_vendor {
+       CC_VENDOR_NONE,
+       CC_VENDOR_AMD,
+       CC_VENDOR_HYPERV,
+       CC_VENDOR_INTEL,
+};
+
+void cc_set_vendor(enum cc_vendor v);
+void cc_set_mask(u64 mask);
+
+#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
+u64 cc_mkenc(u64 val);
+u64 cc_mkdec(u64 val);
+#else
+static inline u64 cc_mkenc(u64 val)
+{
+       return val;
+}
+
+static inline u64 cc_mkdec(u64 val)
+{
+       return val;
+}
+#endif
+
+#endif /* _ASM_X86_COCO_H */
index 6db4e2932b3d865785f179f5486106803b13629e..f7436fccc07645ac20cc3a58b36fc2c55286b8cd 100644 (file)
 /* FREE!                                ( 7*32+10) */
 #define X86_FEATURE_PTI                        ( 7*32+11) /* Kernel Page Table Isolation enabled */
 #define X86_FEATURE_RETPOLINE          ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
-#define X86_FEATURE_RETPOLINE_AMD      ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
+#define X86_FEATURE_RETPOLINE_LFENCE   ( 7*32+13) /* "" Use LFENCE for Spectre variant 2 */
 #define X86_FEATURE_INTEL_PPIN         ( 7*32+14) /* Intel Processor Inventory Number */
 #define X86_FEATURE_CDP_L2             ( 7*32+15) /* Code and Data Prioritization L2 */
 #define X86_FEATURE_MSR_SPEC_CTRL      ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX_VNNI           (12*32+ 4) /* AVX VNNI instructions */
 #define X86_FEATURE_AVX512_BF16                (12*32+ 5) /* AVX512 BFLOAT16 instructions */
-#define X86_FEATURE_AMX_BF16           (18*32+22) /* AMX bf16 Support */
-#define X86_FEATURE_AMX_TILE           (18*32+24) /* AMX tile Support */
-#define X86_FEATURE_AMX_INT8           (18*32+25) /* AMX int8 Support */
 
 /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
 #define X86_FEATURE_CLZERO             (13*32+ 0) /* CLZERO instruction */
 #define X86_FEATURE_TSXLDTRK           (18*32+16) /* TSX Suspend Load Address Tracking */
 #define X86_FEATURE_PCONFIG            (18*32+18) /* Intel PCONFIG */
 #define X86_FEATURE_ARCH_LBR           (18*32+19) /* Intel ARCH LBR */
+#define X86_FEATURE_AMX_BF16           (18*32+22) /* AMX bf16 Support */
 #define X86_FEATURE_AVX512_FP16                (18*32+23) /* AVX512 FP16 */
+#define X86_FEATURE_AMX_TILE           (18*32+24) /* AMX tile Support */
+#define X86_FEATURE_AMX_INT8           (18*32+25) /* AMX int8 Support */
 #define X86_FEATURE_SPEC_CTRL          (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
 #define X86_FEATURE_INTEL_STIBP                (18*32+27) /* "" Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_FLUSH_L1D          (18*32+28) /* Flush L1D cache */
index 05a6ab940f452d48944262c70aba0d8bf663d954..1b29f58f730fde4d2510fa4c7ce3e82600fb40f1 100644 (file)
@@ -124,7 +124,7 @@ struct insn {
 #define X86_VEX_B(vex) ((vex) & 0x20)  /* VEX3 Byte1 */
 #define X86_VEX_L(vex) ((vex) & 0x04)  /* VEX3 Byte2, VEX2 Byte1 */
 /* VEX bit fields */
-#define X86_EVEX_M(vex)        ((vex) & 0x03)          /* EVEX Byte1 */
+#define X86_EVEX_M(vex)        ((vex) & 0x07)          /* EVEX Byte1 */
 #define X86_VEX3_M(vex)        ((vex) & 0x1f)          /* VEX3 Byte1 */
 #define X86_VEX2_M     1                       /* VEX2.M always 1 */
 #define X86_VEX_V(vex) (((vex) & 0x78) >> 3)   /* VEX3 Byte2, VEX2 Byte1 */
index 6dcccb304775411a8f38738526c79a5aa670c820..ec9830d2aabf8882ad12b96fb21a9c6bf7dee84b 100644 (file)
@@ -703,7 +703,6 @@ struct kvm_vcpu_arch {
        struct fpu_guest guest_fpu;
 
        u64 xcr0;
-       u64 guest_supported_xcr0;
 
        struct kvm_pio_request pio;
        void *pio_data;
index cc74dc584836e874de5f83ce1ca4eb17fa13c3f7..acbaeaf83b61adc1f9d0e103eab18e4328047775 100644 (file)
@@ -84,7 +84,7 @@
 #ifdef CONFIG_RETPOLINE
        ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
                      __stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
-                     __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD
+                     __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_LFENCE
 #else
        jmp     *%\reg
 #endif
@@ -94,7 +94,7 @@
 #ifdef CONFIG_RETPOLINE
        ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \
                      __stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
-                     __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_AMD
+                     __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_LFENCE
 #else
        call    *%\reg
 #endif
@@ -146,7 +146,7 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
        "lfence;\n"                                             \
        ANNOTATE_RETPOLINE_SAFE                                 \
        "call *%[thunk_target]\n",                              \
-       X86_FEATURE_RETPOLINE_AMD)
+       X86_FEATURE_RETPOLINE_LFENCE)
 
 # define THUNK_TARGET(addr) [thunk_target] "r" (addr)
 
@@ -176,7 +176,7 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
        "lfence;\n"                                             \
        ANNOTATE_RETPOLINE_SAFE                                 \
        "call *%[thunk_target]\n",                              \
-       X86_FEATURE_RETPOLINE_AMD)
+       X86_FEATURE_RETPOLINE_LFENCE)
 
 # define THUNK_TARGET(addr) [thunk_target] "rm" (addr)
 #endif
@@ -188,9 +188,11 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
 /* The Spectre V2 mitigation variants */
 enum spectre_v2_mitigation {
        SPECTRE_V2_NONE,
-       SPECTRE_V2_RETPOLINE_GENERIC,
-       SPECTRE_V2_RETPOLINE_AMD,
-       SPECTRE_V2_IBRS_ENHANCED,
+       SPECTRE_V2_RETPOLINE,
+       SPECTRE_V2_LFENCE,
+       SPECTRE_V2_EIBRS,
+       SPECTRE_V2_EIBRS_RETPOLINE,
+       SPECTRE_V2_EIBRS_LFENCE,
 };
 
 /* The indirect branch speculation control variants */
index a69012e1903f1d6edab3cc56782fc0382955b64e..e1591467668ed27cdd12e4235e0dd9e6be2fd596 100644 (file)
@@ -279,7 +279,7 @@ extern void (*paravirt_iret)(void);
 
 #define paravirt_type(op)                              \
        [paravirt_typenum] "i" (PARAVIRT_PATCH(op)),    \
-       [paravirt_opptr] "i" (&(pv_ops.op))
+       [paravirt_opptr] "m" (pv_ops.op)
 #define paravirt_clobber(clobber)              \
        [paravirt_clobber] "i" (clobber)
 
@@ -316,7 +316,7 @@ int paravirt_disable_iospace(void);
  */
 #define PARAVIRT_CALL                                  \
        ANNOTATE_RETPOLINE_SAFE                         \
-       "call *%c[paravirt_opptr];"
+       "call *%[paravirt_opptr];"
 
 /*
  * These macros are intended to wrap calls through one of the paravirt
index 8a9432fb3802b3f60e12331b23e43b78f48cddc8..62ab07e24aef93093d0bfa7793c78c672a2759eb 100644 (file)
                     cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)))     \
         : (prot))
 
-/*
- * Macros to add or remove encryption attribute
- */
-#define pgprot_encrypted(prot) __pgprot(__sme_set(pgprot_val(prot)))
-#define pgprot_decrypted(prot) __pgprot(__sme_clr(pgprot_val(prot)))
-
 #ifndef __ASSEMBLY__
 #include <linux/spinlock.h>
 #include <asm/x86_init.h>
 #include <asm/pkru.h>
 #include <asm/fpu/api.h>
+#include <asm/coco.h>
 #include <asm-generic/pgtable_uffd.h>
 #include <linux/page_table_check.h>
 
@@ -38,6 +33,12 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
 void ptdump_walk_pgd_level_checkwx(void);
 void ptdump_walk_user_pgd_level_checkwx(void);
 
+/*
+ * Macros to add or remove encryption attribute
+ */
+#define pgprot_encrypted(prot) __pgprot(cc_mkenc(pgprot_val(prot)))
+#define pgprot_decrypted(prot) __pgprot(cc_mkdec(pgprot_val(prot)))
+
 #ifdef CONFIG_DEBUG_WX
 #define debug_checkwx()                ptdump_walk_pgd_level_checkwx()
 #define debug_checkwx_user()   ptdump_walk_user_pgd_level_checkwx()
index 2c5f12ae7d0427988708922ba79df05023281ee0..a87e7c33d5ac174a7fa0aad12ef75de4a2998eb6 100644 (file)
@@ -119,6 +119,8 @@ struct cpuinfo_x86 {
        int                     x86_cache_mbm_width_offset;
        int                     x86_power;
        unsigned long           loops_per_jiffy;
+       /* protected processor identification number */
+       u64                     ppin;
        /* cpuid returned max cores value: */
        u16                     x86_max_cores;
        u16                     apicid;
index 60bdede41466d63846ea3fe3dcaaf40ce83c73f2..78ca53512486421d17c0a684181972c3fc17a9c4 100644 (file)
@@ -83,7 +83,6 @@ int set_pages_rw(struct page *page, int numpages);
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
 bool kernel_page_present(struct page *page);
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc);
 
 extern int kernel_set_to_readonly;
 
index 2f0b6be8eaabcf14c9aa8e4a770e17cd104445bb..43a89476a5222f43ed0b33f5e4abf698c090e28f 100644 (file)
@@ -110,6 +110,7 @@ extern const struct cpumask *cpu_clustergroup_mask(int cpu);
 #define topology_logical_die_id(cpu)           (cpu_data(cpu).logical_die_id)
 #define topology_die_id(cpu)                   (cpu_data(cpu).cpu_die_id)
 #define topology_core_id(cpu)                  (cpu_data(cpu).cpu_core_id)
+#define topology_ppin(cpu)                     (cpu_data(cpu).ppin)
 
 extern unsigned int __max_die_per_package;
 
index 22b7412c08f63413c3f963827ed56e2297c6168f..e9170457697e4ca6605c151ef08865799ad533e6 100644 (file)
@@ -141,6 +141,21 @@ struct x86_init_acpi {
        void (*reduced_hw_early_init)(void);
 };
 
+/**
+ * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc.
+ *
+ * @enc_status_change_prepare  Notify HV before the encryption status of a range is changed
+ * @enc_status_change_finish   Notify HV after the encryption status of a range is changed
+ * @enc_tlb_flush_required     Returns true if a TLB flush is needed before changing page encryption status
+ * @enc_cache_flush_required   Returns true if a cache flush is needed before changing page encryption status
+ */
+struct x86_guest {
+       void (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+       bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+       bool (*enc_tlb_flush_required)(bool enc);
+       bool (*enc_cache_flush_required)(void);
+};
+
 /**
  * struct x86_init_ops - functions for platform specific setup
  *
@@ -287,6 +302,7 @@ struct x86_platform_ops {
        struct x86_legacy_features legacy;
        void (*set_legacy_features)(void);
        struct x86_hyper_runtime hyper;
+       struct x86_guest guest;
 };
 
 struct x86_apic_ops {
index 6aef9ee28a3940dbf6754cd990df7f61ee4e7798..6462e3dd98f49ac88911f880828af0a8a7e7402c 100644 (file)
@@ -21,7 +21,6 @@ CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 CFLAGS_REMOVE_head64.o = -pg
 CFLAGS_REMOVE_sev.o = -pg
-CFLAGS_REMOVE_cc_platform.o = -pg
 endif
 
 KASAN_SANITIZE_head$(BITS).o                           := n
@@ -30,7 +29,6 @@ KASAN_SANITIZE_dumpstack_$(BITS).o                    := n
 KASAN_SANITIZE_stacktrace.o                            := n
 KASAN_SANITIZE_paravirt.o                              := n
 KASAN_SANITIZE_sev.o                                   := n
-KASAN_SANITIZE_cc_platform.o                           := n
 
 # With some compiler versions the generated code results in boot hangs, caused
 # by several compilation units. To be safe, disable all instrumentation.
@@ -49,7 +47,6 @@ endif
 KCOV_INSTRUMENT                := n
 
 CFLAGS_head$(BITS).o   += -fno-stack-protector
-CFLAGS_cc_platform.o   += -fno-stack-protector
 
 CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace
 
@@ -151,8 +148,6 @@ obj-$(CONFIG_UNWINDER_GUESS)                += unwind_guess.o
 
 obj-$(CONFIG_AMD_MEM_ENCRYPT)          += sev.o
 
-obj-$(CONFIG_ARCH_HAS_CC_PLATFORM)     += cc_platform.o
-
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
index 5007c3ffe96fe71af14cc2363efc76ffe7f9c9f1..b4470eabf151257a6ffb4f123197172b718b0f73 100644 (file)
@@ -389,7 +389,7 @@ static int emit_indirect(int op, int reg, u8 *bytes)
  *
  *   CALL *%\reg
  *
- * It also tries to inline spectre_v2=retpoline,amd when size permits.
+ * It also tries to inline spectre_v2=retpoline,lfence when size permits.
  */
 static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
 {
@@ -407,7 +407,7 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
        BUG_ON(reg == 4);
 
        if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) &&
-           !cpu_feature_enabled(X86_FEATURE_RETPOLINE_AMD))
+           !cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE))
                return -1;
 
        op = insn->opcode.bytes[0];
@@ -438,9 +438,9 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
        }
 
        /*
-        * For RETPOLINE_AMD: prepend the indirect CALL/JMP with an LFENCE.
+        * For RETPOLINE_LFENCE: prepend the indirect CALL/JMP with an LFENCE.
         */
-       if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_AMD)) {
+       if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
                bytes[i++] = 0x0f;
                bytes[i++] = 0xae;
                bytes[i++] = 0xe8; /* LFENCE */
diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/kernel/cc_platform.c
deleted file mode 100644 (file)
index 6a6ffcd..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Confidential Computing Platform Capability checks
- *
- * Copyright (C) 2021 Advanced Micro Devices, Inc.
- *
- * Author: Tom Lendacky <thomas.lendacky@amd.com>
- */
-
-#include <linux/export.h>
-#include <linux/cc_platform.h>
-#include <linux/mem_encrypt.h>
-
-#include <asm/mshyperv.h>
-#include <asm/processor.h>
-
-static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
-{
-#ifdef CONFIG_INTEL_TDX_GUEST
-       return false;
-#else
-       return false;
-#endif
-}
-
-/*
- * SME and SEV are very similar but they are not the same, so there are
- * times that the kernel will need to distinguish between SME and SEV. The
- * cc_platform_has() function is used for this.  When a distinction isn't
- * needed, the CC_ATTR_MEM_ENCRYPT attribute can be used.
- *
- * The trampoline code is a good example for this requirement.  Before
- * paging is activated, SME will access all memory as decrypted, but SEV
- * will access all memory as encrypted.  So, when APs are being brought
- * up under SME the trampoline area cannot be encrypted, whereas under SEV
- * the trampoline area must be encrypted.
- */
-static bool amd_cc_platform_has(enum cc_attr attr)
-{
-#ifdef CONFIG_AMD_MEM_ENCRYPT
-       switch (attr) {
-       case CC_ATTR_MEM_ENCRYPT:
-               return sme_me_mask;
-
-       case CC_ATTR_HOST_MEM_ENCRYPT:
-               return sme_me_mask && !(sev_status & MSR_AMD64_SEV_ENABLED);
-
-       case CC_ATTR_GUEST_MEM_ENCRYPT:
-               return sev_status & MSR_AMD64_SEV_ENABLED;
-
-       case CC_ATTR_GUEST_STATE_ENCRYPT:
-               return sev_status & MSR_AMD64_SEV_ES_ENABLED;
-
-       /*
-        * With SEV, the rep string I/O instructions need to be unrolled
-        * but SEV-ES supports them through the #VC handler.
-        */
-       case CC_ATTR_GUEST_UNROLL_STRING_IO:
-               return (sev_status & MSR_AMD64_SEV_ENABLED) &&
-                       !(sev_status & MSR_AMD64_SEV_ES_ENABLED);
-
-       default:
-               return false;
-       }
-#else
-       return false;
-#endif
-}
-
-static bool hyperv_cc_platform_has(enum cc_attr attr)
-{
-       return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
-}
-
-bool cc_platform_has(enum cc_attr attr)
-{
-       if (sme_me_mask)
-               return amd_cc_platform_has(attr);
-
-       if (hv_is_isolation_supported())
-               return hyperv_cc_platform_has(attr);
-
-       return false;
-}
-EXPORT_SYMBOL_GPL(cc_platform_has);
index 4edb6f0f628c20baee79a6ddd2fd682b67fae28b..0c0b09796ced30153adbaf5cee1c686ba6063201 100644 (file)
@@ -394,35 +394,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
        per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
 }
 
-static void amd_detect_ppin(struct cpuinfo_x86 *c)
-{
-       unsigned long long val;
-
-       if (!cpu_has(c, X86_FEATURE_AMD_PPIN))
-               return;
-
-       /* When PPIN is defined in CPUID, still need to check PPIN_CTL MSR */
-       if (rdmsrl_safe(MSR_AMD_PPIN_CTL, &val))
-               goto clear_ppin;
-
-       /* PPIN is locked in disabled mode, clear feature bit */
-       if ((val & 3UL) == 1UL)
-               goto clear_ppin;
-
-       /* If PPIN is disabled, try to enable it */
-       if (!(val & 2UL)) {
-               wrmsrl_safe(MSR_AMD_PPIN_CTL,  val | 2UL);
-               rdmsrl_safe(MSR_AMD_PPIN_CTL, &val);
-       }
-
-       /* If PPIN_EN bit is 1, return from here; otherwise fall through */
-       if (val & 2UL)
-               return;
-
-clear_ppin:
-       clear_cpu_cap(c, X86_FEATURE_AMD_PPIN);
-}
-
 u32 amd_get_nodes_per_socket(void)
 {
        return nodes_per_socket;
@@ -585,6 +556,8 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
         *            the SME physical address space reduction value.
         *            If BIOS has not enabled SME then don't advertise the
         *            SME feature (set in scattered.c).
+        *            If the kernel has not enabled SME via any means then
+        *            don't advertise the SME feature.
         *   For SEV: If BIOS has not enabled SEV then don't advertise the
         *            SEV and SEV_ES feature (set in scattered.c).
         *
@@ -607,6 +580,9 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
                if (IS_ENABLED(CONFIG_X86_32))
                        goto clear_all;
 
+               if (!sme_me_mask)
+                       setup_clear_cpu_cap(X86_FEATURE_SME);
+
                rdmsrl(MSR_K7_HWCR, msr);
                if (!(msr & MSR_K7_HWCR_SMMLOCK))
                        goto clear_sev;
@@ -947,7 +923,6 @@ static void init_amd(struct cpuinfo_x86 *c)
        amd_detect_cmp(c);
        amd_get_topology(c);
        srat_detect_node(c);
-       amd_detect_ppin(c);
 
        init_amd_cacheinfo(c);
 
index 1c1f218a701d3a6f7b71522f5a964075a5caa51e..6296e1ebed1dbef3e7a1d147d14bf720dcd0cb5e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/prctl.h>
 #include <linux/sched/smt.h>
 #include <linux/pgtable.h>
+#include <linux/bpf.h>
 
 #include <asm/spec-ctrl.h>
 #include <asm/cmdline.h>
@@ -650,6 +651,32 @@ static inline const char *spectre_v2_module_string(void)
 static inline const char *spectre_v2_module_string(void) { return ""; }
 #endif
 
+#define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n"
+#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
+#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n"
+
+#ifdef CONFIG_BPF_SYSCALL
+void unpriv_ebpf_notify(int new_state)
+{
+       if (new_state)
+               return;
+
+       /* Unprivileged eBPF is enabled */
+
+       switch (spectre_v2_enabled) {
+       case SPECTRE_V2_EIBRS:
+               pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
+               break;
+       case SPECTRE_V2_EIBRS_LFENCE:
+               if (sched_smt_active())
+                       pr_err(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG);
+               break;
+       default:
+               break;
+       }
+}
+#endif
+
 static inline bool match_option(const char *arg, int arglen, const char *opt)
 {
        int len = strlen(opt);
@@ -664,7 +691,10 @@ enum spectre_v2_mitigation_cmd {
        SPECTRE_V2_CMD_FORCE,
        SPECTRE_V2_CMD_RETPOLINE,
        SPECTRE_V2_CMD_RETPOLINE_GENERIC,
-       SPECTRE_V2_CMD_RETPOLINE_AMD,
+       SPECTRE_V2_CMD_RETPOLINE_LFENCE,
+       SPECTRE_V2_CMD_EIBRS,
+       SPECTRE_V2_CMD_EIBRS_RETPOLINE,
+       SPECTRE_V2_CMD_EIBRS_LFENCE,
 };
 
 enum spectre_v2_user_cmd {
@@ -737,6 +767,13 @@ spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd)
        return SPECTRE_V2_USER_CMD_AUTO;
 }
 
+static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode)
+{
+       return (mode == SPECTRE_V2_EIBRS ||
+               mode == SPECTRE_V2_EIBRS_RETPOLINE ||
+               mode == SPECTRE_V2_EIBRS_LFENCE);
+}
+
 static void __init
 spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
 {
@@ -804,7 +841,7 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
         */
        if (!boot_cpu_has(X86_FEATURE_STIBP) ||
            !smt_possible ||
-           spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
+           spectre_v2_in_eibrs_mode(spectre_v2_enabled))
                return;
 
        /*
@@ -824,9 +861,11 @@ set_mode:
 
 static const char * const spectre_v2_strings[] = {
        [SPECTRE_V2_NONE]                       = "Vulnerable",
-       [SPECTRE_V2_RETPOLINE_GENERIC]          = "Mitigation: Full generic retpoline",
-       [SPECTRE_V2_RETPOLINE_AMD]              = "Mitigation: Full AMD retpoline",
-       [SPECTRE_V2_IBRS_ENHANCED]              = "Mitigation: Enhanced IBRS",
+       [SPECTRE_V2_RETPOLINE]                  = "Mitigation: Retpolines",
+       [SPECTRE_V2_LFENCE]                     = "Mitigation: LFENCE",
+       [SPECTRE_V2_EIBRS]                      = "Mitigation: Enhanced IBRS",
+       [SPECTRE_V2_EIBRS_LFENCE]               = "Mitigation: Enhanced IBRS + LFENCE",
+       [SPECTRE_V2_EIBRS_RETPOLINE]            = "Mitigation: Enhanced IBRS + Retpolines",
 };
 
 static const struct {
@@ -837,8 +876,12 @@ static const struct {
        { "off",                SPECTRE_V2_CMD_NONE,              false },
        { "on",                 SPECTRE_V2_CMD_FORCE,             true  },
        { "retpoline",          SPECTRE_V2_CMD_RETPOLINE,         false },
-       { "retpoline,amd",      SPECTRE_V2_CMD_RETPOLINE_AMD,     false },
+       { "retpoline,amd",      SPECTRE_V2_CMD_RETPOLINE_LFENCE,  false },
+       { "retpoline,lfence",   SPECTRE_V2_CMD_RETPOLINE_LFENCE,  false },
        { "retpoline,generic",  SPECTRE_V2_CMD_RETPOLINE_GENERIC, false },
+       { "eibrs",              SPECTRE_V2_CMD_EIBRS,             false },
+       { "eibrs,lfence",       SPECTRE_V2_CMD_EIBRS_LFENCE,      false },
+       { "eibrs,retpoline",    SPECTRE_V2_CMD_EIBRS_RETPOLINE,   false },
        { "auto",               SPECTRE_V2_CMD_AUTO,              false },
 };
 
@@ -875,10 +918,30 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
        }
 
        if ((cmd == SPECTRE_V2_CMD_RETPOLINE ||
-            cmd == SPECTRE_V2_CMD_RETPOLINE_AMD ||
-            cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) &&
+            cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE ||
+            cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC ||
+            cmd == SPECTRE_V2_CMD_EIBRS_LFENCE ||
+            cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) &&
            !IS_ENABLED(CONFIG_RETPOLINE)) {
-               pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option);
+               pr_err("%s selected but not compiled in. Switching to AUTO select\n",
+                      mitigation_options[i].option);
+               return SPECTRE_V2_CMD_AUTO;
+       }
+
+       if ((cmd == SPECTRE_V2_CMD_EIBRS ||
+            cmd == SPECTRE_V2_CMD_EIBRS_LFENCE ||
+            cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) &&
+           !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) {
+               pr_err("%s selected but CPU doesn't have eIBRS. Switching to AUTO select\n",
+                      mitigation_options[i].option);
+               return SPECTRE_V2_CMD_AUTO;
+       }
+
+       if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE ||
+            cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) &&
+           !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
+               pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n",
+                      mitigation_options[i].option);
                return SPECTRE_V2_CMD_AUTO;
        }
 
@@ -887,6 +950,16 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
        return cmd;
 }
 
+static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
+{
+       if (!IS_ENABLED(CONFIG_RETPOLINE)) {
+               pr_err("Kernel not compiled with retpoline; no mitigation available!");
+               return SPECTRE_V2_NONE;
+       }
+
+       return SPECTRE_V2_RETPOLINE;
+}
+
 static void __init spectre_v2_select_mitigation(void)
 {
        enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -907,49 +980,64 @@ static void __init spectre_v2_select_mitigation(void)
        case SPECTRE_V2_CMD_FORCE:
        case SPECTRE_V2_CMD_AUTO:
                if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) {
-                       mode = SPECTRE_V2_IBRS_ENHANCED;
-                       /* Force it so VMEXIT will restore correctly */
-                       x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
-                       wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
-                       goto specv2_set_mode;
+                       mode = SPECTRE_V2_EIBRS;
+                       break;
                }
-               if (IS_ENABLED(CONFIG_RETPOLINE))
-                       goto retpoline_auto;
+
+               mode = spectre_v2_select_retpoline();
                break;
-       case SPECTRE_V2_CMD_RETPOLINE_AMD:
-               if (IS_ENABLED(CONFIG_RETPOLINE))
-                       goto retpoline_amd;
+
+       case SPECTRE_V2_CMD_RETPOLINE_LFENCE:
+               pr_err(SPECTRE_V2_LFENCE_MSG);
+               mode = SPECTRE_V2_LFENCE;
                break;
+
        case SPECTRE_V2_CMD_RETPOLINE_GENERIC:
-               if (IS_ENABLED(CONFIG_RETPOLINE))
-                       goto retpoline_generic;
+               mode = SPECTRE_V2_RETPOLINE;
                break;
+
        case SPECTRE_V2_CMD_RETPOLINE:
-               if (IS_ENABLED(CONFIG_RETPOLINE))
-                       goto retpoline_auto;
+               mode = spectre_v2_select_retpoline();
+               break;
+
+       case SPECTRE_V2_CMD_EIBRS:
+               mode = SPECTRE_V2_EIBRS;
+               break;
+
+       case SPECTRE_V2_CMD_EIBRS_LFENCE:
+               mode = SPECTRE_V2_EIBRS_LFENCE;
+               break;
+
+       case SPECTRE_V2_CMD_EIBRS_RETPOLINE:
+               mode = SPECTRE_V2_EIBRS_RETPOLINE;
                break;
        }
-       pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!");
-       return;
 
-retpoline_auto:
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
-           boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
-       retpoline_amd:
-               if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
-                       pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n");
-                       goto retpoline_generic;
-               }
-               mode = SPECTRE_V2_RETPOLINE_AMD;
-               setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD);
-               setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
-       } else {
-       retpoline_generic:
-               mode = SPECTRE_V2_RETPOLINE_GENERIC;
+       if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
+               pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
+
+       if (spectre_v2_in_eibrs_mode(mode)) {
+               /* Force it so VMEXIT will restore correctly */
+               x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
+               wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
+       }
+
+       switch (mode) {
+       case SPECTRE_V2_NONE:
+       case SPECTRE_V2_EIBRS:
+               break;
+
+       case SPECTRE_V2_LFENCE:
+       case SPECTRE_V2_EIBRS_LFENCE:
+               setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE);
+               fallthrough;
+
+       case SPECTRE_V2_RETPOLINE:
+       case SPECTRE_V2_EIBRS_RETPOLINE:
                setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
+               break;
        }
 
-specv2_set_mode:
        spectre_v2_enabled = mode;
        pr_info("%s\n", spectre_v2_strings[mode]);
 
@@ -975,7 +1063,7 @@ specv2_set_mode:
         * the CPU supports Enhanced IBRS, kernel might un-intentionally not
         * enable IBRS around firmware calls.
         */
-       if (boot_cpu_has(X86_FEATURE_IBRS) && mode != SPECTRE_V2_IBRS_ENHANCED) {
+       if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_eibrs_mode(mode)) {
                setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
                pr_info("Enabling Restricted Speculation for firmware calls\n");
        }
@@ -1045,6 +1133,10 @@ void cpu_bugs_smt_update(void)
 {
        mutex_lock(&spec_ctrl_mutex);
 
+       if (sched_smt_active() && unprivileged_ebpf_enabled() &&
+           spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
+               pr_warn_once(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG);
+
        switch (spectre_v2_user_stibp) {
        case SPECTRE_V2_USER_NONE:
                break;
@@ -1684,7 +1776,7 @@ static ssize_t tsx_async_abort_show_state(char *buf)
 
 static char *stibp_state(void)
 {
-       if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
+       if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
                return "";
 
        switch (spectre_v2_user_stibp) {
@@ -1714,6 +1806,27 @@ static char *ibpb_state(void)
        return "";
 }
 
+static ssize_t spectre_v2_show_state(char *buf)
+{
+       if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
+               return sprintf(buf, "Vulnerable: LFENCE\n");
+
+       if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
+               return sprintf(buf, "Vulnerable: eIBRS with unprivileged eBPF\n");
+
+       if (sched_smt_active() && unprivileged_ebpf_enabled() &&
+           spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
+               return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
+
+       return sprintf(buf, "%s%s%s%s%s%s\n",
+                      spectre_v2_strings[spectre_v2_enabled],
+                      ibpb_state(),
+                      boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
+                      stibp_state(),
+                      boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
+                      spectre_v2_module_string());
+}
+
 static ssize_t srbds_show_state(char *buf)
 {
        return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
@@ -1739,12 +1852,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
                return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
 
        case X86_BUG_SPECTRE_V2:
-               return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
-                              ibpb_state(),
-                              boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
-                              stibp_state(),
-                              boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
-                              spectre_v2_module_string());
+               return spectre_v2_show_state(buf);
 
        case X86_BUG_SPEC_STORE_BYPASS:
                return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
index 7b8382c117889b33168a4296a0e6596cbfc82ad6..64deb7727d007c8409d7fd2dde55a63a7575a401 100644 (file)
@@ -88,6 +88,83 @@ EXPORT_SYMBOL_GPL(get_llc_id);
 /* L2 cache ID of each logical CPU */
 DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id) = BAD_APICID;
 
+static struct ppin_info {
+       int     feature;
+       int     msr_ppin_ctl;
+       int     msr_ppin;
+} ppin_info[] = {
+       [X86_VENDOR_INTEL] = {
+               .feature = X86_FEATURE_INTEL_PPIN,
+               .msr_ppin_ctl = MSR_PPIN_CTL,
+               .msr_ppin = MSR_PPIN
+       },
+       [X86_VENDOR_AMD] = {
+               .feature = X86_FEATURE_AMD_PPIN,
+               .msr_ppin_ctl = MSR_AMD_PPIN_CTL,
+               .msr_ppin = MSR_AMD_PPIN
+       },
+};
+
+static const struct x86_cpu_id ppin_cpuids[] = {
+       X86_MATCH_FEATURE(X86_FEATURE_AMD_PPIN, &ppin_info[X86_VENDOR_AMD]),
+       X86_MATCH_FEATURE(X86_FEATURE_INTEL_PPIN, &ppin_info[X86_VENDOR_INTEL]),
+
+       /* Legacy models without CPUID enumeration */
+       X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &ppin_info[X86_VENDOR_INTEL]),
+       X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &ppin_info[X86_VENDOR_INTEL]),
+
+       {}
+};
+
+static void ppin_init(struct cpuinfo_x86 *c)
+{
+       const struct x86_cpu_id *id;
+       unsigned long long val;
+       struct ppin_info *info;
+
+       id = x86_match_cpu(ppin_cpuids);
+       if (!id)
+               return;
+
+       /*
+        * Testing the presence of the MSR is not enough. Need to check
+        * that the PPIN_CTL allows reading of the PPIN.
+        */
+       info = (struct ppin_info *)id->driver_data;
+
+       if (rdmsrl_safe(info->msr_ppin_ctl, &val))
+               goto clear_ppin;
+
+       if ((val & 3UL) == 1UL) {
+               /* PPIN locked in disabled mode */
+               goto clear_ppin;
+       }
+
+       /* If PPIN is disabled, try to enable */
+       if (!(val & 2UL)) {
+               wrmsrl_safe(info->msr_ppin_ctl,  val | 2UL);
+               rdmsrl_safe(info->msr_ppin_ctl, &val);
+       }
+
+       /* Is the enable bit set? */
+       if (val & 2UL) {
+               c->ppin = __rdmsr(info->msr_ppin);
+               set_cpu_cap(c, info->feature);
+               return;
+       }
+
+clear_ppin:
+       clear_cpu_cap(c, info->feature);
+}
+
 /* correctly size the local cpu masks */
 void __init setup_cpu_local_masks(void)
 {
@@ -1655,6 +1732,8 @@ static void identify_cpu(struct cpuinfo_x86 *c)
                        c->x86_capability[i] |= boot_cpu_data.x86_capability[i];
        }
 
+       ppin_init(c);
+
        /* Init Machine Check Exception if available. */
        mcheck_cpu_init(c);
 
index 9f4b508886dde47d90e54adcbc7f7ec5556540a8..1940d305db1c0fc6549dc38569121c85c5d62e14 100644 (file)
@@ -993,6 +993,7 @@ static struct attribute *default_attrs[] = {
        NULL,   /* possibly interrupt_enable if supported, see below */
        NULL,
 };
+ATTRIBUTE_GROUPS(default);
 
 #define to_block(k)    container_of(k, struct threshold_block, kobj)
 #define to_attr(a)     container_of(a, struct threshold_attr, attr)
@@ -1029,7 +1030,7 @@ static void threshold_block_release(struct kobject *kobj);
 
 static struct kobj_type threshold_ktype = {
        .sysfs_ops              = &threshold_ops,
-       .default_attrs          = default_attrs,
+       .default_groups         = default_groups,
        .release                = threshold_block_release,
 };
 
@@ -1101,10 +1102,10 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
        b->threshold_limit      = THRESHOLD_MAX;
 
        if (b->interrupt_capable) {
-               threshold_ktype.default_attrs[2] = &interrupt_enable.attr;
+               default_attrs[2] = &interrupt_enable.attr;
                b->interrupt_enable = 1;
        } else {
-               threshold_ktype.default_attrs[2] = NULL;
+               default_attrs[2] = NULL;
        }
 
        INIT_LIST_HEAD(&b->miscj);
index 5818b837fd4d4cc1512f04aec19f8942c3b71040..4f1e825033ce9c3944ce074e0e31808c420015a9 100644 (file)
@@ -138,12 +138,7 @@ void mce_setup(struct mce *m)
        m->socketid = cpu_data(m->extcpu).phys_proc_id;
        m->apicid = cpu_data(m->extcpu).initial_apicid;
        m->mcgcap = __rdmsr(MSR_IA32_MCG_CAP);
-
-       if (this_cpu_has(X86_FEATURE_INTEL_PPIN))
-               m->ppin = __rdmsr(MSR_PPIN);
-       else if (this_cpu_has(X86_FEATURE_AMD_PPIN))
-               m->ppin = __rdmsr(MSR_AMD_PPIN);
-
+       m->ppin = cpu_data(m->extcpu).ppin;
        m->microcode = boot_cpu_data.microcode;
 }
 
index baafbb37be678dfdf1fe148141c65b93611fd137..95275a5e57e06ca292586a7cd4ff547b3eac69e1 100644 (file)
@@ -470,47 +470,6 @@ void intel_clear_lmce(void)
        wrmsrl(MSR_IA32_MCG_EXT_CTL, val);
 }
 
-static void intel_ppin_init(struct cpuinfo_x86 *c)
-{
-       unsigned long long val;
-
-       /*
-        * Even if testing the presence of the MSR would be enough, we don't
-        * want to risk the situation where other models reuse this MSR for
-        * other purposes.
-        */
-       switch (c->x86_model) {
-       case INTEL_FAM6_IVYBRIDGE_X:
-       case INTEL_FAM6_HASWELL_X:
-       case INTEL_FAM6_BROADWELL_D:
-       case INTEL_FAM6_BROADWELL_X:
-       case INTEL_FAM6_SKYLAKE_X:
-       case INTEL_FAM6_ICELAKE_X:
-       case INTEL_FAM6_ICELAKE_D:
-       case INTEL_FAM6_SAPPHIRERAPIDS_X:
-       case INTEL_FAM6_XEON_PHI_KNL:
-       case INTEL_FAM6_XEON_PHI_KNM:
-
-               if (rdmsrl_safe(MSR_PPIN_CTL, &val))
-                       return;
-
-               if ((val & 3UL) == 1UL) {
-                       /* PPIN locked in disabled mode */
-                       return;
-               }
-
-               /* If PPIN is disabled, try to enable */
-               if (!(val & 2UL)) {
-                       wrmsrl_safe(MSR_PPIN_CTL,  val | 2UL);
-                       rdmsrl_safe(MSR_PPIN_CTL, &val);
-               }
-
-               /* Is the enable bit set? */
-               if (val & 2UL)
-                       set_cpu_cap(c, X86_FEATURE_INTEL_PPIN);
-       }
-}
-
 /*
  * Enable additional error logs from the integrated
  * memory controller on processors that support this.
@@ -535,7 +494,6 @@ void mce_intel_feature_init(struct cpuinfo_x86 *c)
 {
        intel_init_cmci();
        intel_init_lmce();
-       intel_ppin_init(c);
        intel_imc_init(c);
 }
 
index 5a99f993e6392e714b715861664f240acda6b505..e0a57247205236a9dbc575c1a52a3740c33df1eb 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/nmi.h>
 #include <clocksource/hyperv_timer.h>
 #include <asm/numa.h>
+#include <asm/coco.h>
 
 /* Is Linux running as the root partition? */
 bool hv_root_partition;
@@ -344,6 +345,11 @@ static void __init ms_hyperv_init_platform(void)
                 */
                swiotlb_force = SWIOTLB_FORCE;
 #endif
+               /* Isolation VMs are unenlightened SEV-based VMs, thus this check: */
+               if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
+                       if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
+                               cc_set_vendor(CC_VENDOR_HYPERV);
+               }
        }
 
        if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
index 21d1f062895a8dfdf4c66ecbec8d91da3feadb5c..4143b1e4c5c6d8160da5f4ae84075e1470e8e37d 100644 (file)
@@ -26,6 +26,7 @@ struct cpuid_bit {
 static const struct cpuid_bit cpuid_bits[] = {
        { X86_FEATURE_APERFMPERF,       CPUID_ECX,  0, 0x00000006, 0 },
        { X86_FEATURE_EPB,              CPUID_ECX,  3, 0x00000006, 0 },
+       { X86_FEATURE_INTEL_PPIN,       CPUID_EBX,  0, 0x00000007, 1 },
        { X86_FEATURE_CQM_LLC,          CPUID_EDX,  1, 0x0000000f, 0 },
        { X86_FEATURE_CQM_OCCUP_LLC,    CPUID_EDX,  0, 0x0000000f, 1 },
        { X86_FEATURE_CQM_MBM_TOTAL,    CPUID_EDX,  1, 0x0000000f, 1 },
index 48afe96ae0f0f5e6a1ed1fc2850861dc10c3ea8f..7c63a1911fae977b7c00367a659e3958f7fcccc4 100644 (file)
 #include "encls.h"
 #include "sgx.h"
 
+/*
+ * Calculate byte offset of a PCMD struct associated with an enclave page. PCMD's
+ * follow right after the EPC data in the backing storage. In addition to the
+ * visible enclave pages, there's one extra page slot for SECS, before PCMD
+ * structs.
+ */
+static inline pgoff_t sgx_encl_get_backing_page_pcmd_offset(struct sgx_encl *encl,
+                                                           unsigned long page_index)
+{
+       pgoff_t epc_end_off = encl->size + sizeof(struct sgx_secs);
+
+       return epc_end_off + page_index * sizeof(struct sgx_pcmd);
+}
+
+/*
+ * Free a page from the backing storage in the given page index.
+ */
+static inline void sgx_encl_truncate_backing_page(struct sgx_encl *encl, unsigned long page_index)
+{
+       struct inode *inode = file_inode(encl->backing);
+
+       shmem_truncate_range(inode, PFN_PHYS(page_index), PFN_PHYS(page_index) + PAGE_SIZE - 1);
+}
+
 /*
  * ELDU: Load an EPC page as unblocked. For more info, see "OS Management of EPC
  * Pages" in the SDM.
@@ -22,9 +46,11 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
 {
        unsigned long va_offset = encl_page->desc & SGX_ENCL_PAGE_VA_OFFSET_MASK;
        struct sgx_encl *encl = encl_page->encl;
+       pgoff_t page_index, page_pcmd_off;
        struct sgx_pageinfo pginfo;
        struct sgx_backing b;
-       pgoff_t page_index;
+       bool pcmd_page_empty;
+       u8 *pcmd_page;
        int ret;
 
        if (secs_page)
@@ -32,14 +58,16 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
        else
                page_index = PFN_DOWN(encl->size);
 
+       page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index);
+
        ret = sgx_encl_get_backing(encl, page_index, &b);
        if (ret)
                return ret;
 
        pginfo.addr = encl_page->desc & PAGE_MASK;
        pginfo.contents = (unsigned long)kmap_atomic(b.contents);
-       pginfo.metadata = (unsigned long)kmap_atomic(b.pcmd) +
-                         b.pcmd_offset;
+       pcmd_page = kmap_atomic(b.pcmd);
+       pginfo.metadata = (unsigned long)pcmd_page + b.pcmd_offset;
 
        if (secs_page)
                pginfo.secs = (u64)sgx_get_epc_virt_addr(secs_page);
@@ -55,11 +83,24 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
                ret = -EFAULT;
        }
 
-       kunmap_atomic((void *)(unsigned long)(pginfo.metadata - b.pcmd_offset));
+       memset(pcmd_page + b.pcmd_offset, 0, sizeof(struct sgx_pcmd));
+
+       /*
+        * The area for the PCMD in the page was zeroed above.  Check if the
+        * whole page is now empty meaning that all PCMD's have been zeroed:
+        */
+       pcmd_page_empty = !memchr_inv(pcmd_page, 0, PAGE_SIZE);
+
+       kunmap_atomic(pcmd_page);
        kunmap_atomic((void *)(unsigned long)pginfo.contents);
 
        sgx_encl_put_backing(&b, false);
 
+       sgx_encl_truncate_backing_page(encl, page_index);
+
+       if (pcmd_page_empty)
+               sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off));
+
        return ret;
 }
 
@@ -579,7 +620,7 @@ static struct page *sgx_encl_get_backing_page(struct sgx_encl *encl,
 int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
                         struct sgx_backing *backing)
 {
-       pgoff_t pcmd_index = PFN_DOWN(encl->size) + 1 + (page_index >> 5);
+       pgoff_t page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index);
        struct page *contents;
        struct page *pcmd;
 
@@ -587,7 +628,7 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
        if (IS_ERR(contents))
                return PTR_ERR(contents);
 
-       pcmd = sgx_encl_get_backing_page(encl, pcmd_index);
+       pcmd = sgx_encl_get_backing_page(encl, PFN_DOWN(page_pcmd_off));
        if (IS_ERR(pcmd)) {
                put_page(contents);
                return PTR_ERR(pcmd);
@@ -596,9 +637,7 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
        backing->page_index = page_index;
        backing->contents = contents;
        backing->pcmd = pcmd;
-       backing->pcmd_offset =
-               (page_index & (PAGE_SIZE / sizeof(struct sgx_pcmd) - 1)) *
-               sizeof(struct sgx_pcmd);
+       backing->pcmd_offset = page_pcmd_off & (PAGE_SIZE - 1);
 
        return 0;
 }
index bc0657f0deedf2b13641088b9b8ea9173262f70b..f267205f2d5a419e68b66c4053b6cbdedb4273ef 100644 (file)
@@ -995,8 +995,10 @@ early_param("memmap", parse_memmap_opt);
  */
 void __init e820__reserve_setup_data(void)
 {
+       struct setup_indirect *indirect;
        struct setup_data *data;
-       u64 pa_data;
+       u64 pa_data, pa_next;
+       u32 len;
 
        pa_data = boot_params.hdr.setup_data;
        if (!pa_data)
@@ -1004,6 +1006,14 @@ void __init e820__reserve_setup_data(void)
 
        while (pa_data) {
                data = early_memremap(pa_data, sizeof(*data));
+               if (!data) {
+                       pr_warn("e820: failed to memremap setup_data entry\n");
+                       return;
+               }
+
+               len = sizeof(*data);
+               pa_next = data->next;
+
                e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
 
                /*
@@ -1015,18 +1025,27 @@ void __init e820__reserve_setup_data(void)
                                                 sizeof(*data) + data->len,
                                                 E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
 
-               if (data->type == SETUP_INDIRECT &&
-                   ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
-                       e820__range_update(((struct setup_indirect *)data->data)->addr,
-                                          ((struct setup_indirect *)data->data)->len,
-                                          E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
-                       e820__range_update_kexec(((struct setup_indirect *)data->data)->addr,
-                                                ((struct setup_indirect *)data->data)->len,
-                                                E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
+               if (data->type == SETUP_INDIRECT) {
+                       len += data->len;
+                       early_memunmap(data, sizeof(*data));
+                       data = early_memremap(pa_data, len);
+                       if (!data) {
+                               pr_warn("e820: failed to memremap indirect setup_data\n");
+                               return;
+                       }
+
+                       indirect = (struct setup_indirect *)data->data;
+
+                       if (indirect->type != SETUP_INDIRECT) {
+                               e820__range_update(indirect->addr, indirect->len,
+                                                  E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
+                               e820__range_update_kexec(indirect->addr, indirect->len,
+                                                        E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
+                       }
                }
 
-               pa_data = data->next;
-               early_memunmap(data, sizeof(*data));
+               pa_data = pa_next;
+               early_memunmap(data, len);
        }
 
        e820__update_table(e820_table);
index 02b3ddaf4f75b5b021124a31e21acb85fc21fa27..7c7824ae78622d7d201312d0291e63895d7838f1 100644 (file)
@@ -1558,7 +1558,10 @@ static int fpstate_realloc(u64 xfeatures, unsigned int ksize,
                fpregs_restore_userregs();
 
        newfps->xfeatures = curfps->xfeatures | xfeatures;
-       newfps->user_xfeatures = curfps->user_xfeatures | xfeatures;
+
+       if (!guest_fpu)
+               newfps->user_xfeatures = curfps->user_xfeatures | xfeatures;
+
        newfps->xfd = curfps->xfd & ~xfeatures;
 
        /* Do the final updates within the locked region */
index de563db9cdcd24feb458a2a456f8f27930555076..4f5ecbbaae77c7f6f74eb40d82681c94a063a99c 100644 (file)
@@ -126,7 +126,7 @@ static bool __head check_la57_support(unsigned long physaddr)
 }
 #endif
 
-static unsigned long sme_postprocess_startup(struct boot_params *bp, pmdval_t *pmd)
+static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdval_t *pmd)
 {
        unsigned long vaddr, vaddr_end;
        int i;
index 64b6da95af984868962777bb4978b3fa8a4eff16..e2e89bebcbc32840357788cbd803805e5f652c62 100644 (file)
@@ -88,11 +88,13 @@ create_setup_data_node(struct dentry *parent, int no,
 
 static int __init create_setup_data_nodes(struct dentry *parent)
 {
+       struct setup_indirect *indirect;
        struct setup_data_node *node;
        struct setup_data *data;
-       int error;
+       u64 pa_data, pa_next;
        struct dentry *d;
-       u64 pa_data;
+       int error;
+       u32 len;
        int no = 0;
 
        d = debugfs_create_dir("setup_data", parent);
@@ -112,12 +114,29 @@ static int __init create_setup_data_nodes(struct dentry *parent)
                        error = -ENOMEM;
                        goto err_dir;
                }
-
-               if (data->type == SETUP_INDIRECT &&
-                   ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
-                       node->paddr = ((struct setup_indirect *)data->data)->addr;
-                       node->type  = ((struct setup_indirect *)data->data)->type;
-                       node->len   = ((struct setup_indirect *)data->data)->len;
+               pa_next = data->next;
+
+               if (data->type == SETUP_INDIRECT) {
+                       len = sizeof(*data) + data->len;
+                       memunmap(data);
+                       data = memremap(pa_data, len, MEMREMAP_WB);
+                       if (!data) {
+                               kfree(node);
+                               error = -ENOMEM;
+                               goto err_dir;
+                       }
+
+                       indirect = (struct setup_indirect *)data->data;
+
+                       if (indirect->type != SETUP_INDIRECT) {
+                               node->paddr = indirect->addr;
+                               node->type  = indirect->type;
+                               node->len   = indirect->len;
+                       } else {
+                               node->paddr = pa_data;
+                               node->type  = data->type;
+                               node->len   = data->len;
+                       }
                } else {
                        node->paddr = pa_data;
                        node->type  = data->type;
@@ -125,7 +144,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
                }
 
                create_setup_data_node(d, no, node);
-               pa_data = data->next;
+               pa_data = pa_next;
 
                memunmap(data);
                no++;
index d0a19121c6a4f1f4bb1f62e05f12d8350d4710a1..257892fcefa794803d8eaf2d3d1810ebb278957b 100644 (file)
@@ -91,26 +91,41 @@ static int get_setup_data_paddr(int nr, u64 *paddr)
 
 static int __init get_setup_data_size(int nr, size_t *size)
 {
-       int i = 0;
+       u64 pa_data = boot_params.hdr.setup_data, pa_next;
+       struct setup_indirect *indirect;
        struct setup_data *data;
-       u64 pa_data = boot_params.hdr.setup_data;
+       int i = 0;
+       u32 len;
 
        while (pa_data) {
                data = memremap(pa_data, sizeof(*data), MEMREMAP_WB);
                if (!data)
                        return -ENOMEM;
+               pa_next = data->next;
+
                if (nr == i) {
-                       if (data->type == SETUP_INDIRECT &&
-                           ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT)
-                               *size = ((struct setup_indirect *)data->data)->len;
-                       else
+                       if (data->type == SETUP_INDIRECT) {
+                               len = sizeof(*data) + data->len;
+                               memunmap(data);
+                               data = memremap(pa_data, len, MEMREMAP_WB);
+                               if (!data)
+                                       return -ENOMEM;
+
+                               indirect = (struct setup_indirect *)data->data;
+
+                               if (indirect->type != SETUP_INDIRECT)
+                                       *size = indirect->len;
+                               else
+                                       *size = data->len;
+                       } else {
                                *size = data->len;
+                       }
 
                        memunmap(data);
                        return 0;
                }
 
-               pa_data = data->next;
+               pa_data = pa_next;
                memunmap(data);
                i++;
        }
@@ -120,9 +135,11 @@ static int __init get_setup_data_size(int nr, size_t *size)
 static ssize_t type_show(struct kobject *kobj,
                         struct kobj_attribute *attr, char *buf)
 {
+       struct setup_indirect *indirect;
+       struct setup_data *data;
        int nr, ret;
        u64 paddr;
-       struct setup_data *data;
+       u32 len;
 
        ret = kobj_to_setup_data_nr(kobj, &nr);
        if (ret)
@@ -135,10 +152,20 @@ static ssize_t type_show(struct kobject *kobj,
        if (!data)
                return -ENOMEM;
 
-       if (data->type == SETUP_INDIRECT)
-               ret = sprintf(buf, "0x%x\n", ((struct setup_indirect *)data->data)->type);
-       else
+       if (data->type == SETUP_INDIRECT) {
+               len = sizeof(*data) + data->len;
+               memunmap(data);
+               data = memremap(paddr, len, MEMREMAP_WB);
+               if (!data)
+                       return -ENOMEM;
+
+               indirect = (struct setup_indirect *)data->data;
+
+               ret = sprintf(buf, "0x%x\n", indirect->type);
+       } else {
                ret = sprintf(buf, "0x%x\n", data->type);
+       }
+
        memunmap(data);
        return ret;
 }
@@ -149,9 +176,10 @@ static ssize_t setup_data_data_read(struct file *fp,
                                    char *buf,
                                    loff_t off, size_t count)
 {
+       struct setup_indirect *indirect;
+       struct setup_data *data;
        int nr, ret = 0;
        u64 paddr, len;
-       struct setup_data *data;
        void *p;
 
        ret = kobj_to_setup_data_nr(kobj, &nr);
@@ -165,10 +193,27 @@ static ssize_t setup_data_data_read(struct file *fp,
        if (!data)
                return -ENOMEM;
 
-       if (data->type == SETUP_INDIRECT &&
-           ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
-               paddr = ((struct setup_indirect *)data->data)->addr;
-               len = ((struct setup_indirect *)data->data)->len;
+       if (data->type == SETUP_INDIRECT) {
+               len = sizeof(*data) + data->len;
+               memunmap(data);
+               data = memremap(paddr, len, MEMREMAP_WB);
+               if (!data)
+                       return -ENOMEM;
+
+               indirect = (struct setup_indirect *)data->data;
+
+               if (indirect->type != SETUP_INDIRECT) {
+                       paddr = indirect->addr;
+                       len = indirect->len;
+               } else {
+                       /*
+                        * Even though this is technically undefined, return
+                        * the data as though it is a normal setup_data struct.
+                        * This will at least allow it to be inspected.
+                        */
+                       paddr += sizeof(*data);
+                       len = data->len;
+               }
        } else {
                paddr += sizeof(*data);
                len = data->len;
index a438217cbface2f6eb74c3e32000baadb37e92eb..d77481ecb0d5f51fcdd17cd4d4f2c4d32242c05f 100644 (file)
@@ -462,19 +462,24 @@ static bool pv_tlb_flush_supported(void)
 {
        return (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
                !kvm_para_has_hint(KVM_HINTS_REALTIME) &&
-               kvm_para_has_feature(KVM_FEATURE_STEAL_TIME));
+               kvm_para_has_feature(KVM_FEATURE_STEAL_TIME) &&
+               !boot_cpu_has(X86_FEATURE_MWAIT) &&
+               (num_possible_cpus() != 1));
 }
 
 static bool pv_ipi_supported(void)
 {
-       return kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI);
+       return (kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI) &&
+              (num_possible_cpus() != 1));
 }
 
 static bool pv_sched_yield_supported(void)
 {
        return (kvm_para_has_feature(KVM_FEATURE_PV_SCHED_YIELD) &&
                !kvm_para_has_hint(KVM_HINTS_REALTIME) &&
-           kvm_para_has_feature(KVM_FEATURE_STEAL_TIME));
+           kvm_para_has_feature(KVM_FEATURE_STEAL_TIME) &&
+           !boot_cpu_has(X86_FEATURE_MWAIT) &&
+           (num_possible_cpus() != 1));
 }
 
 #define KVM_IPI_CLUSTER_SIZE   (2 * BITS_PER_LONG)
@@ -619,7 +624,7 @@ static void kvm_smp_send_call_func_ipi(const struct cpumask *mask)
 
        /* Make sure other vCPUs get a chance to run if they need to. */
        for_each_cpu(cpu, mask) {
-               if (vcpu_is_preempted(cpu)) {
+               if (!idle_cpu(cpu) && vcpu_is_preempted(cpu)) {
                        kvm_hypercall1(KVM_HC_SCHED_YIELD, per_cpu(x86_cpu_to_apicid, cpu));
                        break;
                }
index a35cbf9107afa81177bd5cce7e71f562938aa3fc..c5caa7311bd826154dbfd93b19a4701803e1fea3 100644 (file)
@@ -239,6 +239,9 @@ static void __init kvmclock_init_mem(void)
 
 static int __init kvm_setup_vsyscall_timeinfo(void)
 {
+       if (!kvm_para_available() || !kvmclock)
+               return 0;
+
        kvmclock_init_mem();
 
 #ifdef CONFIG_X86_64
index 95fa745e310a5fdc97d8fdf2b803d2067c99472e..96d7c27b7093db6eff7301dcac89e9ace347cf8a 100644 (file)
@@ -273,6 +273,14 @@ int module_finalize(const Elf_Ehdr *hdr,
                        retpolines = s;
        }
 
+       /*
+        * See alternative_instructions() for the ordering rules between the
+        * various patching types.
+        */
+       if (para) {
+               void *pseg = (void *)para->sh_addr;
+               apply_paravirt(pseg, pseg + para->sh_size);
+       }
        if (retpolines) {
                void *rseg = (void *)retpolines->sh_addr;
                apply_retpolines(rseg, rseg + retpolines->sh_size);
@@ -290,11 +298,6 @@ int module_finalize(const Elf_Ehdr *hdr,
                                            tseg, tseg + text->sh_size);
        }
 
-       if (para) {
-               void *pseg = (void *)para->sh_addr;
-               apply_paravirt(pseg, pseg + para->sh_size);
-       }
-
        /* make jump label nops */
        jump_label_apply_nops(me);
 
index 81d8ef036637c08dfe56391131f446b59659fb04..e131d71b3cae9a0a48800c3f4368aa4236d2d892 100644 (file)
@@ -765,8 +765,11 @@ void stop_this_cpu(void *dummy)
         * without the encryption bit, they don't race each other when flushed
         * and potentially end up with the wrong entry being committed to
         * memory.
+        *
+        * Test the CPUID bit directly because the machine might've cleared
+        * X86_FEATURE_SME due to cmdline options.
         */
-       if (boot_cpu_has(X86_FEATURE_SME))
+       if (cpuid_eax(0x8000001f) & BIT(0))
                native_wbinvd();
        for (;;) {
                /*
index f7a132eb794d8f12ca916879976aaf70345d4041..90d7e1788c91d25e3ad7538bc5ac0c5351c94b91 100644 (file)
@@ -369,21 +369,41 @@ static void __init parse_setup_data(void)
 
 static void __init memblock_x86_reserve_range_setup_data(void)
 {
+       struct setup_indirect *indirect;
        struct setup_data *data;
-       u64 pa_data;
+       u64 pa_data, pa_next;
+       u32 len;
 
        pa_data = boot_params.hdr.setup_data;
        while (pa_data) {
                data = early_memremap(pa_data, sizeof(*data));
+               if (!data) {
+                       pr_warn("setup: failed to memremap setup_data entry\n");
+                       return;
+               }
+
+               len = sizeof(*data);
+               pa_next = data->next;
+
                memblock_reserve(pa_data, sizeof(*data) + data->len);
 
-               if (data->type == SETUP_INDIRECT &&
-                   ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT)
-                       memblock_reserve(((struct setup_indirect *)data->data)->addr,
-                                        ((struct setup_indirect *)data->data)->len);
+               if (data->type == SETUP_INDIRECT) {
+                       len += data->len;
+                       early_memunmap(data, sizeof(*data));
+                       data = early_memremap(pa_data, len);
+                       if (!data) {
+                               pr_warn("setup: failed to memremap indirect setup_data\n");
+                               return;
+                       }
 
-               pa_data = data->next;
-               early_memunmap(data, sizeof(*data));
+                       indirect = (struct setup_indirect *)data->data;
+
+                       if (indirect->type != SETUP_INDIRECT)
+                               memblock_reserve(indirect->addr, indirect->len);
+               }
+
+               pa_data = pa_next;
+               early_memunmap(data, len);
        }
 }
 
index c9d566dcf89a048b1b61f5092dd40f38b4e056a4..8143693a7ea6e3e1cb300b9924737bb2ee6f74a1 100644 (file)
@@ -659,6 +659,7 @@ static bool do_int3(struct pt_regs *regs)
 
        return res == NOTIFY_STOP;
 }
+NOKPROBE_SYMBOL(do_int3);
 
 static void do_int3_user(struct pt_regs *regs)
 {
index 7d20c1d34a3cdf1bcc9fe143bf540b4e201d1239..e84ee5cdbd8c6eb43060e16cb97036b9a5214470 100644 (file)
@@ -129,6 +129,11 @@ struct x86_cpuinit_ops x86_cpuinit = {
 
 static void default_nmi_init(void) { };
 
+static void enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { }
+static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return false; }
+static bool enc_tlb_flush_required_noop(bool enc) { return false; }
+static bool enc_cache_flush_required_noop(void) { return false; }
+
 struct x86_platform_ops x86_platform __ro_after_init = {
        .calibrate_cpu                  = native_calibrate_cpu_early,
        .calibrate_tsc                  = native_calibrate_tsc,
@@ -138,9 +143,16 @@ struct x86_platform_ops x86_platform __ro_after_init = {
        .is_untracked_pat_range         = is_ISA_range,
        .nmi_init                       = default_nmi_init,
        .get_nmi_reason                 = default_get_nmi_reason,
-       .save_sched_clock_state         = tsc_save_sched_clock_state,
-       .restore_sched_clock_state      = tsc_restore_sched_clock_state,
+       .save_sched_clock_state         = tsc_save_sched_clock_state,
+       .restore_sched_clock_state      = tsc_restore_sched_clock_state,
        .hyper.pin_vcpu                 = x86_op_int_noop,
+
+       .guest = {
+               .enc_status_change_prepare = enc_status_change_prepare_noop,
+               .enc_status_change_finish  = enc_status_change_finish_noop,
+               .enc_tlb_flush_required    = enc_tlb_flush_required_noop,
+               .enc_cache_flush_required  = enc_cache_flush_required_noop,
+       },
 };
 
 EXPORT_SYMBOL_GPL(x86_platform);
index 494d4d3518597f28676ad2cf36f2737234e01572..b8f8d268d0585e9791a5cc06e144e59968fab966 100644 (file)
@@ -282,6 +282,7 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 {
        struct kvm_lapic *apic = vcpu->arch.apic;
        struct kvm_cpuid_entry2 *best;
+       u64 guest_supported_xcr0;
 
        best = kvm_find_cpuid_entry(vcpu, 1, 0);
        if (best && apic) {
@@ -293,9 +294,11 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
                kvm_apic_set_version(vcpu);
        }
 
-       vcpu->arch.guest_supported_xcr0 =
+       guest_supported_xcr0 =
                cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
 
+       vcpu->arch.guest_fpu.fpstate->user_xfeatures = guest_supported_xcr0;
+
        kvm_update_pv_runtime(vcpu);
 
        vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
index 5719d8cfdbd90aff763e306da68262429847f13f..e86d610dc6b7aa503f56a23ff268c9f8ff667b16 100644 (file)
@@ -429,8 +429,23 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop);
        FOP_END
 
 /* Special case for SETcc - 1 instruction per cc */
+
+/*
+ * Depending on .config the SETcc functions look like:
+ *
+ * SETcc %al   [3 bytes]
+ * RET         [1 byte]
+ * INT3        [1 byte; CONFIG_SLS]
+ *
+ * Which gives possible sizes 4 or 5.  When rounded up to the
+ * next power-of-two alignment they become 4 or 8.
+ */
+#define SETCC_LENGTH   (4 + IS_ENABLED(CONFIG_SLS))
+#define SETCC_ALIGN    (4 << IS_ENABLED(CONFIG_SLS))
+static_assert(SETCC_LENGTH <= SETCC_ALIGN);
+
 #define FOP_SETCC(op) \
-       ".align 4 \n\t" \
+       ".align " __stringify(SETCC_ALIGN) " \n\t" \
        ".type " #op ", @function \n\t" \
        #op ": \n\t" \
        #op " %al \n\t" \
@@ -1047,7 +1062,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt)
 static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
 {
        u8 rc;
-       void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf);
+       void (*fop)(void) = (void *)em_setcc + SETCC_ALIGN * (condition & 0xf);
 
        flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
        asm("push %[flags]; popf; " CALL_NOSPEC
index 593093b523953802334d5f83767efadc403892c7..5628d0ba637ec053ac4104e14cdc04249996d7db 100644 (file)
@@ -3565,7 +3565,7 @@ set_root_pgd:
 out_unlock:
        write_unlock(&vcpu->kvm->mmu_lock);
 
-       return 0;
+       return r;
 }
 
 static int mmu_alloc_special_roots(struct kvm_vcpu *vcpu)
@@ -3889,12 +3889,23 @@ static void shadow_page_table_clear_flood(struct kvm_vcpu *vcpu, gva_t addr)
        walk_shadow_page_lockless_end(vcpu);
 }
 
+static u32 alloc_apf_token(struct kvm_vcpu *vcpu)
+{
+       /* make sure the token value is not 0 */
+       u32 id = vcpu->arch.apf.id;
+
+       if (id << 12 == 0)
+               vcpu->arch.apf.id = 1;
+
+       return (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id;
+}
+
 static bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
                                    gfn_t gfn)
 {
        struct kvm_arch_async_pf arch;
 
-       arch.token = (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id;
+       arch.token = alloc_apf_token(vcpu);
        arch.gfn = gfn;
        arch.direct_map = vcpu->arch.mmu->direct_map;
        arch.cr3 = vcpu->arch.mmu->get_guest_pgd(vcpu);
index 821edf664e7a128b82fd550a0e7af4b9f70fe730..fd3a00c892c7977d190a7f565dc385d714f60c6a 100644 (file)
@@ -2693,8 +2693,23 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
        u64 data = msr->data;
        switch (ecx) {
        case MSR_AMD64_TSC_RATIO:
-               if (!msr->host_initiated && !svm->tsc_scaling_enabled)
-                       return 1;
+
+               if (!svm->tsc_scaling_enabled) {
+
+                       if (!msr->host_initiated)
+                               return 1;
+                       /*
+                        * In case TSC scaling is not enabled, always
+                        * leave this MSR at the default value.
+                        *
+                        * Due to bug in qemu 6.2.0, it would try to set
+                        * this msr to 0 if tsc scaling is not enabled.
+                        * Ignore this value as well.
+                        */
+                       if (data != 0 && data != svm->tsc_ratio_msr)
+                               return 1;
+                       break;
+               }
 
                if (data & TSC_RATIO_RSVD)
                        return 1;
index ba34e94049c79127756de6cfeed4159713033af0..dc822a1d403d3d36860b74277595daaf7543f5c6 100644 (file)
@@ -246,8 +246,7 @@ static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
        src = &prev->host_state;
        dest = &vmx->loaded_vmcs->host_state;
 
-       vmx_set_vmcs_host_state(dest, src->cr3, src->fs_sel, src->gs_sel,
-                               src->fs_base, src->gs_base);
+       vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base);
        dest->ldt_sel = src->ldt_sel;
 #ifdef CONFIG_X86_64
        dest->ds_sel = src->ds_sel;
@@ -3056,7 +3055,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
 static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
-       unsigned long cr4;
+       unsigned long cr3, cr4;
        bool vm_fail;
 
        if (!nested_early_check)
@@ -3079,6 +3078,12 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
         */
        vmcs_writel(GUEST_RFLAGS, 0);
 
+       cr3 = __get_current_cr3_fast();
+       if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
+               vmcs_writel(HOST_CR3, cr3);
+               vmx->loaded_vmcs->host_state.cr3 = cr3;
+       }
+
        cr4 = cr4_read_shadow();
        if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
                vmcs_writel(HOST_CR4, cr4);
index efda5e4d624763879778344aca2b4cdcdebb3193..b730d799c26edfd8e452b7c97cf78c154d01829b 100644 (file)
@@ -1080,14 +1080,9 @@ static void pt_guest_exit(struct vcpu_vmx *vmx)
                wrmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl);
 }
 
-void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
-                            u16 fs_sel, u16 gs_sel,
-                            unsigned long fs_base, unsigned long gs_base)
+void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
+                       unsigned long fs_base, unsigned long gs_base)
 {
-       if (unlikely(cr3 != host->cr3)) {
-               vmcs_writel(HOST_CR3, cr3);
-               host->cr3 = cr3;
-       }
        if (unlikely(fs_sel != host->fs_sel)) {
                if (!(fs_sel & 7))
                        vmcs_write16(HOST_FS_SELECTOR, fs_sel);
@@ -1182,9 +1177,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
        gs_base = segment_base(gs_sel);
 #endif
 
-       vmx_set_vmcs_host_state(host_state, __get_current_cr3_fast(),
-                               fs_sel, gs_sel, fs_base, gs_base);
-
+       vmx_set_host_fs_gs(host_state, fs_sel, gs_sel, fs_base, gs_base);
        vmx->guest_state_loaded = true;
 }
 
@@ -6791,7 +6784,7 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
 static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
-       unsigned long cr4;
+       unsigned long cr3, cr4;
 
        /* Record the guest's net vcpu time for enforced NMI injections. */
        if (unlikely(!enable_vnmi &&
@@ -6834,6 +6827,19 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
                vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
        vcpu->arch.regs_dirty = 0;
 
+       /*
+        * Refresh vmcs.HOST_CR3 if necessary.  This must be done immediately
+        * prior to VM-Enter, as the kernel may load a new ASID (PCID) any time
+        * it switches back to the current->mm, which can occur in KVM context
+        * when switching to a temporary mm to patch kernel code, e.g. if KVM
+        * toggles a static key while handling a VM-Exit.
+        */
+       cr3 = __get_current_cr3_fast();
+       if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
+               vmcs_writel(HOST_CR3, cr3);
+               vmx->loaded_vmcs->host_state.cr3 = cr3;
+       }
+
        cr4 = cr4_read_shadow();
        if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
                vmcs_writel(HOST_CR4, cr4);
index 7f2c82e7f38f86073549795c256f6451700faa58..9c6bfcd84008be990153a2bffa327ca3e33e996a 100644 (file)
@@ -374,9 +374,8 @@ int allocate_vpid(void);
 void free_vpid(int vpid);
 void vmx_set_constant_host_state(struct vcpu_vmx *vmx);
 void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
-void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
-                            u16 fs_sel, u16 gs_sel,
-                            unsigned long fs_base, unsigned long gs_base);
+void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
+                       unsigned long fs_base, unsigned long gs_base);
 int vmx_get_cpl(struct kvm_vcpu *vcpu);
 bool vmx_emulation_required(struct kvm_vcpu *vcpu);
 unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu);
index 641044db415dee982c23cd5723dd578dff61a2fd..eb4029660bd9f3769a8931fc30b556f4439cfc8e 100644 (file)
@@ -984,6 +984,18 @@ void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu)
 }
 EXPORT_SYMBOL_GPL(kvm_load_host_xsave_state);
 
+static inline u64 kvm_guest_supported_xcr0(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.guest_fpu.fpstate->user_xfeatures;
+}
+
+#ifdef CONFIG_X86_64
+static inline u64 kvm_guest_supported_xfd(struct kvm_vcpu *vcpu)
+{
+       return kvm_guest_supported_xcr0(vcpu) & XFEATURE_MASK_USER_DYNAMIC;
+}
+#endif
+
 static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 {
        u64 xcr0 = xcr;
@@ -1003,7 +1015,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
         * saving.  However, xcr0 bit 0 is always set, even if the
         * emulated CPU does not support XSAVE (see kvm_vcpu_reset()).
         */
-       valid_bits = vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FP;
+       valid_bits = kvm_guest_supported_xcr0(vcpu) | XFEATURE_MASK_FP;
        if (xcr0 & ~valid_bits)
                return 1;
 
@@ -2351,10 +2363,12 @@ static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
        return tsc;
 }
 
+#ifdef CONFIG_X86_64
 static inline int gtod_is_based_on_tsc(int mode)
 {
        return mode == VDSO_CLOCKMODE_TSC || mode == VDSO_CLOCKMODE_HVCLOCK;
 }
+#endif
 
 static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
 {
@@ -3706,8 +3720,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                    !guest_cpuid_has(vcpu, X86_FEATURE_XFD))
                        return 1;
 
-               if (data & ~(XFEATURE_MASK_USER_DYNAMIC &
-                            vcpu->arch.guest_supported_xcr0))
+               if (data & ~kvm_guest_supported_xfd(vcpu))
                        return 1;
 
                fpu_update_guest_xfd(&vcpu->arch.guest_fpu, data);
@@ -3717,8 +3730,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                    !guest_cpuid_has(vcpu, X86_FEATURE_XFD))
                        return 1;
 
-               if (data & ~(XFEATURE_MASK_USER_DYNAMIC &
-                            vcpu->arch.guest_supported_xcr0))
+               if (data & ~kvm_guest_supported_xfd(vcpu))
                        return 1;
 
                vcpu->arch.guest_fpu.xfd_err = data;
@@ -4233,6 +4245,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_EXIT_ON_EMULATION_FAILURE:
        case KVM_CAP_VCPU_ATTRIBUTES:
        case KVM_CAP_SYS_ATTRIBUTES:
+       case KVM_CAP_ENABLE_CAP:
                r = 1;
                break;
        case KVM_CAP_EXIT_HYPERCALL:
@@ -8942,6 +8955,13 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
        if (clock_type != KVM_CLOCK_PAIRING_WALLCLOCK)
                return -KVM_EOPNOTSUPP;
 
+       /*
+        * When tsc is in permanent catchup mode guests won't be able to use
+        * pvclock_read_retry loop to get consistent view of pvclock
+        */
+       if (vcpu->arch.tsc_always_catchup)
+               return -KVM_EOPNOTSUPP;
+
        if (!kvm_get_walltime_and_clockread(&ts, &cycle))
                return -KVM_EOPNOTSUPP;
 
@@ -9160,6 +9180,7 @@ static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu)
                likely(!pic_in_kernel(vcpu->kvm));
 }
 
+/* Called within kvm->srcu read side.  */
 static void post_kvm_run_save(struct kvm_vcpu *vcpu)
 {
        struct kvm_run *kvm_run = vcpu->run;
@@ -9168,16 +9189,9 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
        kvm_run->cr8 = kvm_get_cr8(vcpu);
        kvm_run->apic_base = kvm_get_apic_base(vcpu);
 
-       /*
-        * The call to kvm_ready_for_interrupt_injection() may end up in
-        * kvm_xen_has_interrupt() which may require the srcu lock to be
-        * held, to protect against changes in the vcpu_info address.
-        */
-       vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
        kvm_run->ready_for_interrupt_injection =
                pic_in_kernel(vcpu->kvm) ||
                kvm_vcpu_ready_for_interrupt_injection(vcpu);
-       srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
 
        if (is_smm(vcpu))
                kvm_run->flags |= KVM_RUN_X86_SMM;
@@ -9795,6 +9809,7 @@ void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
 EXPORT_SYMBOL_GPL(__kvm_request_immediate_exit);
 
 /*
+ * Called within kvm->srcu read side.
  * Returns 1 to let vcpu_run() continue the guest execution loop without
  * exiting to the userspace.  Otherwise, the value will be returned to the
  * userspace.
@@ -10173,6 +10188,7 @@ out:
        return r;
 }
 
+/* Called within kvm->srcu read side.  */
 static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu)
 {
        bool hv_timer;
@@ -10232,12 +10248,12 @@ static inline bool kvm_vcpu_running(struct kvm_vcpu *vcpu)
                !vcpu->arch.apf.halted);
 }
 
+/* Called within kvm->srcu read side.  */
 static int vcpu_run(struct kvm_vcpu *vcpu)
 {
        int r;
        struct kvm *kvm = vcpu->kvm;
 
-       vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
        vcpu->arch.l1tf_flush_l1d = true;
 
        for (;;) {
@@ -10265,14 +10281,12 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
                if (__xfer_to_guest_mode_work_pending()) {
                        srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
                        r = xfer_to_guest_mode_handle_work(vcpu);
+                       vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
                        if (r)
                                return r;
-                       vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
                }
        }
 
-       srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
-
        return r;
 }
 
@@ -10378,6 +10392,7 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 {
        struct kvm_run *kvm_run = vcpu->run;
+       struct kvm *kvm = vcpu->kvm;
        int r;
 
        vcpu_load(vcpu);
@@ -10385,6 +10400,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
        kvm_run->flags = 0;
        kvm_load_guest_fpu(vcpu);
 
+       vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
        if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) {
                if (kvm_run->immediate_exit) {
                        r = -EINTR;
@@ -10395,7 +10411,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
                 * use before KVM has ever run the vCPU.
                 */
                WARN_ON_ONCE(kvm_lapic_hv_timer_in_use(vcpu));
+
+               srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
                kvm_vcpu_block(vcpu);
+               vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
+
                if (kvm_apic_accept_events(vcpu) < 0) {
                        r = 0;
                        goto out;
@@ -10455,8 +10475,9 @@ out:
        if (kvm_run->kvm_valid_regs)
                store_regs(vcpu);
        post_kvm_run_save(vcpu);
-       kvm_sigset_deactivate(vcpu);
+       srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
 
+       kvm_sigset_deactivate(vcpu);
        vcpu_put(vcpu);
        return r;
 }
index 59cf2343f3d906fb1bfb3d712edb8f34c39c62ae..d0d7b9bc6cad394c2de1b241956336a7ed9e255e 100644 (file)
@@ -27,8 +27,7 @@
  * Output:
  * rax original destination
  */
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK(memcpy)
+SYM_FUNC_START(__memcpy)
        ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
                      "jmp memcpy_erms", X86_FEATURE_ERMS
 
@@ -40,11 +39,12 @@ SYM_FUNC_START_WEAK(memcpy)
        movl %edx, %ecx
        rep movsb
        RET
-SYM_FUNC_END(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
-EXPORT_SYMBOL(memcpy)
+SYM_FUNC_END(__memcpy)
 EXPORT_SYMBOL(__memcpy)
 
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
 /*
  * memcpy_erms() - enhanced fast string memcpy. This is faster and
  * simpler than memcpy. Use memcpy_erms when possible.
index 50ea390df7128d6b6cd063e1b6f1839600349537..d83cba364e31d1e9b3c653971c79e5057a33a149 100644 (file)
@@ -24,7 +24,6 @@
  * Output:
  * rax: dest
  */
-SYM_FUNC_START_WEAK(memmove)
 SYM_FUNC_START(__memmove)
 
        mov %rdi, %rax
@@ -207,6 +206,7 @@ SYM_FUNC_START(__memmove)
 13:
        RET
 SYM_FUNC_END(__memmove)
-SYM_FUNC_END_ALIAS(memmove)
 EXPORT_SYMBOL(__memmove)
+
+SYM_FUNC_ALIAS_WEAK(memmove, __memmove)
 EXPORT_SYMBOL(memmove)
index d624f2bc42f1689c732452cc003df043c80f2cab..fc9ffd3ff3b213a38448d5fbff5493989e21a158 100644 (file)
@@ -17,7 +17,6 @@
  *
  * rax   original destination
  */
-SYM_FUNC_START_WEAK(memset)
 SYM_FUNC_START(__memset)
        /*
         * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
@@ -42,10 +41,11 @@ SYM_FUNC_START(__memset)
        movq %r9,%rax
        RET
 SYM_FUNC_END(__memset)
-SYM_FUNC_END_ALIAS(memset)
-EXPORT_SYMBOL(memset)
 EXPORT_SYMBOL(__memset)
 
+SYM_FUNC_ALIAS_WEAK(memset, __memset)
+EXPORT_SYMBOL(memset)
+
 /*
  * ISO C memset - set a memory block to a byte value. This function uses
  * enhanced rep stosb to override the fast string function.
index 89b3fb244e159e63a1c510e23adc8a8219233282..afbdda539b8010af13137825d21b6a5894c654af 100644 (file)
@@ -34,7 +34,7 @@ SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL)
 
        ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
                      __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \
-                     __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_AMD
+                     __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_LFENCE
 
 .endm
 
index ec31f5b60323ded53305f65594c027c1f66c81ca..d12d1358f96d2ec784f4b9281c1ea7f39b3ee0d2 100644 (file)
@@ -690,7 +690,10 @@ AVXcode: 2
 45: vpsrlvd/q Vx,Hx,Wx (66),(v)
 46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
 47: vpsllvd/q Vx,Hx,Wx (66),(v)
-# Skip 0x48-0x4b
+# Skip 0x48
+49: TILERELEASE (v1),(000),(11B) | LDTILECFG Mtc (v1)(000) | STTILECFG Mtc (66),(v1),(000) | TILEZERO Vt (F2),(v1),(11B)
+# Skip 0x4a
+4b: TILELOADD Vt,Wsm (F2),(v1) | TILELOADDT1 Vt,Wsm (66),(v1) | TILESTORED Wsm,Vt (F3),(v)
 4c: vrcp14ps/d Vpd,Wpd (66),(ev)
 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
@@ -705,7 +708,10 @@ AVXcode: 2
 59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
 5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
 5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
-# Skip 0x5c-0x61
+5c: TDPBF16PS Vt,Wt,Ht (F3),(v1)
+# Skip 0x5d
+5e: TDPBSSD Vt,Wt,Ht (F2),(v1) | TDPBSUD Vt,Wt,Ht (F3),(v1) | TDPBUSD Vt,Wt,Ht (66),(v1) | TDPBUUD Vt,Wt,Ht (v1)
+# Skip 0x5f-0x61
 62: vpexpandb/w Vx,Wx (66),(ev)
 63: vpcompressb/w Wx,Vx (66),(ev)
 64: vpblendmd/q Vx,Hx,Wx (66),(ev)
@@ -822,9 +828,9 @@ AVXcode: 3
 05: vpermilpd Vx,Wx,Ib (66),(v)
 06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
 07:
-08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
+08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) | vrndscaleph Vx,Wx,Ib (evo)
 09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
-0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
+0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) | vrndscalesh Vx,Hx,Wx,Ib (evo)
 0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
 0c: vblendps Vx,Hx,Wx,Ib (66)
 0d: vblendpd Vx,Hx,Wx,Ib (66)
@@ -846,8 +852,8 @@ AVXcode: 3
 22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
 23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
 25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
-26: vgetmantps/d Vx,Wx,Ib (66),(ev)
-27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
+26: vgetmantps/d Vx,Wx,Ib (66),(ev) | vgetmantph Vx,Wx,Ib (ev)
+27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) | vgetmantsh Vx,Hx,Wx,Ib (ev)
 30: kshiftrb/w Vk,Uk,Ib (66),(v)
 31: kshiftrd/q Vk,Uk,Ib (66),(v)
 32: kshiftlb/w Vk,Uk,Ib (66),(v)
@@ -871,23 +877,102 @@ AVXcode: 3
 51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
 54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
 55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
-56: vreduceps/d Vx,Wx,Ib (66),(ev)
-57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
+56: vreduceps/d Vx,Wx,Ib (66),(ev) | vreduceph Vx,Wx,Ib (ev)
+57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) | vreducesh Vx,Hx,Wx,Ib (ev)
 60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
 61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
 63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
-66: vfpclassps/d Vk,Wx,Ib (66),(ev)
-67: vfpclassss/d Vk,Wx,Ib (66),(ev)
+66: vfpclassps/d Vk,Wx,Ib (66),(ev) | vfpclassph Vx,Wx,Ib (ev)
+67: vfpclassss/d Vk,Wx,Ib (66),(ev) | vfpclasssh Vx,Wx,Ib (ev)
 70: vpshldw Vx,Hx,Wx,Ib (66),(ev)
 71: vpshldd/q Vx,Hx,Wx,Ib (66),(ev)
 72: vpshrdw Vx,Hx,Wx,Ib (66),(ev)
 73: vpshrdd/q Vx,Hx,Wx,Ib (66),(ev)
+c2: vcmpph Vx,Hx,Wx,Ib (ev) | vcmpsh Vx,Hx,Wx,Ib (F3),(ev)
 cc: sha1rnds4 Vdq,Wdq,Ib
 ce: vgf2p8affineqb Vx,Wx,Ib (66)
 cf: vgf2p8affineinvqb Vx,Wx,Ib (66)
 df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
-f0: RORX Gy,Ey,Ib (F2),(v)
+f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B)
+EndTable
+
+Table: EVEX map 5
+Referrer:
+AVXcode: 5
+10: vmovsh Vx,Hx,Wx (F3),(ev) | vmovsh Vx,Wx (F3),(ev)
+11: vmovsh Wx,Hx,Vx (F3),(ev) | vmovsh Wx,Vx (F3),(ev)
+1d: vcvtps2phx Vx,Wx (66),(ev) | vcvtss2sh Vx,Hx,Wx (ev)
+2a: vcvtsi2sh Vx,Hx,Wx (F3),(ev)
+2c: vcvttsh2si Vx,Wx (F3),(ev)
+2d: vcvtsh2si Vx,Wx (F3),(ev)
+2e: vucomish Vx,Wx (ev)
+2f: vcomish Vx,Wx (ev)
+51: vsqrtph Vx,Wx (ev) | vsqrtsh Vx,Hx,Wx (F3),(ev)
+58: vaddph Vx,Hx,Wx (ev) | vaddsh Vx,Hx,Wx (F3),(ev)
+59: vmulph Vx,Hx,Wx (ev) | vmulsh Vx,Hx,Wx (F3),(ev)
+5a: vcvtpd2ph Vx,Wx (66),(ev) | vcvtph2pd Vx,Wx (ev) | vcvtsd2sh Vx,Hx,Wx (F2),(ev) | vcvtsh2sd Vx,Hx,Wx (F3),(ev)
+5b: vcvtdq2ph Vx,Wx (ev) | vcvtph2dq Vx,Wx (66),(ev) | vcvtqq2ph Vx,Wx (ev) | vcvttph2dq Vx,Wx (F3),(ev)
+5c: vsubph Vx,Hx,Wx (ev) | vsubsh Vx,Hx,Wx (F3),(ev)
+5d: vminph Vx,Hx,Wx (ev) | vminsh Vx,Hx,Wx (F3),(ev)
+5e: vdivph Vx,Hx,Wx (ev) | vdivsh Vx,Hx,Wx (F3),(ev)
+5f: vmaxph Vx,Hx,Wx (ev) | vmaxsh Vx,Hx,Wx (F3),(ev)
+6e: vmovw Vx,Wx (66),(ev)
+78: vcvttph2udq Vx,Wx (ev) | vcvttph2uqq Vx,Wx (66),(ev) | vcvttsh2usi Vx,Wx (F3),(ev)
+79: vcvtph2udq Vx,Wx (ev) | vcvtph2uqq Vx,Wx (66),(ev) | vcvtsh2usi Vx,Wx (F3),(ev)
+7a: vcvttph2qq Vx,Wx (66),(ev) | vcvtudq2ph Vx,Wx (F2),(ev) | vcvtuqq2ph Vx,Wx (F2),(ev)
+7b: vcvtph2qq Vx,Wx (66),(ev) | vcvtusi2sh Vx,Hx,Wx (F3),(ev)
+7c: vcvttph2uw Vx,Wx (ev) | vcvttph2w Vx,Wx (66),(ev)
+7d: vcvtph2uw Vx,Wx (ev) | vcvtph2w Vx,Wx (66),(ev) | vcvtuw2ph Vx,Wx (F2),(ev) | vcvtw2ph Vx,Wx (F3),(ev)
+7e: vmovw Wx,Vx (66),(ev)
+EndTable
+
+Table: EVEX map 6
+Referrer:
+AVXcode: 6
+13: vcvtph2psx Vx,Wx (66),(ev) | vcvtsh2ss Vx,Hx,Wx (ev)
+2c: vscalefph Vx,Hx,Wx (66),(ev)
+2d: vscalefsh Vx,Hx,Wx (66),(ev)
+42: vgetexpph Vx,Wx (66),(ev)
+43: vgetexpsh Vx,Hx,Wx (66),(ev)
+4c: vrcpph Vx,Wx (66),(ev)
+4d: vrcpsh Vx,Hx,Wx (66),(ev)
+4e: vrsqrtph Vx,Wx (66),(ev)
+4f: vrsqrtsh Vx,Hx,Wx (66),(ev)
+56: vfcmaddcph Vx,Hx,Wx (F2),(ev) | vfmaddcph Vx,Hx,Wx (F3),(ev)
+57: vfcmaddcsh Vx,Hx,Wx (F2),(ev) | vfmaddcsh Vx,Hx,Wx (F3),(ev)
+96: vfmaddsub132ph Vx,Hx,Wx (66),(ev)
+97: vfmsubadd132ph Vx,Hx,Wx (66),(ev)
+98: vfmadd132ph Vx,Hx,Wx (66),(ev)
+99: vfmadd132sh Vx,Hx,Wx (66),(ev)
+9a: vfmsub132ph Vx,Hx,Wx (66),(ev)
+9b: vfmsub132sh Vx,Hx,Wx (66),(ev)
+9c: vfnmadd132ph Vx,Hx,Wx (66),(ev)
+9d: vfnmadd132sh Vx,Hx,Wx (66),(ev)
+9e: vfnmsub132ph Vx,Hx,Wx (66),(ev)
+9f: vfnmsub132sh Vx,Hx,Wx (66),(ev)
+a6: vfmaddsub213ph Vx,Hx,Wx (66),(ev)
+a7: vfmsubadd213ph Vx,Hx,Wx (66),(ev)
+a8: vfmadd213ph Vx,Hx,Wx (66),(ev)
+a9: vfmadd213sh Vx,Hx,Wx (66),(ev)
+aa: vfmsub213ph Vx,Hx,Wx (66),(ev)
+ab: vfmsub213sh Vx,Hx,Wx (66),(ev)
+ac: vfnmadd213ph Vx,Hx,Wx (66),(ev)
+ad: vfnmadd213sh Vx,Hx,Wx (66),(ev)
+ae: vfnmsub213ph Vx,Hx,Wx (66),(ev)
+af: vfnmsub213sh Vx,Hx,Wx (66),(ev)
+b6: vfmaddsub231ph Vx,Hx,Wx (66),(ev)
+b7: vfmsubadd231ph Vx,Hx,Wx (66),(ev)
+b8: vfmadd231ph Vx,Hx,Wx (66),(ev)
+b9: vfmadd231sh Vx,Hx,Wx (66),(ev)
+ba: vfmsub231ph Vx,Hx,Wx (66),(ev)
+bb: vfmsub231sh Vx,Hx,Wx (66),(ev)
+bc: vfnmadd231ph Vx,Hx,Wx (66),(ev)
+bd: vfnmadd231sh Vx,Hx,Wx (66),(ev)
+be: vfnmsub231ph Vx,Hx,Wx (66),(ev)
+bf: vfnmsub231sh Vx,Hx,Wx (66),(ev)
+d6: vfcmulcph Vx,Hx,Wx (F2),(ev) | vfmulcph Vx,Hx,Wx (F3),(ev)
+d7: vfcmulcsh Vx,Hx,Wx (F2),(ev) | vfmulcsh Vx,Hx,Wx (F3),(ev)
 EndTable
 
 GrpTable: Grp1
@@ -970,7 +1055,7 @@ GrpTable: Grp7
 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) | ENCLU (111),(11B)
 3: LIDT Ms
 4: SMSW Mw/Rv
-5: rdpkru (110),(11B) | wrpkru (111),(11B) | SAVEPREVSSP (F3),(010),(11B) | RSTORSSP Mq (F3) | SETSSBSY (F3),(000),(11B)
+5: rdpkru (110),(11B) | wrpkru (111),(11B) | SAVEPREVSSP (F3),(010),(11B) | RSTORSSP Mq (F3) | SETSSBSY (F3),(000),(11B) | CLUI (F3),(110),(11B) | SERIALIZE (000),(11B) | STUI (F3),(111),(11B) | TESTUI (F3)(101)(11B) | UIRET (F3),(100),(11B) | XRESLDTRK (F2),(000),(11B) | XSUSLDTRK (F2),(001),(11B)
 6: LMSW Ew
 7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
 EndTable
@@ -987,7 +1072,7 @@ GrpTable: Grp9
 3: xrstors
 4: xsavec
 5: xsaves
-6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
+6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) | SENDUIPI Gq (F3)
 7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
 EndTable
 
index 026031b3b7829517ae0e04295f3c10e430c3cd00..17a492c27306990c2d2d4ed3b0224152ffa2651e 100644 (file)
@@ -615,6 +615,7 @@ static bool memremap_is_efi_data(resource_size_t phys_addr,
 static bool memremap_is_setup_data(resource_size_t phys_addr,
                                   unsigned long size)
 {
+       struct setup_indirect *indirect;
        struct setup_data *data;
        u64 paddr, paddr_next;
 
@@ -627,6 +628,10 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
 
                data = memremap(paddr, sizeof(*data),
                                MEMREMAP_WB | MEMREMAP_DEC);
+               if (!data) {
+                       pr_warn("failed to memremap setup_data entry\n");
+                       return false;
+               }
 
                paddr_next = data->next;
                len = data->len;
@@ -636,10 +641,21 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
                        return true;
                }
 
-               if (data->type == SETUP_INDIRECT &&
-                   ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
-                       paddr = ((struct setup_indirect *)data->data)->addr;
-                       len = ((struct setup_indirect *)data->data)->len;
+               if (data->type == SETUP_INDIRECT) {
+                       memunmap(data);
+                       data = memremap(paddr, sizeof(*data) + len,
+                                       MEMREMAP_WB | MEMREMAP_DEC);
+                       if (!data) {
+                               pr_warn("failed to memremap indirect setup_data\n");
+                               return false;
+                       }
+
+                       indirect = (struct setup_indirect *)data->data;
+
+                       if (indirect->type != SETUP_INDIRECT) {
+                               paddr = indirect->addr;
+                               len = indirect->len;
+                       }
                }
 
                memunmap(data);
@@ -660,22 +676,51 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
 static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
                                                unsigned long size)
 {
+       struct setup_indirect *indirect;
        struct setup_data *data;
        u64 paddr, paddr_next;
 
        paddr = boot_params.hdr.setup_data;
        while (paddr) {
-               unsigned int len;
+               unsigned int len, size;
 
                if (phys_addr == paddr)
                        return true;
 
                data = early_memremap_decrypted(paddr, sizeof(*data));
+               if (!data) {
+                       pr_warn("failed to early memremap setup_data entry\n");
+                       return false;
+               }
+
+               size = sizeof(*data);
 
                paddr_next = data->next;
                len = data->len;
 
-               early_memunmap(data, sizeof(*data));
+               if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
+                       early_memunmap(data, sizeof(*data));
+                       return true;
+               }
+
+               if (data->type == SETUP_INDIRECT) {
+                       size += len;
+                       early_memunmap(data, sizeof(*data));
+                       data = early_memremap_decrypted(paddr, size);
+                       if (!data) {
+                               pr_warn("failed to early memremap indirect setup_data\n");
+                               return false;
+                       }
+
+                       indirect = (struct setup_indirect *)data->data;
+
+                       if (indirect->type != SETUP_INDIRECT) {
+                               paddr = indirect->addr;
+                               len = indirect->len;
+                       }
+               }
+
+               early_memunmap(data, size);
 
                if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
                        return true;
index 2b2d018ea3450dcb384ee4d718e4bf86f17b9f7d..6169053c28541c96e50f5bd7e2276b564571b527 100644 (file)
@@ -177,25 +177,6 @@ void __init sme_map_bootdata(char *real_mode_data)
        __sme_early_map_unmap_mem(__va(cmdline_paddr), COMMAND_LINE_SIZE, true);
 }
 
-void __init sme_early_init(void)
-{
-       unsigned int i;
-
-       if (!sme_me_mask)
-               return;
-
-       early_pmd_flags = __sme_set(early_pmd_flags);
-
-       __supported_pte_mask = __sme_set(__supported_pte_mask);
-
-       /* Update the protection map with memory encryption mask */
-       for (i = 0; i < ARRAY_SIZE(protection_map); i++)
-               protection_map[i] = pgprot_encrypted(protection_map[i]);
-
-       if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
-               swiotlb_force = SWIOTLB_FORCE;
-}
-
 void __init sev_setup_arch(void)
 {
        phys_addr_t total_mem = memblock_phys_mem_size();
@@ -256,7 +237,17 @@ static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot)
        return pfn;
 }
 
-void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
+static bool amd_enc_tlb_flush_required(bool enc)
+{
+       return true;
+}
+
+static bool amd_enc_cache_flush_required(void)
+{
+       return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT);
+}
+
+static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
 #ifdef CONFIG_PARAVIRT
        unsigned long sz = npages << PAGE_SHIFT;
@@ -287,6 +278,19 @@ void notify_range_enc_status_changed(unsigned long vaddr, int npages, bool enc)
 #endif
 }
 
+static void amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+{
+}
+
+/* Return true unconditionally: return value doesn't matter for the SEV side */
+static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+{
+       if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+               enc_dec_hypercall(vaddr, npages, enc);
+
+       return true;
+}
+
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
 {
        pgprot_t old_prot, new_prot;
@@ -392,7 +396,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr,
 
        ret = 0;
 
-       notify_range_enc_status_changed(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
+       early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc);
 out:
        __flush_tlb_all();
        return ret;
@@ -410,7 +414,31 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)
 
 void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc)
 {
-       notify_range_enc_status_changed(vaddr, npages, enc);
+       enc_dec_hypercall(vaddr, npages, enc);
+}
+
+void __init sme_early_init(void)
+{
+       unsigned int i;
+
+       if (!sme_me_mask)
+               return;
+
+       early_pmd_flags = __sme_set(early_pmd_flags);
+
+       __supported_pte_mask = __sme_set(__supported_pte_mask);
+
+       /* Update the protection map with memory encryption mask */
+       for (i = 0; i < ARRAY_SIZE(protection_map); i++)
+               protection_map[i] = pgprot_encrypted(protection_map[i]);
+
+       if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+               swiotlb_force = SWIOTLB_FORCE;
+
+       x86_platform.guest.enc_status_change_prepare = amd_enc_status_change_prepare;
+       x86_platform.guest.enc_status_change_finish  = amd_enc_status_change_finish;
+       x86_platform.guest.enc_tlb_flush_required    = amd_enc_tlb_flush_required;
+       x86_platform.guest.enc_cache_flush_required  = amd_enc_cache_flush_required;
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
index 3f0abb4033403ba46f220a723368540d61b55d6d..b43bc24d2bb6415e4fe5eb7a4bec1914d5767fb1 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/cmdline.h>
+#include <asm/coco.h>
 
 #include "mm_internal.h"
 
@@ -565,8 +566,7 @@ void __init sme_enable(struct boot_params *bp)
        } else {
                /* SEV state cannot be controlled by a command line option */
                sme_me_mask = me_mask;
-               physical_mask &= ~sme_me_mask;
-               return;
+               goto out;
        }
 
        /*
@@ -600,6 +600,10 @@ void __init sme_enable(struct boot_params *bp)
                sme_me_mask = 0;
        else
                sme_me_mask = active_by_default ? me_mask : 0;
-
-       physical_mask &= ~sme_me_mask;
+out:
+       if (sme_me_mask) {
+               physical_mask &= ~sme_me_mask;
+               cc_set_vendor(CC_VENDOR_AMD);
+               cc_set_mask(sme_me_mask);
+       }
 }
index 9bdaf828ee68fb2f40aabc68fa7ecd952944c7de..abf5ed76e4b7bdb9de1d81b10243e5d35b10c148 100644 (file)
@@ -1989,6 +1989,7 @@ int set_memory_global(unsigned long addr, int numpages)
  */
 static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 {
+       pgprot_t empty = __pgprot(0);
        struct cpa_data cpa;
        int ret;
 
@@ -1999,18 +2000,20 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
        memset(&cpa, 0, sizeof(cpa));
        cpa.vaddr = &addr;
        cpa.numpages = numpages;
-       cpa.mask_set = enc ? __pgprot(_PAGE_ENC) : __pgprot(0);
-       cpa.mask_clr = enc ? __pgprot(0) : __pgprot(_PAGE_ENC);
+       cpa.mask_set = enc ? pgprot_encrypted(empty) : pgprot_decrypted(empty);
+       cpa.mask_clr = enc ? pgprot_decrypted(empty) : pgprot_encrypted(empty);
        cpa.pgd = init_mm.pgd;
 
        /* Must avoid aliasing mappings in the highmem code */
        kmap_flush_unused();
        vm_unmap_aliases();
 
-       /*
-        * Before changing the encryption attribute, we need to flush caches.
-        */
-       cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+       /* Flush the caches as needed before changing the encryption attribute. */
+       if (x86_platform.guest.enc_tlb_flush_required(enc))
+               cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
+
+       /* Notify hypervisor that we are about to set/clr encryption attribute. */
+       x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
 
        ret = __change_page_attr_set_clr(&cpa, 1);
 
@@ -2023,11 +2026,11 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
         */
        cpa_flush(&cpa, 0);
 
-       /*
-        * Notify hypervisor that a given memory range is mapped encrypted
-        * or decrypted.
-        */
-       notify_range_enc_status_changed(addr, numpages, enc);
+       /* Notify hypervisor that we have successfully set/clr encryption attribute. */
+       if (!ret) {
+               if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
+                       ret = -EIO;
+       }
 
        return ret;
 }
index 2b1e266ff95c3db3bbfb4b142e2f770487f43cad..0ecb140864b21da1e6b9c4e8d22957c5a1012d07 100644 (file)
@@ -394,7 +394,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
        u8 *prog = *pprog;
 
 #ifdef CONFIG_RETPOLINE
-       if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_AMD)) {
+       if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
                EMIT_LFENCE();
                EMIT2(0xFF, 0xE0 + reg);
        } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
index 40d6a06e41c81b7b9b2328d1526ad8a84676c1d8..ead7e5b3a97573defc132f412bbacc5090dcb1ee 100644 (file)
@@ -8,6 +8,7 @@ endmenu
 
 config UML_X86
        def_bool y
+       select ARCH_BINFMT_ELF_EXTRA_PHDRS if X86_32
 
 config 64BIT
        bool "64-bit kernel" if "$(SUBARCH)" = "x86"
index 1039515c99d6aba244bda3fc9b132c00d2191d09..779b4a1f66ac22db6ac8cabba216bcca5bdfd940 100644 (file)
@@ -50,6 +50,7 @@
 #include "blk-mq-sched.h"
 #include "blk-pm.h"
 #include "blk-throttle.h"
+#include "blk-rq-qos.h"
 
 struct dentry *blk_debugfs_root;
 
@@ -314,6 +315,9 @@ void blk_cleanup_queue(struct request_queue *q)
         */
        blk_freeze_queue(q);
 
+       /* cleanup rq qos structures for queue without disk */
+       rq_qos_exit(q);
+
        blk_queue_flag_set(QUEUE_FLAG_DEAD, q);
 
        blk_sync_queue(q);
index d69ca91fbc8b121b40a2f517b61f8db5fdadeeb6..9a9185a0a2d132f6b1f73ec360f6b6125f899453 100644 (file)
@@ -2718,7 +2718,8 @@ static bool blk_mq_attempt_bio_merge(struct request_queue *q,
 
 static struct request *blk_mq_get_new_requests(struct request_queue *q,
                                               struct blk_plug *plug,
-                                              struct bio *bio)
+                                              struct bio *bio,
+                                              unsigned int nsegs)
 {
        struct blk_mq_alloc_data data = {
                .q              = q,
@@ -2730,6 +2731,11 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
        if (unlikely(bio_queue_enter(bio)))
                return NULL;
 
+       if (blk_mq_attempt_bio_merge(q, bio, nsegs))
+               goto queue_exit;
+
+       rq_qos_throttle(q, bio);
+
        if (plug) {
                data.nr_tags = plug->nr_ios;
                plug->nr_ios = 1;
@@ -2742,12 +2748,13 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
        rq_qos_cleanup(q, bio);
        if (bio->bi_opf & REQ_NOWAIT)
                bio_wouldblock_error(bio);
+queue_exit:
        blk_queue_exit(q);
        return NULL;
 }
 
 static inline struct request *blk_mq_get_cached_request(struct request_queue *q,
-               struct blk_plug *plug, struct bio *bio)
+               struct blk_plug *plug, struct bio **bio, unsigned int nsegs)
 {
        struct request *rq;
 
@@ -2757,12 +2764,19 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q,
        if (!rq || rq->q != q)
                return NULL;
 
-       if (blk_mq_get_hctx_type(bio->bi_opf) != rq->mq_hctx->type)
+       if (blk_mq_attempt_bio_merge(q, *bio, nsegs)) {
+               *bio = NULL;
+               return NULL;
+       }
+
+       rq_qos_throttle(q, *bio);
+
+       if (blk_mq_get_hctx_type((*bio)->bi_opf) != rq->mq_hctx->type)
                return NULL;
-       if (op_is_flush(rq->cmd_flags) != op_is_flush(bio->bi_opf))
+       if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf))
                return NULL;
 
-       rq->cmd_flags = bio->bi_opf;
+       rq->cmd_flags = (*bio)->bi_opf;
        plug->cached_rq = rq_list_next(rq);
        INIT_LIST_HEAD(&rq->queuelist);
        return rq;
@@ -2800,14 +2814,11 @@ void blk_mq_submit_bio(struct bio *bio)
        if (!bio_integrity_prep(bio))
                return;
 
-       if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
-               return;
-
-       rq_qos_throttle(q, bio);
-
-       rq = blk_mq_get_cached_request(q, plug, bio);
+       rq = blk_mq_get_cached_request(q, plug, &bio, nr_segs);
        if (!rq) {
-               rq = blk_mq_get_new_requests(q, plug, bio);
+               if (!bio)
+                       return;
+               rq = blk_mq_get_new_requests(q, plug, bio, nr_segs);
                if (unlikely(!rq))
                        return;
        }
index 4f59e0f5bf30966214064260c9a4119773b2bff7..a18e7fbd97b8bf19ed26d85533782ac58bf6e5a8 100644 (file)
@@ -289,6 +289,8 @@ static void blkdev_bio_end_io_async(struct bio *bio)
        struct kiocb *iocb = dio->iocb;
        ssize_t ret;
 
+       WRITE_ONCE(iocb->private, NULL);
+
        if (likely(!bio->bi_status)) {
                ret = dio->size;
                iocb->ki_pos += ret;
index 692365dee2bd44c50a095c4e97c2df15510eee83..05b66ce9d1c9ed1b6a0fc2abc81ac22fca452152 100644 (file)
@@ -22,6 +22,9 @@ static struct key *builtin_trusted_keys;
 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
 static struct key *secondary_trusted_keys;
 #endif
+#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+static struct key *machine_trusted_keys;
+#endif
 #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
 static struct key *platform_trusted_keys;
 #endif
@@ -86,11 +89,50 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
        if (!restriction)
                panic("Can't allocate secondary trusted keyring restriction\n");
 
-       restriction->check = restrict_link_by_builtin_and_secondary_trusted;
+       if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING))
+               restriction->check = restrict_link_by_builtin_secondary_and_machine;
+       else
+               restriction->check = restrict_link_by_builtin_and_secondary_trusted;
 
        return restriction;
 }
 #endif
+#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+void __init set_machine_trusted_keys(struct key *keyring)
+{
+       machine_trusted_keys = keyring;
+
+       if (key_link(secondary_trusted_keys, machine_trusted_keys) < 0)
+               panic("Can't link (machine) trusted keyrings\n");
+}
+
+/**
+ * restrict_link_by_builtin_secondary_and_machine - Restrict keyring addition.
+ * @dest_keyring: Keyring being linked to.
+ * @type: The type of key being added.
+ * @payload: The payload of the new key.
+ * @restrict_key: A ring of keys that can be used to vouch for the new cert.
+ *
+ * Restrict the addition of keys into a keyring based on the key-to-be-added
+ * being vouched for by a key in either the built-in, the secondary, or
+ * the machine keyrings.
+ */
+int restrict_link_by_builtin_secondary_and_machine(
+       struct key *dest_keyring,
+       const struct key_type *type,
+       const union key_payload *payload,
+       struct key *restrict_key)
+{
+       if (machine_trusted_keys && type == &key_type_keyring &&
+           dest_keyring == secondary_trusted_keys &&
+           payload == &machine_trusted_keys->payload)
+               /* Allow the machine keyring to be added to the secondary */
+               return 0;
+
+       return restrict_link_by_builtin_and_secondary_trusted(dest_keyring, type,
+                                                             payload, restrict_key);
+}
+#endif
 
 /*
  * Create the trusted keyrings
index 1f1f004dc75773ef862f09ce03b630a88efefae3..460bc5d0a828ce21be17433e367d9a035f4845a5 100644 (file)
@@ -22,18 +22,6 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
          appropriate hash algorithms (such as SHA-1) must be available.
          ENOPKG will be reported if the requisite algorithm is unavailable.
 
-config ASYMMETRIC_TPM_KEY_SUBTYPE
-       tristate "Asymmetric TPM backed private key subtype"
-       depends on TCG_TPM
-       depends on TRUSTED_KEYS
-       select CRYPTO_HMAC
-       select CRYPTO_SHA1
-       select CRYPTO_HASH_INFO
-       help
-         This option provides support for TPM backed private key type handling.
-         Operations such as sign, verify, encrypt, decrypt are performed by
-         the TPM after the private key is loaded.
-
 config X509_CERTIFICATE_PARSER
        tristate "X.509 certificate parser"
        depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
@@ -54,15 +42,6 @@ config PKCS8_PRIVATE_KEY_PARSER
          private key data and provides the ability to instantiate a crypto key
          from that data.
 
-config TPM_KEY_PARSER
-       tristate "TPM private key parser"
-       depends on ASYMMETRIC_TPM_KEY_SUBTYPE
-       select ASN1
-       help
-         This option provides support for parsing TPM format blobs for
-         private key data and provides the ability to instantiate a crypto key
-         from that data.
-
 config PKCS7_MESSAGE_PARSER
        tristate "PKCS#7 message parser"
        depends on X509_CERTIFICATE_PARSER
index 28b91adba2aed35f830e6c6f7d356004f1d5248c..c38424f55b08d0a7942921e9e9125fbaa3cf660f 100644 (file)
@@ -11,7 +11,6 @@ asymmetric_keys-y := \
        signature.o
 
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
-obj-$(CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE) += asym_tpm.o
 
 #
 # X.509 Certificate handling
@@ -75,14 +74,3 @@ verify_signed_pefile-y := \
 
 $(obj)/mscode_parser.o: $(obj)/mscode.asn1.h $(obj)/mscode.asn1.h
 $(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h
-
-#
-# TPM private key parsing
-#
-obj-$(CONFIG_TPM_KEY_PARSER) += tpm_key_parser.o
-tpm_key_parser-y := \
-       tpm.asn1.o \
-       tpm_parser.o
-
-$(obj)/tpm_parser.o: $(obj)/tpm.asn1.h
-$(obj)/tpm.asn1.o: $(obj)/tpm.asn1.c $(obj)/tpm.asn1.h
diff --git a/crypto/asymmetric_keys/asym_tpm.c b/crypto/asymmetric_keys/asym_tpm.c
deleted file mode 100644 (file)
index 0959613..0000000
+++ /dev/null
@@ -1,957 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define pr_fmt(fmt) "ASYM-TPM: "fmt
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/seq_file.h>
-#include <linux/scatterlist.h>
-#include <linux/tpm.h>
-#include <linux/tpm_command.h>
-#include <crypto/akcipher.h>
-#include <crypto/hash.h>
-#include <crypto/sha1.h>
-#include <asm/unaligned.h>
-#include <keys/asymmetric-subtype.h>
-#include <keys/trusted_tpm.h>
-#include <crypto/asym_tpm_subtype.h>
-#include <crypto/public_key.h>
-
-#define TPM_ORD_FLUSHSPECIFIC  186
-#define TPM_ORD_LOADKEY2       65
-#define TPM_ORD_UNBIND         30
-#define TPM_ORD_SIGN           60
-
-#define TPM_RT_KEY                      0x00000001
-
-/*
- * Load a TPM key from the blob provided by userspace
- */
-static int tpm_loadkey2(struct tpm_buf *tb,
-                       uint32_t keyhandle, unsigned char *keyauth,
-                       const unsigned char *keyblob, int keybloblen,
-                       uint32_t *newhandle)
-{
-       unsigned char nonceodd[TPM_NONCE_SIZE];
-       unsigned char enonce[TPM_NONCE_SIZE];
-       unsigned char authdata[SHA1_DIGEST_SIZE];
-       uint32_t authhandle = 0;
-       unsigned char cont = 0;
-       uint32_t ordinal;
-       int ret;
-
-       ordinal = htonl(TPM_ORD_LOADKEY2);
-
-       /* session for loading the key */
-       ret = oiap(tb, &authhandle, enonce);
-       if (ret < 0) {
-               pr_info("oiap failed (%d)\n", ret);
-               return ret;
-       }
-
-       /* generate odd nonce */
-       ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
-       if (ret < 0) {
-               pr_info("tpm_get_random failed (%d)\n", ret);
-               return ret;
-       }
-
-       /* calculate authorization HMAC value */
-       ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
-                          nonceodd, cont, sizeof(uint32_t), &ordinal,
-                          keybloblen, keyblob, 0, 0);
-       if (ret < 0)
-               return ret;
-
-       /* build the request buffer */
-       tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LOADKEY2);
-       tpm_buf_append_u32(tb, keyhandle);
-       tpm_buf_append(tb, keyblob, keybloblen);
-       tpm_buf_append_u32(tb, authhandle);
-       tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
-       tpm_buf_append_u8(tb, cont);
-       tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
-       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
-       if (ret < 0) {
-               pr_info("authhmac failed (%d)\n", ret);
-               return ret;
-       }
-
-       ret = TSS_checkhmac1(tb->data, ordinal, nonceodd, keyauth,
-                            SHA1_DIGEST_SIZE, 0, 0);
-       if (ret < 0) {
-               pr_info("TSS_checkhmac1 failed (%d)\n", ret);
-               return ret;
-       }
-
-       *newhandle = LOAD32(tb->data, TPM_DATA_OFFSET);
-       return 0;
-}
-
-/*
- * Execute the FlushSpecific TPM command
- */
-static int tpm_flushspecific(struct tpm_buf *tb, uint32_t handle)
-{
-       tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_FLUSHSPECIFIC);
-       tpm_buf_append_u32(tb, handle);
-       tpm_buf_append_u32(tb, TPM_RT_KEY);
-
-       return trusted_tpm_send(tb->data, MAX_BUF_SIZE);
-}
-
-/*
- * Decrypt a blob provided by userspace using a specific key handle.
- * The handle is a well known handle or previously loaded by e.g. LoadKey2
- */
-static int tpm_unbind(struct tpm_buf *tb,
-                       uint32_t keyhandle, unsigned char *keyauth,
-                       const unsigned char *blob, uint32_t bloblen,
-                       void *out, uint32_t outlen)
-{
-       unsigned char nonceodd[TPM_NONCE_SIZE];
-       unsigned char enonce[TPM_NONCE_SIZE];
-       unsigned char authdata[SHA1_DIGEST_SIZE];
-       uint32_t authhandle = 0;
-       unsigned char cont = 0;
-       uint32_t ordinal;
-       uint32_t datalen;
-       int ret;
-
-       ordinal = htonl(TPM_ORD_UNBIND);
-       datalen = htonl(bloblen);
-
-       /* session for loading the key */
-       ret = oiap(tb, &authhandle, enonce);
-       if (ret < 0) {
-               pr_info("oiap failed (%d)\n", ret);
-               return ret;
-       }
-
-       /* generate odd nonce */
-       ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
-       if (ret < 0) {
-               pr_info("tpm_get_random failed (%d)\n", ret);
-               return ret;
-       }
-
-       /* calculate authorization HMAC value */
-       ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
-                          nonceodd, cont, sizeof(uint32_t), &ordinal,
-                          sizeof(uint32_t), &datalen,
-                          bloblen, blob, 0, 0);
-       if (ret < 0)
-               return ret;
-
-       /* build the request buffer */
-       tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UNBIND);
-       tpm_buf_append_u32(tb, keyhandle);
-       tpm_buf_append_u32(tb, bloblen);
-       tpm_buf_append(tb, blob, bloblen);
-       tpm_buf_append_u32(tb, authhandle);
-       tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
-       tpm_buf_append_u8(tb, cont);
-       tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
-       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
-       if (ret < 0) {
-               pr_info("authhmac failed (%d)\n", ret);
-               return ret;
-       }
-
-       datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
-
-       ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
-                            keyauth, SHA1_DIGEST_SIZE,
-                            sizeof(uint32_t), TPM_DATA_OFFSET,
-                            datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
-                            0, 0);
-       if (ret < 0) {
-               pr_info("TSS_checkhmac1 failed (%d)\n", ret);
-               return ret;
-       }
-
-       memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
-              min(outlen, datalen));
-
-       return datalen;
-}
-
-/*
- * Sign a blob provided by userspace (that has had the hash function applied)
- * using a specific key handle.  The handle is assumed to have been previously
- * loaded by e.g. LoadKey2.
- *
- * Note that the key signature scheme of the used key should be set to
- * TPM_SS_RSASSAPKCS1v15_DER.  This allows the hashed input to be of any size
- * up to key_length_in_bytes - 11 and not be limited to size 20 like the
- * TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
- */
-static int tpm_sign(struct tpm_buf *tb,
-                   uint32_t keyhandle, unsigned char *keyauth,
-                   const unsigned char *blob, uint32_t bloblen,
-                   void *out, uint32_t outlen)
-{
-       unsigned char nonceodd[TPM_NONCE_SIZE];
-       unsigned char enonce[TPM_NONCE_SIZE];
-       unsigned char authdata[SHA1_DIGEST_SIZE];
-       uint32_t authhandle = 0;
-       unsigned char cont = 0;
-       uint32_t ordinal;
-       uint32_t datalen;
-       int ret;
-
-       ordinal = htonl(TPM_ORD_SIGN);
-       datalen = htonl(bloblen);
-
-       /* session for loading the key */
-       ret = oiap(tb, &authhandle, enonce);
-       if (ret < 0) {
-               pr_info("oiap failed (%d)\n", ret);
-               return ret;
-       }
-
-       /* generate odd nonce */
-       ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
-       if (ret < 0) {
-               pr_info("tpm_get_random failed (%d)\n", ret);
-               return ret;
-       }
-
-       /* calculate authorization HMAC value */
-       ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
-                          nonceodd, cont, sizeof(uint32_t), &ordinal,
-                          sizeof(uint32_t), &datalen,
-                          bloblen, blob, 0, 0);
-       if (ret < 0)
-               return ret;
-
-       /* build the request buffer */
-       tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SIGN);
-       tpm_buf_append_u32(tb, keyhandle);
-       tpm_buf_append_u32(tb, bloblen);
-       tpm_buf_append(tb, blob, bloblen);
-       tpm_buf_append_u32(tb, authhandle);
-       tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
-       tpm_buf_append_u8(tb, cont);
-       tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
-       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
-       if (ret < 0) {
-               pr_info("authhmac failed (%d)\n", ret);
-               return ret;
-       }
-
-       datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
-
-       ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
-                            keyauth, SHA1_DIGEST_SIZE,
-                            sizeof(uint32_t), TPM_DATA_OFFSET,
-                            datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
-                            0, 0);
-       if (ret < 0) {
-               pr_info("TSS_checkhmac1 failed (%d)\n", ret);
-               return ret;
-       }
-
-       memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
-              min(datalen, outlen));
-
-       return datalen;
-}
-
-/* Room to fit two u32 zeros for algo id and parameters length. */
-#define SETKEY_PARAMS_SIZE (sizeof(u32) * 2)
-
-/*
- * Maximum buffer size for the BER/DER encoded public key.  The public key
- * is of the form SEQUENCE { INTEGER n, INTEGER e } where n is a maximum 2048
- * bit key and e is usually 65537
- * The encoding overhead is:
- * - max 4 bytes for SEQUENCE
- *   - max 4 bytes for INTEGER n type/length
- *     - 257 bytes of n
- *   - max 2 bytes for INTEGER e type/length
- *     - 3 bytes of e
- * - 4+4 of zeros for set_pub_key parameters (SETKEY_PARAMS_SIZE)
- */
-#define PUB_KEY_BUF_SIZE (4 + 4 + 257 + 2 + 3 + SETKEY_PARAMS_SIZE)
-
-/*
- * Provide a part of a description of the key for /proc/keys.
- */
-static void asym_tpm_describe(const struct key *asymmetric_key,
-                             struct seq_file *m)
-{
-       struct tpm_key *tk = asymmetric_key->payload.data[asym_crypto];
-
-       if (!tk)
-               return;
-
-       seq_printf(m, "TPM1.2/Blob");
-}
-
-static void asym_tpm_destroy(void *payload0, void *payload3)
-{
-       struct tpm_key *tk = payload0;
-
-       if (!tk)
-               return;
-
-       kfree(tk->blob);
-       tk->blob_len = 0;
-
-       kfree(tk);
-}
-
-/* How many bytes will it take to encode the length */
-static inline uint32_t definite_length(uint32_t len)
-{
-       if (len <= 127)
-               return 1;
-       if (len <= 255)
-               return 2;
-       return 3;
-}
-
-static inline uint8_t *encode_tag_length(uint8_t *buf, uint8_t tag,
-                                        uint32_t len)
-{
-       *buf++ = tag;
-
-       if (len <= 127) {
-               buf[0] = len;
-               return buf + 1;
-       }
-
-       if (len <= 255) {
-               buf[0] = 0x81;
-               buf[1] = len;
-               return buf + 2;
-       }
-
-       buf[0] = 0x82;
-       put_unaligned_be16(len, buf + 1);
-       return buf + 3;
-}
-
-static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf)
-{
-       uint8_t *cur = buf;
-       uint32_t n_len = definite_length(len) + 1 + len + 1;
-       uint32_t e_len = definite_length(3) + 1 + 3;
-       uint8_t e[3] = { 0x01, 0x00, 0x01 };
-
-       /* SEQUENCE */
-       cur = encode_tag_length(cur, 0x30, n_len + e_len);
-       /* INTEGER n */
-       cur = encode_tag_length(cur, 0x02, len + 1);
-       cur[0] = 0x00;
-       memcpy(cur + 1, pub_key, len);
-       cur += len + 1;
-       cur = encode_tag_length(cur, 0x02, sizeof(e));
-       memcpy(cur, e, sizeof(e));
-       cur += sizeof(e);
-       /* Zero parameters to satisfy set_pub_key ABI. */
-       memzero_explicit(cur, SETKEY_PARAMS_SIZE);
-
-       return cur - buf;
-}
-
-/*
- * Determine the crypto algorithm name.
- */
-static int determine_akcipher(const char *encoding, const char *hash_algo,
-                             char alg_name[CRYPTO_MAX_ALG_NAME])
-{
-       if (strcmp(encoding, "pkcs1") == 0) {
-               if (!hash_algo) {
-                       strcpy(alg_name, "pkcs1pad(rsa)");
-                       return 0;
-               }
-
-               if (snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(rsa,%s)",
-                            hash_algo) >= CRYPTO_MAX_ALG_NAME)
-                       return -EINVAL;
-
-               return 0;
-       }
-
-       if (strcmp(encoding, "raw") == 0) {
-               strcpy(alg_name, "rsa");
-               return 0;
-       }
-
-       return -ENOPKG;
-}
-
-/*
- * Query information about a key.
- */
-static int tpm_key_query(const struct kernel_pkey_params *params,
-                        struct kernel_pkey_query *info)
-{
-       struct tpm_key *tk = params->key->payload.data[asym_crypto];
-       int ret;
-       char alg_name[CRYPTO_MAX_ALG_NAME];
-       struct crypto_akcipher *tfm;
-       uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
-       uint32_t der_pub_key_len;
-       int len;
-
-       /* TPM only works on private keys, public keys still done in software */
-       ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
-       if (ret < 0)
-               return ret;
-
-       tfm = crypto_alloc_akcipher(alg_name, 0, 0);
-       if (IS_ERR(tfm))
-               return PTR_ERR(tfm);
-
-       der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
-                                        der_pub_key);
-
-       ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
-       if (ret < 0)
-               goto error_free_tfm;
-
-       len = crypto_akcipher_maxsize(tfm);
-
-       info->key_size = tk->key_len;
-       info->max_data_size = tk->key_len / 8;
-       info->max_sig_size = len;
-       info->max_enc_size = len;
-       info->max_dec_size = tk->key_len / 8;
-
-       info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT |
-                             KEYCTL_SUPPORTS_DECRYPT |
-                             KEYCTL_SUPPORTS_VERIFY |
-                             KEYCTL_SUPPORTS_SIGN;
-
-       ret = 0;
-error_free_tfm:
-       crypto_free_akcipher(tfm);
-       pr_devel("<==%s() = %d\n", __func__, ret);
-       return ret;
-}
-
-/*
- * Encryption operation is performed with the public key.  Hence it is done
- * in software
- */
-static int tpm_key_encrypt(struct tpm_key *tk,
-                          struct kernel_pkey_params *params,
-                          const void *in, void *out)
-{
-       char alg_name[CRYPTO_MAX_ALG_NAME];
-       struct crypto_akcipher *tfm;
-       struct akcipher_request *req;
-       struct crypto_wait cwait;
-       struct scatterlist in_sg, out_sg;
-       uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
-       uint32_t der_pub_key_len;
-       int ret;
-
-       pr_devel("==>%s()\n", __func__);
-
-       ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
-       if (ret < 0)
-               return ret;
-
-       tfm = crypto_alloc_akcipher(alg_name, 0, 0);
-       if (IS_ERR(tfm))
-               return PTR_ERR(tfm);
-
-       der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
-                                        der_pub_key);
-
-       ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
-       if (ret < 0)
-               goto error_free_tfm;
-
-       ret = -ENOMEM;
-       req = akcipher_request_alloc(tfm, GFP_KERNEL);
-       if (!req)
-               goto error_free_tfm;
-
-       sg_init_one(&in_sg, in, params->in_len);
-       sg_init_one(&out_sg, out, params->out_len);
-       akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
-                                  params->out_len);
-       crypto_init_wait(&cwait);
-       akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
-                                     CRYPTO_TFM_REQ_MAY_SLEEP,
-                                     crypto_req_done, &cwait);
-
-       ret = crypto_akcipher_encrypt(req);
-       ret = crypto_wait_req(ret, &cwait);
-
-       if (ret == 0)
-               ret = req->dst_len;
-
-       akcipher_request_free(req);
-error_free_tfm:
-       crypto_free_akcipher(tfm);
-       pr_devel("<==%s() = %d\n", __func__, ret);
-       return ret;
-}
-
-/*
- * Decryption operation is performed with the private key in the TPM.
- */
-static int tpm_key_decrypt(struct tpm_key *tk,
-                          struct kernel_pkey_params *params,
-                          const void *in, void *out)
-{
-       struct tpm_buf tb;
-       uint32_t keyhandle;
-       uint8_t srkauth[SHA1_DIGEST_SIZE];
-       uint8_t keyauth[SHA1_DIGEST_SIZE];
-       int r;
-
-       pr_devel("==>%s()\n", __func__);
-
-       if (params->hash_algo)
-               return -ENOPKG;
-
-       if (strcmp(params->encoding, "pkcs1"))
-               return -ENOPKG;
-
-       r = tpm_buf_init(&tb, 0, 0);
-       if (r)
-               return r;
-
-       /* TODO: Handle a non-all zero SRK authorization */
-       memset(srkauth, 0, sizeof(srkauth));
-
-       r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
-                               tk->blob, tk->blob_len, &keyhandle);
-       if (r < 0) {
-               pr_devel("loadkey2 failed (%d)\n", r);
-               goto error;
-       }
-
-       /* TODO: Handle a non-all zero key authorization */
-       memset(keyauth, 0, sizeof(keyauth));
-
-       r = tpm_unbind(&tb, keyhandle, keyauth,
-                      in, params->in_len, out, params->out_len);
-       if (r < 0)
-               pr_devel("tpm_unbind failed (%d)\n", r);
-
-       if (tpm_flushspecific(&tb, keyhandle) < 0)
-               pr_devel("flushspecific failed (%d)\n", r);
-
-error:
-       tpm_buf_destroy(&tb);
-       pr_devel("<==%s() = %d\n", __func__, r);
-       return r;
-}
-
-/*
- * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
- */
-static const u8 digest_info_md5[] = {
-       0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
-       0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
-       0x05, 0x00, 0x04, 0x10
-};
-
-static const u8 digest_info_sha1[] = {
-       0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
-       0x2b, 0x0e, 0x03, 0x02, 0x1a,
-       0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 digest_info_rmd160[] = {
-       0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
-       0x2b, 0x24, 0x03, 0x02, 0x01,
-       0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 digest_info_sha224[] = {
-       0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
-       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
-       0x05, 0x00, 0x04, 0x1c
-};
-
-static const u8 digest_info_sha256[] = {
-       0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
-       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-       0x05, 0x00, 0x04, 0x20
-};
-
-static const u8 digest_info_sha384[] = {
-       0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
-       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
-       0x05, 0x00, 0x04, 0x30
-};
-
-static const u8 digest_info_sha512[] = {
-       0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
-       0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
-       0x05, 0x00, 0x04, 0x40
-};
-
-static const struct asn1_template {
-       const char      *name;
-       const u8        *data;
-       size_t          size;
-} asn1_templates[] = {
-#define _(X) { #X, digest_info_##X, sizeof(digest_info_##X) }
-       _(md5),
-       _(sha1),
-       _(rmd160),
-       _(sha256),
-       _(sha384),
-       _(sha512),
-       _(sha224),
-       { NULL }
-#undef _
-};
-
-static const struct asn1_template *lookup_asn1(const char *name)
-{
-       const struct asn1_template *p;
-
-       for (p = asn1_templates; p->name; p++)
-               if (strcmp(name, p->name) == 0)
-                       return p;
-       return NULL;
-}
-
-/*
- * Sign operation is performed with the private key in the TPM.
- */
-static int tpm_key_sign(struct tpm_key *tk,
-                       struct kernel_pkey_params *params,
-                       const void *in, void *out)
-{
-       struct tpm_buf tb;
-       uint32_t keyhandle;
-       uint8_t srkauth[SHA1_DIGEST_SIZE];
-       uint8_t keyauth[SHA1_DIGEST_SIZE];
-       void *asn1_wrapped = NULL;
-       uint32_t in_len = params->in_len;
-       int r;
-
-       pr_devel("==>%s()\n", __func__);
-
-       if (strcmp(params->encoding, "pkcs1"))
-               return -ENOPKG;
-
-       if (params->hash_algo) {
-               const struct asn1_template *asn1 =
-                                               lookup_asn1(params->hash_algo);
-
-               if (!asn1)
-                       return -ENOPKG;
-
-               /* request enough space for the ASN.1 template + input hash */
-               asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
-               if (!asn1_wrapped)
-                       return -ENOMEM;
-
-               /* Copy ASN.1 template, then the input */
-               memcpy(asn1_wrapped, asn1->data, asn1->size);
-               memcpy(asn1_wrapped + asn1->size, in, in_len);
-
-               in = asn1_wrapped;
-               in_len += asn1->size;
-       }
-
-       if (in_len > tk->key_len / 8 - 11) {
-               r = -EOVERFLOW;
-               goto error_free_asn1_wrapped;
-       }
-
-       r = tpm_buf_init(&tb, 0, 0);
-       if (r)
-               goto error_free_asn1_wrapped;
-
-       /* TODO: Handle a non-all zero SRK authorization */
-       memset(srkauth, 0, sizeof(srkauth));
-
-       r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
-                        tk->blob, tk->blob_len, &keyhandle);
-       if (r < 0) {
-               pr_devel("loadkey2 failed (%d)\n", r);
-               goto error_free_tb;
-       }
-
-       /* TODO: Handle a non-all zero key authorization */
-       memset(keyauth, 0, sizeof(keyauth));
-
-       r = tpm_sign(&tb, keyhandle, keyauth, in, in_len, out, params->out_len);
-       if (r < 0)
-               pr_devel("tpm_sign failed (%d)\n", r);
-
-       if (tpm_flushspecific(&tb, keyhandle) < 0)
-               pr_devel("flushspecific failed (%d)\n", r);
-
-error_free_tb:
-       tpm_buf_destroy(&tb);
-error_free_asn1_wrapped:
-       kfree(asn1_wrapped);
-       pr_devel("<==%s() = %d\n", __func__, r);
-       return r;
-}
-
-/*
- * Do encryption, decryption and signing ops.
- */
-static int tpm_key_eds_op(struct kernel_pkey_params *params,
-                         const void *in, void *out)
-{
-       struct tpm_key *tk = params->key->payload.data[asym_crypto];
-       int ret = -EOPNOTSUPP;
-
-       /* Perform the encryption calculation. */
-       switch (params->op) {
-       case kernel_pkey_encrypt:
-               ret = tpm_key_encrypt(tk, params, in, out);
-               break;
-       case kernel_pkey_decrypt:
-               ret = tpm_key_decrypt(tk, params, in, out);
-               break;
-       case kernel_pkey_sign:
-               ret = tpm_key_sign(tk, params, in, out);
-               break;
-       default:
-               BUG();
-       }
-
-       return ret;
-}
-
-/*
- * Verify a signature using a public key.
- */
-static int tpm_key_verify_signature(const struct key *key,
-                                   const struct public_key_signature *sig)
-{
-       const struct tpm_key *tk = key->payload.data[asym_crypto];
-       struct crypto_wait cwait;
-       struct crypto_akcipher *tfm;
-       struct akcipher_request *req;
-       struct scatterlist src_sg[2];
-       char alg_name[CRYPTO_MAX_ALG_NAME];
-       uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
-       uint32_t der_pub_key_len;
-       int ret;
-
-       pr_devel("==>%s()\n", __func__);
-
-       BUG_ON(!tk);
-       BUG_ON(!sig);
-       BUG_ON(!sig->s);
-
-       if (!sig->digest)
-               return -ENOPKG;
-
-       ret = determine_akcipher(sig->encoding, sig->hash_algo, alg_name);
-       if (ret < 0)
-               return ret;
-
-       tfm = crypto_alloc_akcipher(alg_name, 0, 0);
-       if (IS_ERR(tfm))
-               return PTR_ERR(tfm);
-
-       der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
-                                        der_pub_key);
-
-       ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
-       if (ret < 0)
-               goto error_free_tfm;
-
-       ret = -ENOMEM;
-       req = akcipher_request_alloc(tfm, GFP_KERNEL);
-       if (!req)
-               goto error_free_tfm;
-
-       sg_init_table(src_sg, 2);
-       sg_set_buf(&src_sg[0], sig->s, sig->s_size);
-       sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
-       akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
-                                  sig->digest_size);
-       crypto_init_wait(&cwait);
-       akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
-                                     CRYPTO_TFM_REQ_MAY_SLEEP,
-                                     crypto_req_done, &cwait);
-       ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
-
-       akcipher_request_free(req);
-error_free_tfm:
-       crypto_free_akcipher(tfm);
-       pr_devel("<==%s() = %d\n", __func__, ret);
-       if (WARN_ON_ONCE(ret > 0))
-               ret = -EINVAL;
-       return ret;
-}
-
-/*
- * Parse enough information out of TPM_KEY structure:
- * TPM_STRUCT_VER -> 4 bytes
- * TPM_KEY_USAGE -> 2 bytes
- * TPM_KEY_FLAGS -> 4 bytes
- * TPM_AUTH_DATA_USAGE -> 1 byte
- * TPM_KEY_PARMS -> variable
- * UINT32 PCRInfoSize -> 4 bytes
- * BYTE* -> PCRInfoSize bytes
- * TPM_STORE_PUBKEY
- * UINT32 encDataSize;
- * BYTE* -> encDataSize;
- *
- * TPM_KEY_PARMS:
- * TPM_ALGORITHM_ID -> 4 bytes
- * TPM_ENC_SCHEME -> 2 bytes
- * TPM_SIG_SCHEME -> 2 bytes
- * UINT32 parmSize -> 4 bytes
- * BYTE* -> variable
- */
-static int extract_key_parameters(struct tpm_key *tk)
-{
-       const void *cur = tk->blob;
-       uint32_t len = tk->blob_len;
-       const void *pub_key;
-       uint32_t sz;
-       uint32_t key_len;
-
-       if (len < 11)
-               return -EBADMSG;
-
-       /* Ensure this is a legacy key */
-       if (get_unaligned_be16(cur + 4) != 0x0015)
-               return -EBADMSG;
-
-       /* Skip to TPM_KEY_PARMS */
-       cur += 11;
-       len -= 11;
-
-       if (len < 12)
-               return -EBADMSG;
-
-       /* Make sure this is an RSA key */
-       if (get_unaligned_be32(cur) != 0x00000001)
-               return -EBADMSG;
-
-       /* Make sure this is TPM_ES_RSAESPKCSv15 encoding scheme */
-       if (get_unaligned_be16(cur + 4) != 0x0002)
-               return -EBADMSG;
-
-       /* Make sure this is TPM_SS_RSASSAPKCS1v15_DER signature scheme */
-       if (get_unaligned_be16(cur + 6) != 0x0003)
-               return -EBADMSG;
-
-       sz = get_unaligned_be32(cur + 8);
-       if (len < sz + 12)
-               return -EBADMSG;
-
-       /* Move to TPM_RSA_KEY_PARMS */
-       len -= 12;
-       cur += 12;
-
-       /* Grab the RSA key length */
-       key_len = get_unaligned_be32(cur);
-
-       switch (key_len) {
-       case 512:
-       case 1024:
-       case 1536:
-       case 2048:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* Move just past TPM_KEY_PARMS */
-       cur += sz;
-       len -= sz;
-
-       if (len < 4)
-               return -EBADMSG;
-
-       sz = get_unaligned_be32(cur);
-       if (len < 4 + sz)
-               return -EBADMSG;
-
-       /* Move to TPM_STORE_PUBKEY */
-       cur += 4 + sz;
-       len -= 4 + sz;
-
-       /* Grab the size of the public key, it should jive with the key size */
-       sz = get_unaligned_be32(cur);
-       if (sz > 256)
-               return -EINVAL;
-
-       pub_key = cur + 4;
-
-       tk->key_len = key_len;
-       tk->pub_key = pub_key;
-       tk->pub_key_len = sz;
-
-       return 0;
-}
-
-/* Given the blob, parse it and load it into the TPM */
-struct tpm_key *tpm_key_create(const void *blob, uint32_t blob_len)
-{
-       int r;
-       struct tpm_key *tk;
-
-       r = tpm_is_tpm2(NULL);
-       if (r < 0)
-               goto error;
-
-       /* We don't support TPM2 yet */
-       if (r > 0) {
-               r = -ENODEV;
-               goto error;
-       }
-
-       r = -ENOMEM;
-       tk = kzalloc(sizeof(struct tpm_key), GFP_KERNEL);
-       if (!tk)
-               goto error;
-
-       tk->blob = kmemdup(blob, blob_len, GFP_KERNEL);
-       if (!tk->blob)
-               goto error_memdup;
-
-       tk->blob_len = blob_len;
-
-       r = extract_key_parameters(tk);
-       if (r < 0)
-               goto error_extract;
-
-       return tk;
-
-error_extract:
-       kfree(tk->blob);
-       tk->blob_len = 0;
-error_memdup:
-       kfree(tk);
-error:
-       return ERR_PTR(r);
-}
-EXPORT_SYMBOL_GPL(tpm_key_create);
-
-/*
- * TPM-based asymmetric key subtype
- */
-struct asymmetric_key_subtype asym_tpm_subtype = {
-       .owner                  = THIS_MODULE,
-       .name                   = "asym_tpm",
-       .name_len               = sizeof("asym_tpm") - 1,
-       .describe               = asym_tpm_describe,
-       .destroy                = asym_tpm_destroy,
-       .query                  = tpm_key_query,
-       .eds_op                 = tpm_key_eds_op,
-       .verify_signature       = tpm_key_verify_signature,
-};
-EXPORT_SYMBOL_GPL(asym_tpm_subtype);
-
-MODULE_DESCRIPTION("TPM based asymmetric key subtype");
-MODULE_AUTHOR("Intel Corporation");
-MODULE_LICENSE("GPL v2");
index 0b4d07aa88111e332d16faeb2f97d8b594585741..f6321c785714c90a78999716188d79fe05ab4a33 100644 (file)
@@ -174,12 +174,6 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
                pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
                         sinfo->index, certix);
 
-               if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
-                       pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
-                               sinfo->index);
-                       continue;
-               }
-
                sinfo->signer = x509;
                return 0;
        }
@@ -226,9 +220,6 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
                        return 0;
                }
 
-               if (x509->unsupported_key)
-                       goto unsupported_crypto_in_x509;
-
                pr_debug("- issuer %s\n", x509->issuer);
                sig = x509->sig;
                if (sig->auth_ids[0])
@@ -245,7 +236,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
                         * authority.
                         */
                        if (x509->unsupported_sig)
-                               goto unsupported_crypto_in_x509;
+                               goto unsupported_sig_in_x509;
                        x509->signer = x509;
                        pr_debug("- self-signed\n");
                        return 0;
@@ -309,7 +300,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
                might_sleep();
        }
 
-unsupported_crypto_in_x509:
+unsupported_sig_in_x509:
        /* Just prune the certificate chain at this point if we lack some
         * crypto module to go further.  Note, however, we don't want to set
         * sinfo->unsupported_crypto as the signed info block may still be
index 4fefb219bfdc86318f33b822eef7bc8214a2a106..7c9e6be35c30c1278f3e38fad15efa85d5b7e991 100644 (file)
@@ -60,39 +60,83 @@ static void public_key_destroy(void *payload0, void *payload3)
 }
 
 /*
- * Determine the crypto algorithm name.
+ * Given a public_key, and an encoding and hash_algo to be used for signing
+ * and/or verification with that key, determine the name of the corresponding
+ * akcipher algorithm.  Also check that encoding and hash_algo are allowed.
  */
-static
-int software_key_determine_akcipher(const char *encoding,
-                                   const char *hash_algo,
-                                   const struct public_key *pkey,
-                                   char alg_name[CRYPTO_MAX_ALG_NAME])
+static int
+software_key_determine_akcipher(const struct public_key *pkey,
+                               const char *encoding, const char *hash_algo,
+                               char alg_name[CRYPTO_MAX_ALG_NAME])
 {
        int n;
 
-       if (strcmp(encoding, "pkcs1") == 0) {
-               /* The data wangled by the RSA algorithm is typically padded
-                * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
-                * sec 8.2].
+       if (!encoding)
+               return -EINVAL;
+
+       if (strcmp(pkey->pkey_algo, "rsa") == 0) {
+               /*
+                * RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2].
+                */
+               if (strcmp(encoding, "pkcs1") == 0) {
+                       if (!hash_algo)
+                               n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+                                            "pkcs1pad(%s)",
+                                            pkey->pkey_algo);
+                       else
+                               n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+                                            "pkcs1pad(%s,%s)",
+                                            pkey->pkey_algo, hash_algo);
+                       return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
+               }
+               if (strcmp(encoding, "raw") != 0)
+                       return -EINVAL;
+               /*
+                * Raw RSA cannot differentiate between different hash
+                * algorithms.
+                */
+               if (hash_algo)
+                       return -EINVAL;
+       } else if (strncmp(pkey->pkey_algo, "ecdsa", 5) == 0) {
+               if (strcmp(encoding, "x962") != 0)
+                       return -EINVAL;
+               /*
+                * ECDSA signatures are taken over a raw hash, so they don't
+                * differentiate between different hash algorithms.  That means
+                * that the verifier should hard-code a specific hash algorithm.
+                * Unfortunately, in practice ECDSA is used with multiple SHAs,
+                * so we have to allow all of them and not just one.
                 */
                if (!hash_algo)
-                       n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
-                                    "pkcs1pad(%s)",
-                                    pkey->pkey_algo);
-               else
-                       n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
-                                    "pkcs1pad(%s,%s)",
-                                    pkey->pkey_algo, hash_algo);
-               return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
-       }
-
-       if (strcmp(encoding, "raw") == 0 ||
-           strcmp(encoding, "x962") == 0) {
-               strcpy(alg_name, pkey->pkey_algo);
-               return 0;
+                       return -EINVAL;
+               if (strcmp(hash_algo, "sha1") != 0 &&
+                   strcmp(hash_algo, "sha224") != 0 &&
+                   strcmp(hash_algo, "sha256") != 0 &&
+                   strcmp(hash_algo, "sha384") != 0 &&
+                   strcmp(hash_algo, "sha512") != 0)
+                       return -EINVAL;
+       } else if (strcmp(pkey->pkey_algo, "sm2") == 0) {
+               if (strcmp(encoding, "raw") != 0)
+                       return -EINVAL;
+               if (!hash_algo)
+                       return -EINVAL;
+               if (strcmp(hash_algo, "sm3") != 0)
+                       return -EINVAL;
+       } else if (strcmp(pkey->pkey_algo, "ecrdsa") == 0) {
+               if (strcmp(encoding, "raw") != 0)
+                       return -EINVAL;
+               if (!hash_algo)
+                       return -EINVAL;
+               if (strcmp(hash_algo, "streebog256") != 0 &&
+                   strcmp(hash_algo, "streebog512") != 0)
+                       return -EINVAL;
+       } else {
+               /* Unknown public key algorithm */
+               return -ENOPKG;
        }
-
-       return -ENOPKG;
+       if (strscpy(alg_name, pkey->pkey_algo, CRYPTO_MAX_ALG_NAME) < 0)
+               return -EINVAL;
+       return 0;
 }
 
 static u8 *pkey_pack_u32(u8 *dst, u32 val)
@@ -113,9 +157,8 @@ static int software_key_query(const struct kernel_pkey_params *params,
        u8 *key, *ptr;
        int ret, len;
 
-       ret = software_key_determine_akcipher(params->encoding,
-                                             params->hash_algo,
-                                             pkey, alg_name);
+       ret = software_key_determine_akcipher(pkey, params->encoding,
+                                             params->hash_algo, alg_name);
        if (ret < 0)
                return ret;
 
@@ -179,9 +222,8 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
 
        pr_devel("==>%s()\n", __func__);
 
-       ret = software_key_determine_akcipher(params->encoding,
-                                             params->hash_algo,
-                                             pkey, alg_name);
+       ret = software_key_determine_akcipher(pkey, params->encoding,
+                                             params->hash_algo, alg_name);
        if (ret < 0)
                return ret;
 
@@ -325,9 +367,23 @@ int public_key_verify_signature(const struct public_key *pkey,
        BUG_ON(!sig);
        BUG_ON(!sig->s);
 
-       ret = software_key_determine_akcipher(sig->encoding,
-                                             sig->hash_algo,
-                                             pkey, alg_name);
+       /*
+        * If the signature specifies a public key algorithm, it *must* match
+        * the key's actual public key algorithm.
+        *
+        * Small exception: ECDSA signatures don't specify the curve, but ECDSA
+        * keys do.  So the strings can mismatch slightly in that case:
+        * "ecdsa-nist-*" for the key, but "ecdsa" for the signature.
+        */
+       if (sig->pkey_algo) {
+               if (strcmp(pkey->pkey_algo, sig->pkey_algo) != 0 &&
+                   (strncmp(pkey->pkey_algo, "ecdsa-", 6) != 0 ||
+                    strcmp(sig->pkey_algo, "ecdsa") != 0))
+                       return -EKEYREJECTED;
+       }
+
+       ret = software_key_determine_akcipher(pkey, sig->encoding,
+                                             sig->hash_algo, alg_name);
        if (ret < 0)
                return ret;
 
diff --git a/crypto/asymmetric_keys/tpm.asn1 b/crypto/asymmetric_keys/tpm.asn1
deleted file mode 100644 (file)
index d7f1942..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
---
--- Unencryted TPM Blob.  For details of the format, see:
--- http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#I-D.mavrogiannopoulos-tpmuri
---
-PrivateKeyInfo ::= OCTET STRING ({ tpm_note_key })
diff --git a/crypto/asymmetric_keys/tpm_parser.c b/crypto/asymmetric_keys/tpm_parser.c
deleted file mode 100644 (file)
index 96405d8..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define pr_fmt(fmt) "TPM-PARSER: "fmt
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <keys/asymmetric-subtype.h>
-#include <keys/asymmetric-parser.h>
-#include <crypto/asym_tpm_subtype.h>
-#include "tpm.asn1.h"
-
-struct tpm_parse_context {
-       const void      *blob;
-       u32             blob_len;
-};
-
-/*
- * Note the key data of the ASN.1 blob.
- */
-int tpm_note_key(void *context, size_t hdrlen,
-                  unsigned char tag,
-                  const void *value, size_t vlen)
-{
-       struct tpm_parse_context *ctx = context;
-
-       ctx->blob = value;
-       ctx->blob_len = vlen;
-
-       return 0;
-}
-
-/*
- * Parse a TPM-encrypted private key blob.
- */
-static struct tpm_key *tpm_parse(const void *data, size_t datalen)
-{
-       struct tpm_parse_context ctx;
-       long ret;
-
-       memset(&ctx, 0, sizeof(ctx));
-
-       /* Attempt to decode the private key */
-       ret = asn1_ber_decoder(&tpm_decoder, &ctx, data, datalen);
-       if (ret < 0)
-               goto error;
-
-       return tpm_key_create(ctx.blob, ctx.blob_len);
-
-error:
-       return ERR_PTR(ret);
-}
-/*
- * Attempt to parse a data blob for a key as a TPM private key blob.
- */
-static int tpm_key_preparse(struct key_preparsed_payload *prep)
-{
-       struct tpm_key *tk;
-
-       /*
-        * TPM 1.2 keys are max 2048 bits long, so assume the blob is no
-        * more than 4x that
-        */
-       if (prep->datalen > 256 * 4)
-               return -EMSGSIZE;
-
-       tk = tpm_parse(prep->data, prep->datalen);
-
-       if (IS_ERR(tk))
-               return PTR_ERR(tk);
-
-       /* We're pinning the module by being linked against it */
-       __module_get(asym_tpm_subtype.owner);
-       prep->payload.data[asym_subtype] = &asym_tpm_subtype;
-       prep->payload.data[asym_key_ids] = NULL;
-       prep->payload.data[asym_crypto] = tk;
-       prep->payload.data[asym_auth] = NULL;
-       prep->quotalen = 100;
-       return 0;
-}
-
-static struct asymmetric_key_parser tpm_key_parser = {
-       .owner  = THIS_MODULE,
-       .name   = "tpm_parser",
-       .parse  = tpm_key_preparse,
-};
-
-static int __init tpm_key_init(void)
-{
-       return register_asymmetric_key_parser(&tpm_key_parser);
-}
-
-static void __exit tpm_key_exit(void)
-{
-       unregister_asymmetric_key_parser(&tpm_key_parser);
-}
-
-module_init(tpm_key_init);
-module_exit(tpm_key_exit);
-
-MODULE_DESCRIPTION("TPM private key-blob parser");
-MODULE_LICENSE("GPL v2");
index 5c9f4e4a52310c94cdb8cfb8d9a7df4bd43c7602..92d59c32f96a8e6ae132212f51ad0453fefdd59c 100644 (file)
@@ -7,7 +7,7 @@ Certificate ::= SEQUENCE {
 TBSCertificate ::= SEQUENCE {
        version           [ 0 ] Version DEFAULT,
        serialNumber            CertificateSerialNumber ({ x509_note_serial }),
-       signature               AlgorithmIdentifier ({ x509_note_pkey_algo }),
+       signature               AlgorithmIdentifier ({ x509_note_sig_algo }),
        issuer                  Name ({ x509_note_issuer }),
        validity                Validity,
        subject                 Name ({ x509_note_subject }),
index 083405eb80c32a2b13173d7d3a8a737c946feb20..2899ed80bb18e31f957ca38f5708ca495b1dc072 100644 (file)
 struct x509_parse_context {
        struct x509_certificate *cert;          /* Certificate being constructed */
        unsigned long   data;                   /* Start of data */
-       const void      *cert_start;            /* Start of cert content */
        const void      *key;                   /* Key data */
        size_t          key_size;               /* Size of key data */
        const void      *params;                /* Key parameters */
        size_t          params_size;            /* Size of key parameters */
-       enum OID        key_algo;               /* Public key algorithm */
+       enum OID        key_algo;               /* Algorithm used by the cert's key */
        enum OID        last_oid;               /* Last OID encountered */
-       enum OID        algo_oid;               /* Algorithm OID */
-       unsigned char   nr_mpi;                 /* Number of MPIs stored */
+       enum OID        sig_algo;               /* Algorithm used to sign the cert */
        u8              o_size;                 /* Size of organizationName (O) */
        u8              cn_size;                /* Size of commonName (CN) */
        u8              email_size;             /* Size of emailAddress */
@@ -187,11 +185,10 @@ int x509_note_tbs_certificate(void *context, size_t hdrlen,
 }
 
 /*
- * Record the public key algorithm
+ * Record the algorithm that was used to sign this certificate.
  */
-int x509_note_pkey_algo(void *context, size_t hdrlen,
-                       unsigned char tag,
-                       const void *value, size_t vlen)
+int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
+                      const void *value, size_t vlen)
 {
        struct x509_parse_context *ctx = context;
 
@@ -263,22 +260,22 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 rsa_pkcs1:
        ctx->cert->sig->pkey_algo = "rsa";
        ctx->cert->sig->encoding = "pkcs1";
-       ctx->algo_oid = ctx->last_oid;
+       ctx->sig_algo = ctx->last_oid;
        return 0;
 ecrdsa:
        ctx->cert->sig->pkey_algo = "ecrdsa";
        ctx->cert->sig->encoding = "raw";
-       ctx->algo_oid = ctx->last_oid;
+       ctx->sig_algo = ctx->last_oid;
        return 0;
 sm2:
        ctx->cert->sig->pkey_algo = "sm2";
        ctx->cert->sig->encoding = "raw";
-       ctx->algo_oid = ctx->last_oid;
+       ctx->sig_algo = ctx->last_oid;
        return 0;
 ecdsa:
        ctx->cert->sig->pkey_algo = "ecdsa";
        ctx->cert->sig->encoding = "x962";
-       ctx->algo_oid = ctx->last_oid;
+       ctx->sig_algo = ctx->last_oid;
        return 0;
 }
 
@@ -291,11 +288,16 @@ int x509_note_signature(void *context, size_t hdrlen,
 {
        struct x509_parse_context *ctx = context;
 
-       pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
+       pr_debug("Signature: alg=%u, size=%zu\n", ctx->last_oid, vlen);
 
-       if (ctx->last_oid != ctx->algo_oid) {
-               pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
-                       ctx->algo_oid, ctx->last_oid);
+       /*
+        * In X.509 certificates, the signature's algorithm is stored in two
+        * places: inside the TBSCertificate (the data that is signed), and
+        * alongside the signature.  These *must* match.
+        */
+       if (ctx->last_oid != ctx->sig_algo) {
+               pr_warn("signatureAlgorithm (%u) differs from tbsCertificate.signature (%u)\n",
+                       ctx->last_oid, ctx->sig_algo);
                return -EINVAL;
        }
 
index c233f136fb354db9987bf72fcba9b6560b6b30bf..da854c94f1115e4d62f001364a8b05f4628bd419 100644 (file)
@@ -36,7 +36,6 @@ struct x509_certificate {
        bool            seen;                   /* Infinite recursion prevention */
        bool            verified;
        bool            self_signed;            /* T if self-signed (check unsupported_sig too) */
-       bool            unsupported_key;        /* T if key uses unsupported crypto */
        bool            unsupported_sig;        /* T if signature uses unsupported crypto */
        bool            blacklisted;
 };
index fe14cae115b51bd03853cfcea3ac2e14cf05d871..91a4ad50dea268d20fec0f944e64ff3425ed82d6 100644 (file)
@@ -33,18 +33,6 @@ int x509_get_sig_params(struct x509_certificate *cert)
        sig->data = cert->tbs;
        sig->data_size = cert->tbs_size;
 
-       if (!cert->pub->pkey_algo)
-               cert->unsupported_key = true;
-
-       if (!sig->pkey_algo)
-               cert->unsupported_sig = true;
-
-       /* We check the hash if we can - even if we can't then verify it */
-       if (!sig->hash_algo) {
-               cert->unsupported_sig = true;
-               return 0;
-       }
-
        sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
        if (!sig->s)
                return -ENOMEM;
@@ -128,12 +116,6 @@ int x509_check_for_self_signed(struct x509_certificate *cert)
                        goto out;
        }
 
-       ret = -EKEYREJECTED;
-       if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0 &&
-           (strncmp(cert->pub->pkey_algo, "ecdsa-", 6) != 0 ||
-            strcmp(cert->sig->pkey_algo, "ecdsa") != 0))
-               goto out;
-
        ret = public_key_verify_signature(cert->pub, cert->sig);
        if (ret < 0) {
                if (ret == -ENOPKG) {
@@ -173,12 +155,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
 
        pr_devel("Cert Issuer: %s\n", cert->issuer);
        pr_devel("Cert Subject: %s\n", cert->subject);
-
-       if (cert->unsupported_key) {
-               ret = -ENOPKG;
-               goto error_free_cert;
-       }
-
        pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
        pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
 
index 1331756d4cfce0613d20cebebc4b059bd455c842..8b2e5ef155595e5222a2cf9ab4b461143f82327d 100644 (file)
@@ -1377,11 +1377,11 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
                if (info->valid & ACPI_VALID_HID) {
                        acpi_add_id(pnp, info->hardware_id.string);
                        pnp->type.platform_id = 1;
-                       if (info->valid & ACPI_VALID_CID) {
-                               cid_list = &info->compatible_id_list;
-                               for (i = 0; i < cid_list->count; i++)
-                                       acpi_add_id(pnp, cid_list->ids[i].string);
-                       }
+               }
+               if (info->valid & ACPI_VALID_CID) {
+                       cid_list = &info->compatible_id_list;
+                       for (i = 0; i < cid_list->count; i++)
+                               acpi_add_id(pnp, cid_list->ids[i].string);
                }
                if (info->valid & ACPI_VALID_ADR) {
                        pnp->bus_address = info->address;
index e1a5eca3ae3cc9dddc2c9ca4aadf88ba28d934f5..d3bd14aaabf6e6e0c0bca90a7b3aa9a84672305d 100644 (file)
@@ -370,6 +370,7 @@ int amba_driver_register(struct amba_driver *drv)
 
        return driver_register(&drv->drv);
 }
+EXPORT_SYMBOL(amba_driver_register);
 
 /**
  *     amba_driver_unregister - remove an AMBA device driver
@@ -383,7 +384,7 @@ void amba_driver_unregister(struct amba_driver *drv)
 {
        driver_unregister(&drv->drv);
 }
-
+EXPORT_SYMBOL(amba_driver_unregister);
 
 static void amba_device_release(struct device *dev)
 {
@@ -642,6 +643,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
 
        return amba_device_add(dev, parent);
 }
+EXPORT_SYMBOL(amba_device_register);
 
 /**
  *     amba_device_put - put an AMBA device
@@ -668,66 +670,7 @@ void amba_device_unregister(struct amba_device *dev)
 {
        device_unregister(&dev->dev);
 }
-
-
-struct find_data {
-       struct amba_device *dev;
-       struct device *parent;
-       const char *busid;
-       unsigned int id;
-       unsigned int mask;
-};
-
-static int amba_find_match(struct device *dev, void *data)
-{
-       struct find_data *d = data;
-       struct amba_device *pcdev = to_amba_device(dev);
-       int r;
-
-       r = (pcdev->periphid & d->mask) == d->id;
-       if (d->parent)
-               r &= d->parent == dev->parent;
-       if (d->busid)
-               r &= strcmp(dev_name(dev), d->busid) == 0;
-
-       if (r) {
-               get_device(dev);
-               d->dev = pcdev;
-       }
-
-       return r;
-}
-
-/**
- *     amba_find_device - locate an AMBA device given a bus id
- *     @busid: bus id for device (or NULL)
- *     @parent: parent device (or NULL)
- *     @id: peripheral ID (or 0)
- *     @mask: peripheral ID mask (or 0)
- *
- *     Return the AMBA device corresponding to the supplied parameters.
- *     If no device matches, returns NULL.
- *
- *     NOTE: When a valid device is found, its refcount is
- *     incremented, and must be decremented before the returned
- *     reference.
- */
-struct amba_device *
-amba_find_device(const char *busid, struct device *parent, unsigned int id,
-                unsigned int mask)
-{
-       struct find_data data;
-
-       data.dev = NULL;
-       data.parent = parent;
-       data.busid = busid;
-       data.id = id;
-       data.mask = mask;
-
-       bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match);
-
-       return data.dev;
-}
+EXPORT_SYMBOL(amba_device_unregister);
 
 /**
  *     amba_request_regions - request all mem regions associated with device
@@ -749,6 +692,7 @@ int amba_request_regions(struct amba_device *dev, const char *name)
 
        return ret;
 }
+EXPORT_SYMBOL(amba_request_regions);
 
 /**
  *     amba_release_regions - release mem regions associated with device
@@ -763,11 +707,4 @@ void amba_release_regions(struct amba_device *dev)
        size = resource_size(&dev->res);
        release_mem_region(dev->res.start, size);
 }
-
-EXPORT_SYMBOL(amba_driver_register);
-EXPORT_SYMBOL(amba_driver_unregister);
-EXPORT_SYMBOL(amba_device_register);
-EXPORT_SYMBOL(amba_device_unregister);
-EXPORT_SYMBOL(amba_find_device);
-EXPORT_SYMBOL(amba_request_regions);
 EXPORT_SYMBOL(amba_release_regions);
index 7abc7e04f65616ae17a3e08ea947389d7397f613..6fa4a2faf49c93c6ffba07fcb43747f6801653cc 100644 (file)
@@ -919,6 +919,20 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        irqmask &= ~0x10;
        pci_write_config_byte(dev, 0x5a, irqmask);
 
+       /*
+        * HPT371 chips physically have only one channel, the secondary one,
+        * but the primary channel registers do exist!  Go figure...
+        * So,  we manually disable the non-existing channel here
+        * (if the BIOS hasn't done this already).
+        */
+       if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
+               u8 mcr1;
+
+               pci_read_config_byte(dev, 0x50, &mcr1);
+               mcr1 &= ~0x04;
+               pci_write_config_byte(dev, 0x50, mcr1);
+       }
+
        /*
         * default to pci clock. make sure MA15/16 are set to output
         * to prevent drives having problems with 40-pin cables. Needed
@@ -950,14 +964,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 
        if ((freq >> 12) != 0xABCDE) {
                int i;
-               u8 sr;
+               u16 sr;
                u32 total = 0;
 
                dev_warn(&dev->dev, "BIOS has not set timing clocks\n");
 
                /* This is the process the HPT371 BIOS is reported to use */
                for (i = 0; i < 128; i++) {
-                       pci_read_config_byte(dev, 0x78, &sr);
+                       pci_read_config_word(dev, 0x78, &sr);
                        total += sr & 0x1FF;
                        udelay(15);
                }
index 422753d52244bd446664e2b68f427f9a3a6ff32b..a31ffe16e626f71b9ef89fa7ee376c97c1aabfe1 100644 (file)
@@ -1112,6 +1112,8 @@ DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
        skb_data3 = skb->data[3];
        paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
                               DMA_TO_DEVICE);
+       if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr))
+               return enq_next;
        ENI_PRV_PADDR(skb) = paddr;
        /* prepare DMA queue entries */
        j = 0;
index 3bc3c314a467b0bb508ac4a9a63aafd06e789ac5..4f67404fe64c743c873f01e1cf1738667881ccde 100644 (file)
@@ -1676,6 +1676,8 @@ static int fs_init(struct fs_dev *dev)
        dev->hw_base = pci_resource_start(pci_dev, 0);
 
        dev->base = ioremap(dev->hw_base, 0x1000);
+       if (!dev->base)
+               return 1;
 
        reset_chip (dev);
   
index 38ba08628ccb3df36a980bff7870656d36348e54..2578b2d454397a20ce2248a759993b0655b17f64 100644 (file)
@@ -238,7 +238,7 @@ static int lcd2s_redefine_char(struct charlcd *lcd, char *esc)
        if (buf[1] > 7)
                return 1;
 
-       i = 0;
+       i = 2;
        shift = 0;
        value = 0;
        while (*esc && i < LCD2S_CHARACTER_SIZE + 2) {
@@ -298,6 +298,10 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
                        I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
                return -EIO;
 
+       lcd2s = devm_kzalloc(&i2c->dev, sizeof(*lcd2s), GFP_KERNEL);
+       if (!lcd2s)
+               return -ENOMEM;
+
        /* Test, if the display is responding */
        err = lcd2s_i2c_smbus_write_byte(i2c, LCD2S_CMD_DISPLAY_OFF);
        if (err < 0)
@@ -307,12 +311,6 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
        if (!lcd)
                return -ENOMEM;
 
-       lcd2s = kzalloc(sizeof(struct lcd2s_data), GFP_KERNEL);
-       if (!lcd2s) {
-               err = -ENOMEM;
-               goto fail1;
-       }
-
        lcd->drvdata = lcd2s;
        lcd2s->i2c = i2c;
        lcd2s->charlcd = lcd;
@@ -321,26 +319,24 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c,
        err = device_property_read_u32(&i2c->dev, "display-height-chars",
                        &lcd->height);
        if (err)
-               goto fail2;
+               goto fail1;
 
        err = device_property_read_u32(&i2c->dev, "display-width-chars",
                        &lcd->width);
        if (err)
-               goto fail2;
+               goto fail1;
 
        lcd->ops = &lcd2s_ops;
 
        err = charlcd_register(lcd2s->charlcd);
        if (err)
-               goto fail2;
+               goto fail1;
 
        i2c_set_clientdata(i2c, lcd2s);
        return 0;
 
-fail2:
-       kfree(lcd2s);
 fail1:
-       kfree(lcd);
+       charlcd_free(lcd2s->charlcd);
        return err;
 }
 
@@ -349,7 +345,7 @@ static int lcd2s_i2c_remove(struct i2c_client *i2c)
        struct lcd2s_data *lcd2s = i2c_get_clientdata(i2c);
 
        charlcd_unregister(lcd2s->charlcd);
-       kfree(lcd2s->charlcd);
+       charlcd_free(lcd2s->charlcd);
        return 0;
 }
 
index 9eaaff2f556ceaed4d389ab040548313d590a55c..f47cab21430f9fb3764b033116729554a29ff802 100644 (file)
@@ -629,6 +629,9 @@ re_probe:
                        drv->remove(dev);
 
                devres_release_all(dev);
+               arch_teardown_dma_ops(dev);
+               kfree(dev->dma_range_map);
+               dev->dma_range_map = NULL;
                driver_sysfs_remove(dev);
                dev->driver = NULL;
                dev_set_drvdata(dev, NULL);
@@ -1209,6 +1212,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 
                devres_release_all(dev);
                arch_teardown_dma_ops(dev);
+               kfree(dev->dma_range_map);
+               dev->dma_range_map = NULL;
                dev->driver = NULL;
                dev_set_drvdata(dev, NULL);
                if (dev->pm_domain && dev->pm_domain->dismiss)
index d2656581a60853ae21f519afc967e7359fa33869..4a446259a184e9f8cbd2277c97e123deda923875 100644 (file)
@@ -189,11 +189,9 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
                                ret = regmap_write(map, reg, d->mask_buf[i]);
                        if (d->chip->clear_ack) {
                                if (d->chip->ack_invert && !ret)
-                                       ret = regmap_write(map, reg,
-                                                          d->mask_buf[i]);
+                                       ret = regmap_write(map, reg, UINT_MAX);
                                else if (!ret)
-                                       ret = regmap_write(map, reg,
-                                                          ~d->mask_buf[i]);
+                                       ret = regmap_write(map, reg, 0);
                        }
                        if (ret != 0)
                                dev_err(d->map->dev, "Failed to ack 0x%x: %d\n",
@@ -556,11 +554,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                                                data->status_buf[i]);
                        if (chip->clear_ack) {
                                if (chip->ack_invert && !ret)
-                                       ret = regmap_write(map, reg,
-                                                       data->status_buf[i]);
+                                       ret = regmap_write(map, reg, UINT_MAX);
                                else if (!ret)
-                                       ret = regmap_write(map, reg,
-                                                       ~data->status_buf[i]);
+                                       ret = regmap_write(map, reg, 0);
                        }
                        if (ret != 0)
                                dev_err(map->dev, "Failed to ack 0x%x: %d\n",
@@ -817,13 +813,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
                                        d->status_buf[i] & d->mask_buf[i]);
                        if (chip->clear_ack) {
                                if (chip->ack_invert && !ret)
-                                       ret = regmap_write(map, reg,
-                                               (d->status_buf[i] &
-                                                d->mask_buf[i]));
+                                       ret = regmap_write(map, reg, UINT_MAX);
                                else if (!ret)
-                                       ret = regmap_write(map, reg,
-                                               ~(d->status_buf[i] &
-                                                 d->mask_buf[i]));
+                                       ret = regmap_write(map, reg, 0);
                        }
                        if (ret != 0) {
                                dev_err(map->dev, "Failed to ack 0x%x: %d\n",
index fc24e89f9592f099e415f707eee30d333f4d0914..e9d1efcda89b3be1c4d8f12509c170b8957cb470 100644 (file)
 #include <linux/hardirq.h>
 #include <linux/topology.h>
 
-#define define_id_show_func(name)                                      \
+#define define_id_show_func(name, fmt)                                 \
 static ssize_t name##_show(struct device *dev,                         \
                           struct device_attribute *attr, char *buf)    \
 {                                                                      \
-       return sysfs_emit(buf, "%d\n", topology_##name(dev->id));       \
+       return sysfs_emit(buf, fmt "\n", topology_##name(dev->id));     \
 }
 
 #define define_siblings_read_func(name, mask)                                  \
@@ -42,22 +42,25 @@ static ssize_t name##_list_read(struct file *file, struct kobject *kobj,    \
                                        off, count);                            \
 }
 
-define_id_show_func(physical_package_id);
+define_id_show_func(physical_package_id, "%d");
 static DEVICE_ATTR_RO(physical_package_id);
 
 #ifdef TOPOLOGY_DIE_SYSFS
-define_id_show_func(die_id);
+define_id_show_func(die_id, "%d");
 static DEVICE_ATTR_RO(die_id);
 #endif
 
 #ifdef TOPOLOGY_CLUSTER_SYSFS
-define_id_show_func(cluster_id);
+define_id_show_func(cluster_id, "%d");
 static DEVICE_ATTR_RO(cluster_id);
 #endif
 
-define_id_show_func(core_id);
+define_id_show_func(core_id, "%d");
 static DEVICE_ATTR_RO(core_id);
 
+define_id_show_func(ppin, "0x%llx");
+static DEVICE_ATTR_ADMIN_RO(ppin);
+
 define_siblings_read_func(thread_siblings, sibling_cpumask);
 static BIN_ATTR_RO(thread_siblings, 0);
 static BIN_ATTR_RO(thread_siblings_list, 0);
@@ -87,7 +90,7 @@ static BIN_ATTR_RO(package_cpus, 0);
 static BIN_ATTR_RO(package_cpus_list, 0);
 
 #ifdef TOPOLOGY_BOOK_SYSFS
-define_id_show_func(book_id);
+define_id_show_func(book_id, "%d");
 static DEVICE_ATTR_RO(book_id);
 define_siblings_read_func(book_siblings, book_cpumask);
 static BIN_ATTR_RO(book_siblings, 0);
@@ -95,7 +98,7 @@ static BIN_ATTR_RO(book_siblings_list, 0);
 #endif
 
 #ifdef TOPOLOGY_DRAWER_SYSFS
-define_id_show_func(drawer_id);
+define_id_show_func(drawer_id, "%d");
 static DEVICE_ATTR_RO(drawer_id);
 define_siblings_read_func(drawer_siblings, drawer_cpumask);
 static BIN_ATTR_RO(drawer_siblings, 0);
@@ -145,6 +148,7 @@ static struct attribute *default_attrs[] = {
 #ifdef TOPOLOGY_DRAWER_SYSFS
        &dev_attr_drawer_id.attr,
 #endif
+       &dev_attr_ppin.attr,
        NULL
 };
 
index c443cd64fc9b46051d978adb5bd95ce0b1d3a5fe..8c415be8673275b82b252d978ec56b20968b2060 100644 (file)
@@ -76,9 +76,6 @@ struct virtio_blk {
         */
        refcount_t refs;
 
-       /* What host tells us, plus 2 for header & tailer. */
-       unsigned int sg_elems;
-
        /* Ida index - used to track minor number allocations. */
        int index;
 
@@ -322,8 +319,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
        blk_status_t status;
        int err;
 
-       BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
-
        status = virtblk_setup_cmd(vblk->vdev, req, vbr);
        if (unlikely(status))
                return status;
@@ -783,8 +778,6 @@ static int virtblk_probe(struct virtio_device *vdev)
        /* Prevent integer overflows and honor max vq size */
        sg_elems = min_t(u32, sg_elems, VIRTIO_BLK_MAX_SG_ELEMS - 2);
 
-       /* We need extra sg elements at head and tail. */
-       sg_elems += 2;
        vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL);
        if (!vblk) {
                err = -ENOMEM;
@@ -796,7 +789,6 @@ static int virtblk_probe(struct virtio_device *vdev)
        mutex_init(&vblk->vdev_mutex);
 
        vblk->vdev = vdev;
-       vblk->sg_elems = sg_elems;
 
        INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
 
@@ -853,7 +845,7 @@ static int virtblk_probe(struct virtio_device *vdev)
                set_disk_ro(vblk->disk, 1);
 
        /* We can handle whatever the host told us to handle. */
-       blk_queue_max_segments(q, vblk->sg_elems-2);
+       blk_queue_max_segments(q, sg_elems);
 
        /* No real sector limit. */
        blk_queue_max_hw_sectors(q, -1U);
@@ -925,9 +917,15 @@ static int virtblk_probe(struct virtio_device *vdev)
 
                virtio_cread(vdev, struct virtio_blk_config, max_discard_seg,
                             &v);
+
+               /*
+                * max_discard_seg == 0 is out of spec but we always
+                * handled it.
+                */
+               if (!v)
+                       v = sg_elems;
                blk_queue_max_discard_segments(q,
-                                              min_not_zero(v,
-                                                           MAX_DISCARD_SEGMENTS));
+                                              min(v, MAX_DISCARD_SEGMENTS));
 
                blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
        }
index ca71a0585333fbbe1e553ddb9c37a0d8b6ec3072..03b5fb341e5890a83bfdb125d093569d528e1237 100644 (file)
@@ -1288,7 +1288,8 @@ free_shadow:
                        rinfo->ring_ref[i] = GRANT_INVALID_REF;
                }
        }
-       free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * XEN_PAGE_SIZE));
+       free_pages_exact(rinfo->ring.sring,
+                        info->nr_ring_pages * XEN_PAGE_SIZE);
        rinfo->ring.sring = NULL;
 
        if (rinfo->irq)
@@ -1372,9 +1373,15 @@ static int blkif_get_final_status(enum blk_req_status s1,
        return BLKIF_RSP_OKAY;
 }
 
-static bool blkif_completion(unsigned long *id,
-                            struct blkfront_ring_info *rinfo,
-                            struct blkif_response *bret)
+/*
+ * Return values:
+ *  1 response processed.
+ *  0 missing further responses.
+ * -1 error while processing.
+ */
+static int blkif_completion(unsigned long *id,
+                           struct blkfront_ring_info *rinfo,
+                           struct blkif_response *bret)
 {
        int i = 0;
        struct scatterlist *sg;
@@ -1397,7 +1404,7 @@ static bool blkif_completion(unsigned long *id,
 
                /* Wait the second response if not yet here. */
                if (s2->status < REQ_DONE)
-                       return false;
+                       return 0;
 
                bret->status = blkif_get_final_status(s->status,
                                                      s2->status);
@@ -1448,42 +1455,43 @@ static bool blkif_completion(unsigned long *id,
        }
        /* Add the persistent grant into the list of free grants */
        for (i = 0; i < num_grant; i++) {
-               if (gnttab_query_foreign_access(s->grants_used[i]->gref)) {
+               if (!gnttab_try_end_foreign_access(s->grants_used[i]->gref)) {
                        /*
                         * If the grant is still mapped by the backend (the
                         * backend has chosen to make this grant persistent)
                         * we add it at the head of the list, so it will be
                         * reused first.
                         */
-                       if (!info->feature_persistent)
-                               pr_alert_ratelimited("backed has not unmapped grant: %u\n",
-                                                    s->grants_used[i]->gref);
+                       if (!info->feature_persistent) {
+                               pr_alert("backed has not unmapped grant: %u\n",
+                                        s->grants_used[i]->gref);
+                               return -1;
+                       }
                        list_add(&s->grants_used[i]->node, &rinfo->grants);
                        rinfo->persistent_gnts_c++;
                } else {
                        /*
-                        * If the grant is not mapped by the backend we end the
-                        * foreign access and add it to the tail of the list,
-                        * so it will not be picked again unless we run out of
-                        * persistent grants.
+                        * If the grant is not mapped by the backend we add it
+                        * to the tail of the list, so it will not be picked
+                        * again unless we run out of persistent grants.
                         */
-                       gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
                        s->grants_used[i]->gref = GRANT_INVALID_REF;
                        list_add_tail(&s->grants_used[i]->node, &rinfo->grants);
                }
        }
        if (s->req.operation == BLKIF_OP_INDIRECT) {
                for (i = 0; i < INDIRECT_GREFS(num_grant); i++) {
-                       if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) {
-                               if (!info->feature_persistent)
-                                       pr_alert_ratelimited("backed has not unmapped grant: %u\n",
-                                                            s->indirect_grants[i]->gref);
+                       if (!gnttab_try_end_foreign_access(s->indirect_grants[i]->gref)) {
+                               if (!info->feature_persistent) {
+                                       pr_alert("backed has not unmapped grant: %u\n",
+                                                s->indirect_grants[i]->gref);
+                                       return -1;
+                               }
                                list_add(&s->indirect_grants[i]->node, &rinfo->grants);
                                rinfo->persistent_gnts_c++;
                        } else {
                                struct page *indirect_page;
 
-                               gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL);
                                /*
                                 * Add the used indirect page back to the list of
                                 * available pages for indirect grefs.
@@ -1498,7 +1506,7 @@ static bool blkif_completion(unsigned long *id,
                }
        }
 
-       return true;
+       return 1;
 }
 
 static irqreturn_t blkif_interrupt(int irq, void *dev_id)
@@ -1564,12 +1572,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                }
 
                if (bret.operation != BLKIF_OP_DISCARD) {
+                       int ret;
+
                        /*
                         * We may need to wait for an extra response if the
                         * I/O request is split in 2
                         */
-                       if (!blkif_completion(&id, rinfo, &bret))
+                       ret = blkif_completion(&id, rinfo, &bret);
+                       if (!ret)
                                continue;
+                       if (unlikely(ret < 0))
+                               goto err;
                }
 
                if (add_id_to_freelist(rinfo, id)) {
@@ -1676,8 +1689,7 @@ static int setup_blkring(struct xenbus_device *dev,
        for (i = 0; i < info->nr_ring_pages; i++)
                rinfo->ring_ref[i] = GRANT_INVALID_REF;
 
-       sring = (struct blkif_sring *)__get_free_pages(GFP_NOIO | __GFP_HIGH,
-                                                      get_order(ring_size));
+       sring = alloc_pages_exact(ring_size, GFP_NOIO);
        if (!sring) {
                xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
                return -ENOMEM;
@@ -1687,7 +1699,7 @@ static int setup_blkring(struct xenbus_device *dev,
 
        err = xenbus_grant_ring(dev, rinfo->ring.sring, info->nr_ring_pages, gref);
        if (err < 0) {
-               free_pages((unsigned long)sring, get_order(ring_size));
+               free_pages_exact(sring, ring_size);
                rinfo->ring.sring = NULL;
                goto fail;
        }
@@ -2532,11 +2544,10 @@ static void purge_persistent_grants(struct blkfront_info *info)
                list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants,
                                         node) {
                        if (gnt_list_entry->gref == GRANT_INVALID_REF ||
-                           gnttab_query_foreign_access(gnt_list_entry->gref))
+                           !gnttab_try_end_foreign_access(gnt_list_entry->gref))
                                continue;
 
                        list_del(&gnt_list_entry->node);
-                       gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
                        rinfo->persistent_gnts_c--;
                        gnt_list_entry->gref = GRANT_INVALID_REF;
                        list_add_tail(&gnt_list_entry->node, &rinfo->grants);
index b009e7479b702f861997beed160b33be5a97d479..783d65fc71f07da60dc777a0a3cd4b76f3ad2366 100644 (file)
@@ -274,14 +274,6 @@ static void tpm_dev_release(struct device *dev)
        kfree(chip);
 }
 
-static void tpm_devs_release(struct device *dev)
-{
-       struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
-
-       /* release the master device reference */
-       put_device(&chip->dev);
-}
-
 /**
  * tpm_class_shutdown() - prepare the TPM device for loss of power.
  * @dev: device to which the chip is associated.
@@ -344,7 +336,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
        chip->dev_num = rc;
 
        device_initialize(&chip->dev);
-       device_initialize(&chip->devs);
 
        chip->dev.class = tpm_class;
        chip->dev.class->shutdown_pre = tpm_class_shutdown;
@@ -352,29 +343,12 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
        chip->dev.parent = pdev;
        chip->dev.groups = chip->groups;
 
-       chip->devs.parent = pdev;
-       chip->devs.class = tpmrm_class;
-       chip->devs.release = tpm_devs_release;
-       /* get extra reference on main device to hold on
-        * behalf of devs.  This holds the chip structure
-        * while cdevs is in use.  The corresponding put
-        * is in the tpm_devs_release (TPM2 only)
-        */
-       if (chip->flags & TPM_CHIP_FLAG_TPM2)
-               get_device(&chip->dev);
-
        if (chip->dev_num == 0)
                chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
        else
                chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
 
-       chip->devs.devt =
-               MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
-
        rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
-       if (rc)
-               goto out;
-       rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
        if (rc)
                goto out;
 
@@ -382,9 +356,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
                chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
 
        cdev_init(&chip->cdev, &tpm_fops);
-       cdev_init(&chip->cdevs, &tpmrm_fops);
        chip->cdev.owner = THIS_MODULE;
-       chip->cdevs.owner = THIS_MODULE;
 
        rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
        if (rc) {
@@ -396,7 +368,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
        return chip;
 
 out:
-       put_device(&chip->devs);
        put_device(&chip->dev);
        return ERR_PTR(rc);
 }
@@ -445,14 +416,9 @@ static int tpm_add_char_device(struct tpm_chip *chip)
        }
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) {
-               rc = cdev_device_add(&chip->cdevs, &chip->devs);
-               if (rc) {
-                       dev_err(&chip->devs,
-                               "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
-                               dev_name(&chip->devs), MAJOR(chip->devs.devt),
-                               MINOR(chip->devs.devt), rc);
-                       return rc;
-               }
+               rc = tpm_devs_add(chip);
+               if (rc)
+                       goto err_del_cdev;
        }
 
        /* Make the chip available. */
@@ -460,6 +426,10 @@ static int tpm_add_char_device(struct tpm_chip *chip)
        idr_replace(&dev_nums_idr, chip, chip->dev_num);
        mutex_unlock(&idr_lock);
 
+       return 0;
+
+err_del_cdev:
+       cdev_device_del(&chip->cdev, &chip->dev);
        return rc;
 }
 
@@ -654,7 +624,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
                hwrng_unregister(&chip->hwrng);
        tpm_bios_log_teardown(chip);
        if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))
-               cdev_device_del(&chip->cdevs, &chip->devs);
+               tpm_devs_remove(chip);
        tpm_del_char_device(chip);
 }
 EXPORT_SYMBOL_GPL(tpm_chip_unregister);
index c08cbb306636badabbb04c0333172814215fe876..dc4c0a0a512903235d9c580789cf2c74453ad5c0 100644 (file)
@@ -69,7 +69,13 @@ static void tpm_dev_async_work(struct work_struct *work)
        ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
                               sizeof(priv->data_buffer));
        tpm_put_ops(priv->chip);
-       if (ret > 0) {
+
+       /*
+        * If ret is > 0 then tpm_dev_transmit returned the size of the
+        * response. If ret is < 0 then tpm_dev_transmit failed and
+        * returned an error code.
+        */
+       if (ret != 0) {
                priv->response_length = ret;
                mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
        }
index 283f78211c3a7bc09092085d12834c48571f93f3..2163c6ee0d364f3f8ee935e5abae8f547b4a886f 100644 (file)
@@ -234,6 +234,8 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
                       size_t cmdsiz);
 int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf,
                      size_t *bufsiz);
+int tpm_devs_add(struct tpm_chip *chip);
+void tpm_devs_remove(struct tpm_chip *chip);
 
 void tpm_bios_log_setup(struct tpm_chip *chip);
 void tpm_bios_log_teardown(struct tpm_chip *chip);
index 97e916856cf3e25445c94256dbe94569f5e84524..ffb35f0154c16c463082962426dcc7bdaa4c3a38 100644 (file)
@@ -58,12 +58,12 @@ int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
 
 void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
 {
-       mutex_lock(&chip->tpm_mutex);
-       if (!tpm_chip_start(chip)) {
+
+       if (tpm_try_get_ops(chip) == 0) {
                tpm2_flush_sessions(chip, space);
-               tpm_chip_stop(chip);
+               tpm_put_ops(chip);
        }
-       mutex_unlock(&chip->tpm_mutex);
+
        kfree(space->context_buf);
        kfree(space->session_buf);
 }
@@ -574,3 +574,68 @@ out:
        dev_err(&chip->dev, "%s: error %d\n", __func__, rc);
        return rc;
 }
+
+/*
+ * Put the reference to the main device.
+ */
+static void tpm_devs_release(struct device *dev)
+{
+       struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
+
+       /* release the master device reference */
+       put_device(&chip->dev);
+}
+
+/*
+ * Remove the device file for exposed TPM spaces and release the device
+ * reference. This may also release the reference to the master device.
+ */
+void tpm_devs_remove(struct tpm_chip *chip)
+{
+       cdev_device_del(&chip->cdevs, &chip->devs);
+       put_device(&chip->devs);
+}
+
+/*
+ * Add a device file to expose TPM spaces. Also take a reference to the
+ * main device.
+ */
+int tpm_devs_add(struct tpm_chip *chip)
+{
+       int rc;
+
+       device_initialize(&chip->devs);
+       chip->devs.parent = chip->dev.parent;
+       chip->devs.class = tpmrm_class;
+
+       /*
+        * Get extra reference on main device to hold on behalf of devs.
+        * This holds the chip structure while cdevs is in use. The
+        * corresponding put is in the tpm_devs_release.
+        */
+       get_device(&chip->dev);
+       chip->devs.release = tpm_devs_release;
+       chip->devs.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
+       cdev_init(&chip->cdevs, &tpmrm_fops);
+       chip->cdevs.owner = THIS_MODULE;
+
+       rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
+       if (rc)
+               goto err_put_devs;
+
+       rc = cdev_device_add(&chip->cdevs, &chip->devs);
+       if (rc) {
+               dev_err(&chip->devs,
+                       "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
+                       dev_name(&chip->devs), MAJOR(chip->devs.devt),
+                       MINOR(chip->devs.devt), rc);
+               goto err_put_devs;
+       }
+
+       return 0;
+
+err_put_devs:
+       put_device(&chip->devs);
+
+       return rc;
+}
index da5b30771418f39930c13b7b35b46e24421764ff..f53e0cf1ec7e9d9fb50675a36f205c86eb75fddb 100644 (file)
@@ -126,16 +126,16 @@ static void vtpm_cancel(struct tpm_chip *chip)
        notify_remote_via_evtchn(priv->evtchn);
 }
 
-static unsigned int shr_data_offset(struct vtpm_shared_page *shr)
+static size_t shr_data_offset(struct vtpm_shared_page *shr)
 {
-       return sizeof(*shr) + sizeof(u32) * shr->nr_extra_pages;
+       return struct_size(shr, extra_pages, shr->nr_extra_pages);
 }
 
 static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
        struct tpm_private *priv = dev_get_drvdata(&chip->dev);
        struct vtpm_shared_page *shr = priv->shr;
-       unsigned int offset = shr_data_offset(shr);
+       size_t offset = shr_data_offset(shr);
 
        u32 ordinal;
        unsigned long duration;
@@ -177,7 +177,7 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
        struct tpm_private *priv = dev_get_drvdata(&chip->dev);
        struct vtpm_shared_page *shr = priv->shr;
-       unsigned int offset = shr_data_offset(shr);
+       size_t offset = shr_data_offset(shr);
        size_t length = shr->length;
 
        if (shr->state == VTPM_STATE_IDLE)
index 2359889a35a0a6711964d35df3bce342e6bc2f54..e3c430539a176096a2532bb2ae5d6d0058ec7252 100644 (file)
@@ -1957,6 +1957,13 @@ static void virtcons_remove(struct virtio_device *vdev)
        list_del(&portdev->list);
        spin_unlock_irq(&pdrvdata_lock);
 
+       /* Device is going away, exit any polling for buffers */
+       virtio_break_device(vdev);
+       if (use_multiport(portdev))
+               flush_work(&portdev->control_work);
+       else
+               flush_work(&portdev->config_work);
+
        /* Disable interrupts for vqs */
        virtio_reset_device(vdev);
        /* Finish up work that's lined up */
index ad4256d543613e545ef4e4fa9518e70536f3ada1..d4d67fbae8690b3f335216b7d3aefd01008b2599 100644 (file)
@@ -231,6 +231,8 @@ config COMMON_CLK_GEMINI
 
 config COMMON_CLK_LAN966X
        bool "Generic Clock Controller driver for LAN966X SoC"
+       depends on HAS_IOMEM
+       depends on OF
        help
          This driver provides support for Generic Clock Controller(GCK) on
          LAN966X SoC. GCK generates and supplies clock to various peripherals
index 744d136b721bce889ee0aaa4172f7c571a66ca3a..15d61793f53b13729a2a37a67e1e1c3519b37f78 100644 (file)
@@ -139,11 +139,10 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
        },
 
        [JZ4725B_CLK_I2S] = {
-               "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               "i2s", CGU_CLK_MUX | CGU_CLK_DIV,
                .parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 },
                .mux = { CGU_REG_CPCCR, 31, 1 },
                .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
-               .gate = { CGU_REG_CLKGR, 6 },
        },
 
        [JZ4725B_CLK_SPI] = {
index 538e4963c9152c62d28dbd81258fcce0f4aae88a..5d2ae297e7413f8c89e6adaba57ef727edaef5dd 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, 2022, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -625,6 +625,9 @@ static struct clk_branch disp_cc_mdss_vsync_clk = {
 
 static struct gdsc mdss_gdsc = {
        .gdscr = 0x3000,
+       .en_rest_wait_val = 0x2,
+       .en_few_wait_val = 0x2,
+       .clk_dis_wait_val = 0xf,
        .pd = {
                .name = "mdss_gdsc",
        },
index 4ef4ae231794bf844f4c115e4ff46554f8ff3771..ad596d567f6ab7f5e04d109b50d741f2a4ce1ae7 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2022, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -787,6 +787,9 @@ static struct clk_branch disp_cc_sleep_clk = {
 
 static struct gdsc disp_cc_mdss_core_gdsc = {
        .gdscr = 0x1004,
+       .en_rest_wait_val = 0x2,
+       .en_few_wait_val = 0x2,
+       .clk_dis_wait_val = 0xf,
        .pd = {
                .name = "disp_cc_mdss_core_gdsc",
        },
index 566fdfa0a15bb2f92b27b4269e1d4e6c2b65fc74..db9379634fb220d0135b347077e51d29e0213bc6 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, 2022, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -1126,6 +1126,9 @@ static struct clk_branch disp_cc_mdss_vsync_clk = {
 
 static struct gdsc mdss_gdsc = {
        .gdscr = 0x3000,
+       .en_rest_wait_val = 0x2,
+       .en_few_wait_val = 0x2,
+       .clk_dis_wait_val = 0xf,
        .pd = {
                .name = "mdss_gdsc",
        },
index 71aa630fa4bd533eecb6de8ac17d75ca69e007ba..f09499999eb3a9324594bd947f5f165b2372c304 100644 (file)
@@ -108,42 +108,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll4[] = {
        { .hw = &gpll4.clkr.hw },
 };
 
-static struct clk_rcg2 system_noc_clk_src = {
-       .cmd_rcgr = 0x0120,
-       .hid_width = 5,
-       .parent_map = gcc_xo_gpll0_map,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "system_noc_clk_src",
-               .parent_data = gcc_xo_gpll0,
-               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
-               .ops = &clk_rcg2_ops,
-       },
-};
-
-static struct clk_rcg2 config_noc_clk_src = {
-       .cmd_rcgr = 0x0150,
-       .hid_width = 5,
-       .parent_map = gcc_xo_gpll0_map,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "config_noc_clk_src",
-               .parent_data = gcc_xo_gpll0,
-               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
-               .ops = &clk_rcg2_ops,
-       },
-};
-
-static struct clk_rcg2 periph_noc_clk_src = {
-       .cmd_rcgr = 0x0190,
-       .hid_width = 5,
-       .parent_map = gcc_xo_gpll0_map,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "periph_noc_clk_src",
-               .parent_data = gcc_xo_gpll0,
-               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
-               .ops = &clk_rcg2_ops,
-       },
-};
-
 static struct freq_tbl ftbl_ufs_axi_clk_src[] = {
        F(50000000, P_GPLL0, 12, 0, 0),
        F(100000000, P_GPLL0, 6, 0, 0),
@@ -1150,8 +1114,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
                .enable_mask = BIT(17),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1435,8 +1397,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = {
                .enable_mask = BIT(15),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1764,8 +1724,6 @@ static struct clk_branch gcc_lpass_q6_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_lpass_q6_axi_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1778,8 +1736,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mss_q6_bimc_axi_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1807,9 +1763,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_0_cfg_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1822,9 +1775,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_0_mstr_axi_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1854,9 +1804,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_0_slv_axi_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1884,9 +1831,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_1_cfg_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1899,9 +1843,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_1_mstr_axi_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1930,9 +1871,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_1_slv_axi_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1960,8 +1898,6 @@ static struct clk_branch gcc_pdm_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pdm_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -1989,9 +1925,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc1_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2004,9 +1937,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc2_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2034,9 +1964,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc3_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2064,9 +1991,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc4_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
-                       .flags = CLK_SET_RATE_PARENT,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2124,8 +2048,6 @@ static struct clk_branch gcc_tsif_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_tsif_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2153,8 +2075,6 @@ static struct clk_branch gcc_ufs_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2198,8 +2118,6 @@ static struct clk_branch gcc_ufs_rx_symbol_0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_rx_symbol_0_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2213,8 +2131,6 @@ static struct clk_branch gcc_ufs_rx_symbol_1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_rx_symbol_1_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2243,8 +2159,6 @@ static struct clk_branch gcc_ufs_tx_symbol_0_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_tx_symbol_0_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2258,8 +2172,6 @@ static struct clk_branch gcc_ufs_tx_symbol_1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_tx_symbol_1_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &system_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2364,8 +2276,6 @@ static struct clk_branch gcc_usb_hs_ahb_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb_hs_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2488,8 +2398,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
                .enable_mask = BIT(10),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_boot_rom_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &config_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2503,8 +2411,6 @@ static struct clk_branch gcc_prng_ahb_clk = {
                .enable_mask = BIT(13),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_prng_ahb_clk",
-                       .parent_hws = (const struct clk_hw *[]){ &periph_noc_clk_src.clkr.hw },
-                       .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
        },
@@ -2547,9 +2453,6 @@ static struct clk_regmap *gcc_msm8994_clocks[] = {
        [GPLL0] = &gpll0.clkr,
        [GPLL4_EARLY] = &gpll4_early.clkr,
        [GPLL4] = &gpll4.clkr,
-       [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr,
-       [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr,
-       [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr,
        [UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
        [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
        [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
@@ -2696,6 +2599,15 @@ static struct clk_regmap *gcc_msm8994_clocks[] = {
        [USB_SS_PHY_LDO] = &usb_ss_phy_ldo.clkr,
        [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
        [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+
+       /*
+        * The following clocks should NOT be managed by this driver, but they once were
+        * mistakengly added. Now they are only here to indicate that they are not defined
+        * on purpose, even though the names will stay in the header file (for ABI sanity).
+        */
+       [CONFIG_NOC_CLK_SRC] = NULL,
+       [PERIPH_NOC_CLK_SRC] = NULL,
+       [SYSTEM_NOC_CLK_SRC] = NULL,
 };
 
 static struct gdsc *gcc_msm8994_gdscs[] = {
index 7e1dd8ccfa384d04441f0b79276c88fa2a4edda8..44520efc6c72b8c56fbc45be0659343b5598daaf 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/bitops.h>
 #define CFG_GDSCR_OFFSET               0x4
 
 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
-#define EN_REST_WAIT_VAL       (0x2 << 20)
-#define EN_FEW_WAIT_VAL                (0x8 << 16)
-#define CLK_DIS_WAIT_VAL       (0x2 << 12)
+#define EN_REST_WAIT_VAL       0x2
+#define EN_FEW_WAIT_VAL                0x8
+#define CLK_DIS_WAIT_VAL       0x2
+
+/* Transition delay shifts */
+#define EN_REST_WAIT_SHIFT     20
+#define EN_FEW_WAIT_SHIFT      16
+#define CLK_DIS_WAIT_SHIFT     12
 
 #define RETAIN_MEM             BIT(14)
 #define RETAIN_PERIPH          BIT(13)
@@ -380,7 +385,18 @@ static int gdsc_init(struct gdsc *sc)
         */
        mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
               EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
-       val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+
+       if (!sc->en_rest_wait_val)
+               sc->en_rest_wait_val = EN_REST_WAIT_VAL;
+       if (!sc->en_few_wait_val)
+               sc->en_few_wait_val = EN_FEW_WAIT_VAL;
+       if (!sc->clk_dis_wait_val)
+               sc->clk_dis_wait_val = CLK_DIS_WAIT_VAL;
+
+       val = sc->en_rest_wait_val << EN_REST_WAIT_SHIFT |
+               sc->en_few_wait_val << EN_FEW_WAIT_SHIFT |
+               sc->clk_dis_wait_val << CLK_DIS_WAIT_SHIFT;
+
        ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
        if (ret)
                return ret;
index d7cc4c21a9d48e7de3a0812cb103d02eae96163d..ad313d7210bd32a35103bc1ac3aeb4326e01d661 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __QCOM_GDSC_H__
@@ -22,6 +22,9 @@ struct reset_controller_dev;
  * @cxcs: offsets of branch registers to toggle mem/periph bits in
  * @cxc_count: number of @cxcs
  * @pwrsts: Possible powerdomain power states
+ * @en_rest_wait_val: transition delay value for receiving enr ack signal
+ * @en_few_wait_val: transition delay value for receiving enf ack signal
+ * @clk_dis_wait_val: transition delay value for halting clock
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
@@ -36,6 +39,9 @@ struct gdsc {
        unsigned int                    clamp_io_ctrl;
        unsigned int                    *cxcs;
        unsigned int                    cxc_count;
+       unsigned int                    en_rest_wait_val;
+       unsigned int                    en_few_wait_val;
+       unsigned int                    clk_dis_wait_val;
        const u8                        pwrsts;
 /* Powerdomain allowable state bitfields */
 #define PWRSTS_OFF             BIT(0)
index 5c40ca1d4740e7f67f4a674dd08a433f78488ffc..1fccb457fcc54233507a654813c3eeb220fb90c6 100644 (file)
@@ -241,8 +241,7 @@ static void __init dmtimer_systimer_assign_alwon(void)
        bool quirk_unreliable_oscillator = false;
 
        /* Quirk unreliable 32 KiHz oscillator with incomplete dts */
-       if (of_machine_is_compatible("ti,omap3-beagle-ab4") ||
-           of_machine_is_compatible("timll,omap3-devkit8000")) {
+       if (of_machine_is_compatible("ti,omap3-beagle-ab4")) {
                quirk_unreliable_oscillator = true;
                counter_32k = -ENODEV;
        }
index 7cc4d1d523ea48697a9c0834d8a2221b98cd21f7..04eac41dad33e9227647cbd54a28cdf2468a67f7 100644 (file)
 
 #include "counter-sysfs.h"
 
+static inline struct counter_device *counter_from_dev(struct device *dev)
+{
+       return container_of(dev, struct counter_device, dev);
+}
+
 /**
  * struct counter_attribute - Counter sysfs attribute
  * @dev_attr:  device attribute for sysfs
@@ -90,7 +95,7 @@ static ssize_t counter_comp_u8_show(struct device *dev,
                                    struct device_attribute *attr, char *buf)
 {
        const struct counter_attribute *const a = to_counter_attribute(attr);
-       struct counter_device *const counter = dev_get_drvdata(dev);
+       struct counter_device *const counter = counter_from_dev(dev);
        int err;
        u8 data = 0;
 
@@ -122,7 +127,7 @@ static ssize_t counter_comp_u8_store(struct device *dev,
                                     const char *buf, size_t len)
 {
        const struct counter_attribute *const a = to_counter_attribute(attr);
-       struct counter_device *const counter = dev_get_drvdata(dev);
+       struct counter_device *const counter = counter_from_dev(dev);
        int err;
        bool bool_data = 0;
        u8 data = 0;
@@ -158,7 +163,7 @@ static ssize_t counter_comp_u32_show(struct device *dev,
                                     struct device_attribute *attr, char *buf)
 {
        const struct counter_attribute *const a = to_counter_attribute(attr);
-       struct counter_device *const counter = dev_get_drvdata(dev);
+       struct counter_device *const counter = counter_from_dev(dev);
        const struct counter_available *const avail = a->comp.priv;
        int err;
        u32 data = 0;
@@ -221,7 +226,7 @@ static ssize_t counter_comp_u32_store(struct device *dev,
                                      const char *buf, size_t len)
 {
        const struct counter_attribute *const a = to_counter_attribute(attr);
-       struct counter_device *const counter = dev_get_drvdata(dev);
+       struct counter_device *const counter = counter_from_dev(dev);
        struct counter_count *const count = a->parent;
        struct counter_synapse *const synapse = a->comp.priv;
        const struct counter_available *const avail = a->comp.priv;
@@ -281,7 +286,7 @@ static ssize_t counter_comp_u64_show(struct device *dev,
                                     struct device_attribute *attr, char *buf)
 {
        const struct counter_attribute *const a = to_counter_attribute(attr);
-       struct counter_device *const counter = dev_get_drvdata(dev);
+       struct counter_device *const counter = counter_from_dev(dev);
        int err;
        u64 data = 0;
 
@@ -309,7 +314,7 @@ static ssize_t counter_comp_u64_store(struct device *dev,
                                      const char *buf, size_t len)
 {
        const struct counter_attribute *const a = to_counter_attribute(attr);
-       struct counter_device *const counter = dev_get_drvdata(dev);
+       struct counter_device *const counter = counter_from_dev(dev);
        int err;
        u64 data = 0;
 
index b8d95536ee22e8530fedb72fb199c3ff8dcbf57b..80f535cc8a757fe8222ed9ff4eafc55de0d471e6 100644 (file)
@@ -1518,6 +1518,10 @@ static int cpufreq_online(unsigned int cpu)
 
        kobject_uevent(&policy->kobj, KOBJ_ADD);
 
+       /* Callback for handling stuff after policy is ready */
+       if (cpufreq_driver->ready)
+               cpufreq_driver->ready(policy);
+
        if (cpufreq_thermal_control_enabled(cpufreq_driver))
                policy->cdev = of_cpufreq_cooling_register(policy);
 
index 05f3d7876e448d8db78ecd16b07ee4f4fd671bb3..effbb680b453f27fc819cc7dfcf92ac4748e5e1d 100644 (file)
@@ -388,7 +388,7 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
 
        snprintf(data->irq_name, sizeof(data->irq_name), "dcvsh-irq-%u", policy->cpu);
        ret = request_threaded_irq(data->throttle_irq, NULL, qcom_lmh_dcvs_handle_irq,
-                                  IRQF_ONESHOT, data->irq_name, data);
+                                  IRQF_ONESHOT | IRQF_NO_AUTOEN, data->irq_name, data);
        if (ret) {
                dev_err(&pdev->dev, "Error registering %s: %d\n", data->irq_name, ret);
                return 0;
@@ -542,6 +542,14 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
        return 0;
 }
 
+static void qcom_cpufreq_ready(struct cpufreq_policy *policy)
+{
+       struct qcom_cpufreq_data *data = policy->driver_data;
+
+       if (data->throttle_irq >= 0)
+               enable_irq(data->throttle_irq);
+}
+
 static struct freq_attr *qcom_cpufreq_hw_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
        &cpufreq_freq_attr_scaling_boost_freqs,
@@ -561,6 +569,7 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = {
        .fast_switch    = qcom_cpufreq_hw_fast_switch,
        .name           = "qcom-cpufreq-hw",
        .attr           = qcom_cpufreq_hw_attr,
+       .ready          = qcom_cpufreq_ready,
 };
 
 static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
index 99ba8d51d10209de2d99c666bb790c181d800c64..11f30fd48c1414780006ec57b7fca020ce1e891d 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/clk.h>
 #include <linux/crypto.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -43,16 +44,19 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
 {
        unsigned int currsize = 0;
        u32 val;
+       int ret;
 
        /* read random data from hardware */
        do {
-               val = readl_relaxed(rng->base + PRNG_STATUS);
-               if (!(val & PRNG_STATUS_DATA_AVAIL))
-                       break;
+               ret = readl_poll_timeout(rng->base + PRNG_STATUS, val,
+                                        val & PRNG_STATUS_DATA_AVAIL,
+                                        200, 10000);
+               if (ret)
+                       return ret;
 
                val = readl_relaxed(rng->base + PRNG_DATA_OUT);
                if (!val)
-                       break;
+                       return -EINVAL;
 
                if ((max - currsize) >= WORD_SZ) {
                        memcpy(data, &val, WORD_SZ);
@@ -61,11 +65,10 @@ static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
                } else {
                        /* copy only remaining bytes */
                        memcpy(data, &val, max - currsize);
-                       break;
                }
        } while (currsize < max);
 
-       return currsize;
+       return 0;
 }
 
 static int qcom_rng_generate(struct crypto_rng *tfm,
@@ -87,7 +90,7 @@ static int qcom_rng_generate(struct crypto_rng *tfm,
        mutex_unlock(&rng->lock);
        clk_disable_unprepare(rng->clk);
 
-       return 0;
+       return ret;
 }
 
 static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
index 110de8a6005884d2cbea9e5d7d60278a89d65d39..858400e42ec05c5541f703bdd7e901552cda77a8 100644 (file)
@@ -2968,7 +2968,7 @@ static int __maybe_unused pl330_suspend(struct device *dev)
        struct amba_device *pcdev = to_amba_device(dev);
 
        pm_runtime_force_suspend(dev);
-       amba_pclk_unprepare(pcdev);
+       clk_unprepare(pcdev->pclk);
 
        return 0;
 }
@@ -2978,7 +2978,7 @@ static int __maybe_unused pl330_resume(struct device *dev)
        struct amba_device *pcdev = to_amba_device(dev);
        int ret;
 
-       ret = amba_pclk_prepare(pcdev);
+       ret = clk_prepare(pcdev->pclk);
        if (ret)
                return ret;
 
index 5dd29789f97d3d5d8411ea306c8cbcb317ac9f07..e7e8e624a4362b3ee6a60998a1ddf0928f682d4e 100644 (file)
@@ -1083,8 +1083,46 @@ static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
 
 #ifdef CONFIG_EDAC_ALTERA_SDRAM
 
+/*
+ * A legacy U-Boot bug only enabled memory mapped access to the ECC Enable
+ * register if ECC is enabled. Linux checks the ECC Enable register to
+ * determine ECC status.
+ * Use an SMC call (which always works) to determine ECC enablement.
+ */
+static int altr_s10_sdram_check_ecc_deps(struct altr_edac_device_dev *device)
+{
+       const struct edac_device_prv_data *prv = device->data;
+       unsigned long sdram_ecc_addr;
+       struct arm_smccc_res result;
+       struct device_node *np;
+       phys_addr_t sdram_addr;
+       u32 read_reg;
+       int ret;
+
+       np = of_find_compatible_node(NULL, NULL, "altr,sdr-ctl");
+       if (!np)
+               goto sdram_err;
+
+       sdram_addr = of_translate_address(np, of_get_address(np, 0,
+                                                            NULL, NULL));
+       of_node_put(np);
+       sdram_ecc_addr = (unsigned long)sdram_addr + prv->ecc_en_ofst;
+       arm_smccc_smc(INTEL_SIP_SMC_REG_READ, sdram_ecc_addr,
+                     0, 0, 0, 0, 0, 0, &result);
+       read_reg = (unsigned int)result.a1;
+       ret = (int)result.a0;
+       if (!ret && (read_reg & prv->ecc_enable_mask))
+               return 0;
+
+sdram_err:
+       edac_printk(KERN_ERR, EDAC_DEVICE,
+                   "%s: No ECC present or ECC disabled.\n",
+                   device->edac_dev_name);
+       return -ENODEV;
+}
+
 static const struct edac_device_prv_data s10_sdramecc_data = {
-       .setup = altr_check_ecc_deps,
+       .setup = altr_s10_sdram_check_ecc_deps,
        .ce_clear_mask = ALTR_S10_ECC_SERRPENA,
        .ue_clear_mask = ALTR_S10_ECC_DERRPENA,
        .ecc_enable_mask = ALTR_S10_ECC_EN,
index fba609ada0e6793dfb25fa62b7fa90b59b08b649..812baa48b29065d322e822a04dc5fca02be8b082 100644 (file)
@@ -15,6 +15,21 @@ static struct msr __percpu *msrs;
 
 static struct amd64_family_type *fam_type;
 
+static inline u32 get_umc_reg(u32 reg)
+{
+       if (!fam_type->flags.zn_regs_v2)
+               return reg;
+
+       switch (reg) {
+       case UMCCH_ADDR_CFG:            return UMCCH_ADDR_CFG_DDR5;
+       case UMCCH_ADDR_MASK_SEC:       return UMCCH_ADDR_MASK_SEC_DDR5;
+       case UMCCH_DIMM_CFG:            return UMCCH_DIMM_CFG_DDR5;
+       }
+
+       WARN_ONCE(1, "%s: unknown register 0x%x", __func__, reg);
+       return 0;
+}
+
 /* Per-node stuff */
 static struct ecc_settings **ecc_stngs;
 
@@ -1429,8 +1444,10 @@ static void __dump_misc_regs_df(struct amd64_pvt *pvt)
                edac_dbg(1, "UMC%d x16 DIMMs present: %s\n",
                                i, (umc->dimm_cfg & BIT(7)) ? "yes" : "no");
 
-               if (pvt->dram_type == MEM_LRDDR4) {
-                       amd_smn_read(pvt->mc_node_id, umc_base + UMCCH_ADDR_CFG, &tmp);
+               if (umc->dram_type == MEM_LRDDR4 || umc->dram_type == MEM_LRDDR5) {
+                       amd_smn_read(pvt->mc_node_id,
+                                    umc_base + get_umc_reg(UMCCH_ADDR_CFG),
+                                    &tmp);
                        edac_dbg(1, "UMC%d LRDIMM %dx rank multiply\n",
                                        i, 1 << ((tmp >> 4) & 0x3));
                }
@@ -1505,7 +1522,7 @@ static void prep_chip_selects(struct amd64_pvt *pvt)
 
                for_each_umc(umc) {
                        pvt->csels[umc].b_cnt = 4;
-                       pvt->csels[umc].m_cnt = 2;
+                       pvt->csels[umc].m_cnt = fam_type->flags.zn_regs_v2 ? 4 : 2;
                }
 
        } else {
@@ -1545,7 +1562,7 @@ static void read_umc_base_mask(struct amd64_pvt *pvt)
                }
 
                umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK;
-               umc_mask_reg_sec = get_umc_base(umc) + UMCCH_ADDR_MASK_SEC;
+               umc_mask_reg_sec = get_umc_base(umc) + get_umc_reg(UMCCH_ADDR_MASK_SEC);
 
                for_each_chip_select_mask(cs, umc, pvt) {
                        mask = &pvt->csels[umc].csmasks[cs];
@@ -1616,19 +1633,49 @@ static void read_dct_base_mask(struct amd64_pvt *pvt)
        }
 }
 
+static void determine_memory_type_df(struct amd64_pvt *pvt)
+{
+       struct amd64_umc *umc;
+       u32 i;
+
+       for_each_umc(i) {
+               umc = &pvt->umc[i];
+
+               if (!(umc->sdp_ctrl & UMC_SDP_INIT)) {
+                       umc->dram_type = MEM_EMPTY;
+                       continue;
+               }
+
+               /*
+                * Check if the system supports the "DDR Type" field in UMC Config
+                * and has DDR5 DIMMs in use.
+                */
+               if (fam_type->flags.zn_regs_v2 && ((umc->umc_cfg & GENMASK(2, 0)) == 0x1)) {
+                       if (umc->dimm_cfg & BIT(5))
+                               umc->dram_type = MEM_LRDDR5;
+                       else if (umc->dimm_cfg & BIT(4))
+                               umc->dram_type = MEM_RDDR5;
+                       else
+                               umc->dram_type = MEM_DDR5;
+               } else {
+                       if (umc->dimm_cfg & BIT(5))
+                               umc->dram_type = MEM_LRDDR4;
+                       else if (umc->dimm_cfg & BIT(4))
+                               umc->dram_type = MEM_RDDR4;
+                       else
+                               umc->dram_type = MEM_DDR4;
+               }
+
+               edac_dbg(1, "  UMC%d DIMM type: %s\n", i, edac_mem_types[umc->dram_type]);
+       }
+}
+
 static void determine_memory_type(struct amd64_pvt *pvt)
 {
        u32 dram_ctrl, dcsm;
 
-       if (pvt->umc) {
-               if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5))
-                       pvt->dram_type = MEM_LRDDR4;
-               else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4))
-                       pvt->dram_type = MEM_RDDR4;
-               else
-                       pvt->dram_type = MEM_DDR4;
-               return;
-       }
+       if (pvt->umc)
+               return determine_memory_type_df(pvt);
 
        switch (pvt->fam) {
        case 0xf:
@@ -2149,6 +2196,7 @@ static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
 {
        u32 addr_mask_orig, addr_mask_deinterleaved;
        u32 msb, weight, num_zero_bits;
+       int cs_mask_nr = csrow_nr;
        int dimm, size = 0;
 
        /* No Chip Selects are enabled. */
@@ -2164,17 +2212,33 @@ static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
                return size;
 
        /*
-        * There is one mask per DIMM, and two Chip Selects per DIMM.
-        *      CS0 and CS1 -> DIMM0
-        *      CS2 and CS3 -> DIMM1
+        * Family 17h introduced systems with one mask per DIMM,
+        * and two Chip Selects per DIMM.
+        *
+        *      CS0 and CS1 -> MASK0 / DIMM0
+        *      CS2 and CS3 -> MASK1 / DIMM1
+        *
+        * Family 19h Model 10h introduced systems with one mask per Chip Select,
+        * and two Chip Selects per DIMM.
+        *
+        *      CS0 -> MASK0 -> DIMM0
+        *      CS1 -> MASK1 -> DIMM0
+        *      CS2 -> MASK2 -> DIMM1
+        *      CS3 -> MASK3 -> DIMM1
+        *
+        * Keep the mask number equal to the Chip Select number for newer systems,
+        * and shift the mask number for older systems.
         */
        dimm = csrow_nr >> 1;
 
+       if (!fam_type->flags.zn_regs_v2)
+               cs_mask_nr >>= 1;
+
        /* Asymmetric dual-rank DIMM support. */
        if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY))
-               addr_mask_orig = pvt->csels[umc].csmasks_sec[dimm];
+               addr_mask_orig = pvt->csels[umc].csmasks_sec[cs_mask_nr];
        else
-               addr_mask_orig = pvt->csels[umc].csmasks[dimm];
+               addr_mask_orig = pvt->csels[umc].csmasks[cs_mask_nr];
 
        /*
         * The number of zero bits in the mask is equal to the number of bits
@@ -2930,6 +2994,7 @@ static struct amd64_family_type family_types[] = {
                .f0_id = PCI_DEVICE_ID_AMD_19H_M10H_DF_F0,
                .f6_id = PCI_DEVICE_ID_AMD_19H_M10H_DF_F6,
                .max_mcs = 12,
+               .flags.zn_regs_v2 = 1,
                .ops = {
                        .early_channel_count    = f17_early_channel_count,
                        .dbam_to_cs             = f17_addr_mask_to_cs_size,
@@ -3368,7 +3433,7 @@ static void __read_mc_regs_df(struct amd64_pvt *pvt)
                umc_base = get_umc_base(i);
                umc = &pvt->umc[i];
 
-               amd_smn_read(nid, umc_base + UMCCH_DIMM_CFG, &umc->dimm_cfg);
+               amd_smn_read(nid, umc_base + get_umc_reg(UMCCH_DIMM_CFG), &umc->dimm_cfg);
                amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg);
                amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &umc->sdp_ctrl);
                amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &umc->ecc_ctrl);
@@ -3452,7 +3517,9 @@ skip:
        read_dct_base_mask(pvt);
 
        determine_memory_type(pvt);
-       edac_dbg(1, "  DIMM type: %s\n", edac_mem_types[pvt->dram_type]);
+
+       if (!pvt->umc)
+               edac_dbg(1, "  DIMM type: %s\n", edac_mem_types[pvt->dram_type]);
 
        determine_ecc_sym_sz(pvt);
 }
@@ -3548,7 +3615,7 @@ static int init_csrows_df(struct mem_ctl_info *mci)
                                        pvt->mc_node_id, cs);
 
                        dimm->nr_pages = get_csrow_nr_pages(pvt, umc, cs);
-                       dimm->mtype = pvt->dram_type;
+                       dimm->mtype = pvt->umc[umc].dram_type;
                        dimm->edac_mode = edac_mode;
                        dimm->dtype = dev_type;
                        dimm->grain = 64;
index 352bda9803f6c96573fe6eeb5530b7b3c917d637..38e5ad95d01097f7940712585f6fbf86bda5d5b6 100644 (file)
 #define UMCCH_BASE_ADDR_SEC            0x10
 #define UMCCH_ADDR_MASK                        0x20
 #define UMCCH_ADDR_MASK_SEC            0x28
+#define UMCCH_ADDR_MASK_SEC_DDR5       0x30
 #define UMCCH_ADDR_CFG                 0x30
+#define UMCCH_ADDR_CFG_DDR5            0x40
 #define UMCCH_DIMM_CFG                 0x80
+#define UMCCH_DIMM_CFG_DDR5            0x90
 #define UMCCH_UMC_CFG                  0x100
 #define UMCCH_SDP_CTRL                 0x104
 #define UMCCH_ECC_CTRL                 0x14C
@@ -344,6 +347,9 @@ struct amd64_umc {
        u32 sdp_ctrl;           /* SDP Control reg */
        u32 ecc_ctrl;           /* DRAM ECC Control reg */
        u32 umc_cap_hi;         /* Capabilities High reg */
+
+       /* cache the dram_type */
+       enum mem_type dram_type;
 };
 
 struct amd64_pvt {
@@ -391,7 +397,12 @@ struct amd64_pvt {
        /* place to store error injection parameters prior to issue */
        struct error_injection injection;
 
-       /* cache the dram_type */
+       /*
+        * cache the dram_type
+        *
+        * NOTE: Don't use this for Family 17h and later.
+        *       Use dram_type in struct amd64_umc instead.
+        */
        enum mem_type dram_type;
 
        struct amd64_umc *umc;  /* UMC registers */
@@ -480,11 +491,22 @@ struct low_ops {
                                         unsigned cs_mode, int cs_mask_nr);
 };
 
+struct amd64_family_flags {
+       /*
+        * Indicates that the system supports the new register offsets, etc.
+        * first introduced with Family 19h Model 10h.
+        */
+       __u64 zn_regs_v2        : 1,
+
+             __reserved        : 63;
+};
+
 struct amd64_family_type {
        const char *ctl_name;
        u16 f0_id, f1_id, f2_id, f6_id;
        /* Maximum number of memory controllers per die/node. */
        u8 max_mcs;
+       struct amd64_family_flags flags;
        struct low_ops ops;
 };
 
index 5e75937537997c2a49fba9da0252909b50a11e56..9a61d92bdf42045e6d02d62ee10b4febc1864e45 100644 (file)
@@ -163,13 +163,14 @@ CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,
        edac_device_ctl_poll_msec_show, edac_device_ctl_poll_msec_store);
 
 /* Base Attributes of the EDAC_DEVICE ECC object */
-static struct ctl_info_attribute *device_ctrl_attr[] = {
-       &attr_ctl_info_panic_on_ue,
-       &attr_ctl_info_log_ue,
-       &attr_ctl_info_log_ce,
-       &attr_ctl_info_poll_msec,
+static struct attribute *device_ctrl_attrs[] = {
+       &attr_ctl_info_panic_on_ue.attr,
+       &attr_ctl_info_log_ue.attr,
+       &attr_ctl_info_log_ce.attr,
+       &attr_ctl_info_poll_msec.attr,
        NULL,
 };
+ATTRIBUTE_GROUPS(device_ctrl);
 
 /*
  * edac_device_ctrl_master_release
@@ -217,7 +218,7 @@ static void edac_device_ctrl_master_release(struct kobject *kobj)
 static struct kobj_type ktype_device_ctrl = {
        .release = edac_device_ctrl_master_release,
        .sysfs_ops = &device_ctl_info_ops,
-       .default_attrs = (struct attribute **)device_ctrl_attr,
+       .default_groups = device_ctrl_groups,
 };
 
 /*
@@ -389,17 +390,18 @@ INSTANCE_ATTR(ce_count, S_IRUGO, instance_ce_count_show, NULL);
 INSTANCE_ATTR(ue_count, S_IRUGO, instance_ue_count_show, NULL);
 
 /* list of edac_dev 'instance' attributes */
-static struct instance_attribute *device_instance_attr[] = {
-       &attr_instance_ce_count,
-       &attr_instance_ue_count,
+static struct attribute *device_instance_attrs[] = {
+       &attr_instance_ce_count.attr,
+       &attr_instance_ue_count.attr,
        NULL,
 };
+ATTRIBUTE_GROUPS(device_instance);
 
 /* The 'ktype' for each edac_dev 'instance' */
 static struct kobj_type ktype_instance_ctrl = {
        .release = edac_device_ctrl_instance_release,
        .sysfs_ops = &device_instance_ops,
-       .default_attrs = (struct attribute **)device_instance_attr,
+       .default_groups = device_instance_groups,
 };
 
 /* edac_dev -> instance -> block information */
@@ -487,17 +489,18 @@ BLOCK_ATTR(ce_count, S_IRUGO, block_ce_count_show, NULL);
 BLOCK_ATTR(ue_count, S_IRUGO, block_ue_count_show, NULL);
 
 /* list of edac_dev 'block' attributes */
-static struct edac_dev_sysfs_block_attribute *device_block_attr[] = {
-       &attr_block_ce_count,
-       &attr_block_ue_count,
+static struct attribute *device_block_attrs[] = {
+       &attr_block_ce_count.attr,
+       &attr_block_ue_count.attr,
        NULL,
 };
+ATTRIBUTE_GROUPS(device_block);
 
 /* The 'ktype' for each edac_dev 'block' */
 static struct kobj_type ktype_block_ctrl = {
        .release = edac_device_ctrl_block_release,
        .sysfs_ops = &device_block_ops,
-       .default_attrs = (struct attribute **)device_block_attr,
+       .default_groups = device_block_groups,
 };
 
 /* block ctor/dtor  code */
index f5677d81bd2d5675fe5f4dc261c73d893bb911b3..d2715774af6fb3a0b07ff2c6ce6bb510091c0a68 100644 (file)
@@ -213,12 +213,12 @@ void *edac_align_ptr(void **p, unsigned int size, int n_elems)
        else if (size > sizeof(char))
                align = sizeof(short);
        else
-               return (char *)ptr;
+               return ptr;
 
        r = (unsigned long)ptr % align;
 
        if (r == 0)
-               return (char *)ptr;
+               return ptr;
 
        *p += align - r;
 
index 53042af7262e2a6aca5843c85dcd1cacbe0a658c..888d5728ecef7f18a71d7c6f03eb953b79d79849 100644 (file)
@@ -135,17 +135,18 @@ INSTANCE_ATTR(pe_count, S_IRUGO, instance_pe_count_show, NULL);
 INSTANCE_ATTR(npe_count, S_IRUGO, instance_npe_count_show, NULL);
 
 /* pci instance attributes */
-static struct instance_attribute *pci_instance_attr[] = {
-       &attr_instance_pe_count,
-       &attr_instance_npe_count,
+static struct attribute *pci_instance_attrs[] = {
+       &attr_instance_pe_count.attr,
+       &attr_instance_npe_count.attr,
        NULL
 };
+ATTRIBUTE_GROUPS(pci_instance);
 
 /* the ktype for a pci instance */
 static struct kobj_type ktype_pci_instance = {
        .release = edac_pci_instance_release,
        .sysfs_ops = &pci_instance_ops,
-       .default_attrs = (struct attribute **)pci_instance_attr,
+       .default_groups = pci_instance_groups,
 };
 
 /*
@@ -292,15 +293,16 @@ EDAC_PCI_ATTR(pci_parity_count, S_IRUGO, edac_pci_int_show, NULL);
 EDAC_PCI_ATTR(pci_nonparity_count, S_IRUGO, edac_pci_int_show, NULL);
 
 /* Base Attributes of the memory ECC object */
-static struct edac_pci_dev_attribute *edac_pci_attr[] = {
-       &edac_pci_attr_check_pci_errors,
-       &edac_pci_attr_edac_pci_log_pe,
-       &edac_pci_attr_edac_pci_log_npe,
-       &edac_pci_attr_edac_pci_panic_on_pe,
-       &edac_pci_attr_pci_parity_count,
-       &edac_pci_attr_pci_nonparity_count,
+static struct attribute *edac_pci_attrs[] = {
+       &edac_pci_attr_check_pci_errors.attr,
+       &edac_pci_attr_edac_pci_log_pe.attr,
+       &edac_pci_attr_edac_pci_log_npe.attr,
+       &edac_pci_attr_edac_pci_panic_on_pe.attr,
+       &edac_pci_attr_pci_parity_count.attr,
+       &edac_pci_attr_pci_nonparity_count.attr,
        NULL,
 };
+ATTRIBUTE_GROUPS(edac_pci);
 
 /*
  * edac_pci_release_main_kobj
@@ -327,7 +329,7 @@ static void edac_pci_release_main_kobj(struct kobject *kobj)
 static struct kobj_type ktype_edac_pci_main_kobj = {
        .release = edac_pci_release_main_kobj,
        .sysfs_ops = &edac_pci_sysfs_ops,
-       .default_attrs = (struct attribute **)edac_pci_attr,
+       .default_groups = edac_pci_groups,
 };
 
 /**
index b406b3f78f4678142a5ac76c1c45f580d7ba7bd3..d76bab3aaac45b3d45c7c748464f616f7a7e08a3 100644 (file)
@@ -2112,7 +2112,7 @@ static void __exit scmi_driver_exit(void)
 }
 module_exit(scmi_driver_exit);
 
-MODULE_ALIAS("platform: arm-scmi");
+MODULE_ALIAS("platform:arm-scmi");
 MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
 MODULE_DESCRIPTION("ARM SCMI protocol driver");
 MODULE_LICENSE("GPL v2");
index 4c3201e290e29ff01367dc471513dc55b1b9a23a..ea84108035eb0329f61e6c3bac945ae525a786d8 100644 (file)
@@ -24,7 +24,7 @@ static bool dump_properties __initdata;
 static int __init dump_properties_enable(char *arg)
 {
        dump_properties = true;
-       return 0;
+       return 1;
 }
 
 __setup("dump_apple_properties", dump_properties_enable);
index 7de3f5b6e8d0acbd93de793c87db10d442a9d250..5502e176d51bee14deba8d37bc240244d3e9878b 100644 (file)
@@ -212,7 +212,7 @@ static int __init efivar_ssdt_setup(char *str)
                memcpy(efivar_ssdt, str, strlen(str));
        else
                pr_warn("efivar_ssdt: name too long: %s\n", str);
-       return 0;
+       return 1;
 }
 __setup("efivar_ssdt=", efivar_ssdt_setup);
 
index 380e4e2513994e9d21fa7ecc520c00218d645ce3..9c460843442f5ad56a8865a19088d7a2cb3dbcbd 100644 (file)
@@ -25,7 +25,7 @@ typedef void __noreturn (*jump_kernel_func)(unsigned int, unsigned long);
 
 static u32 hartid;
 
-static u32 get_boot_hartid_from_fdt(void)
+static int get_boot_hartid_from_fdt(void)
 {
        const void *fdt;
        int chosen_node, len;
@@ -33,23 +33,26 @@ static u32 get_boot_hartid_from_fdt(void)
 
        fdt = get_efi_config_table(DEVICE_TREE_GUID);
        if (!fdt)
-               return U32_MAX;
+               return -EINVAL;
 
        chosen_node = fdt_path_offset(fdt, "/chosen");
        if (chosen_node < 0)
-               return U32_MAX;
+               return -EINVAL;
 
        prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len);
        if (!prop || len != sizeof(u32))
-               return U32_MAX;
+               return -EINVAL;
 
-       return fdt32_to_cpu(*prop);
+       hartid = fdt32_to_cpu(*prop);
+       return 0;
 }
 
 efi_status_t check_platform_features(void)
 {
-       hartid = get_boot_hartid_from_fdt();
-       if (hartid == U32_MAX) {
+       int ret;
+
+       ret = get_boot_hartid_from_fdt();
+       if (ret) {
                efi_err("/chosen/boot-hartid missing or invalid!\n");
                return EFI_UNSUPPORTED;
        }
index 38722d2009e2060f28523a12918509684f995712..5ed0602c2f75f06a247971ade04b87069d59ffa6 100644 (file)
@@ -359,4 +359,4 @@ static int __init efi_mokvar_sysfs_init(void)
        }
        return err;
 }
-device_initcall(efi_mokvar_sysfs_init);
+fs_initcall(efi_mokvar_sysfs_init);
index abdc8a6a396318a915455dd73e26439b88c1b003..cae590bd08f27c3c769459802d3546d1542c2ff8 100644 (file)
@@ -742,6 +742,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
 {
        const struct efivar_operations *ops;
        efi_status_t status;
+       unsigned long varsize;
 
        if (!__efivars)
                return -EINVAL;
@@ -764,15 +765,17 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
                return efivar_entry_set_nonblocking(name, vendor, attributes,
                                                    size, data);
 
+       varsize = size + ucs2_strsize(name, 1024);
        if (!block) {
                if (down_trylock(&efivars_lock))
                        return -EBUSY;
+               status = check_var_size_nonblocking(attributes, varsize);
        } else {
                if (down_interruptible(&efivars_lock))
                        return -EINTR;
+               status = check_var_size(attributes, varsize);
        }
 
-       status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
        if (status != EFI_SUCCESS) {
                up(&efivars_lock);
                return -ENOSPC;
index a4c4e4584f5b8c4c4b5ff520435c983b3790bf1f..099e358d2491557a1f35ccf3809852d3441f00b8 100644 (file)
@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
        level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
        polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
 
-       switch (type) {
-       case IRQ_TYPE_EDGE_BOTH:
+       if (type == IRQ_TYPE_EDGE_BOTH) {
                if (bank->gpio_type == GPIO_TYPE_V2) {
-                       bank->toggle_edge_mode &= ~mask;
                        rockchip_gpio_writel_bit(bank, d->hwirq, 1,
                                                 bank->gpio_regs->int_bothedge);
                        goto out;
@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
                        else
                                polarity |= mask;
                }
-               break;
-       case IRQ_TYPE_EDGE_RISING:
-               bank->toggle_edge_mode &= ~mask;
-               level |= mask;
-               polarity |= mask;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               bank->toggle_edge_mode &= ~mask;
-               level |= mask;
-               polarity &= ~mask;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               bank->toggle_edge_mode &= ~mask;
-               level &= ~mask;
-               polarity |= mask;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               bank->toggle_edge_mode &= ~mask;
-               level &= ~mask;
-               polarity &= ~mask;
-               break;
-       default:
-               ret = -EINVAL;
-               goto out;
+       } else {
+               if (bank->gpio_type == GPIO_TYPE_V2) {
+                       rockchip_gpio_writel_bit(bank, d->hwirq, 0,
+                                                bank->gpio_regs->int_bothedge);
+               } else {
+                       bank->toggle_edge_mode &= ~mask;
+               }
+               switch (type) {
+               case IRQ_TYPE_EDGE_RISING:
+                       level |= mask;
+                       polarity |= mask;
+                       break;
+               case IRQ_TYPE_EDGE_FALLING:
+                       level |= mask;
+                       polarity &= ~mask;
+                       break;
+               case IRQ_TYPE_LEVEL_HIGH:
+                       level &= ~mask;
+                       polarity |= mask;
+                       break;
+               case IRQ_TYPE_LEVEL_LOW:
+                       level &= ~mask;
+                       polarity &= ~mask;
+                       break;
+               default:
+                       ret = -EINVAL;
+                       goto out;
+               }
        }
 
        rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);
index 153fe79e1bf3e7d113c62d783ba86f9815a2247b..8e5d87984a48957d9a7c4856511a490e0978f45a 100644 (file)
@@ -547,7 +547,7 @@ struct gpio_sim_bank {
         *
         * So we need to store the pointer to the parent struct here. We can
         * dereference it anywhere we need with no checks and no locking as
-        * it's guaranteed to survive the childred and protected by configfs
+        * it's guaranteed to survive the children and protected by configfs
         * locks.
         *
         * Same for other structures.
@@ -1322,7 +1322,7 @@ static void gpio_sim_hog_config_item_release(struct config_item *item)
        kfree(hog);
 }
 
-struct configfs_item_operations gpio_sim_hog_config_item_ops = {
+static struct configfs_item_operations gpio_sim_hog_config_item_ops = {
        .release        = gpio_sim_hog_config_item_release,
 };
 
index 34b36a8c035f58abda72afbe92cb014d34cdf906..031fe105b58ed34a2d54f381eef189093fcfc078 100644 (file)
@@ -343,9 +343,12 @@ static int tegra186_gpio_of_xlate(struct gpio_chip *chip,
        return offset + pin;
 }
 
+#define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio)
+
 static void tegra186_irq_ack(struct irq_data *data)
 {
-       struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+       struct tegra_gpio *gpio = to_tegra_gpio(gc);
        void __iomem *base;
 
        base = tegra186_gpio_get_base(gpio, data->hwirq);
@@ -357,7 +360,8 @@ static void tegra186_irq_ack(struct irq_data *data)
 
 static void tegra186_irq_mask(struct irq_data *data)
 {
-       struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+       struct tegra_gpio *gpio = to_tegra_gpio(gc);
        void __iomem *base;
        u32 value;
 
@@ -372,7 +376,8 @@ static void tegra186_irq_mask(struct irq_data *data)
 
 static void tegra186_irq_unmask(struct irq_data *data)
 {
-       struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+       struct tegra_gpio *gpio = to_tegra_gpio(gc);
        void __iomem *base;
        u32 value;
 
@@ -387,7 +392,8 @@ static void tegra186_irq_unmask(struct irq_data *data)
 
 static int tegra186_irq_set_type(struct irq_data *data, unsigned int type)
 {
-       struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+       struct tegra_gpio *gpio = to_tegra_gpio(gc);
        void __iomem *base;
        u32 value;
 
@@ -1069,6 +1075,7 @@ static const struct tegra_gpio_soc tegra241_main_soc = {
        .ports = tegra241_main_ports,
        .name = "tegra241-gpio",
        .instance = 0,
+       .num_irqs_per_bank = 8,
 };
 
 #define TEGRA241_AON_GPIO_PORT(_name, _bank, _port, _pins)     \
@@ -1089,6 +1096,7 @@ static const struct tegra_gpio_soc tegra241_aon_soc = {
        .ports = tegra241_aon_ports,
        .name = "tegra241-gpio-aon",
        .instance = 1,
+       .num_irqs_per_bank = 8,
 };
 
 static const struct of_device_id tegra186_gpio_of_match[] = {
index d885032cf814d89e184f7a10ab51fa09b2efc033..d918d2df4de2cbf536a67483b496f5079640ebfd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Digital I/O driver for Technologic Systems I2C FPGA Core
  *
- * Copyright (C) 2015 Technologic Systems
+ * Copyright (C) 2015, 2018 Technologic Systems
  * Copyright (C) 2016 Savoir-Faire Linux
  *
  * This program is free software; you can redistribute it and/or
@@ -55,19 +55,33 @@ static int ts4900_gpio_direction_input(struct gpio_chip *chip,
 {
        struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
 
-       /*
-        * This will clear the output enable bit, the other bits are
-        * dontcare when this is cleared
+       /* Only clear the OE bit here, requires a RMW. Prevents potential issue
+        * with OE and data getting to the physical pin at different times.
         */
-       return regmap_write(priv->regmap, offset, 0);
+       return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0);
 }
 
 static int ts4900_gpio_direction_output(struct gpio_chip *chip,
                                        unsigned int offset, int value)
 {
        struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
+       unsigned int reg;
        int ret;
 
+       /* If changing from an input to an output, we need to first set the
+        * proper data bit to what is requested and then set OE bit. This
+        * prevents a glitch that can occur on the IO line
+        */
+       regmap_read(priv->regmap, offset, &reg);
+       if (!(reg & TS4900_GPIO_OE)) {
+               if (value)
+                       reg = TS4900_GPIO_OUT;
+               else
+                       reg &= ~TS4900_GPIO_OUT;
+
+               regmap_write(priv->regmap, offset, reg);
+       }
+
        if (value)
                ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE |
                                                         TS4900_GPIO_OUT);
index c0f6a25c327944b26489f24f72ac41a768291a9b..a5495ad31c9ce6ad8b523fadeba6b83a3e9403a1 100644 (file)
@@ -307,7 +307,8 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
        if (IS_ERR(desc))
                return desc;
 
-       ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout);
+       /* ACPI uses hundredths of milliseconds units */
+       ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout * 10);
        if (ret)
                dev_warn(chip->parent,
                         "Failed to set debounce-timeout for pin 0x%04X, err %d\n",
@@ -1035,7 +1036,8 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind
                        if (ret < 0)
                                return ret;
 
-                       ret = gpio_set_debounce_timeout(desc, info.debounce);
+                       /* ACPI uses hundredths of milliseconds units */
+                       ret = gpio_set_debounce_timeout(desc, info.debounce * 10);
                        if (ret)
                                return ret;
 
index 3859911b61e9d45b7437cf68079686a08880af3a..6630d92e30ada8af1478e93e8cd1e70366fcc2ac 100644 (file)
@@ -2227,6 +2227,16 @@ static int gpio_set_bias(struct gpio_desc *desc)
        return gpio_set_config_with_argument_optional(desc, bias, arg);
 }
 
+/**
+ * gpio_set_debounce_timeout() - Set debounce timeout
+ * @desc:      GPIO descriptor to set the debounce timeout
+ * @debounce:  Debounce timeout in microseconds
+ *
+ * The function calls the certain GPIO driver to set debounce timeout
+ * in the hardware.
+ *
+ * Returns 0 on success, or negative error code otherwise.
+ */
 int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce)
 {
        return gpio_set_config_with_argument_optional(desc,
@@ -3147,6 +3157,16 @@ int gpiod_to_irq(const struct gpio_desc *desc)
 
                return retirq;
        }
+#ifdef CONFIG_GPIOLIB_IRQCHIP
+       if (gc->irq.chip) {
+               /*
+                * Avoid race condition with other code, which tries to lookup
+                * an IRQ before the irqchip has been properly registered,
+                * i.e. while gpiochip is still being brought up.
+                */
+               return -EPROBE_DEFER;
+       }
+#endif
        return -ENXIO;
 }
 EXPORT_SYMBOL_GPL(gpiod_to_irq);
index 82011e75ed85999ae3fa3fa95ad26e9979e481c2..c4387b38229c2570b9afe424a97e359e23338709 100644 (file)
@@ -1141,7 +1141,7 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
        if (ret)
                return ret;
 
-       if (!dev->mode_config.allow_fb_modifiers) {
+       if (!dev->mode_config.allow_fb_modifiers && !adev->enable_virtual_display) {
                drm_WARN_ONCE(dev, adev->family >= AMDGPU_FAMILY_AI,
                              "GFX9+ requires FB check based on format modifier\n");
                ret = check_tiling_flags_gfx6(rfb);
index 63a08999264517f98655bfa18f3fab1f0f3ac74c..0ead08ba58c2a5927af0d71a8e0e1d07f42bd015 100644 (file)
@@ -2011,6 +2011,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
                        return -ENODEV;
        }
 
+       if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev))
+               amdgpu_aspm = 0;
+
        if (amdgpu_virtual_display ||
            amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
                supports_atomic = true;
index d99c8779b51e916782c93c24c6e8af9c8128267b..5224d9a39737f24f747549d43b207acbd8361ebd 100644 (file)
@@ -391,7 +391,6 @@ static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
                                                int index)
 {
        struct drm_plane *plane;
-       uint64_t modifiers[] = {DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID};
        int ret;
 
        plane = kzalloc(sizeof(*plane), GFP_KERNEL);
@@ -402,7 +401,7 @@ static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
                                       &amdgpu_vkms_plane_funcs,
                                       amdgpu_vkms_formats,
                                       ARRAY_SIZE(amdgpu_vkms_formats),
-                                      modifiers, type, NULL);
+                                      NULL, type, NULL);
        if (ret) {
                kfree(plane);
                return ERR_PTR(ret);
index b37fc7d7d2c76392ad7cfd9f3d6c6cc7948b7622..418341a6751716c2beb69506c326cc7565ebc340 100644 (file)
@@ -768,11 +768,17 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
  * Check if all VM PDs/PTs are ready for updates
  *
  * Returns:
- * True if eviction list is empty.
+ * True if VM is not evicting.
  */
 bool amdgpu_vm_ready(struct amdgpu_vm *vm)
 {
-       return list_empty(&vm->evicted);
+       bool ret;
+
+       amdgpu_vm_eviction_lock(vm);
+       ret = !vm->evicting;
+       amdgpu_vm_eviction_unlock(vm);
+
+       return ret && list_empty(&vm->evicted);
 }
 
 /**
index 0fc1747e4a70f3f0ea0e1e5f3577a133c4b4dcc2..12f80fdc1fbc948e11046a612745b2bdf06d2cb8 100644 (file)
@@ -619,8 +619,8 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
 static int soc15_asic_reset(struct amdgpu_device *adev)
 {
        /* original raven doesn't have full asic reset */
-       if ((adev->apu_flags & AMD_APU_IS_RAVEN) &&
-           !(adev->apu_flags & AMD_APU_IS_RAVEN2))
+       if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
+           (adev->apu_flags & AMD_APU_IS_RAVEN2))
                return 0;
 
        switch (soc15_asic_reset_method(adev)) {
@@ -1114,8 +1114,11 @@ static int soc15_common_early_init(void *handle)
                                AMD_CG_SUPPORT_SDMA_LS |
                                AMD_CG_SUPPORT_VCN_MGCG;
 
+                       /*
+                        * MMHUB PG needs to be disabled for Picasso for
+                        * stability reasons.
+                        */
                        adev->pg_flags = AMD_PG_SUPPORT_SDMA |
-                               AMD_PG_SUPPORT_MMHUB |
                                AMD_PG_SUPPORT_VCN;
                } else {
                        adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
index 7c1c623ba79930a6fa4779d93287e8f57b96adfa..075429bea4275d529763e74b57097121f297e1a5 100644 (file)
@@ -4256,6 +4256,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
        }
 #endif
 
+       /* Disable vblank IRQs aggressively for power-saving. */
+       adev_to_drm(adev)->vblank_disable_immediate = true;
+
        /* loops over all connectors on the board */
        for (i = 0; i < link_cnt; i++) {
                struct dc_link *link = NULL;
@@ -4301,19 +4304,17 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
                                update_connector_ext_caps(aconnector);
                        if (psr_feature_enabled)
                                amdgpu_dm_set_psr_caps(link);
+
+                       /* TODO: Fix vblank control helpers to delay PSR entry to allow this when
+                        * PSR is also supported.
+                        */
+                       if (link->psr_settings.psr_feature_enabled)
+                               adev_to_drm(adev)->vblank_disable_immediate = false;
                }
 
 
        }
 
-       /*
-        * Disable vblank IRQs aggressively for power-saving.
-        *
-        * TODO: Fix vblank control helpers to delay PSR entry to allow this when PSR
-        * is also supported.
-        */
-       adev_to_drm(adev)->vblank_disable_immediate = !psr_feature_enabled;
-
        /* Software is initialized. Now we can register interrupt handlers. */
        switch (adev->asic_type) {
 #if defined(CONFIG_DRM_AMD_DC_SI)
index f977f29907df5898bc88c712dff6f7c510fb5516..10c7be40dfb0cdabc8fcc154de50818706dad00e 100644 (file)
@@ -473,8 +473,10 @@ static void dcn3_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base)
        clk_mgr_base->bw_params->dc_mode_softmax_memclk = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_UCLK);
 
        /* Refresh bounding box */
+       DC_FP_START();
        clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box(
                        clk_mgr->base.ctx->dc, clk_mgr_base->bw_params);
+       DC_FP_END();
 }
 
 static bool dcn3_is_smu_present(struct clk_mgr *clk_mgr_base)
index d18e9f3ea99832799fd6935278c476571caf1584..ba1aa994db4b79f0672a207cfeee665c9318390e 100644 (file)
@@ -985,10 +985,13 @@ static bool dc_construct(struct dc *dc,
                goto fail;
 #ifdef CONFIG_DRM_AMD_DC_DCN
        dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present;
-#endif
 
-       if (dc->res_pool->funcs->update_bw_bounding_box)
+       if (dc->res_pool->funcs->update_bw_bounding_box) {
+               DC_FP_START();
                dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
+               DC_FP_END();
+       }
+#endif
 
        /* Creation of current_state must occur after dc->dml
         * is initialized in dc_create_resource_pool because
index b3912ff9dc91135b5aceb37972876a44bba7a42e..18757c15852328abfeaefc20c7fabe1db4bb7761 100644 (file)
@@ -1964,10 +1964,6 @@ enum dc_status dc_remove_stream_from_ctx(
                                dc->res_pool,
                        del_pipe->stream_res.stream_enc,
                        false);
-       /* Release link encoder from stream in new dc_state. */
-       if (dc->res_pool->funcs->link_enc_unassign)
-               dc->res_pool->funcs->link_enc_unassign(new_ctx, del_pipe->stream);
-
 #if defined(CONFIG_DRM_AMD_DC_DCN)
        if (is_dp_128b_132b_signal(del_pipe)) {
                update_hpo_dp_stream_engine_usage(
index 2320bd7508767c77e159d8b388be354effb03c7f..5488a0edb942d0dfcb115353098ae8560dd4cf9d 100644 (file)
@@ -421,6 +421,36 @@ static int sienna_cichlid_store_powerplay_table(struct smu_context *smu)
        return 0;
 }
 
+static int sienna_cichlid_patch_pptable_quirk(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+       uint32_t *board_reserved;
+       uint16_t *freq_table_gfx;
+       uint32_t i;
+
+       /* Fix some OEM SKU specific stability issues */
+       GET_PPTABLE_MEMBER(BoardReserved, &board_reserved);
+       if ((adev->pdev->device == 0x73DF) &&
+           (adev->pdev->revision == 0XC3) &&
+           (adev->pdev->subsystem_device == 0x16C2) &&
+           (adev->pdev->subsystem_vendor == 0x1043))
+               board_reserved[0] = 1387;
+
+       GET_PPTABLE_MEMBER(FreqTableGfx, &freq_table_gfx);
+       if ((adev->pdev->device == 0x73DF) &&
+           (adev->pdev->revision == 0XC3) &&
+           ((adev->pdev->subsystem_device == 0x16C2) ||
+           (adev->pdev->subsystem_device == 0x133C)) &&
+           (adev->pdev->subsystem_vendor == 0x1043)) {
+               for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++) {
+                       if (freq_table_gfx[i] > 2500)
+                               freq_table_gfx[i] = 2500;
+               }
+       }
+
+       return 0;
+}
+
 static int sienna_cichlid_setup_pptable(struct smu_context *smu)
 {
        int ret = 0;
@@ -441,7 +471,7 @@ static int sienna_cichlid_setup_pptable(struct smu_context *smu)
        if (ret)
                return ret;
 
-       return ret;
+       return sienna_cichlid_patch_pptable_quirk(smu);
 }
 
 static int sienna_cichlid_tables_init(struct smu_context *smu)
index 58a242871b28ee5a11d8a80e0c3913d6d6ce6ccf..6e3f1d600541aae14ae25d38cd7fd5458fec955b 100644 (file)
@@ -6,6 +6,7 @@ config DRM_HDLCD
        depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST)
        depends on COMMON_CLK
        select DRM_KMS_HELPER
+       select DRM_GEM_CMA_HELPER
        help
          Choose this option if you have an ARM High Definition Colour LCD
          controller.
index 61db5a66b49345826fc485977ba897cf1b21b058..44ad709396630371acc24912d809a5c63e619d7c 100644 (file)
@@ -8,7 +8,6 @@ config DRM_BRIDGE
 config DRM_PANEL_BRIDGE
        def_bool y
        depends on DRM_BRIDGE
-       depends on DRM_KMS_HELPER
        select DRM_PANEL
        help
          DRM bridge wrapper of DRM panels
@@ -30,6 +29,7 @@ config DRM_CDNS_DSI
 config DRM_CHIPONE_ICN6211
        tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge"
        depends on OF
+       select DRM_KMS_HELPER
        select DRM_MIPI_DSI
        select DRM_PANEL_BRIDGE
        help
index dab8f76618f372c46589946d73efd72251c455a4..68d8415e6c284596692c40666f192c9c3ecc6403 100644 (file)
@@ -1802,6 +1802,7 @@ static inline void ti_sn_gpio_unregister(void) {}
 
 static void ti_sn65dsi86_runtime_disable(void *data)
 {
+       pm_runtime_dont_use_autosuspend(data);
        pm_runtime_disable(data);
 }
 
@@ -1861,11 +1862,11 @@ static int ti_sn65dsi86_probe(struct i2c_client *client,
                                     "failed to get reference clock\n");
 
        pm_runtime_enable(dev);
+       pm_runtime_set_autosuspend_delay(pdata->dev, 500);
+       pm_runtime_use_autosuspend(pdata->dev);
        ret = devm_add_action_or_reset(dev, ti_sn65dsi86_runtime_disable, dev);
        if (ret)
                return ret;
-       pm_runtime_set_autosuspend_delay(pdata->dev, 500);
-       pm_runtime_use_autosuspend(pdata->dev);
 
        ti_sn65dsi86_debugfs_init(pdata);
 
index a50c82bc2b2fecd3182529d5e1f640e25b8f8674..76a8c707c34b948168b5a8b7827c53a7006f2984 100644 (file)
@@ -2330,6 +2330,9 @@ EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);
 void drm_connector_set_vrr_capable_property(
                struct drm_connector *connector, bool capable)
 {
+       if (!connector->vrr_capable_property)
+               return;
+
        drm_object_property_set_value(&connector->base,
                                      connector->vrr_capable_property,
                                      capable);
index 12893e7be89bb8108f7b65c112724ce897e188c0..f5f5de362ff2c722734fea68c6c17885e03510e2 100644 (file)
@@ -5345,6 +5345,7 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
        if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
                return quirks;
 
+       info->color_formats |= DRM_COLOR_FORMAT_RGB444;
        drm_parse_cea_ext(connector, edid);
 
        /*
@@ -5393,7 +5394,6 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
        DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n",
                          connector->name, info->bpc);
 
-       info->color_formats |= DRM_COLOR_FORMAT_RGB444;
        if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444)
                info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
        if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
index 12571ac455404345cb076d2ea050388d93d28c2c..c04264f70ad172e8ad4980dc4301b37f35d225d4 100644 (file)
@@ -678,7 +678,6 @@ static int decon_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct decon_context *ctx;
        struct device_node *i80_if_timings;
-       struct resource *res;
        int ret;
 
        if (!dev->of_node)
@@ -728,16 +727,11 @@ static int decon_probe(struct platform_device *pdev)
                goto err_iounmap;
        }
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-                                          ctx->i80_if ? "lcd_sys" : "vsync");
-       if (!res) {
-               dev_err(dev, "irq request failed.\n");
-               ret = -ENXIO;
+       ret =  platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync");
+       if (ret < 0)
                goto err_iounmap;
-       }
 
-       ret = devm_request_irq(dev, res->start, decon_irq_handler,
-                                                       0, "drm_decon", ctx);
+       ret = devm_request_irq(dev, ret, decon_irq_handler, 0, "drm_decon", ctx);
        if (ret) {
                dev_err(dev, "irq request failed.\n");
                goto err_iounmap;
index 32a36572b89473e567e18eb1eb6e406025b40f52..d13f5e3a030d3290a49c55b8fe5365c6fb601ff6 100644 (file)
@@ -1334,8 +1334,10 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi,
        int ret;
        int te_gpio_irq;
 
-       dsi->te_gpio = devm_gpiod_get_optional(dsi->dev, "te", GPIOD_IN);
-       if (IS_ERR(dsi->te_gpio)) {
+       dsi->te_gpio = gpiod_get_optional(panel, "te", GPIOD_IN);
+       if (!dsi->te_gpio) {
+               return 0;
+       } else if (IS_ERR(dsi->te_gpio)) {
                dev_err(dsi->dev, "gpio request failed with %ld\n",
                                PTR_ERR(dsi->te_gpio));
                return PTR_ERR(dsi->te_gpio);
index 023f54ee61a81df98d21ab33207def8870cea7ce..0ee32e4b1e4308dbfa303f15c64bf09ab60eacad 100644 (file)
@@ -1267,7 +1267,6 @@ static int fimc_probe(struct platform_device *pdev)
        struct exynos_drm_ipp_formats *formats;
        struct device *dev = &pdev->dev;
        struct fimc_context *ctx;
-       struct resource *res;
        int ret;
        int i, j, num_limits, num_formats;
 
@@ -1330,14 +1329,12 @@ static int fimc_probe(struct platform_device *pdev)
                return PTR_ERR(ctx->regs);
 
        /* resource irq */
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!res) {
-               dev_err(dev, "failed to request irq resource.\n");
-               return -ENOENT;
-       }
+       ret = platform_get_irq(pdev, 0);
+       if (ret < 0)
+               return ret;
 
-       ret = devm_request_irq(dev, res->start, fimc_irq_handler,
-               0, dev_name(dev), ctx);
+       ret = devm_request_irq(dev, ret, fimc_irq_handler,
+                              0, dev_name(dev), ctx);
        if (ret < 0) {
                dev_err(dev, "failed to request irq.\n");
                return ret;
index c735e53939d88c86799afb873afbb75f4dd54ea9..7d5a483a54dee16de9f4b9f8c70799222ceb2884 100644 (file)
@@ -1133,7 +1133,6 @@ static int fimd_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct fimd_context *ctx;
        struct device_node *i80_if_timings;
-       struct resource *res;
        int ret;
 
        if (!dev->of_node)
@@ -1206,15 +1205,11 @@ static int fimd_probe(struct platform_device *pdev)
        if (IS_ERR(ctx->regs))
                return PTR_ERR(ctx->regs);
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-                                          ctx->i80_if ? "lcd_sys" : "vsync");
-       if (!res) {
-               dev_err(dev, "irq request failed.\n");
-               return -ENXIO;
-       }
+       ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync");
+       if (ret < 0)
+               return ret;
 
-       ret = devm_request_irq(dev, res->start, fimd_irq_handler,
-                                                       0, "drm_fimd", ctx);
+       ret = devm_request_irq(dev, ret, fimd_irq_handler, 0, "drm_fimd", ctx);
        if (ret) {
                dev_err(dev, "irq request failed.\n");
                return ret;
index 166a802628963226b6678d5668660a0761c3e29d..964dceb28c1eb880901da7b30220383f630592b2 100644 (file)
@@ -1220,7 +1220,6 @@ static int gsc_probe(struct platform_device *pdev)
        struct gsc_driverdata *driver_data;
        struct exynos_drm_ipp_formats *formats;
        struct gsc_context *ctx;
-       struct resource *res;
        int num_formats, ret, i, j;
 
        ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
@@ -1275,13 +1274,10 @@ static int gsc_probe(struct platform_device *pdev)
                return PTR_ERR(ctx->regs);
 
        /* resource irq */
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!res) {
-               dev_err(dev, "failed to request irq resource.\n");
-               return -ENOENT;
-       }
+       ctx->irq = platform_get_irq(pdev, 0);
+       if (ctx->irq < 0)
+               return ctx->irq;
 
-       ctx->irq = res->start;
        ret = devm_request_irq(dev, ctx->irq, gsc_irq_handler, 0,
                               dev_name(dev), ctx);
        if (ret < 0) {
index 41c54f1f60bc0f8fed1240ce725aa3a3622b4d85..e5204be86093273de2f46ab049efa36f0aef8f88 100644 (file)
@@ -809,19 +809,17 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
                return -ENXIO;
        }
 
-       res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
-       if (res == NULL) {
-               dev_err(dev, "get interrupt resource failed.\n");
-               return -ENXIO;
-       }
+       ret = platform_get_irq(mixer_ctx->pdev, 0);
+       if (ret < 0)
+               return ret;
+       mixer_ctx->irq = ret;
 
-       ret = devm_request_irq(dev, res->start, mixer_irq_handler,
-                                               0, "drm_mixer", mixer_ctx);
+       ret = devm_request_irq(dev, mixer_ctx->irq, mixer_irq_handler,
+                              0, "drm_mixer", mixer_ctx);
        if (ret) {
                dev_err(dev, "request interrupt failed.\n");
                return ret;
        }
-       mixer_ctx->irq = res->start;
 
        return 0;
 }
index 2da4aacc956bb86b824a1d07491ca0484a02291b..8ac196e814d5d314913bab9d44b043ceea1b6490 100644 (file)
@@ -825,6 +825,7 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
        unsigned int max_bw_point = 0, max_bw = 0;
        unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
        unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points;
+       bool changed = false;
        u32 mask = 0;
 
        /* FIXME earlier gens need some checks too */
@@ -868,6 +869,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
                new_bw_state->data_rate[crtc->pipe] = new_data_rate;
                new_bw_state->num_active_planes[crtc->pipe] = new_active_planes;
 
+               changed = true;
+
                drm_dbg_kms(&dev_priv->drm,
                            "pipe %c data rate %u num active planes %u\n",
                            pipe_name(crtc->pipe),
@@ -875,7 +878,19 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
                            new_bw_state->num_active_planes[crtc->pipe]);
        }
 
-       if (!new_bw_state)
+       old_bw_state = intel_atomic_get_old_bw_state(state);
+       new_bw_state = intel_atomic_get_new_bw_state(state);
+
+       if (new_bw_state &&
+           intel_can_enable_sagv(dev_priv, old_bw_state) !=
+           intel_can_enable_sagv(dev_priv, new_bw_state))
+               changed = true;
+
+       /*
+        * If none of our inputs (data rates, number of active
+        * planes, SAGV yes/no) changed then nothing to do here.
+        */
+       if (!changed)
                return 0;
 
        ret = intel_atomic_lock_global_state(&new_bw_state->base);
@@ -961,7 +976,6 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
         */
        new_bw_state->qgv_points_mask = ~allowed_points & mask;
 
-       old_bw_state = intel_atomic_get_old_bw_state(state);
        /*
         * If the actual mask had changed we need to make sure that
         * the commits are serialized(in case this is a nomodeset, nonblocking)
index 46c6eecbd9175ba51eaa90041f97bc2a3dc63280..0ceaed1c96562adfa97b239bd8ede37915f2e716 100644 (file)
@@ -30,19 +30,19 @@ struct intel_bw_state {
         */
        u8 pipe_sagv_reject;
 
+       /* bitmask of active pipes */
+       u8 active_pipes;
+
        /*
         * Current QGV points mask, which restricts
         * some particular SAGV states, not to confuse
         * with pipe_sagv_mask.
         */
-       u8 qgv_points_mask;
+       u16 qgv_points_mask;
 
        unsigned int data_rate[I915_MAX_PIPES];
        u8 num_active_planes[I915_MAX_PIPES];
 
-       /* bitmask of active pipes */
-       u8 active_pipes;
-
        int min_cdclk;
 };
 
index a1a663f362e7d5fef9c001ba5999b1fef628fc2e..00279e8c277563bc5c10a61eebedc6c77898ea6c 100644 (file)
@@ -1406,6 +1406,13 @@ static inline u32 man_trk_ctl_single_full_frame_bit_get(struct drm_i915_private
               PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME;
 }
 
+static inline u32 man_trk_ctl_partial_frame_bit_get(struct drm_i915_private *dev_priv)
+{
+       return IS_ALDERLAKE_P(dev_priv) ?
+              ADLP_PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE :
+              PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE;
+}
+
 static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1510,7 +1517,13 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       u32 val = PSR2_MAN_TRK_CTL_ENABLE;
+       u32 val = 0;
+
+       if (!IS_ALDERLAKE_P(dev_priv))
+               val = PSR2_MAN_TRK_CTL_ENABLE;
+
+       /* SF partial frame enable has to be set even on full update */
+       val |= man_trk_ctl_partial_frame_bit_get(dev_priv);
 
        if (full_update) {
                /*
@@ -1530,7 +1543,6 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
        } else {
                drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip->y2 % 4);
 
-               val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE;
                val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 / 4 + 1);
                val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / 4 + 1);
        }
index 09f405e4d363f6e40ffdee900677436675ffd49a..92ff654f54f5699e0d6e1fd2f276739a1cfa1e17 100644 (file)
@@ -34,7 +34,7 @@ void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv)
                if (intel_de_wait_for_clear(dev_priv, ICL_PHY_MISC(phy),
                                            DG2_PHY_DP_TX_ACK_MASK, 25))
                        DRM_ERROR("SNPS PHY %c failed to calibrate after 25ms.\n",
-                                 phy);
+                                 phy_name(phy));
        }
 }
 
index dbd7d0d83a141ca33073cfeca89194f56e8d5d1e..7784c30fe8937026ad3dba7c7a29120f4bcb0c32 100644 (file)
@@ -691,6 +691,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
 {
        struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
        struct intel_encoder *encoder = &dig_port->base;
+       intel_wakeref_t tc_cold_wref;
+       enum intel_display_power_domain domain;
        int active_links = 0;
 
        mutex_lock(&dig_port->tc_lock);
@@ -702,12 +704,11 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
 
        drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
        drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
-       if (active_links) {
-               enum intel_display_power_domain domain;
-               intel_wakeref_t tc_cold_wref = tc_cold_block(dig_port, &domain);
 
-               dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
+       tc_cold_wref = tc_cold_block(dig_port, &domain);
 
+       dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
+       if (active_links) {
                if (!icl_tc_phy_is_connected(dig_port))
                        drm_dbg_kms(&i915->drm,
                                    "Port %s: PHY disconnected with %d active link(s)\n",
@@ -716,10 +717,23 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
 
                dig_port->tc_lock_wakeref = tc_cold_block(dig_port,
                                                          &dig_port->tc_lock_power_domain);
-
-               tc_cold_unblock(dig_port, domain, tc_cold_wref);
+       } else {
+               /*
+                * TBT-alt is the default mode in any case the PHY ownership is not
+                * held (regardless of the sink's connected live state), so
+                * we'll just switch to disconnected mode from it here without
+                * a note.
+                */
+               if (dig_port->tc_mode != TC_PORT_TBT_ALT)
+                       drm_dbg_kms(&i915->drm,
+                                   "Port %s: PHY left in %s mode on disabled port, disconnecting it\n",
+                                   dig_port->tc_port_name,
+                                   tc_port_mode_name(dig_port->tc_mode));
+               icl_tc_phy_disconnect(dig_port);
        }
 
+       tc_cold_unblock(dig_port, domain, tc_cold_wref);
+
        drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n",
                    dig_port->tc_port_name,
                    tc_port_mode_name(dig_port->tc_mode));
index 13b27b8ff74e5ddd019fb07e5ec4ad5dcd83a234..ba21ace973da143ce0b06ec268d22b4b9587f26d 100644 (file)
@@ -110,7 +110,7 @@ static int guc_action_slpc_unset_param(struct intel_guc *guc, u8 id)
 {
        u32 request[] = {
                GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST,
-               SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 2),
+               SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1),
                id,
        };
 
index c2bb33febb68e45354c608f9c7fae2b204530d3e..902e4c802a1239b6add952a41f5c4f0ef76ccb84 100644 (file)
@@ -4829,6 +4829,7 @@ enum {
 #define  ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val)       REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val)
 #define  ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK         REG_GENMASK(12, 0)
 #define  ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val)         REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val)
+#define  ADLP_PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE         REG_BIT(31)
 #define  ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME            REG_BIT(14)
 #define  ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME         REG_BIT(13)
 
index da8f82c2342f4c23a092aa172b716acfd9d0a7f1..fc8a68f3a2eda0e4242c3345a83fc98588c2ee32 100644 (file)
@@ -108,6 +108,7 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
                /* Comet Lake V PCH is based on KBP, which is SPT compatible */
                return PCH_SPT;
        case INTEL_PCH_ICP_DEVICE_ID_TYPE:
+       case INTEL_PCH_ICP2_DEVICE_ID_TYPE:
                drm_dbg_kms(&dev_priv->drm, "Found Ice Lake PCH\n");
                drm_WARN_ON(&dev_priv->drm, !IS_ICELAKE(dev_priv));
                return PCH_ICP;
@@ -123,7 +124,6 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
                            !IS_GEN9_BC(dev_priv));
                return PCH_TGP;
        case INTEL_PCH_JSP_DEVICE_ID_TYPE:
-       case INTEL_PCH_JSP2_DEVICE_ID_TYPE:
                drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n");
                drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv));
                return PCH_JSP;
index 6bff775210943a2971b3c212eae60b3aa22347a8..4ba0f1967cca982fc2f5a87dfb8cb75803bf04cb 100644 (file)
@@ -50,11 +50,11 @@ enum intel_pch {
 #define INTEL_PCH_CMP2_DEVICE_ID_TYPE          0x0680
 #define INTEL_PCH_CMP_V_DEVICE_ID_TYPE         0xA380
 #define INTEL_PCH_ICP_DEVICE_ID_TYPE           0x3480
+#define INTEL_PCH_ICP2_DEVICE_ID_TYPE          0x3880
 #define INTEL_PCH_MCC_DEVICE_ID_TYPE           0x4B00
 #define INTEL_PCH_TGP_DEVICE_ID_TYPE           0xA080
 #define INTEL_PCH_TGP2_DEVICE_ID_TYPE          0x4380
 #define INTEL_PCH_JSP_DEVICE_ID_TYPE           0x4D80
-#define INTEL_PCH_JSP2_DEVICE_ID_TYPE          0x3880
 #define INTEL_PCH_ADP_DEVICE_ID_TYPE           0x7A80
 #define INTEL_PCH_ADP2_DEVICE_ID_TYPE          0x5180
 #define INTEL_PCH_ADP3_DEVICE_ID_TYPE          0x7A00
index 32bc155f5dc0a39bbf285f42061b4f3532d9b4ae..fae4f7818d28b5c3c749027442e78552e400315d 100644 (file)
@@ -4029,6 +4029,17 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state)
                        return ret;
        }
 
+       if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
+           intel_can_enable_sagv(dev_priv, old_bw_state)) {
+               ret = intel_atomic_serialize_global_state(&new_bw_state->base);
+               if (ret)
+                       return ret;
+       } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
+               ret = intel_atomic_lock_global_state(&new_bw_state->base);
+               if (ret)
+                       return ret;
+       }
+
        for_each_new_intel_crtc_in_state(state, crtc,
                                         new_crtc_state, i) {
                struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal;
@@ -4044,17 +4055,6 @@ static int intel_compute_sagv_mask(struct intel_atomic_state *state)
                        intel_can_enable_sagv(dev_priv, new_bw_state);
        }
 
-       if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
-           intel_can_enable_sagv(dev_priv, old_bw_state)) {
-               ret = intel_atomic_serialize_global_state(&new_bw_state->base);
-               if (ret)
-                       return ret;
-       } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) {
-               ret = intel_atomic_lock_global_state(&new_bw_state->base);
-               if (ret)
-                       return ret;
-       }
-
        return 0;
 }
 
index 7374f1952762e672cb99493d1ba5a75ec0f901d5..5c2b2277afbf54510aad9ece357ef09b517a9013 100644 (file)
@@ -2,6 +2,7 @@ config DRM_IMX_DCSS
        tristate "i.MX8MQ DCSS"
        select IMX_IRQSTEER
        select DRM_KMS_HELPER
+       select DRM_GEM_CMA_HELPER
        select VIDEOMODE_HELPERS
        depends on DRM && ARCH_MXC && ARM64
        help
index a8aba0141ce712db31dcedef39fb287e7afb37c2..06cb1a59b9bcd6fd38f573abfdbca904f9a69cc2 100644 (file)
@@ -217,14 +217,6 @@ static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge,
        if (!imx_pd_format_supported(bus_fmt))
                return -EINVAL;
 
-       if (bus_flags &
-           ~(DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_DE_HIGH |
-             DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE |
-             DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)) {
-               dev_warn(imxpd->dev, "invalid bus_flags (%x)\n", bus_flags);
-               return -EINVAL;
-       }
-
        bridge_state->output_bus_cfg.flags = bus_flags;
        bridge_state->input_bus_cfg.flags = bus_flags;
        imx_crtc_state->bus_flags = bus_flags;
index e9ae22b4f8138b1261779f84d86f305603d78789..52be08b744ade257cb51d71d5a3c7f9b7fcd3861 100644 (file)
@@ -404,9 +404,9 @@ mgag200_pixpll_update_g200wb(struct mgag200_pll *pixpll, const struct mgag200_pl
                udelay(50);
 
                /* program pixel pll register */
-               WREG_DAC(MGA1064_PIX_PLLC_N, xpixpllcn);
-               WREG_DAC(MGA1064_PIX_PLLC_M, xpixpllcm);
-               WREG_DAC(MGA1064_PIX_PLLC_P, xpixpllcp);
+               WREG_DAC(MGA1064_WB_PIX_PLLC_N, xpixpllcn);
+               WREG_DAC(MGA1064_WB_PIX_PLLC_M, xpixpllcm);
+               WREG_DAC(MGA1064_WB_PIX_PLLC_P, xpixpllcp);
 
                udelay(50);
 
index 434c2861bb40c0a4be85fece9abb340c2483ca50..9989a316fe8868fc54a71c4c9c71322d459682d2 100644 (file)
@@ -106,6 +106,8 @@ config DRM_PANEL_EDP
        depends on PM
        select VIDEOMODE_HELPERS
        select DRM_DP_AUX_BUS
+       select DRM_DP_HELPER
+       select DRM_KMS_HELPER
        help
          DRM panel driver for dumb eDP panels that need at most a regulator and
          a GPIO to be powered up. Optionally a backlight can be attached so
index 3c08f9827acf1935efbe0ee0f61c07a6d246cce0..b42c1d816e792d846328c0373912841191131382 100644 (file)
@@ -2017,7 +2017,7 @@ static const struct display_timing innolux_g070y2_l01_timing = {
 static const struct panel_desc innolux_g070y2_l01 = {
        .timings = &innolux_g070y2_l01_timing,
        .num_timings = 1,
-       .bpc = 6,
+       .bpc = 8,
        .size = {
                .width = 152,
                .height = 91,
index 377f9cdb5b53fff3aa09985b007f99d214776859..84013faa4756f41fb398877e01cddabb8957ce50 100644 (file)
@@ -470,8 +470,8 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
        int32_t *msg, msg_type, handle;
        unsigned img_size = 0;
        void *ptr;
-
-       int i, r;
+       long r;
+       int i;
 
        if (offset & 0x3F) {
                DRM_ERROR("UVD messages must be 64 byte aligned!\n");
@@ -481,13 +481,13 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
        r = dma_resv_wait_timeout(bo->tbo.base.resv, false, false,
                                  MAX_SCHEDULE_TIMEOUT);
        if (r <= 0) {
-               DRM_ERROR("Failed waiting for UVD message (%d)!\n", r);
+               DRM_ERROR("Failed waiting for UVD message (%ld)!\n", r);
                return r ? r : -ETIME;
        }
 
        r = radeon_bo_kmap(bo, &ptr);
        if (r) {
-               DRM_ERROR("Failed mapping the UVD message (%d)!\n", r);
+               DRM_ERROR("Failed mapping the UVD message (%ld)!\n", r);
                return r;
        }
 
index 145833a9d82d46c0d65e08797ca8c7e0e3618f26..5b3fbee18671301a4d63d80ede641306750a3608 100644 (file)
 /* format 13 is semi-planar YUV411 VUVU */
 #define SUN8I_MIXER_FBFMT_YUV411       14
 /* format 15 doesn't exist */
-/* format 16 is P010 YVU */
-#define SUN8I_MIXER_FBFMT_P010_YUV     17
-/* format 18 is P210 YVU */
-#define SUN8I_MIXER_FBFMT_P210_YUV     19
+#define SUN8I_MIXER_FBFMT_P010_YUV     16
+/* format 17 is P010 YVU */
+#define SUN8I_MIXER_FBFMT_P210_YUV     18
+/* format 19 is P210 YVU */
 /* format 20 is packed YVU444 10-bit */
 /* format 21 is packed YUV444 10-bit */
 
index 8cf5aeb9db6c6b612c18e692a19042704a932a1e..201f5175ecfec7a5d4a711fe64ed54e9d0cae5f1 100644 (file)
@@ -5,6 +5,7 @@ config DRM_TEGRA
        depends on COMMON_CLK
        depends on DRM
        depends on OF
+       select DRM_DP_AUX_BUS
        select DRM_KMS_HELPER
        select DRM_MIPI_DSI
        select DRM_PANEL
index 1f96e416fa0828a4fecb1530c03a93d6f3e4b7a6..d7a731d287d2344dcab9aa7be0dcd8e2dfc4997d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/workqueue.h>
 
 #include <drm/drm_dp_helper.h>
+#include <drm/drm_dp_aux_bus.h>
 #include <drm/drm_panel.h>
 
 #include "dp.h"
@@ -570,6 +571,12 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
        list_add_tail(&dpaux->list, &dpaux_list);
        mutex_unlock(&dpaux_lock);
 
+       err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux);
+       if (err < 0) {
+               dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err);
+               return err;
+       }
+
        return 0;
 }
 
index 223ab2ceb7e626a8fd69e88ddbb68784dd86d2ed..3762d87759d98cba5bbd39a5c36ed0611841fe7a 100644 (file)
@@ -63,7 +63,7 @@ static void falcon_copy_firmware_image(struct falcon *falcon,
 
        /* copy the whole thing taking into account endianness */
        for (i = 0; i < firmware->size / sizeof(u32); i++)
-               virt[i] = le32_to_cpu(((u32 *)firmware->data)[i]);
+               virt[i] = le32_to_cpu(((__le32 *)firmware->data)[i]);
 }
 
 static int falcon_parse_firmware_image(struct falcon *falcon)
index e6cc47470e03094f42e02f676198399d16d70205..783890e8d43a2e4d24036c53ca468274181a3a4e 100644 (file)
@@ -525,9 +525,11 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
        if (ret)
                return ret;
 
-       ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
-       if (ret)
-               return ret;
+       /*
+        * post_crtc_powerdown will have called pm_runtime_put, so we
+        * don't need it here otherwise we'll get the reference counting
+        * wrong.
+        */
 
        return 0;
 }
index b30500405fa79ddd9bfc92b215f482d4ee7a0e2c..3a1626f261e5a0dd8c689c95bced763877dc6203 100644 (file)
@@ -1749,6 +1749,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
                dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev));
                return PTR_ERR(codec_pdev);
        }
+       vc4_hdmi->audio.codec_pdev = codec_pdev;
 
        dai_link->cpus          = &vc4_hdmi->audio.cpu;
        dai_link->codecs        = &vc4_hdmi->audio.codec;
@@ -1788,6 +1789,12 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
 
 }
 
+static void vc4_hdmi_audio_exit(struct vc4_hdmi *vc4_hdmi)
+{
+       platform_device_unregister(vc4_hdmi->audio.codec_pdev);
+       vc4_hdmi->audio.codec_pdev = NULL;
+}
+
 static irqreturn_t vc4_hdmi_hpd_irq_thread(int irq, void *priv)
 {
        struct vc4_hdmi *vc4_hdmi = priv;
@@ -2660,6 +2667,7 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
        kfree(vc4_hdmi->hdmi_regset.regs);
        kfree(vc4_hdmi->hd_regset.regs);
 
+       vc4_hdmi_audio_exit(vc4_hdmi);
        vc4_hdmi_cec_exit(vc4_hdmi);
        vc4_hdmi_hotplug_exit(vc4_hdmi);
        vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
index 31b77a94c526deaaf3470e3667e8f65e52a7b5f3..6ffdd4ec5fb6af1d041ef1013119f58990e68ed5 100644 (file)
@@ -116,6 +116,7 @@ struct vc4_hdmi_audio {
        struct snd_soc_dai_link_component platform;
        struct snd_dmaengine_dai_dma_data dma_data;
        struct hdmi_audio_infoframe infoframe;
+       struct platform_device *codec_pdev;
        bool streaming;
 };
 
index e08e331e46aea7a5e3484cea2f8f4012d474e542..f87a8705f51834cb9fc568b82a8a0ac31cd5447c 100644 (file)
@@ -137,8 +137,15 @@ void host1x_syncpt_restore(struct host1x *host)
        struct host1x_syncpt *sp_base = host->syncpt;
        unsigned int i;
 
-       for (i = 0; i < host1x_syncpt_nb_pts(host); i++)
+       for (i = 0; i < host1x_syncpt_nb_pts(host); i++) {
+               /*
+                * Unassign syncpt from channels for purposes of Tegra186
+                * syncpoint protection. This prevents any channel from
+                * accessing it until it is reassigned.
+                */
+               host1x_hw_syncpt_assign_to_channel(host, sp_base + i, NULL);
                host1x_hw_syncpt_restore(host, sp_base + i);
+       }
 
        for (i = 0; i < host1x_syncpt_nb_bases(host); i++)
                host1x_hw_syncpt_restore_wait_base(host, sp_base + i);
@@ -227,27 +234,12 @@ int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
        void *ref;
        struct host1x_waitlist *waiter;
        int err = 0, check_count = 0;
-       u32 val;
 
        if (value)
-               *value = 0;
-
-       /* first check cache */
-       if (host1x_syncpt_is_expired(sp, thresh)) {
-               if (value)
-                       *value = host1x_syncpt_load(sp);
+               *value = host1x_syncpt_load(sp);
 
+       if (host1x_syncpt_is_expired(sp, thresh))
                return 0;
-       }
-
-       /* try to read from register */
-       val = host1x_hw_syncpt_load(sp->host, sp);
-       if (host1x_syncpt_is_expired(sp, thresh)) {
-               if (value)
-                       *value = val;
-
-               goto done;
-       }
 
        if (!timeout) {
                err = -EAGAIN;
@@ -352,13 +344,6 @@ int host1x_syncpt_init(struct host1x *host)
        for (i = 0; i < host->info->nb_pts; i++) {
                syncpt[i].id = i;
                syncpt[i].host = host;
-
-               /*
-                * Unassign syncpt from channels for purposes of Tegra186
-                * syncpoint protection. This prevents any channel from
-                * accessing it until it is reassigned.
-                */
-               host1x_hw_syncpt_assign_to_channel(host, &syncpt[i], NULL);
        }
 
        for (i = 0; i < host->info->nb_bases; i++)
index 26c31d759914b9bed859bd9c616765ff40dc8915..81e7e404a5fce7bc0cf5d779b657475f8862f1f9 100644 (file)
@@ -860,7 +860,9 @@ static const char *keys[KEY_MAX + 1] = {
        [KEY_F22] = "F22",                      [KEY_F23] = "F23",
        [KEY_F24] = "F24",                      [KEY_PLAYCD] = "PlayCD",
        [KEY_PAUSECD] = "PauseCD",              [KEY_PROG3] = "Prog3",
-       [KEY_PROG4] = "Prog4",                  [KEY_SUSPEND] = "Suspend",
+       [KEY_PROG4] = "Prog4",
+       [KEY_ALL_APPLICATIONS] = "AllApplications",
+       [KEY_SUSPEND] = "Suspend",
        [KEY_CLOSE] = "Close",                  [KEY_PLAY] = "Play",
        [KEY_FASTFORWARD] = "FastForward",      [KEY_BASSBOOST] = "BassBoost",
        [KEY_PRINT] = "Print",                  [KEY_HP] = "HP",
@@ -969,6 +971,7 @@ static const char *keys[KEY_MAX + 1] = {
        [KEY_ASSISTANT] = "Assistant",
        [KEY_KBD_LAYOUT_NEXT] = "KbdLayoutNext",
        [KEY_EMOJI_PICKER] = "EmojiPicker",
+       [KEY_DICTATE] = "Dictate",
        [KEY_BRIGHTNESS_MIN] = "BrightnessMin",
        [KEY_BRIGHTNESS_MAX] = "BrightnessMax",
        [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
index 9b42b0cdeef06b00b8ba140397156cf7e9b5e966..2876cb6a7dcab0b22791f217ee1bd21e366ad756 100644 (file)
@@ -228,7 +228,6 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
        struct elo_priv *priv;
        int ret;
-       struct usb_device *udev;
 
        if (!hid_is_usb(hdev))
                return -EINVAL;
@@ -238,8 +237,7 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
                return -ENOMEM;
 
        INIT_DELAYED_WORK(&priv->work, elo_work);
-       udev = interface_to_usbdev(to_usb_interface(hdev->dev.parent));
-       priv->usbdev = usb_get_dev(udev);
+       priv->usbdev = interface_to_usbdev(to_usb_interface(hdev->dev.parent));
 
        hid_set_drvdata(hdev, priv);
 
@@ -262,7 +260,6 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
        return 0;
 err_free:
-       usb_put_dev(udev);
        kfree(priv);
        return ret;
 }
@@ -271,8 +268,6 @@ static void elo_remove(struct hid_device *hdev)
 {
        struct elo_priv *priv = hid_get_drvdata(hdev);
 
-       usb_put_dev(priv->usbdev);
-
        hid_hw_stop(hdev);
        cancel_delayed_work_sync(&priv->work);
        kfree(priv);
index 112901d2d8d2a0db34e2df53e59c521fd0dae145..56ec27398a0061d28d0fc74bf9661bd6a3d988d8 100644 (file)
@@ -992,6 +992,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                case 0x0cd: map_key_clear(KEY_PLAYPAUSE);       break;
                case 0x0cf: map_key_clear(KEY_VOICECOMMAND);    break;
 
+               case 0x0d8: map_key_clear(KEY_DICTATE);         break;
                case 0x0d9: map_key_clear(KEY_EMOJI_PICKER);    break;
 
                case 0x0e0: map_abs_clear(ABS_VOLUME);          break;
@@ -1083,6 +1084,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
                case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT); break;
 
+               case 0x2a2: map_key_clear(KEY_ALL_APPLICATIONS);        break;
+
                case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV);             break;
                case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT);             break;
                case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP);                break;
index 7106b921b53cf5038137fef8aeaead8b91affa00..c358778e070bca20b05e804c292b905aec2ec749 100644 (file)
@@ -1068,6 +1068,7 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
                workitem.reports_supported |= STD_KEYBOARD;
                break;
        case 0x0f:
+       case 0x11:
                device_type = "eQUAD Lightspeed 1.2";
                logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
                workitem.reports_supported |= STD_KEYBOARD;
index b6a9a0f3966ee0d1853aba4b42c1fca2f94d70a1..2204de889739f526be3fa7fa585f3b11b11b8b06 100644 (file)
@@ -2128,6 +2128,10 @@ static int nintendo_hid_probe(struct hid_device *hdev,
        spin_lock_init(&ctlr->lock);
        ctlr->rumble_queue = alloc_workqueue("hid-nintendo-rumble_wq",
                                             WQ_FREEZABLE | WQ_MEM_RECLAIM, 0);
+       if (!ctlr->rumble_queue) {
+               ret = -ENOMEM;
+               goto err;
+       }
        INIT_WORK(&ctlr->rumble_worker, joycon_rumble_worker);
 
        ret = hid_parse(hdev);
index 03b935ff02d5616f67e3287ceeb0dc9926703429..c3e6d69fdfbd9775da293634a9c8404b73de4517 100644 (file)
@@ -64,7 +64,9 @@ struct tm_wheel_info {
  */
 static const struct tm_wheel_info tm_wheels_infos[] = {
        {0x0306, 0x0006, "Thrustmaster T150RS"},
+       {0x0200, 0x0005, "Thrustmaster T300RS (Missing Attachment)"},
        {0x0206, 0x0005, "Thrustmaster T300RS"},
+       {0x0209, 0x0005, "Thrustmaster T300RS (Open Wheel Attachment)"},
        {0x0204, 0x0005, "Thrustmaster T300 Ferrari Alcantara Edition"},
        {0x0002, 0x0002, "Thrustmaster T500RS"}
        //{0x0407, 0x0001, "Thrustmaster TMX"}
@@ -158,6 +160,12 @@ static void thrustmaster_interrupts(struct hid_device *hdev)
                return;
        }
 
+       if (usbif->cur_altsetting->desc.bNumEndpoints < 2) {
+               kfree(send_buf);
+               hid_err(hdev, "Wrong number of endpoints?\n");
+               return;
+       }
+
        ep = &usbif->cur_altsetting->endpoint[1];
        b_ep = ep->desc.bEndpointAddress;
 
index efa6140915f4416182dfd9686c79ed3178f802be..42ceb2058a094e00582f17edde9a73e91657b75a 100644 (file)
@@ -144,7 +144,7 @@ out:
 static int vivaldi_input_configured(struct hid_device *hdev,
                                    struct hid_input *hidinput)
 {
-       return sysfs_create_group(&hdev->dev.kobj, &input_attribute_group);
+       return devm_device_add_group(&hdev->dev, &input_attribute_group);
 }
 
 static const struct hid_device_id vivaldi_table[] = {
index 3501a3ead4ba608d6f4f571c20bc0ac49f60649f..3ae961986fc312eb7334161eadb4e505ff2f2767 100644 (file)
@@ -214,12 +214,14 @@ static int hwmon_thermal_add_sensor(struct device *dev, int index)
 
        tzd = devm_thermal_zone_of_sensor_register(dev, index, tdata,
                                                   &hwmon_thermal_ops);
-       /*
-        * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV,
-        * so ignore that error but forward any other error.
-        */
-       if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV))
-               return PTR_ERR(tzd);
+       if (IS_ERR(tzd)) {
+               if (PTR_ERR(tzd) != -ENODEV)
+                       return PTR_ERR(tzd);
+               dev_info(dev, "temp%d_input not attached to any thermal zone\n",
+                        index + 1);
+               devm_kfree(dev, tdata);
+               return 0;
+       }
 
        err = devm_add_action(dev, hwmon_thermal_remove_sensor, &tdata->node);
        if (err)
index 414204f5704c105897c5c8a88f9e67c50517244c..9c9e9f4ccb9e938b750de685380e7ffa26dc9d3f 100644 (file)
@@ -59,7 +59,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
        [NTC_NCP15XH103]      = { "ncp15xh103",      TYPE_NCPXXXH103 },
        [NTC_NCP18WB473]      = { "ncp18wb473",      TYPE_NCPXXWB473 },
        [NTC_NCP21WB473]      = { "ncp21wb473",      TYPE_NCPXXWB473 },
-       [NTC_SSG1404001221]   = { "ssg1404-001221",  TYPE_NCPXXWB473 },
+       [NTC_SSG1404001221]   = { "ssg1404_001221",  TYPE_NCPXXWB473 },
        [NTC_LAST]            = { },
 };
 
index 776ee2237be20ad7c0af6b8b16d335d82cdf67eb..ac2fbee1ba9c0dbd5ed65e0a17636ab58a19c9b7 100644 (file)
@@ -911,6 +911,11 @@ static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b,
                pmbus_update_sensor_data(client, s2);
 
        regval = status & mask;
+       if (regval) {
+               ret = pmbus_write_byte_data(client, page, reg, regval);
+               if (ret)
+                       goto unlock;
+       }
        if (s1 && s2) {
                s64 v1, v2;
 
index e6081dd0a8800cd0787b55f847d523a59bc2151a..d11f668016a6aa8ea5a1a5500f63b94b8ebba0fd 100644 (file)
@@ -1783,11 +1783,14 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(dev, "Unable to register iio device\n");
-               goto err_trigger_unregister;
+               goto err_pm_cleanup;
        }
 
        return 0;
 
+err_pm_cleanup:
+       pm_runtime_dont_use_autosuspend(dev);
+       pm_runtime_disable(dev);
 err_trigger_unregister:
        bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1);
 err_buffer_cleanup:
index 32989d91b9829ebef7dcdc343cb874cd6c4dcaf1..f7fd9e046588bd50feef1dd9a7ac346cbd80eb37 100644 (file)
@@ -173,12 +173,20 @@ struct fxls8962af_data {
        u16 upper_thres;
 };
 
-const struct regmap_config fxls8962af_regmap_conf = {
+const struct regmap_config fxls8962af_i2c_regmap_conf = {
        .reg_bits = 8,
        .val_bits = 8,
        .max_register = FXLS8962AF_MAX_REG,
 };
-EXPORT_SYMBOL_GPL(fxls8962af_regmap_conf);
+EXPORT_SYMBOL_GPL(fxls8962af_i2c_regmap_conf);
+
+const struct regmap_config fxls8962af_spi_regmap_conf = {
+       .reg_bits = 8,
+       .pad_bits = 8,
+       .val_bits = 8,
+       .max_register = FXLS8962AF_MAX_REG,
+};
+EXPORT_SYMBOL_GPL(fxls8962af_spi_regmap_conf);
 
 enum {
        fxls8962af_idx_x,
index cfb004b204559886d9ac61d374eb580c4594a7c4..6bde9891effbf16ca4991b08b7d287ddf76b4e4c 100644 (file)
@@ -18,7 +18,7 @@ static int fxls8962af_probe(struct i2c_client *client)
 {
        struct regmap *regmap;
 
-       regmap = devm_regmap_init_i2c(client, &fxls8962af_regmap_conf);
+       regmap = devm_regmap_init_i2c(client, &fxls8962af_i2c_regmap_conf);
        if (IS_ERR(regmap)) {
                dev_err(&client->dev, "Failed to initialize i2c regmap\n");
                return PTR_ERR(regmap);
index 57108d3d480b6346c9d13cb8f8622bf086ed06b9..6f4dff3238d3c215de7a0b7fecc8a0135b262702 100644 (file)
@@ -18,7 +18,7 @@ static int fxls8962af_probe(struct spi_device *spi)
 {
        struct regmap *regmap;
 
-       regmap = devm_regmap_init_spi(spi, &fxls8962af_regmap_conf);
+       regmap = devm_regmap_init_spi(spi, &fxls8962af_spi_regmap_conf);
        if (IS_ERR(regmap)) {
                dev_err(&spi->dev, "Failed to initialize spi regmap\n");
                return PTR_ERR(regmap);
index b67572c3ef0693141f42285f099e1cfc3d03d880..9cbe98c3ba9a2950635e6eec4a001ae66d3a134c 100644 (file)
@@ -17,6 +17,7 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq);
 int fxls8962af_core_remove(struct device *dev);
 
 extern const struct dev_pm_ops fxls8962af_pm_ops;
-extern const struct regmap_config fxls8962af_regmap_conf;
+extern const struct regmap_config fxls8962af_i2c_regmap_conf;
+extern const struct regmap_config fxls8962af_spi_regmap_conf;
 
 #endif                         /* _FXLS8962AF_H_ */
index 0fe570316848276c9b1f8612618737c6e5f305a5..ac74cdcd2bc8c959eee453d2be489287c64d2f2a 100644 (file)
@@ -1590,11 +1590,14 @@ static int kxcjk1013_probe(struct i2c_client *client,
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(&client->dev, "unable to register iio device\n");
-               goto err_buffer_cleanup;
+               goto err_pm_cleanup;
        }
 
        return 0;
 
+err_pm_cleanup:
+       pm_runtime_dont_use_autosuspend(&client->dev);
+       pm_runtime_disable(&client->dev);
 err_buffer_cleanup:
        iio_triggered_buffer_cleanup(indio_dev);
 err_trigger_unregister:
index 4c359fb05480189212189e35702c90957e653acd..c53a3398b14c4a719ff7f1cc6f231fc80f16e027 100644 (file)
@@ -495,11 +495,14 @@ static int mma9551_probe(struct i2c_client *client,
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(&client->dev, "unable to register iio device\n");
-               goto out_poweroff;
+               goto err_pm_cleanup;
        }
 
        return 0;
 
+err_pm_cleanup:
+       pm_runtime_dont_use_autosuspend(&client->dev);
+       pm_runtime_disable(&client->dev);
 out_poweroff:
        mma9551_set_device_state(client, false);
 
index 0570ab1cc0643699944f06178dc126d4776b1aec..5ff6bc70708b649e5cb213c62b79f345d0fa89e2 100644 (file)
@@ -1134,12 +1134,15 @@ static int mma9553_probe(struct i2c_client *client,
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(&client->dev, "unable to register iio device\n");
-               goto out_poweroff;
+               goto err_pm_cleanup;
        }
 
        dev_dbg(&indio_dev->dev, "Registered device %s\n", name);
        return 0;
 
+err_pm_cleanup:
+       pm_runtime_dont_use_autosuspend(&client->dev);
+       pm_runtime_disable(&client->dev);
 out_poweroff:
        mma9551_set_device_state(client, false);
        return ret;
index bc2cfa5f9592242ab02541d8f2b11eebc53a18df..b400bbe291aa4868f7c5155169ebac0f176beaeb 100644 (file)
@@ -76,7 +76,7 @@
 #define AD7124_CONFIG_REF_SEL(x)       FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x)
 #define AD7124_CONFIG_PGA_MSK          GENMASK(2, 0)
 #define AD7124_CONFIG_PGA(x)           FIELD_PREP(AD7124_CONFIG_PGA_MSK, x)
-#define AD7124_CONFIG_IN_BUFF_MSK      GENMASK(7, 6)
+#define AD7124_CONFIG_IN_BUFF_MSK      GENMASK(6, 5)
 #define AD7124_CONFIG_IN_BUFF(x)       FIELD_PREP(AD7124_CONFIG_IN_BUFF_MSK, x)
 
 /* AD7124_FILTER_X */
index 42ea8bc7e78051c16bc8f1dcd7546393c99153d5..adc5ceaef8c93a373daef26dbaded4d4be1904ca 100644 (file)
@@ -103,6 +103,7 @@ static int men_z188_probe(struct mcb_device *dev,
        struct z188_adc *adc;
        struct iio_dev *indio_dev;
        struct resource *mem;
+       int ret;
 
        indio_dev = devm_iio_device_alloc(&dev->dev, sizeof(struct z188_adc));
        if (!indio_dev)
@@ -128,8 +129,14 @@ static int men_z188_probe(struct mcb_device *dev,
        adc->mem = mem;
        mcb_set_drvdata(dev, indio_dev);
 
-       return iio_device_register(indio_dev);
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto err_unmap;
+
+       return 0;
 
+err_unmap:
+       iounmap(adc->base);
 err:
        mcb_release_mem(mem);
        return -ENXIO;
index d84ae6b008c1b024a55d4f1bf670e73ec20cd232..e8fc4d01f30b65cfa32fdbf9de2f190c0b4b7a87 100644 (file)
@@ -388,7 +388,7 @@ static int tsc2046_adc_update_scan_mode(struct iio_dev *indio_dev,
        mutex_lock(&priv->slock);
 
        size = 0;
-       for_each_set_bit(ch_idx, active_scan_mask, indio_dev->num_channels) {
+       for_each_set_bit(ch_idx, active_scan_mask, ARRAY_SIZE(priv->l)) {
                size += tsc2046_adc_group_set_layout(priv, group, ch_idx);
                tsc2046_adc_group_set_cmd(priv, group, ch_idx);
                group++;
@@ -548,7 +548,7 @@ static int tsc2046_adc_setup_spi_msg(struct tsc2046_adc_priv *priv)
         * enabled.
         */
        size = 0;
-       for (ch_idx = 0; ch_idx < priv->dcfg->num_channels; ch_idx++)
+       for (ch_idx = 0; ch_idx < ARRAY_SIZE(priv->l); ch_idx++)
                size += tsc2046_adc_group_set_layout(priv, ch_idx, ch_idx);
 
        priv->tx = devm_kzalloc(&priv->spi->dev, size, GFP_KERNEL);
index 5271073bb74e773dcef171bafc8fc504c6b1120e..acd230a6af35a726fe01ca53c5a5ab6ce2ea2def 100644 (file)
@@ -134,7 +134,6 @@ struct ad74413r_state {
 #define AD74413R_CH_EN_MASK(x)         BIT(x)
 
 #define AD74413R_REG_DIN_COMP_OUT              0x25
-#define AD74413R_DIN_COMP_OUT_SHIFT_X(x)       x
 
 #define AD74413R_REG_ADC_RESULT_X(x)   (0x26 + (x))
 #define AD74413R_ADC_RESULT_MAX                GENMASK(15, 0)
@@ -288,7 +287,7 @@ static void ad74413r_gpio_set_multiple(struct gpio_chip *chip,
        unsigned int offset = 0;
        int ret;
 
-       for_each_set_bit_from(offset, mask, AD74413R_CHANNEL_MAX) {
+       for_each_set_bit_from(offset, mask, chip->ngpio) {
                unsigned int real_offset = st->gpo_gpio_offsets[offset];
 
                ret = ad74413r_set_gpo_config(st, real_offset,
@@ -316,7 +315,7 @@ static int ad74413r_gpio_get(struct gpio_chip *chip, unsigned int offset)
        if (ret)
                return ret;
 
-       status &= AD74413R_DIN_COMP_OUT_SHIFT_X(real_offset);
+       status &= BIT(real_offset);
 
        return status ? 1 : 0;
 }
@@ -334,11 +333,10 @@ static int ad74413r_gpio_get_multiple(struct gpio_chip *chip,
        if (ret)
                return ret;
 
-       for_each_set_bit_from(offset, mask, AD74413R_CHANNEL_MAX) {
+       for_each_set_bit_from(offset, mask, chip->ngpio) {
                unsigned int real_offset = st->comp_gpio_offsets[offset];
 
-               if (val & BIT(real_offset))
-                       *bits |= offset;
+               __assign_bit(offset, bits, val & BIT(real_offset));
        }
 
        return ret;
@@ -840,7 +838,7 @@ static int ad74413r_update_scan_mode(struct iio_dev *indio_dev,
 {
        struct ad74413r_state *st = iio_priv(indio_dev);
        struct spi_transfer *xfer = st->adc_samples_xfer;
-       u8 *rx_buf = &st->adc_samples_buf.rx_buf[-1 * AD74413R_FRAME_SIZE];
+       u8 *rx_buf = st->adc_samples_buf.rx_buf;
        u8 *tx_buf = st->adc_samples_tx_buf;
        unsigned int channel;
        int ret = -EINVAL;
@@ -894,9 +892,10 @@ static int ad74413r_update_scan_mode(struct iio_dev *indio_dev,
 
                spi_message_add_tail(xfer, &st->adc_samples_msg);
 
-               xfer++;
                tx_buf += AD74413R_FRAME_SIZE;
-               rx_buf += AD74413R_FRAME_SIZE;
+               if (xfer != st->adc_samples_xfer)
+                       rx_buf += AD74413R_FRAME_SIZE;
+               xfer++;
        }
 
        xfer->rx_buf = rx_buf;
index 6cdeb50143afc504cdf66702a77d115870d84a33..3f3c478e9baab3041b118b58b48790ae914c2aba 100644 (file)
@@ -348,7 +348,7 @@ static int admv1013_update_mixer_vgate(struct admv1013_state *st)
 
        vcm = regulator_get_voltage(st->reg);
 
-       if (vcm >= 0 && vcm < 1800000)
+       if (vcm < 1800000)
                mixer_vgate = (2389 * vcm / 1000000 + 8100) / 100;
        else if (vcm > 1800000 && vcm < 2600000)
                mixer_vgate = (2375 * vcm / 1000000 + 125) / 100;
index 17b939a367ad049b78eeff14b033b1391d20c318..81a6d09788bd7c1ee7892c7f0b11293a34a74de2 100644 (file)
@@ -1188,11 +1188,14 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq,
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(dev, "unable to register iio device\n");
-               goto err_buffer_cleanup;
+               goto err_pm_cleanup;
        }
 
        return 0;
 
+err_pm_cleanup:
+       pm_runtime_dont_use_autosuspend(dev);
+       pm_runtime_disable(dev);
 err_buffer_cleanup:
        iio_triggered_buffer_cleanup(indio_dev);
 err_trigger_unregister:
index ed129321a14da1175bb29cfae062a90879056e2c..f9b4540db1f437944b785ded54c5ce809f613c4d 100644 (file)
@@ -1403,6 +1403,7 @@ static int adis16480_probe(struct spi_device *spi)
 {
        const struct spi_device_id *id = spi_get_device_id(spi);
        const struct adis_data *adis16480_data;
+       irq_handler_t trigger_handler = NULL;
        struct iio_dev *indio_dev;
        struct adis16480 *st;
        int ret;
@@ -1474,8 +1475,12 @@ static int adis16480_probe(struct spi_device *spi)
                st->clk_freq = st->chip_info->int_clk;
        }
 
+       /* Only use our trigger handler if burst mode is supported */
+       if (adis16480_data->burst_len)
+               trigger_handler = adis16480_trigger_handler;
+
        ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev,
-                                                adis16480_trigger_handler);
+                                                trigger_handler);
        if (ret)
                return ret;
 
index 1dabfd615dabff0ff71c34438497cbd94a6d1116..f89724481df9323ef520a41ed891b60c84134746 100644 (file)
@@ -1385,7 +1385,7 @@ static int kmx61_probe(struct i2c_client *client,
        ret = iio_device_register(data->acc_indio_dev);
        if (ret < 0) {
                dev_err(&client->dev, "Failed to register acc iio device\n");
-               goto err_buffer_cleanup_mag;
+               goto err_pm_cleanup;
        }
 
        ret = iio_device_register(data->mag_indio_dev);
@@ -1398,6 +1398,9 @@ static int kmx61_probe(struct i2c_client *client,
 
 err_iio_unregister_acc:
        iio_device_unregister(data->acc_indio_dev);
+err_pm_cleanup:
+       pm_runtime_dont_use_autosuspend(&client->dev);
+       pm_runtime_disable(&client->dev);
 err_buffer_cleanup_mag:
        if (client->irq > 0)
                iio_triggered_buffer_cleanup(data->mag_indio_dev);
index 727b4b6ac69663a7e9a435a2fa3405bbc3a415d6..93f0c6bce502cd59fab579f059bf4a2aac7f6fc7 100644 (file)
@@ -1374,8 +1374,12 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
        if (err < 0)
                return err;
 
+       /*
+        * we need to wait for sensor settling time before
+        * reading data in order to avoid corrupted samples
+        */
        delay = 1000000000 / sensor->odr;
-       usleep_range(delay, 2 * delay);
+       usleep_range(3 * delay, 4 * delay);
 
        err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
        if (err < 0)
index f96f531753495f9029b34fb6abf20f28f41781ef..3d4d21f979fab0ffcd570f7b503656bd39e8235d 100644 (file)
@@ -962,13 +962,14 @@ int bmc150_magn_probe(struct device *dev, struct regmap *regmap,
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(dev, "unable to register iio device\n");
-               goto err_disable_runtime_pm;
+               goto err_pm_cleanup;
        }
 
        dev_dbg(dev, "Registered device %s\n", name);
        return 0;
 
-err_disable_runtime_pm:
+err_pm_cleanup:
+       pm_runtime_dont_use_autosuspend(dev);
        pm_runtime_disable(dev);
 err_buffer_cleanup:
        iio_triggered_buffer_cleanup(indio_dev);
index c447526288f49e6614380d2635650d16c8621ece..50c53409ceb61bf6e992a979e0c262b322628ac1 100644 (file)
@@ -3370,22 +3370,30 @@ err:
 static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
                         const struct sockaddr *dst_addr)
 {
-       if (!src_addr || !src_addr->sa_family) {
-               src_addr = (struct sockaddr *) &id->route.addr.src_addr;
-               src_addr->sa_family = dst_addr->sa_family;
-               if (IS_ENABLED(CONFIG_IPV6) &&
-                   dst_addr->sa_family == AF_INET6) {
-                       struct sockaddr_in6 *src_addr6 = (struct sockaddr_in6 *) src_addr;
-                       struct sockaddr_in6 *dst_addr6 = (struct sockaddr_in6 *) dst_addr;
-                       src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id;
-                       if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
-                               id->route.addr.dev_addr.bound_dev_if = dst_addr6->sin6_scope_id;
-               } else if (dst_addr->sa_family == AF_IB) {
-                       ((struct sockaddr_ib *) src_addr)->sib_pkey =
-                               ((struct sockaddr_ib *) dst_addr)->sib_pkey;
-               }
-       }
-       return rdma_bind_addr(id, src_addr);
+       struct sockaddr_storage zero_sock = {};
+
+       if (src_addr && src_addr->sa_family)
+               return rdma_bind_addr(id, src_addr);
+
+       /*
+        * When the src_addr is not specified, automatically supply an any addr
+        */
+       zero_sock.ss_family = dst_addr->sa_family;
+       if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) {
+               struct sockaddr_in6 *src_addr6 =
+                       (struct sockaddr_in6 *)&zero_sock;
+               struct sockaddr_in6 *dst_addr6 =
+                       (struct sockaddr_in6 *)dst_addr;
+
+               src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id;
+               if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                       id->route.addr.dev_addr.bound_dev_if =
+                               dst_addr6->sin6_scope_id;
+       } else if (dst_addr->sa_family == AF_IB) {
+               ((struct sockaddr_ib *)&zero_sock)->sib_pkey =
+                       ((struct sockaddr_ib *)dst_addr)->sib_pkey;
+       }
+       return rdma_bind_addr(id, (struct sockaddr *)&zero_sock);
 }
 
 /*
index 0a3b28142c05b6b5d76910f310e2cdf79159ac5a..41c272980f91cc5e468fb17fb7161c8d0f542a8e 100644 (file)
@@ -541,7 +541,7 @@ static struct attribute *port_diagc_attributes[] = {
 };
 
 static const struct attribute_group port_diagc_group = {
-       .name = "linkcontrol",
+       .name = "diag_counters",
        .attrs = port_diagc_attributes,
 };
 
index 7c3f98e57889f82e735272593166650123791923..759b85f033315df4a608869072aeeba56bbae072 100644 (file)
@@ -2682,6 +2682,8 @@ static void rtrs_clt_dev_release(struct device *dev)
        struct rtrs_clt_sess *clt = container_of(dev, struct rtrs_clt_sess,
                                                 dev);
 
+       mutex_destroy(&clt->paths_ev_mutex);
+       mutex_destroy(&clt->paths_mutex);
        kfree(clt);
 }
 
@@ -2711,6 +2713,8 @@ static struct rtrs_clt_sess *alloc_clt(const char *sessname, size_t paths_num,
                return ERR_PTR(-ENOMEM);
        }
 
+       clt->dev.class = rtrs_clt_dev_class;
+       clt->dev.release = rtrs_clt_dev_release;
        uuid_gen(&clt->paths_uuid);
        INIT_LIST_HEAD_RCU(&clt->paths_list);
        clt->paths_num = paths_num;
@@ -2727,53 +2731,51 @@ static struct rtrs_clt_sess *alloc_clt(const char *sessname, size_t paths_num,
        init_waitqueue_head(&clt->permits_wait);
        mutex_init(&clt->paths_ev_mutex);
        mutex_init(&clt->paths_mutex);
+       device_initialize(&clt->dev);
 
-       clt->dev.class = rtrs_clt_dev_class;
-       clt->dev.release = rtrs_clt_dev_release;
        err = dev_set_name(&clt->dev, "%s", sessname);
        if (err)
-               goto err;
+               goto err_put;
+
        /*
         * Suppress user space notification until
         * sysfs files are created
         */
        dev_set_uevent_suppress(&clt->dev, true);
-       err = device_register(&clt->dev);
-       if (err) {
-               put_device(&clt->dev);
-               goto err;
-       }
+       err = device_add(&clt->dev);
+       if (err)
+               goto err_put;
 
        clt->kobj_paths = kobject_create_and_add("paths", &clt->dev.kobj);
        if (!clt->kobj_paths) {
                err = -ENOMEM;
-               goto err_dev;
+               goto err_del;
        }
        err = rtrs_clt_create_sysfs_root_files(clt);
        if (err) {
                kobject_del(clt->kobj_paths);
                kobject_put(clt->kobj_paths);
-               goto err_dev;
+               goto err_del;
        }
        dev_set_uevent_suppress(&clt->dev, false);
        kobject_uevent(&clt->dev.kobj, KOBJ_ADD);
 
        return clt;
-err_dev:
-       device_unregister(&clt->dev);
-err:
+err_del:
+       device_del(&clt->dev);
+err_put:
        free_percpu(clt->pcpu_path);
-       kfree(clt);
+       put_device(&clt->dev);
        return ERR_PTR(err);
 }
 
 static void free_clt(struct rtrs_clt_sess *clt)
 {
-       free_permits(clt);
        free_percpu(clt->pcpu_path);
-       mutex_destroy(&clt->paths_ev_mutex);
-       mutex_destroy(&clt->paths_mutex);
-       /* release callback will free clt in last put */
+
+       /*
+        * release callback will free clt and destroy mutexes in last put
+        */
        device_unregister(&clt->dev);
 }
 
@@ -2890,6 +2892,7 @@ void rtrs_clt_close(struct rtrs_clt_sess *clt)
                rtrs_clt_destroy_path_files(clt_path, NULL);
                kobject_put(&clt_path->kobj);
        }
+       free_permits(clt);
        free_clt(clt);
 }
 EXPORT_SYMBOL(rtrs_clt_close);
index e174e853f8a40cb9fa10ae71632dac50d663ae18..285b766e4e7049b11b776909c0ca470c5ad18cc8 100644 (file)
@@ -4047,9 +4047,11 @@ static void srp_remove_one(struct ib_device *device, void *client_data)
                spin_unlock(&host->target_lock);
 
                /*
-                * Wait for tl_err and target port removal tasks.
+                * srp_queue_remove_work() queues a call to
+                * srp_remove_target(). The latter function cancels
+                * target->tl_err_work so waiting for the remove works to
+                * finish is sufficient.
                 */
-               flush_workqueue(system_long_wq);
                flush_workqueue(srp_remove_wq);
 
                kfree(host);
index 0c607da9ee10d3f540e53e89da65306eb356a219..9417ee0b1eff8fd6c45883c89806eb2e9297c337 100644 (file)
@@ -556,7 +556,7 @@ config KEYBOARD_PMIC8XXX
 
 config KEYBOARD_SAMSUNG
        tristate "Samsung keypad support"
-       depends on HAVE_CLK
+       depends on HAS_IOMEM && HAVE_CLK
        select INPUT_MATRIXKMAP
        help
          Say Y here if you want to use the keypad on your Samsung mobile
index 47af62c122672256ec0d882fd22b2d9cf14f4ad0..e1758d5ffe421831f64a198daa5db33e920c3033 100644 (file)
@@ -186,55 +186,21 @@ static int elan_get_fwinfo(u16 ic_type, u8 iap_version, u16 *validpage_count,
        return 0;
 }
 
-static int elan_enable_power(struct elan_tp_data *data)
+static int elan_set_power(struct elan_tp_data *data, bool on)
 {
        int repeat = ETP_RETRY_COUNT;
        int error;
 
-       error = regulator_enable(data->vcc);
-       if (error) {
-               dev_err(&data->client->dev,
-                       "failed to enable regulator: %d\n", error);
-               return error;
-       }
-
        do {
-               error = data->ops->power_control(data->client, true);
+               error = data->ops->power_control(data->client, on);
                if (error >= 0)
                        return 0;
 
                msleep(30);
        } while (--repeat > 0);
 
-       dev_err(&data->client->dev, "failed to enable power: %d\n", error);
-       return error;
-}
-
-static int elan_disable_power(struct elan_tp_data *data)
-{
-       int repeat = ETP_RETRY_COUNT;
-       int error;
-
-       do {
-               error = data->ops->power_control(data->client, false);
-               if (!error) {
-                       error = regulator_disable(data->vcc);
-                       if (error) {
-                               dev_err(&data->client->dev,
-                                       "failed to disable regulator: %d\n",
-                                       error);
-                               /* Attempt to power the chip back up */
-                               data->ops->power_control(data->client, true);
-                               break;
-                       }
-
-                       return 0;
-               }
-
-               msleep(30);
-       } while (--repeat > 0);
-
-       dev_err(&data->client->dev, "failed to disable power: %d\n", error);
+       dev_err(&data->client->dev, "failed to set power %s: %d\n",
+               on ? "on" : "off", error);
        return error;
 }
 
@@ -1399,9 +1365,19 @@ static int __maybe_unused elan_suspend(struct device *dev)
                /* Enable wake from IRQ */
                data->irq_wake = (enable_irq_wake(client->irq) == 0);
        } else {
-               ret = elan_disable_power(data);
+               ret = elan_set_power(data, false);
+               if (ret)
+                       goto err;
+
+               ret = regulator_disable(data->vcc);
+               if (ret) {
+                       dev_err(dev, "error %d disabling regulator\n", ret);
+                       /* Attempt to power the chip back up */
+                       elan_set_power(data, true);
+               }
        }
 
+err:
        mutex_unlock(&data->sysfs_mutex);
        return ret;
 }
@@ -1412,12 +1388,18 @@ static int __maybe_unused elan_resume(struct device *dev)
        struct elan_tp_data *data = i2c_get_clientdata(client);
        int error;
 
-       if (device_may_wakeup(dev) && data->irq_wake) {
+       if (!device_may_wakeup(dev)) {
+               error = regulator_enable(data->vcc);
+               if (error) {
+                       dev_err(dev, "error %d enabling regulator\n", error);
+                       goto err;
+               }
+       } else if (data->irq_wake) {
                disable_irq_wake(client->irq);
                data->irq_wake = false;
        }
 
-       error = elan_enable_power(data);
+       error = elan_set_power(data, true);
        if (error) {
                dev_err(dev, "power up when resuming failed: %d\n", error);
                goto err;
index fcb1b646436a561458f00ba0620b608719ad968a..1581f6ef0927933118affc39a47a11870fc8aa1a 100644 (file)
@@ -1787,15 +1787,13 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
        input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
 
-       /* Verify that a device really has an endpoint */
-       if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
+       err = usb_find_common_endpoints(intf->cur_altsetting,
+                                       NULL, NULL, &endpoint, NULL);
+       if (err) {
                dev_err(&intf->dev,
-                       "interface has %d endpoints, but must have minimum 1\n",
-                       intf->cur_altsetting->desc.bNumEndpoints);
-               err = -EINVAL;
+                       "interface has no int in endpoints, but must have minimum 1\n");
                goto fail3;
        }
-       endpoint = &intf->cur_altsetting->endpoint[0].desc;
 
        /* Go set up our URB, which is called when the tablet receives
         * input.
index a3bfc7a4167974a5290da864abdff811a4f71ca1..752e8ba4fecb1c7c1c4dc3983d941fb47c606bd2 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/platform_data/x86/soc.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/of.h>
@@ -805,21 +806,6 @@ static int goodix_reset(struct goodix_ts_data *ts)
 }
 
 #ifdef ACPI_GPIO_SUPPORT
-#include <asm/cpu_device_id.h>
-#include <asm/intel-family.h>
-
-static const struct x86_cpu_id baytrail_cpu_ids[] = {
-       { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT, X86_FEATURE_ANY, },
-       {}
-};
-
-static inline bool is_byt(void)
-{
-       const struct x86_cpu_id *id = x86_match_cpu(baytrail_cpu_ids);
-
-       return !!id;
-}
-
 static const struct acpi_gpio_params first_gpio = { 0, 0, false };
 static const struct acpi_gpio_params second_gpio = { 1, 0, false };
 
@@ -878,7 +864,7 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
        const struct acpi_gpio_mapping *gpio_mapping = NULL;
        struct device *dev = &ts->client->dev;
        LIST_HEAD(resources);
-       int ret;
+       int irq, ret;
 
        ts->gpio_count = 0;
        ts->gpio_int_idx = -1;
@@ -891,6 +877,20 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
 
        acpi_dev_free_resource_list(&resources);
 
+       /*
+        * CHT devices should have a GpioInt + a regular GPIO ACPI resource.
+        * Some CHT devices have a bug (where the also is bogus Interrupt
+        * resource copied from a previous BYT based generation). i2c-core-acpi
+        * will use the non-working Interrupt resource, fix this up.
+        */
+       if (soc_intel_is_cht() && ts->gpio_count == 2 && ts->gpio_int_idx != -1) {
+               irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0);
+               if (irq > 0 && irq != ts->client->irq) {
+                       dev_warn(dev, "Overriding IRQ %d -> %d\n", ts->client->irq, irq);
+                       ts->client->irq = irq;
+               }
+       }
+
        if (ts->gpio_count == 2 && ts->gpio_int_idx == 0) {
                ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
                gpio_mapping = acpi_goodix_int_first_gpios;
@@ -903,7 +903,7 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
                dev_info(dev, "Using ACPI INTI and INTO methods for IRQ pin access\n");
                ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_METHOD;
                gpio_mapping = acpi_goodix_reset_only_gpios;
-       } else if (is_byt() && ts->gpio_count == 2 && ts->gpio_int_idx == -1) {
+       } else if (soc_intel_is_byt() && ts->gpio_count == 2 && ts->gpio_int_idx == -1) {
                dev_info(dev, "No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n");
                ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
                gpio_mapping = acpi_goodix_int_last_gpios;
index 129ebc810de87c11a1b62ab55b1b27b6af318734..8bd03278ad9a72b7700d07923965ef7794400fa0 100644 (file)
@@ -135,7 +135,7 @@ struct point_coord {
 
 struct touch_event {
        __le16  status;
-       u8      finger_cnt;
+       u8      finger_mask;
        u8      time_stamp;
        struct point_coord point_coord[MAX_SUPPORTED_FINGER_NUM];
 };
@@ -322,11 +322,32 @@ static int zinitix_send_power_on_sequence(struct bt541_ts_data *bt541)
 static void zinitix_report_finger(struct bt541_ts_data *bt541, int slot,
                                  const struct point_coord *p)
 {
+       u16 x, y;
+
+       if (unlikely(!(p->sub_status &
+                      (SUB_BIT_UP | SUB_BIT_DOWN | SUB_BIT_MOVE)))) {
+               dev_dbg(&bt541->client->dev, "unknown finger event %#02x\n",
+                       p->sub_status);
+               return;
+       }
+
+       x = le16_to_cpu(p->x);
+       y = le16_to_cpu(p->y);
+
        input_mt_slot(bt541->input_dev, slot);
-       input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER, true);
-       touchscreen_report_pos(bt541->input_dev, &bt541->prop,
-                              le16_to_cpu(p->x), le16_to_cpu(p->y), true);
-       input_report_abs(bt541->input_dev, ABS_MT_TOUCH_MAJOR, p->width);
+       if (input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER,
+                                      !(p->sub_status & SUB_BIT_UP))) {
+               touchscreen_report_pos(bt541->input_dev,
+                                      &bt541->prop, x, y, true);
+               input_report_abs(bt541->input_dev,
+                                ABS_MT_TOUCH_MAJOR, p->width);
+               dev_dbg(&bt541->client->dev, "finger %d %s (%u, %u)\n",
+                       slot, p->sub_status & SUB_BIT_DOWN ? "down" : "move",
+                       x, y);
+       } else {
+               dev_dbg(&bt541->client->dev, "finger %d up (%u, %u)\n",
+                       slot, x, y);
+       }
 }
 
 static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
@@ -334,6 +355,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
        struct bt541_ts_data *bt541 = bt541_handler;
        struct i2c_client *client = bt541->client;
        struct touch_event touch_event;
+       unsigned long finger_mask;
        int error;
        int i;
 
@@ -346,10 +368,14 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
                goto out;
        }
 
-       for (i = 0; i < MAX_SUPPORTED_FINGER_NUM; i++)
-               if (touch_event.point_coord[i].sub_status & SUB_BIT_EXIST)
-                       zinitix_report_finger(bt541, i,
-                                             &touch_event.point_coord[i]);
+       finger_mask = touch_event.finger_mask;
+       for_each_set_bit(i, &finger_mask, MAX_SUPPORTED_FINGER_NUM) {
+               const struct point_coord *p = &touch_event.point_coord[i];
+
+               /* Only process contacts that are actually reported */
+               if (p->sub_status & SUB_BIT_EXIST)
+                       zinitix_report_finger(bt541, i, p);
+       }
 
        input_mt_sync_frame(bt541->input_dev);
        input_sync(bt541->input_dev);
index 416815a525d671916a896297b67b28006bb03236..bb95edf74415b0a6806237ade2382c8090e1b465 100644 (file)
@@ -14,6 +14,7 @@
 extern irqreturn_t amd_iommu_int_thread(int irq, void *data);
 extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
 extern void amd_iommu_apply_erratum_63(u16 devid);
+extern void amd_iommu_restart_event_logging(struct amd_iommu *iommu);
 extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
 extern int amd_iommu_init_devices(void);
 extern void amd_iommu_uninit_devices(void);
index ffc89c4fb120511317c8496303946b6446f56941..47108ed44fbba5dbba19365891ea98b83df13da8 100644 (file)
 #define PASID_MASK             0x0000ffff
 
 /* MMIO status bits */
+#define MMIO_STATUS_EVT_OVERFLOW_INT_MASK      (1 << 0)
 #define MMIO_STATUS_EVT_INT_MASK       (1 << 1)
 #define MMIO_STATUS_COM_WAIT_INT_MASK  (1 << 2)
 #define MMIO_STATUS_PPR_INT_MASK       (1 << 6)
index b10fb52ea44288747e0d992385a7b656541d92b7..7bfe37e52e2100dbdf8c43134b226ffc4899417d 100644 (file)
@@ -657,6 +657,16 @@ static int __init alloc_command_buffer(struct amd_iommu *iommu)
        return iommu->cmd_buf ? 0 : -ENOMEM;
 }
 
+/*
+ * This function restarts event logging in case the IOMMU experienced
+ * an event log buffer overflow.
+ */
+void amd_iommu_restart_event_logging(struct amd_iommu *iommu)
+{
+       iommu_feature_disable(iommu, CONTROL_EVT_LOG_EN);
+       iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN);
+}
+
 /*
  * This function resets the command buffer if the IOMMU stopped fetching
  * commands from it.
index b1bf4125b0f7e32c0a1f7f17efe1b5d4f45eb583..6608d171757445e3d90030bd04b5c55ec3d4fe1c 100644 (file)
@@ -492,18 +492,18 @@ static void v1_free_pgtable(struct io_pgtable *iop)
 
        dom = container_of(pgtable, struct protection_domain, iop);
 
-       /* Update data structure */
-       amd_iommu_domain_clr_pt_root(dom);
-
-       /* Make changes visible to IOMMUs */
-       amd_iommu_domain_update(dom);
-
        /* Page-table is not visible to IOMMU anymore, so free it */
        BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
               pgtable->mode > PAGE_MODE_6_LEVEL);
 
        free_sub_pt(pgtable->root, pgtable->mode, &freelist);
 
+       /* Update data structure */
+       amd_iommu_domain_clr_pt_root(dom);
+
+       /* Make changes visible to IOMMUs */
+       amd_iommu_domain_update(dom);
+
        put_pages_list(&freelist);
 }
 
index 461f1844ed1fbd6f7904055ab7d4facc9bf90982..a18b549951bb899c0c7cd30e1c56a4a565e3c0a8 100644 (file)
@@ -764,7 +764,8 @@ amd_iommu_set_pci_msi_domain(struct device *dev, struct amd_iommu *iommu) { }
 #endif /* !CONFIG_IRQ_REMAP */
 
 #define AMD_IOMMU_INT_MASK     \
-       (MMIO_STATUS_EVT_INT_MASK | \
+       (MMIO_STATUS_EVT_OVERFLOW_INT_MASK | \
+        MMIO_STATUS_EVT_INT_MASK | \
         MMIO_STATUS_PPR_INT_MASK | \
         MMIO_STATUS_GALOG_INT_MASK)
 
@@ -774,7 +775,7 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)
        u32 status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
 
        while (status & AMD_IOMMU_INT_MASK) {
-               /* Enable EVT and PPR and GA interrupts again */
+               /* Enable interrupt sources again */
                writel(AMD_IOMMU_INT_MASK,
                        iommu->mmio_base + MMIO_STATUS_OFFSET);
 
@@ -795,6 +796,11 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)
                }
 #endif
 
+               if (status & MMIO_STATUS_EVT_OVERFLOW_INT_MASK) {
+                       pr_info_ratelimited("IOMMU event log overflow\n");
+                       amd_iommu_restart_event_logging(iommu);
+               }
+
                /*
                 * Hardware bug: ERBT1312
                 * When re-enabling interrupt (by writing 1
index 92fea3fbbb114549888da4bec1900eafc44e1369..5b196cfe9ed236f24f6101ef75be4f401a69be77 100644 (file)
@@ -2738,7 +2738,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
        spin_unlock_irqrestore(&device_domain_lock, flags);
 
        /* PASID table is mandatory for a PCI device in scalable mode. */
-       if (dev && dev_is_pci(dev) && sm_supported(iommu)) {
+       if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
                ret = intel_pasid_alloc_table(dev);
                if (ret) {
                        dev_err(dev, "PASID table allocation failed\n");
index e900e3c46903b1b909d07ae7000b3cad99f0326f..2561ce8a2ce8f0cb05701623ed751c0805264222 100644 (file)
@@ -808,8 +808,10 @@ static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
                return NULL;
 
        mc = platform_get_drvdata(pdev);
-       if (!mc)
+       if (!mc) {
+               put_device(&pdev->dev);
                return NULL;
+       }
 
        return mc->smmu;
 }
index 38091ebb940330675c306df56c1e5adc4a893682..b40199c6625e3f14a8c61717f4da9676557b6c5a 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/limits.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
+#include <asm/apple_m1_pmu.h>
 #include <asm/exception.h>
 #include <asm/sysreg.h>
 #include <asm/virt.h>
  * Note: sysreg-based IPIs are not supported yet.
  */
 
-/* Core PMC control register */
-#define SYS_IMP_APL_PMCR0_EL1          sys_reg(3, 1, 15, 0, 0)
-#define PMCR0_IMODE                    GENMASK(10, 8)
-#define PMCR0_IMODE_OFF                        0
-#define PMCR0_IMODE_PMI                        1
-#define PMCR0_IMODE_AIC                        2
-#define PMCR0_IMODE_HALT               3
-#define PMCR0_IMODE_FIQ                        4
-#define PMCR0_IACT                     BIT(11)
-
 /* IPI request registers */
 #define SYS_IMP_APL_IPI_RR_LOCAL_EL1   sys_reg(3, 5, 15, 0, 0)
 #define SYS_IMP_APL_IPI_RR_GLOBAL_EL1  sys_reg(3, 5, 15, 0, 1)
 #define SYS_IMP_APL_UPMSR_EL1          sys_reg(3, 7, 15, 6, 4)
 #define UPMSR_IACT                     BIT(0)
 
-#define AIC_NR_FIQ             4
+#define AIC_NR_FIQ             6
 #define AIC_NR_SWIPI           32
 
 /*
@@ -177,6 +168,9 @@ struct aic_irq_chip {
        void __iomem *base;
        struct irq_domain *hw_domain;
        struct irq_domain *ipi_domain;
+       struct {
+               cpumask_t aff;
+       } *fiq_aff[AIC_NR_FIQ];
        int nr_hw;
 };
 
@@ -412,16 +406,15 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
                                                  aic_irqc->nr_hw + AIC_TMR_EL02_VIRT);
        }
 
-       if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) ==
-                       (FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {
-               /*
-                * Not supported yet, let's figure out how to handle this when
-                * we implement these proprietary performance counters. For now,
-                * just mask it and move on.
-                */
-               pr_err_ratelimited("PMC FIQ fired. Masking.\n");
-               sysreg_clear_set_s(SYS_IMP_APL_PMCR0_EL1, PMCR0_IMODE | PMCR0_IACT,
-                                  FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
+       if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) {
+               int irq;
+               if (cpumask_test_cpu(smp_processor_id(),
+                                    &aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff))
+                       irq = AIC_CPU_PMU_P;
+               else
+                       irq = AIC_CPU_PMU_E;
+               generic_handle_domain_irq(aic_irqc->hw_domain,
+                                         aic_irqc->nr_hw + irq);
        }
 
        if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ &&
@@ -461,7 +454,18 @@ static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
                                    handle_fasteoi_irq, NULL, NULL);
                irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
        } else {
-               irq_set_percpu_devid(irq);
+               int fiq = hw - ic->nr_hw;
+
+               switch (fiq) {
+               case AIC_CPU_PMU_P:
+               case AIC_CPU_PMU_E:
+                       irq_set_percpu_devid_partition(irq, &ic->fiq_aff[fiq]->aff);
+                       break;
+               default:
+                       irq_set_percpu_devid(irq);
+                       break;
+               }
+
                irq_domain_set_info(id, irq, hw, &fiq_chip, id->host_data,
                                    handle_percpu_devid_irq, NULL, NULL);
        }
@@ -793,12 +797,50 @@ static struct gic_kvm_info vgic_info __initdata = {
        .no_hw_deactivation     = true,
 };
 
+static void build_fiq_affinity(struct aic_irq_chip *ic, struct device_node *aff)
+{
+       int i, n;
+       u32 fiq;
+
+       if (of_property_read_u32(aff, "apple,fiq-index", &fiq) ||
+           WARN_ON(fiq >= AIC_NR_FIQ) || ic->fiq_aff[fiq])
+               return;
+
+       n = of_property_count_elems_of_size(aff, "cpus", sizeof(u32));
+       if (WARN_ON(n < 0))
+               return;
+
+       ic->fiq_aff[fiq] = kzalloc(sizeof(ic->fiq_aff[fiq]), GFP_KERNEL);
+       if (!ic->fiq_aff[fiq])
+               return;
+
+       for (i = 0; i < n; i++) {
+               struct device_node *cpu_node;
+               u32 cpu_phandle;
+               int cpu;
+
+               if (of_property_read_u32_index(aff, "cpus", i, &cpu_phandle))
+                       continue;
+
+               cpu_node = of_find_node_by_phandle(cpu_phandle);
+               if (WARN_ON(!cpu_node))
+                       continue;
+
+               cpu = of_cpu_node_to_id(cpu_node);
+               if (WARN_ON(cpu < 0))
+                       continue;
+
+               cpumask_set_cpu(cpu, &ic->fiq_aff[fiq]->aff);
+       }
+}
+
 static int __init aic_of_ic_init(struct device_node *node, struct device_node *parent)
 {
        int i;
        void __iomem *regs;
        u32 info;
        struct aic_irq_chip *irqc;
+       struct device_node *affs;
 
        regs = of_iomap(node, 0);
        if (WARN_ON(!regs))
@@ -832,6 +874,14 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
                return -ENODEV;
        }
 
+       affs = of_get_child_by_name(node, "affinities");
+       if (affs) {
+               struct device_node *chld;
+
+               for_each_child_of_node(affs, chld)
+                       build_fiq_affinity(irqc, chld);
+       }
+
        set_handle_irq(aic_handle_irq);
        set_handle_fiq(aic_handle_fiq);
 
index bd087cca1c1d2d0aca56d7479598d0c2f50c228b..af17459c1a5c02d847d801be97f72605c1870e51 100644 (file)
@@ -2005,7 +2005,11 @@ setup_hw(struct hfc_pci *hc)
        }
        /* Allocate memory for FIFOS */
        /* the memory needs to be on a 32k boundary within the first 4G */
-       dma_set_mask(&hc->pdev->dev, 0xFFFF8000);
+       if (dma_set_mask(&hc->pdev->dev, 0xFFFF8000)) {
+               printk(KERN_WARNING
+                      "HFC-PCI: No usable DMA configuration!\n");
+               return -EIO;
+       }
        buffer = dma_alloc_coherent(&hc->pdev->dev, 0x8000, &hc->hw.dmahandle,
                                    GFP_KERNEL);
        /* We silently assume the address is okay if nonzero */
index e11ca6bbc7f41d559ace1fabfa1f0527b7e32318..c3b2c99b5cd5ceaf12c9fc7dcd929840ec6b3870 100644 (file)
@@ -192,7 +192,7 @@ void dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
 int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
 {
        int found = 0;
-       char *dup, *tok, *name, *args;
+       char *dup, *next, *tok, *name, *args;
        struct dsp_element_entry *entry, *n;
        struct dsp_pipeline_entry *pipeline_entry;
        struct mISDN_dsp_element *elem;
@@ -203,10 +203,10 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
        if (!list_empty(&pipeline->list))
                _dsp_pipeline_destroy(pipeline);
 
-       dup = kstrdup(cfg, GFP_ATOMIC);
+       dup = next = kstrdup(cfg, GFP_ATOMIC);
        if (!dup)
                return 0;
-       while ((tok = strsep(&dup, "|"))) {
+       while ((tok = strsep(&next, "|"))) {
                if (!strlen(tok))
                        continue;
                name = strsep(&tok, "(");
index 8d718aa56d33e68ea81ca3d032f002d78cdc236d..4e67c1403cc93bb48302fe8747deec8a7195cea8 100644 (file)
@@ -1908,7 +1908,7 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req)
 
        cb_data.card = card;
        cb_data.status = 0;
-       err = __mmc_poll_for_busy(card->host, MMC_BLK_TIMEOUT_MS,
+       err = __mmc_poll_for_busy(card->host, 0, MMC_BLK_TIMEOUT_MS,
                                  &mmc_blk_busy_cb, &cb_data);
 
        /*
index bbbbcaf70a5951c14147cd985a690371d9369ce0..8421519c2a98311c530015fa631a5944ceee0fd6 100644 (file)
@@ -1962,7 +1962,7 @@ static int mmc_sleep(struct mmc_host *host)
                goto out_release;
        }
 
-       err = __mmc_poll_for_busy(host, timeout_ms, &mmc_sleep_busy_cb, host);
+       err = __mmc_poll_for_busy(host, 0, timeout_ms, &mmc_sleep_busy_cb, host);
 
 out_release:
        mmc_retune_release(host);
index d63d1c735335c21b8ca7261066b7330c0b2b2710..180d7e9d3400a5305b3d5d9b416b9f0942212762 100644 (file)
@@ -21,6 +21,8 @@
 
 #define MMC_BKOPS_TIMEOUT_MS           (120 * 1000) /* 120s */
 #define MMC_SANITIZE_TIMEOUT_MS                (240 * 1000) /* 240s */
+#define MMC_OP_COND_PERIOD_US          (1 * 1000) /* 1ms */
+#define MMC_OP_COND_TIMEOUT_MS         1000 /* 1s */
 
 static const u8 tuning_blk_pattern_4bit[] = {
        0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
@@ -232,7 +234,9 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
        cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
-       err = __mmc_poll_for_busy(host, 1000, &__mmc_send_op_cond_cb, &cb_data);
+       err = __mmc_poll_for_busy(host, MMC_OP_COND_PERIOD_US,
+                                 MMC_OP_COND_TIMEOUT_MS,
+                                 &__mmc_send_op_cond_cb, &cb_data);
        if (err)
                return err;
 
@@ -495,13 +499,14 @@ static int mmc_busy_cb(void *cb_data, bool *busy)
        return 0;
 }
 
-int __mmc_poll_for_busy(struct mmc_host *host, unsigned int timeout_ms,
+int __mmc_poll_for_busy(struct mmc_host *host, unsigned int period_us,
+                       unsigned int timeout_ms,
                        int (*busy_cb)(void *cb_data, bool *busy),
                        void *cb_data)
 {
        int err;
        unsigned long timeout;
-       unsigned int udelay = 32, udelay_max = 32768;
+       unsigned int udelay = period_us ? period_us : 32, udelay_max = 32768;
        bool expired = false;
        bool busy = false;
 
@@ -546,7 +551,7 @@ int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
        cb_data.retry_crc_err = retry_crc_err;
        cb_data.busy_cmd = busy_cmd;
 
-       return __mmc_poll_for_busy(host, timeout_ms, &mmc_busy_cb, &cb_data);
+       return __mmc_poll_for_busy(host, 0, timeout_ms, &mmc_busy_cb, &cb_data);
 }
 EXPORT_SYMBOL_GPL(mmc_poll_for_busy);
 
index 9c813b851d0b12dee2aac6afdfa439dce57b7be3..09ffbc00908bb78931e7b9596a500e591df7e43d 100644 (file)
@@ -41,7 +41,8 @@ int mmc_can_ext_csd(struct mmc_card *card);
 int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
 bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd,
                          unsigned int timeout_ms);
-int __mmc_poll_for_busy(struct mmc_host *host, unsigned int timeout_ms,
+int __mmc_poll_for_busy(struct mmc_host *host, unsigned int period_us,
+                       unsigned int timeout_ms,
                        int (*busy_cb)(void *cb_data, bool *busy),
                        void *cb_data);
 int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
index bd87012c220c2b04d2b2faee9449f76cef2f13de..bfbfed30dc4d81061ec22239ee455b5fea52442c 100644 (file)
@@ -1672,7 +1672,7 @@ static int sd_poweroff_notify(struct mmc_card *card)
 
        cb_data.card = card;
        cb_data.reg_buf = reg_buf;
-       err = __mmc_poll_for_busy(card->host, SD_POWEROFF_NOTIFY_TIMEOUT_MS,
+       err = __mmc_poll_for_busy(card->host, 0, SD_POWEROFF_NOTIFY_TIMEOUT_MS,
                                  &sd_busy_poweroff_notify_cb, &cb_data);
 
 out:
index 8f36536cb1b6d0d33242e9287104851e95b92bf0..58ab9d90bc8b9f3ba63518dbd2d954e38277e599 100644 (file)
@@ -173,6 +173,8 @@ struct meson_host {
        int irq;
 
        bool vqmmc_enabled;
+       bool needs_pre_post_req;
+
 };
 
 #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
@@ -663,6 +665,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
        struct meson_host *host = mmc_priv(mmc);
 
        host->cmd = NULL;
+       if (host->needs_pre_post_req)
+               meson_mmc_post_req(mmc, mrq, 0);
        mmc_request_done(host->mmc, mrq);
 }
 
@@ -880,7 +884,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data
 static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
        struct meson_host *host = mmc_priv(mmc);
-       bool needs_pre_post_req = mrq->data &&
+       host->needs_pre_post_req = mrq->data &&
                        !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
 
        /*
@@ -896,22 +900,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
                }
        }
 
-       if (needs_pre_post_req) {
+       if (host->needs_pre_post_req) {
                meson_mmc_get_transfer_mode(mmc, mrq);
                if (!meson_mmc_desc_chain_mode(mrq->data))
-                       needs_pre_post_req = false;
+                       host->needs_pre_post_req = false;
        }
 
-       if (needs_pre_post_req)
+       if (host->needs_pre_post_req)
                meson_mmc_pre_req(mmc, mrq);
 
        /* Stop execution */
        writel(0, host->regs + SD_EMMC_START);
 
        meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
-
-       if (needs_pre_post_req)
-               meson_mmc_post_req(mmc, mrq, 0);
 }
 
 static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
index 70f492dce15892aa30020f019e1db63fffec7596..eef87b28d6c843120434fbf41d763ca057611ada 100644 (file)
@@ -546,6 +546,7 @@ static int mtd_nvmem_add(struct mtd_info *mtd)
        config.stride = 1;
        config.read_only = true;
        config.root_only = true;
+       config.ignore_wp = true;
        config.no_of_node = !of_device_is_compatible(node, "nvmem-cells");
        config.priv = mtd;
 
@@ -833,6 +834,7 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd,
        config.owner = THIS_MODULE;
        config.type = NVMEM_TYPE_OTP;
        config.root_only = true;
+       config.ignore_wp = true;
        config.reg_read = reg_read;
        config.size = size;
        config.of_node = np;
index d986ab4e4c35fd366650e8f43fbaf4ff79372893..820e5dc3bc9b4a8a9ec1741af2d81fc44a710bc7 100644 (file)
@@ -42,8 +42,7 @@ config MTD_NAND_OMAP2
        tristate "OMAP2, OMAP3, OMAP4 and Keystone NAND controller"
        depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
        depends on HAS_IOMEM
-       select MEMORY
-       select OMAP_GPMC
+       depends on OMAP_GPMC
        help
          Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4
          and Keystone platforms.
index 6382e1937cca2e10b4c335bece56f8e84fe860bc..c580acb8b1d34e75a87c079a6a17e3f395b62878 100644 (file)
@@ -138,6 +138,9 @@ static int com20020pci_probe(struct pci_dev *pdev,
                return -ENOMEM;
 
        ci = (struct com20020_pci_card_info *)id->driver_data;
+       if (!ci)
+               return -EINVAL;
+
        priv->ci = ci;
        mm = &ci->misc_map;
 
index b7dc1c32875f21ef2ed21c19b107b820b18e0be5..acd74725831f2c03d649d815412323be90d905f4 100644 (file)
@@ -1715,15 +1715,15 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
 
        netif_napi_add(ndev, &priv->napi, rcar_canfd_rx_poll,
                       RCANFD_NAPI_WEIGHT);
+       spin_lock_init(&priv->tx_lock);
+       devm_can_led_init(ndev);
+       gpriv->ch[priv->channel] = priv;
        err = register_candev(ndev);
        if (err) {
                dev_err(&pdev->dev,
                        "register_candev() failed, error %d\n", err);
                goto fail_candev;
        }
-       spin_lock_init(&priv->tx_lock);
-       devm_can_led_init(ndev);
-       gpriv->ch[priv->channel] = priv;
        dev_info(&pdev->dev, "device registered (channel %u)\n", priv->channel);
        return 0;
 
index 2ed2370a316673e6812ffb3976b17fa58430505b..2d73ebbf38364b7320760fdf22f2e98708a349f8 100644 (file)
@@ -1787,7 +1787,7 @@ static int es58x_open(struct net_device *netdev)
        struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev;
        int ret;
 
-       if (atomic_inc_return(&es58x_dev->opened_channel_cnt) == 1) {
+       if (!es58x_dev->opened_channel_cnt) {
                ret = es58x_alloc_rx_urbs(es58x_dev);
                if (ret)
                        return ret;
@@ -1805,12 +1805,13 @@ static int es58x_open(struct net_device *netdev)
        if (ret)
                goto free_urbs;
 
+       es58x_dev->opened_channel_cnt++;
        netif_start_queue(netdev);
 
        return ret;
 
  free_urbs:
-       if (atomic_dec_and_test(&es58x_dev->opened_channel_cnt))
+       if (!es58x_dev->opened_channel_cnt)
                es58x_free_urbs(es58x_dev);
        netdev_err(netdev, "%s: Could not open the network device: %pe\n",
                   __func__, ERR_PTR(ret));
@@ -1845,7 +1846,8 @@ static int es58x_stop(struct net_device *netdev)
 
        es58x_flush_pending_tx_msg(netdev);
 
-       if (atomic_dec_and_test(&es58x_dev->opened_channel_cnt))
+       es58x_dev->opened_channel_cnt--;
+       if (!es58x_dev->opened_channel_cnt)
                es58x_free_urbs(es58x_dev);
 
        return 0;
@@ -2215,7 +2217,6 @@ static struct es58x_device *es58x_init_es58x_dev(struct usb_interface *intf,
        init_usb_anchor(&es58x_dev->tx_urbs_idle);
        init_usb_anchor(&es58x_dev->tx_urbs_busy);
        atomic_set(&es58x_dev->tx_urbs_idle_cnt, 0);
-       atomic_set(&es58x_dev->opened_channel_cnt, 0);
        usb_set_intfdata(intf, es58x_dev);
 
        es58x_dev->rx_pipe = usb_rcvbulkpipe(es58x_dev->udev,
index 826a15871573a754a55069cc8f201b70f7f0597e..e5033cb5e6959f53e52c562cc5f289a59a238baa 100644 (file)
@@ -373,8 +373,6 @@ struct es58x_operators {
  *     queue wake/stop logic should prevent this URB from getting
  *     empty. Please refer to es58x_get_tx_urb() for more details.
  * @tx_urbs_idle_cnt: number of urbs in @tx_urbs_idle.
- * @opened_channel_cnt: number of channels opened (c.f. es58x_open()
- *     and es58x_stop()).
  * @ktime_req_ns: kernel timestamp when es58x_set_realtime_diff_ns()
  *     was called.
  * @realtime_diff_ns: difference in nanoseconds between the clocks of
@@ -384,6 +382,10 @@ struct es58x_operators {
  *     in RX branches.
  * @rx_max_packet_size: Maximum length of bulk-in URB.
  * @num_can_ch: Number of CAN channel (i.e. number of elements of @netdev).
+ * @opened_channel_cnt: number of channels opened. Free of race
+ *     conditions because its two users (net_device_ops:ndo_open()
+ *     and net_device_ops:ndo_close()) guarantee that the network
+ *     stack big kernel lock (a.k.a. rtnl_mutex) is being hold.
  * @rx_cmd_buf_len: Length of @rx_cmd_buf.
  * @rx_cmd_buf: The device might split the URB commands in an
  *     arbitrary amount of pieces. This buffer is used to concatenate
@@ -406,7 +408,6 @@ struct es58x_device {
        struct usb_anchor tx_urbs_busy;
        struct usb_anchor tx_urbs_idle;
        atomic_t tx_urbs_idle_cnt;
-       atomic_t opened_channel_cnt;
 
        u64 ktime_req_ns;
        s64 realtime_diff_ns;
@@ -415,6 +416,7 @@ struct es58x_device {
 
        u16 rx_max_packet_size;
        u8 num_can_ch;
+       u8 opened_channel_cnt;
 
        u16 rx_cmd_buf_len;
        union es58x_urb_cmd rx_cmd_buf;
index b487e3fe770ae2bb6b4c73e9b4a25c3f51e71dad..d35749fad1efae8eb36bbaaa6a5123268ab19b83 100644 (file)
@@ -191,8 +191,8 @@ struct gs_can {
 struct gs_usb {
        struct gs_can *canch[GS_MAX_INTF];
        struct usb_anchor rx_submitted;
-       atomic_t active_channels;
        struct usb_device *udev;
+       u8 active_channels;
 };
 
 /* 'allocate' a tx context.
@@ -589,7 +589,7 @@ static int gs_can_open(struct net_device *netdev)
        if (rc)
                return rc;
 
-       if (atomic_add_return(1, &parent->active_channels) == 1) {
+       if (!parent->active_channels) {
                for (i = 0; i < GS_MAX_RX_URBS; i++) {
                        struct urb *urb;
                        u8 *buf;
@@ -690,6 +690,7 @@ static int gs_can_open(struct net_device *netdev)
 
        dev->can.state = CAN_STATE_ERROR_ACTIVE;
 
+       parent->active_channels++;
        if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
                netif_start_queue(netdev);
 
@@ -705,7 +706,8 @@ static int gs_can_close(struct net_device *netdev)
        netif_stop_queue(netdev);
 
        /* Stop polling */
-       if (atomic_dec_and_test(&parent->active_channels))
+       parent->active_channels--;
+       if (!parent->active_channels)
                usb_kill_anchored_urbs(&parent->rx_submitted);
 
        /* Stop sending URBs */
@@ -984,8 +986,6 @@ static int gs_usb_probe(struct usb_interface *intf,
 
        init_usb_anchor(&dev->rx_submitted);
 
-       atomic_set(&dev->active_channels, 0);
-
        usb_set_intfdata(intf, dev);
        dev->udev = interface_to_usbdev(intf);
 
index 866767b70d65bbc0097c748d81c7b8e463c0966c..b0a7dee27ffc983f7df7f2aea6fcc9e67c8ceccf 100644 (file)
@@ -124,12 +124,23 @@ static const struct of_device_id ksz8795_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, ksz8795_dt_ids);
 
+static const struct spi_device_id ksz8795_spi_ids[] = {
+       { "ksz8765" },
+       { "ksz8794" },
+       { "ksz8795" },
+       { "ksz8863" },
+       { "ksz8873" },
+       { },
+};
+MODULE_DEVICE_TABLE(spi, ksz8795_spi_ids);
+
 static struct spi_driver ksz8795_spi_driver = {
        .driver = {
                .name   = "ksz8795-switch",
                .owner  = THIS_MODULE,
                .of_match_table = of_match_ptr(ksz8795_dt_ids),
        },
+       .id_table = ksz8795_spi_ids,
        .probe  = ksz8795_spi_probe,
        .remove = ksz8795_spi_remove,
        .shutdown = ksz8795_spi_shutdown,
index e3cb0e6c9f6f2cbcb032b3b128d7aa0388552a39..43addeabfc25911c93c05ae6c667430dc55ab37a 100644 (file)
@@ -98,12 +98,24 @@ static const struct of_device_id ksz9477_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);
 
+static const struct spi_device_id ksz9477_spi_ids[] = {
+       { "ksz9477" },
+       { "ksz9897" },
+       { "ksz9893" },
+       { "ksz9563" },
+       { "ksz8563" },
+       { "ksz9567" },
+       { },
+};
+MODULE_DEVICE_TABLE(spi, ksz9477_spi_ids);
+
 static struct spi_driver ksz9477_spi_driver = {
        .driver = {
                .name   = "ksz9477-switch",
                .owner  = THIS_MODULE,
                .of_match_table = of_match_ptr(ksz9477_dt_ids),
        },
+       .id_table = ksz9477_spi_ids,
        .probe  = ksz9477_spi_probe,
        .remove = ksz9477_spi_remove,
        .shutdown = ksz9477_spi_shutdown,
index 55dbda04ea6289d5a8d1db95403830140044452f..243f8ad6d06efc10b98d25933493a90a7711a3fb 100644 (file)
@@ -26,7 +26,7 @@ void ksz_update_port_member(struct ksz_device *dev, int port)
        struct dsa_switch *ds = dev->ds;
        u8 port_member = 0, cpu_port;
        const struct dsa_port *dp;
-       int i;
+       int i, j;
 
        if (!dsa_is_user_port(ds, port))
                return;
@@ -45,13 +45,33 @@ void ksz_update_port_member(struct ksz_device *dev, int port)
                        continue;
                if (!dsa_port_bridge_same(dp, other_dp))
                        continue;
+               if (other_p->stp_state != BR_STATE_FORWARDING)
+                       continue;
 
-               if (other_p->stp_state == BR_STATE_FORWARDING &&
-                   p->stp_state == BR_STATE_FORWARDING) {
+               if (p->stp_state == BR_STATE_FORWARDING) {
                        val |= BIT(port);
                        port_member |= BIT(i);
                }
 
+               /* Retain port [i]'s relationship to other ports than [port] */
+               for (j = 0; j < ds->num_ports; j++) {
+                       const struct dsa_port *third_dp;
+                       struct ksz_port *third_p;
+
+                       if (j == i)
+                               continue;
+                       if (j == port)
+                               continue;
+                       if (!dsa_is_user_port(ds, j))
+                               continue;
+                       third_p = &dev->ports[j];
+                       if (third_p->stp_state != BR_STATE_FORWARDING)
+                               continue;
+                       third_dp = dsa_to_port(ds, j);
+                       if (dsa_port_bridge_same(other_dp, third_dp))
+                               val |= BIT(j);
+               }
+
                dev->dev_ops->cfg_port_member(dev, i, val | cpu_port);
        }
 
index ff3c267d0f268cbc46658763a75802eb8645c2ff..a251bc55727ff180d65beca59085f0337fdde908 100644 (file)
@@ -2936,7 +2936,7 @@ mt753x_phylink_validate(struct dsa_switch *ds, int port,
 
        phylink_set_port_modes(mask);
 
-       if (state->interface != PHY_INTERFACE_MODE_TRGMII ||
+       if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
            !phy_interface_mode_is_8023z(state->interface)) {
                phylink_set(mask, 10baseT_Half);
                phylink_set(mask, 10baseT_Full);
index e320cccba61a6821e4f668990529974b35481d0e..90cd7bdf06f5d92b8e420eceab33c0e2c680834b 100644 (file)
@@ -405,12 +405,12 @@ static int mcf8390_init(struct net_device *dev)
 static int mcf8390_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
-       struct resource *mem, *irq;
+       struct resource *mem;
        resource_size_t msize;
-       int ret;
+       int ret, irq;
 
-       irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (irq == NULL) {
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
                dev_err(&pdev->dev, "no IRQ specified?\n");
                return -ENXIO;
        }
@@ -433,7 +433,7 @@ static int mcf8390_probe(struct platform_device *pdev)
        SET_NETDEV_DEV(dev, &pdev->dev);
        platform_set_drvdata(pdev, dev);
 
-       dev->irq = irq->start;
+       dev->irq = irq;
        dev->base_addr = mem->start;
 
        ret = mcf8390_init(dev);
index 9acf589b1178bbe994c136dea2185add417c02ac..87f40c2ba90404111dfbadb5c03cec117fee5486 100644 (file)
@@ -132,6 +132,7 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
 {
        struct arc_emac_mdio_bus_data *data = &priv->bus_data;
        struct device_node *np = priv->dev->of_node;
+       const char *name = "Synopsys MII Bus";
        struct mii_bus *bus;
        int error;
 
@@ -142,7 +143,7 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
        priv->bus = bus;
        bus->priv = priv;
        bus->parent = priv->dev;
-       bus->name = "Synopsys MII Bus";
+       bus->name = name;
        bus->read = &arc_mdio_read;
        bus->write = &arc_mdio_write;
        bus->reset = &arc_mdio_reset;
@@ -167,7 +168,7 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
        if (error) {
                mdiobus_free(bus);
                return dev_err_probe(priv->dev, error,
-                                    "cannot register MDIO bus %s\n", bus->name);
+                                    "cannot register MDIO bus %s\n", name);
        }
 
        return 0;
index 4ad3fc72e74e323f65a333bd2baad0e815ea34b0..a89b93cb4e26d91c8ab1be848b4a06696b30946b 100644 (file)
@@ -1181,8 +1181,11 @@ static int alx_change_mtu(struct net_device *netdev, int mtu)
        alx->hw.mtu = mtu;
        alx->rxbuf_size = max(max_frame, ALX_DEF_RXBUF_SIZE);
        netdev_update_features(netdev);
-       if (netif_running(netdev))
+       if (netif_running(netdev)) {
+               mutex_lock(&alx->mtx);
                alx_reinit(alx);
+               mutex_unlock(&alx->mtx);
+       }
        return 0;
 }
 
index e20aafeb4ca953b6f3c35d947a1bf3d9b27d61f0..b97ed9b5f685c3c7dddb3ae2d11c0c32a7263380 100644 (file)
@@ -8216,7 +8216,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                rc = dma_set_coherent_mask(&pdev->dev, persist_dma_mask);
                if (rc) {
                        dev_err(&pdev->dev,
-                               "pci_set_consistent_dma_mask failed, aborting\n");
+                               "dma_set_coherent_mask failed, aborting\n");
                        goto err_out_unmap;
                }
        } else if ((rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) != 0) {
index a19dd6797070cc4de3c81408b4be72a08f3e1880..2209d99b3404781a9621c339166e34c6ee30dddb 100644 (file)
@@ -2533,6 +2533,4 @@ void bnx2x_register_phc(struct bnx2x *bp);
  * Meant for implicit re-load flows.
  */
 int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp);
-int bnx2x_init_firmware(struct bnx2x *bp);
-void bnx2x_release_firmware(struct bnx2x *bp);
 #endif /* bnx2x.h */
index 8d36ebbf08e166b796b317e73c3dce0b9fc06dd5..5729a5ab059d7cbc1b2314f23577708fb9bf964e 100644 (file)
@@ -2364,24 +2364,30 @@ int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err)
        /* is another pf loaded on this engine? */
        if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP &&
            load_code != FW_MSG_CODE_DRV_LOAD_COMMON) {
-               /* build my FW version dword */
-               u32 my_fw = (bp->fw_major) + (bp->fw_minor << 8) +
-                               (bp->fw_rev << 16) + (bp->fw_eng << 24);
+               u8 loaded_fw_major, loaded_fw_minor, loaded_fw_rev, loaded_fw_eng;
+               u32 loaded_fw;
 
                /* read loaded FW from chip */
-               u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
+               loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
 
-               DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x\n",
-                  loaded_fw, my_fw);
+               loaded_fw_major = loaded_fw & 0xff;
+               loaded_fw_minor = (loaded_fw >> 8) & 0xff;
+               loaded_fw_rev = (loaded_fw >> 16) & 0xff;
+               loaded_fw_eng = (loaded_fw >> 24) & 0xff;
+
+               DP(BNX2X_MSG_SP, "loaded fw 0x%x major 0x%x minor 0x%x rev 0x%x eng 0x%x\n",
+                  loaded_fw, loaded_fw_major, loaded_fw_minor, loaded_fw_rev, loaded_fw_eng);
 
                /* abort nic load if version mismatch */
-               if (my_fw != loaded_fw) {
+               if (loaded_fw_major != BCM_5710_FW_MAJOR_VERSION ||
+                   loaded_fw_minor != BCM_5710_FW_MINOR_VERSION ||
+                   loaded_fw_eng != BCM_5710_FW_ENGINEERING_VERSION ||
+                   loaded_fw_rev < BCM_5710_FW_REVISION_VERSION_V15) {
                        if (print_err)
-                               BNX2X_ERR("bnx2x with FW %x was already loaded which mismatches my %x FW. Aborting\n",
-                                         loaded_fw, my_fw);
+                               BNX2X_ERR("loaded FW incompatible. Aborting\n");
                        else
-                               BNX2X_DEV_INFO("bnx2x with FW %x was already loaded which mismatches my %x FW, possibly due to MF UNDI\n",
-                                              loaded_fw, my_fw);
+                               BNX2X_DEV_INFO("loaded FW incompatible, possibly due to MF UNDI\n");
+
                        return -EBUSY;
                }
        }
index 774c1f1a57c3a6bd71689aaf2e3f6988c51bdaf2..c19b072f3a2375c8bf2bfccd856172644b0da7ff 100644 (file)
@@ -100,6 +100,9 @@ MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(FW_FILE_NAME_E1);
 MODULE_FIRMWARE(FW_FILE_NAME_E1H);
 MODULE_FIRMWARE(FW_FILE_NAME_E2);
+MODULE_FIRMWARE(FW_FILE_NAME_E1_V15);
+MODULE_FIRMWARE(FW_FILE_NAME_E1H_V15);
+MODULE_FIRMWARE(FW_FILE_NAME_E2_V15);
 
 int bnx2x_num_queues;
 module_param_named(num_queues, bnx2x_num_queues, int, 0444);
@@ -12316,15 +12319,6 @@ static int bnx2x_init_bp(struct bnx2x *bp)
 
        bnx2x_read_fwinfo(bp);
 
-       if (IS_PF(bp)) {
-               rc = bnx2x_init_firmware(bp);
-
-               if (rc) {
-                       bnx2x_free_mem_bp(bp);
-                       return rc;
-               }
-       }
-
        func = BP_FUNC(bp);
 
        /* need to reset chip if undi was active */
@@ -12337,7 +12331,6 @@ static int bnx2x_init_bp(struct bnx2x *bp)
 
                rc = bnx2x_prev_unload(bp);
                if (rc) {
-                       bnx2x_release_firmware(bp);
                        bnx2x_free_mem_bp(bp);
                        return rc;
                }
@@ -13406,7 +13399,7 @@ do {                                                                    \
             (u8 *)bp->arr, len);                                       \
 } while (0)
 
-int bnx2x_init_firmware(struct bnx2x *bp)
+static int bnx2x_init_firmware(struct bnx2x *bp)
 {
        const char *fw_file_name, *fw_file_name_v15;
        struct bnx2x_fw_file_hdr *fw_hdr;
@@ -13506,7 +13499,7 @@ request_firmware_exit:
        return rc;
 }
 
-void bnx2x_release_firmware(struct bnx2x *bp)
+static void bnx2x_release_firmware(struct bnx2x *bp)
 {
        kfree(bp->init_ops_offsets);
        kfree(bp->init_ops);
@@ -14023,7 +14016,6 @@ static int bnx2x_init_one(struct pci_dev *pdev,
        return 0;
 
 init_one_freemem:
-       bnx2x_release_firmware(bp);
        bnx2x_free_mem_bp(bp);
 
 init_one_exit:
index 4f94136a011a19d073fcfa33f0659514ed237bd5..b1c98d1408b82604e7223fe0102e54a4f64322ff 100644 (file)
@@ -4747,8 +4747,10 @@ static int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, u16 vnic_id)
                return rc;
 
        req->vnic_id = cpu_to_le32(vnic->fw_vnic_id);
-       req->num_mc_entries = cpu_to_le32(vnic->mc_list_count);
-       req->mc_tbl_addr = cpu_to_le64(vnic->mc_list_mapping);
+       if (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST) {
+               req->num_mc_entries = cpu_to_le32(vnic->mc_list_count);
+               req->mc_tbl_addr = cpu_to_le64(vnic->mc_list_mapping);
+       }
        req->mask = cpu_to_le32(vnic->rx_mask);
        return hwrm_req_send_silent(bp, req);
 }
@@ -7787,6 +7789,19 @@ static int bnxt_map_fw_health_regs(struct bnxt *bp)
        return 0;
 }
 
+static void bnxt_remap_fw_health_regs(struct bnxt *bp)
+{
+       if (!bp->fw_health)
+               return;
+
+       if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) {
+               bp->fw_health->status_reliable = true;
+               bp->fw_health->resets_reliable = true;
+       } else {
+               bnxt_try_map_fw_health_reg(bp);
+       }
+}
+
 static int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp)
 {
        struct bnxt_fw_health *fw_health = bp->fw_health;
@@ -8639,6 +8654,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
        vnic->uc_filter_count = 1;
 
        vnic->rx_mask = 0;
+       if (test_bit(BNXT_STATE_HALF_OPEN, &bp->state))
+               goto skip_rx_mask;
+
        if (bp->dev->flags & IFF_BROADCAST)
                vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;
 
@@ -8648,7 +8666,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
        if (bp->dev->flags & IFF_ALLMULTI) {
                vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
                vnic->mc_list_count = 0;
-       } else {
+       } else if (bp->dev->flags & IFF_MULTICAST) {
                u32 mask = 0;
 
                bnxt_mc_list_updated(bp, &mask);
@@ -8659,6 +8677,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
        if (rc)
                goto err_out;
 
+skip_rx_mask:
        rc = bnxt_hwrm_set_coal(bp);
        if (rc)
                netdev_warn(bp->dev, "HWRM set coalescing failure rc: %x\n",
@@ -9850,8 +9869,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
                resc_reinit = true;
        if (flags & FUNC_DRV_IF_CHANGE_RESP_FLAGS_HOT_FW_RESET_DONE)
                fw_reset = true;
-       else if (bp->fw_health && !bp->fw_health->status_reliable)
-               bnxt_try_map_fw_health_reg(bp);
+       else
+               bnxt_remap_fw_health_regs(bp);
 
        if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) {
                netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n");
@@ -10330,13 +10349,15 @@ int bnxt_half_open_nic(struct bnxt *bp)
                goto half_open_err;
        }
 
-       rc = bnxt_alloc_mem(bp, false);
+       rc = bnxt_alloc_mem(bp, true);
        if (rc) {
                netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
                goto half_open_err;
        }
-       rc = bnxt_init_nic(bp, false);
+       set_bit(BNXT_STATE_HALF_OPEN, &bp->state);
+       rc = bnxt_init_nic(bp, true);
        if (rc) {
+               clear_bit(BNXT_STATE_HALF_OPEN, &bp->state);
                netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc);
                goto half_open_err;
        }
@@ -10344,7 +10365,7 @@ int bnxt_half_open_nic(struct bnxt *bp)
 
 half_open_err:
        bnxt_free_skbs(bp);
-       bnxt_free_mem(bp, false);
+       bnxt_free_mem(bp, true);
        dev_close(bp->dev);
        return rc;
 }
@@ -10354,9 +10375,10 @@ half_open_err:
  */
 void bnxt_half_close_nic(struct bnxt *bp)
 {
-       bnxt_hwrm_resource_free(bp, false, false);
+       bnxt_hwrm_resource_free(bp, false, true);
        bnxt_free_skbs(bp);
-       bnxt_free_mem(bp, false);
+       bnxt_free_mem(bp, true);
+       clear_bit(BNXT_STATE_HALF_OPEN, &bp->state);
 }
 
 void bnxt_reenable_sriov(struct bnxt *bp)
@@ -10772,7 +10794,7 @@ static void bnxt_set_rx_mode(struct net_device *dev)
        if (dev->flags & IFF_ALLMULTI) {
                mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
                vnic->mc_list_count = 0;
-       } else {
+       } else if (dev->flags & IFF_MULTICAST) {
                mc_update = bnxt_mc_list_updated(bp, &mask);
        }
 
@@ -10849,9 +10871,10 @@ skip_uc:
            !bnxt_promisc_ok(bp))
                vnic->rx_mask &= ~CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
        rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0);
-       if (rc && vnic->mc_list_count) {
+       if (rc && (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST)) {
                netdev_info(bp->dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST mode\n",
                            rc);
+               vnic->rx_mask &= ~CFA_L2_SET_RX_MASK_REQ_MASK_MCAST;
                vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
                vnic->mc_list_count = 0;
                rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0);
index 440dfeb4948bc67fe3f3d7036471b21b3075b4f7..666fc1e7a7d2f5efef820f6e627d7b20ef925ad9 100644 (file)
@@ -1921,6 +1921,7 @@ struct bnxt {
 #define BNXT_STATE_RECOVER             12
 #define BNXT_STATE_FW_NON_FATAL_COND   13
 #define BNXT_STATE_FW_ACTIVATE_RESET   14
+#define BNXT_STATE_HALF_OPEN           15      /* For offline ethtool tests */
 
 #define BNXT_NO_FW_ACCESS(bp)                                  \
        (test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) ||    \
index 4da31b1b84f9c2ebb7a5aaecf1b869f55c6db104..f6e21fac0e690d958fe0066c09443307d48a6e7e 100644 (file)
@@ -367,6 +367,16 @@ bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack,
        }
 }
 
+/* Live patch status in NVM */
+#define BNXT_LIVEPATCH_NOT_INSTALLED   0
+#define BNXT_LIVEPATCH_INSTALLED       FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL
+#define BNXT_LIVEPATCH_REMOVED         FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE
+#define BNXT_LIVEPATCH_MASK            (FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | \
+                                        FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE)
+#define BNXT_LIVEPATCH_ACTIVATED       BNXT_LIVEPATCH_MASK
+
+#define BNXT_LIVEPATCH_STATE(flags)    ((flags) & BNXT_LIVEPATCH_MASK)
+
 static int
 bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
 {
@@ -374,8 +384,9 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
        struct hwrm_fw_livepatch_query_input *query_req;
        struct hwrm_fw_livepatch_output *patch_resp;
        struct hwrm_fw_livepatch_input *patch_req;
+       u16 flags, live_patch_state;
+       bool activated = false;
        u32 installed = 0;
-       u16 flags;
        u8 target;
        int rc;
 
@@ -394,7 +405,6 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
                hwrm_req_drop(bp, query_req);
                return rc;
        }
-       patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE;
        patch_req->loadtype = FW_LIVEPATCH_REQ_LOADTYPE_NVM_INSTALL;
        patch_resp = hwrm_req_hold(bp, patch_req);
 
@@ -407,12 +417,20 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
                }
 
                flags = le16_to_cpu(query_resp->status_flags);
-               if (~flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL)
+               live_patch_state = BNXT_LIVEPATCH_STATE(flags);
+
+               if (live_patch_state == BNXT_LIVEPATCH_NOT_INSTALLED)
                        continue;
-               if ((flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) &&
-                   !strncmp(query_resp->active_ver, query_resp->install_ver,
-                            sizeof(query_resp->active_ver)))
+
+               if (live_patch_state == BNXT_LIVEPATCH_ACTIVATED) {
+                       activated = true;
                        continue;
+               }
+
+               if (live_patch_state == BNXT_LIVEPATCH_INSTALLED)
+                       patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE;
+               else if (live_patch_state == BNXT_LIVEPATCH_REMOVED)
+                       patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_DEACTIVATE;
 
                patch_req->fw_target = target;
                rc = hwrm_req_send(bp, patch_req);
@@ -424,8 +442,13 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
        }
 
        if (!rc && !installed) {
-               NL_SET_ERR_MSG_MOD(extack, "No live patches found");
-               rc = -ENOENT;
+               if (activated) {
+                       NL_SET_ERR_MSG_MOD(extack, "Live patch already activated");
+                       rc = -EEXIST;
+               } else {
+                       NL_SET_ERR_MSG_MOD(extack, "No live patches found");
+                       rc = -ENOENT;
+               }
        }
        hwrm_req_drop(bp, query_req);
        hwrm_req_drop(bp, patch_req);
index 003330e8cd58bde45305e746307c9e693461eaaf..8aaa2335f848aa627dc3ef7bb182e87acd1c9995 100644 (file)
@@ -25,6 +25,7 @@
 #include "bnxt_hsi.h"
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
+#include "bnxt_ulp.h"
 #include "bnxt_xdp.h"
 #include "bnxt_ptp.h"
 #include "bnxt_ethtool.h"
@@ -1969,6 +1970,9 @@ static int bnxt_get_fecparam(struct net_device *dev,
        case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE:
                fec->active_fec |= ETHTOOL_FEC_LLRS;
                break;
+       case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE:
+               fec->active_fec |= ETHTOOL_FEC_OFF;
+               break;
        }
        return 0;
 }
@@ -3454,7 +3458,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
        if (!skb)
                return -ENOMEM;
        data = skb_put(skb, pkt_size);
-       eth_broadcast_addr(data);
+       ether_addr_copy(&data[i], bp->dev->dev_addr);
        i += ETH_ALEN;
        ether_addr_copy(&data[i], bp->dev->dev_addr);
        i += ETH_ALEN;
@@ -3548,9 +3552,12 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
        if (!offline) {
                bnxt_run_fw_tests(bp, test_mask, &test_results);
        } else {
-               rc = bnxt_close_nic(bp, false, false);
-               if (rc)
+               bnxt_ulp_stop(bp);
+               rc = bnxt_close_nic(bp, true, false);
+               if (rc) {
+                       bnxt_ulp_start(bp, rc);
                        return;
+               }
                bnxt_run_fw_tests(bp, test_mask, &test_results);
 
                buf[BNXT_MACLPBK_TEST_IDX] = 1;
@@ -3560,6 +3567,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
                if (rc) {
                        bnxt_hwrm_mac_loopback(bp, false);
                        etest->flags |= ETH_TEST_FL_FAILED;
+                       bnxt_ulp_start(bp, rc);
                        return;
                }
                if (bnxt_run_loopback(bp))
@@ -3585,7 +3593,8 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
                }
                bnxt_hwrm_phy_loopback(bp, false, false);
                bnxt_half_close_nic(bp);
-               rc = bnxt_open_nic(bp, false, true);
+               rc = bnxt_open_nic(bp, true, true);
+               bnxt_ulp_start(bp, rc);
        }
        if (rc || bnxt_test_irq(bp)) {
                buf[BNXT_IRQ_TEST_IDX] = 1;
index 566c9487ef556d457471310d6ea809057b90e104..b01d42928a53c5594f5d92cc09cbbb2a050ad6f6 100644 (file)
@@ -644,17 +644,23 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
 
                /* Last byte of resp contains valid bit */
                valid = ((u8 *)ctx->resp) + len - 1;
-               for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) {
+               for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; ) {
                        /* make sure we read from updated DMA memory */
                        dma_rmb();
                        if (*valid)
                                break;
-                       usleep_range(1, 5);
+                       if (j < 10) {
+                               udelay(1);
+                               j++;
+                       } else {
+                               usleep_range(20, 30);
+                               j += 20;
+                       }
                }
 
                if (j >= HWRM_VALID_BIT_DELAY_USEC) {
                        hwrm_err(bp, ctx, "Error (timeout: %u) msg {0x%x 0x%x} len:%d v:%d\n",
-                                hwrm_total_timeout(i), req_type,
+                                hwrm_total_timeout(i) + j, req_type,
                                 le16_to_cpu(ctx->req->seq_id), len, *valid);
                        goto exit;
                }
index d52bd2d63aec060ed218c0510959afd3ba58a9ee..c98032e381881da718a1f55659258e8ebc11a5cb 100644 (file)
@@ -90,7 +90,7 @@ static inline unsigned int hwrm_total_timeout(unsigned int n)
 }
 
 
-#define HWRM_VALID_BIT_DELAY_USEC      150
+#define HWRM_VALID_BIT_DELAY_USEC      50000
 
 static inline bool bnxt_cfa_hwrm_message(u16 req_type)
 {
index 87f1056e29ff234bac5e3fbf37c7b55e7d0b4349..2da804f84b480803142e8ac97d621519bfe56b5a 100644 (file)
@@ -2287,8 +2287,10 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
                dma_length_status = status->length_status;
                if (dev->features & NETIF_F_RXCSUM) {
                        rx_csum = (__force __be16)(status->rx_csum & 0xffff);
-                       skb->csum = (__force __wsum)ntohs(rx_csum);
-                       skb->ip_summed = CHECKSUM_COMPLETE;
+                       if (rx_csum) {
+                               skb->csum = (__force __wsum)ntohs(rx_csum);
+                               skb->ip_summed = CHECKSUM_COMPLETE;
+                       }
                }
 
                /* DMA flags and length are still valid no matter how
index e31a5a397f1141a0191b9f4ce2fc90b3befb02a0..f55d9d9c01a857d48e5d0a9c632dbaa87319a918 100644 (file)
 void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
+       struct device *kdev = &priv->pdev->dev;
+
+       if (!device_can_wakeup(kdev)) {
+               wol->supported = 0;
+               wol->wolopts = 0;
+               return;
+       }
 
        wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
        wol->wolopts = priv->wolopts;
index 98498a76ae162e1c15551098ade064fb64b8efce..d13f06cf0308a6e89acfc6e414cf54b159b35990 100644 (file)
@@ -1573,7 +1573,14 @@ static int macb_poll(struct napi_struct *napi, int budget)
        if (work_done < budget) {
                napi_complete_done(napi, work_done);
 
-               /* Packets received while interrupts were disabled */
+               /* RSR bits only seem to propagate to raise interrupts when
+                * interrupts are enabled at the time, so if bits are already
+                * set due to packets received while interrupts were disabled,
+                * they will not cause another interrupt to be generated when
+                * interrupts are re-enabled.
+                * Check for this case here. This has been seen to happen
+                * around 30% of the time under heavy network load.
+                */
                status = macb_readl(bp, RSR);
                if (status) {
                        if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
@@ -1581,6 +1588,22 @@ static int macb_poll(struct napi_struct *napi, int budget)
                        napi_reschedule(napi);
                } else {
                        queue_writel(queue, IER, bp->rx_intr_mask);
+
+                       /* In rare cases, packets could have been received in
+                        * the window between the check above and re-enabling
+                        * interrupts. Therefore, a double-check is required
+                        * to avoid losing a wakeup. This can potentially race
+                        * with the interrupt handler doing the same actions
+                        * if an interrupt is raised just after enabling them,
+                        * but this should be harmless.
+                        */
+                       status = macb_readl(bp, RSR);
+                       if (unlikely(status)) {
+                               queue_writel(queue, IDR, bp->rx_intr_mask);
+                               if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                                       queue_writel(queue, ISR, MACB_BIT(RCOMP));
+                               napi_schedule(napi);
+                       }
                }
        }
 
index da41eee2f25c7933ee1f72164508e0d23d49a313..a06003bfa04b9e72ec79074e9541c3fa3ec25ebd 100644 (file)
@@ -3613,6 +3613,8 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
            MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
        adapter->params.pci.vpd_cap_addr =
            pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD);
+       if (!adapter->params.pci.vpd_cap_addr)
+               return -ENODEV;
        ret = get_vpd_params(adapter, &adapter->params.vpd);
        if (ret < 0)
                return ret;
index 691605c152659b8c182df87a9ffab5aaaba99dff..d5356db7539a43773e9496c29dc707995aaa00d2 100644 (file)
@@ -989,117 +989,6 @@ static int ftgmac100_alloc_rx_buffers(struct ftgmac100 *priv)
        return 0;
 }
 
-static void ftgmac100_adjust_link(struct net_device *netdev)
-{
-       struct ftgmac100 *priv = netdev_priv(netdev);
-       struct phy_device *phydev = netdev->phydev;
-       bool tx_pause, rx_pause;
-       int new_speed;
-
-       /* We store "no link" as speed 0 */
-       if (!phydev->link)
-               new_speed = 0;
-       else
-               new_speed = phydev->speed;
-
-       /* Grab pause settings from PHY if configured to do so */
-       if (priv->aneg_pause) {
-               rx_pause = tx_pause = phydev->pause;
-               if (phydev->asym_pause)
-                       tx_pause = !rx_pause;
-       } else {
-               rx_pause = priv->rx_pause;
-               tx_pause = priv->tx_pause;
-       }
-
-       /* Link hasn't changed, do nothing */
-       if (phydev->speed == priv->cur_speed &&
-           phydev->duplex == priv->cur_duplex &&
-           rx_pause == priv->rx_pause &&
-           tx_pause == priv->tx_pause)
-               return;
-
-       /* Print status if we have a link or we had one and just lost it,
-        * don't print otherwise.
-        */
-       if (new_speed || priv->cur_speed)
-               phy_print_status(phydev);
-
-       priv->cur_speed = new_speed;
-       priv->cur_duplex = phydev->duplex;
-       priv->rx_pause = rx_pause;
-       priv->tx_pause = tx_pause;
-
-       /* Link is down, do nothing else */
-       if (!new_speed)
-               return;
-
-       /* Disable all interrupts */
-       iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
-
-       /* Reset the adapter asynchronously */
-       schedule_work(&priv->reset_task);
-}
-
-static int ftgmac100_mii_probe(struct net_device *netdev)
-{
-       struct ftgmac100 *priv = netdev_priv(netdev);
-       struct platform_device *pdev = to_platform_device(priv->dev);
-       struct device_node *np = pdev->dev.of_node;
-       struct phy_device *phydev;
-       phy_interface_t phy_intf;
-       int err;
-
-       /* Default to RGMII. It's a gigabit part after all */
-       err = of_get_phy_mode(np, &phy_intf);
-       if (err)
-               phy_intf = PHY_INTERFACE_MODE_RGMII;
-
-       /* Aspeed only supports these. I don't know about other IP
-        * block vendors so I'm going to just let them through for
-        * now. Note that this is only a warning if for some obscure
-        * reason the DT really means to lie about it or it's a newer
-        * part we don't know about.
-        *
-        * On the Aspeed SoC there are additionally straps and SCU
-        * control bits that could tell us what the interface is
-        * (or allow us to configure it while the IP block is held
-        * in reset). For now I chose to keep this driver away from
-        * those SoC specific bits and assume the device-tree is
-        * right and the SCU has been configured properly by pinmux
-        * or the firmware.
-        */
-       if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) {
-               netdev_warn(netdev,
-                           "Unsupported PHY mode %s !\n",
-                           phy_modes(phy_intf));
-       }
-
-       phydev = phy_find_first(priv->mii_bus);
-       if (!phydev) {
-               netdev_info(netdev, "%s: no PHY found\n", netdev->name);
-               return -ENODEV;
-       }
-
-       phydev = phy_connect(netdev, phydev_name(phydev),
-                            &ftgmac100_adjust_link, phy_intf);
-
-       if (IS_ERR(phydev)) {
-               netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name);
-               return PTR_ERR(phydev);
-       }
-
-       /* Indicate that we support PAUSE frames (see comment in
-        * Documentation/networking/phy.rst)
-        */
-       phy_support_asym_pause(phydev);
-
-       /* Display what we found */
-       phy_attached_info(phydev);
-
-       return 0;
-}
-
 static int ftgmac100_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
 {
        struct net_device *netdev = bus->priv;
@@ -1410,10 +1299,8 @@ static int ftgmac100_init_all(struct ftgmac100 *priv, bool ignore_alloc_err)
        return err;
 }
 
-static void ftgmac100_reset_task(struct work_struct *work)
+static void ftgmac100_reset(struct ftgmac100 *priv)
 {
-       struct ftgmac100 *priv = container_of(work, struct ftgmac100,
-                                             reset_task);
        struct net_device *netdev = priv->netdev;
        int err;
 
@@ -1459,6 +1346,134 @@ static void ftgmac100_reset_task(struct work_struct *work)
        rtnl_unlock();
 }
 
+static void ftgmac100_reset_task(struct work_struct *work)
+{
+       struct ftgmac100 *priv = container_of(work, struct ftgmac100,
+                                             reset_task);
+
+       ftgmac100_reset(priv);
+}
+
+static void ftgmac100_adjust_link(struct net_device *netdev)
+{
+       struct ftgmac100 *priv = netdev_priv(netdev);
+       struct phy_device *phydev = netdev->phydev;
+       bool tx_pause, rx_pause;
+       int new_speed;
+
+       /* We store "no link" as speed 0 */
+       if (!phydev->link)
+               new_speed = 0;
+       else
+               new_speed = phydev->speed;
+
+       /* Grab pause settings from PHY if configured to do so */
+       if (priv->aneg_pause) {
+               rx_pause = tx_pause = phydev->pause;
+               if (phydev->asym_pause)
+                       tx_pause = !rx_pause;
+       } else {
+               rx_pause = priv->rx_pause;
+               tx_pause = priv->tx_pause;
+       }
+
+       /* Link hasn't changed, do nothing */
+       if (phydev->speed == priv->cur_speed &&
+           phydev->duplex == priv->cur_duplex &&
+           rx_pause == priv->rx_pause &&
+           tx_pause == priv->tx_pause)
+               return;
+
+       /* Print status if we have a link or we had one and just lost it,
+        * don't print otherwise.
+        */
+       if (new_speed || priv->cur_speed)
+               phy_print_status(phydev);
+
+       priv->cur_speed = new_speed;
+       priv->cur_duplex = phydev->duplex;
+       priv->rx_pause = rx_pause;
+       priv->tx_pause = tx_pause;
+
+       /* Link is down, do nothing else */
+       if (!new_speed)
+               return;
+
+       /* Disable all interrupts */
+       iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
+
+       /* Release phy lock to allow ftgmac100_reset to aquire it, keeping lock
+        * order consistent to prevent dead lock.
+        */
+       if (netdev->phydev)
+               mutex_unlock(&netdev->phydev->lock);
+
+       ftgmac100_reset(priv);
+
+       if (netdev->phydev)
+               mutex_lock(&netdev->phydev->lock);
+
+}
+
+static int ftgmac100_mii_probe(struct net_device *netdev)
+{
+       struct ftgmac100 *priv = netdev_priv(netdev);
+       struct platform_device *pdev = to_platform_device(priv->dev);
+       struct device_node *np = pdev->dev.of_node;
+       struct phy_device *phydev;
+       phy_interface_t phy_intf;
+       int err;
+
+       /* Default to RGMII. It's a gigabit part after all */
+       err = of_get_phy_mode(np, &phy_intf);
+       if (err)
+               phy_intf = PHY_INTERFACE_MODE_RGMII;
+
+       /* Aspeed only supports these. I don't know about other IP
+        * block vendors so I'm going to just let them through for
+        * now. Note that this is only a warning if for some obscure
+        * reason the DT really means to lie about it or it's a newer
+        * part we don't know about.
+        *
+        * On the Aspeed SoC there are additionally straps and SCU
+        * control bits that could tell us what the interface is
+        * (or allow us to configure it while the IP block is held
+        * in reset). For now I chose to keep this driver away from
+        * those SoC specific bits and assume the device-tree is
+        * right and the SCU has been configured properly by pinmux
+        * or the firmware.
+        */
+       if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) {
+               netdev_warn(netdev,
+                           "Unsupported PHY mode %s !\n",
+                           phy_modes(phy_intf));
+       }
+
+       phydev = phy_find_first(priv->mii_bus);
+       if (!phydev) {
+               netdev_info(netdev, "%s: no PHY found\n", netdev->name);
+               return -ENODEV;
+       }
+
+       phydev = phy_connect(netdev, phydev_name(phydev),
+                            &ftgmac100_adjust_link, phy_intf);
+
+       if (IS_ERR(phydev)) {
+               netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name);
+               return PTR_ERR(phydev);
+       }
+
+       /* Indicate that we support PAUSE frames (see comment in
+        * Documentation/networking/phy.rst)
+        */
+       phy_support_asym_pause(phydev);
+
+       /* Display what we found */
+       phy_attached_info(phydev);
+
+       return 0;
+}
+
 static int ftgmac100_open(struct net_device *netdev)
 {
        struct ftgmac100 *priv = netdev_priv(netdev);
index ff756265d58faf2e2d5af0e05e7a41d927ee8745..9a2c16d69e2c1ae7657811cd6060d4187ee719b7 100644 (file)
@@ -1464,6 +1464,7 @@ static int gfar_get_ts_info(struct net_device *dev,
        ptp_node = of_find_compatible_node(NULL, NULL, "fsl,etsec-ptp");
        if (ptp_node) {
                ptp_dev = of_find_device_by_node(ptp_node);
+               of_node_put(ptp_node);
                if (ptp_dev)
                        ptp = platform_get_drvdata(ptp_dev);
        }
index 29617a86b2995b882a5a74f7017d40339fdc1889..b423e94956f1088a1b27afa963597e1873f8c4fc 100644 (file)
@@ -2212,6 +2212,19 @@ static const char *reset_reason_to_string(enum ibmvnic_reset_reason reason)
        return "UNKNOWN";
 }
 
+/*
+ * Initialize the init_done completion and return code values. We
+ * can get a transport event just after registering the CRQ and the
+ * tasklet will use this to communicate the transport event. To ensure
+ * we don't miss the notification/error, initialize these _before_
+ * regisering the CRQ.
+ */
+static inline void reinit_init_done(struct ibmvnic_adapter *adapter)
+{
+       reinit_completion(&adapter->init_done);
+       adapter->init_done_rc = 0;
+}
+
 /*
  * do_reset returns zero if we are able to keep processing reset events, or
  * non-zero if we hit a fatal error and must halt.
@@ -2318,6 +2331,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
                 */
                adapter->state = VNIC_PROBED;
 
+               reinit_init_done(adapter);
+
                if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM) {
                        rc = init_crq_queue(adapter);
                } else if (adapter->reset_reason == VNIC_RESET_MOBILITY) {
@@ -2461,7 +2476,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
         */
        adapter->state = VNIC_PROBED;
 
-       reinit_completion(&adapter->init_done);
+       reinit_init_done(adapter);
+
        rc = init_crq_queue(adapter);
        if (rc) {
                netdev_err(adapter->netdev,
@@ -2602,23 +2618,82 @@ out:
 static void __ibmvnic_reset(struct work_struct *work)
 {
        struct ibmvnic_adapter *adapter;
-       bool saved_state = false;
+       unsigned int timeout = 5000;
        struct ibmvnic_rwi *tmprwi;
+       bool saved_state = false;
        struct ibmvnic_rwi *rwi;
        unsigned long flags;
-       u32 reset_state;
+       struct device *dev;
+       bool need_reset;
        int num_fails = 0;
+       u32 reset_state;
        int rc = 0;
 
        adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset);
+               dev = &adapter->vdev->dev;
 
-       if (test_and_set_bit_lock(0, &adapter->resetting)) {
+       /* Wait for ibmvnic_probe() to complete. If probe is taking too long
+        * or if another reset is in progress, defer work for now. If probe
+        * eventually fails it will flush and terminate our work.
+        *
+        * Three possibilities here:
+        * 1. Adpater being removed  - just return
+        * 2. Timed out on probe or another reset in progress - delay the work
+        * 3. Completed probe - perform any resets in queue
+        */
+       if (adapter->state == VNIC_PROBING &&
+           !wait_for_completion_timeout(&adapter->probe_done, timeout)) {
+               dev_err(dev, "Reset thread timed out on probe");
                queue_delayed_work(system_long_wq,
                                   &adapter->ibmvnic_delayed_reset,
                                   IBMVNIC_RESET_DELAY);
                return;
        }
 
+       /* adapter is done with probe (i.e state is never VNIC_PROBING now) */
+       if (adapter->state == VNIC_REMOVING)
+               return;
+
+       /* ->rwi_list is stable now (no one else is removing entries) */
+
+       /* ibmvnic_probe() may have purged the reset queue after we were
+        * scheduled to process a reset so there maybe no resets to process.
+        * Before setting the ->resetting bit though, we have to make sure
+        * that there is infact a reset to process. Otherwise we may race
+        * with ibmvnic_open() and end up leaving the vnic down:
+        *
+        *      __ibmvnic_reset()           ibmvnic_open()
+        *      -----------------           --------------
+        *
+        *  set ->resetting bit
+        *                              find ->resetting bit is set
+        *                              set ->state to IBMVNIC_OPEN (i.e
+        *                              assume reset will open device)
+        *                              return
+        *  find reset queue empty
+        *  return
+        *
+        *      Neither performed vnic login/open and vnic stays down
+        *
+        * If we hold the lock and conditionally set the bit, either we
+        * or ibmvnic_open() will complete the open.
+        */
+       need_reset = false;
+       spin_lock(&adapter->rwi_lock);
+       if (!list_empty(&adapter->rwi_list)) {
+               if (test_and_set_bit_lock(0, &adapter->resetting)) {
+                       queue_delayed_work(system_long_wq,
+                                          &adapter->ibmvnic_delayed_reset,
+                                          IBMVNIC_RESET_DELAY);
+               } else {
+                       need_reset = true;
+               }
+       }
+       spin_unlock(&adapter->rwi_lock);
+
+       if (!need_reset)
+               return;
+
        rwi = get_next_rwi(adapter);
        while (rwi) {
                spin_lock_irqsave(&adapter->state_lock, flags);
@@ -2735,12 +2810,23 @@ static void __ibmvnic_delayed_reset(struct work_struct *work)
        __ibmvnic_reset(&adapter->ibmvnic_reset);
 }
 
+static void flush_reset_queue(struct ibmvnic_adapter *adapter)
+{
+       struct list_head *entry, *tmp_entry;
+
+       if (!list_empty(&adapter->rwi_list)) {
+               list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) {
+                       list_del(entry);
+                       kfree(list_entry(entry, struct ibmvnic_rwi, list));
+               }
+       }
+}
+
 static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
                         enum ibmvnic_reset_reason reason)
 {
-       struct list_head *entry, *tmp_entry;
-       struct ibmvnic_rwi *rwi, *tmp;
        struct net_device *netdev = adapter->netdev;
+       struct ibmvnic_rwi *rwi, *tmp;
        unsigned long flags;
        int ret;
 
@@ -2759,13 +2845,6 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
                goto err;
        }
 
-       if (adapter->state == VNIC_PROBING) {
-               netdev_warn(netdev, "Adapter reset during probe\n");
-               adapter->init_done_rc = -EAGAIN;
-               ret = EAGAIN;
-               goto err;
-       }
-
        list_for_each_entry(tmp, &adapter->rwi_list, list) {
                if (tmp->reset_reason == reason) {
                        netdev_dbg(netdev, "Skipping matching reset, reason=%s\n",
@@ -2783,10 +2862,9 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
        /* if we just received a transport event,
         * flush reset queue and process this reset
         */
-       if (adapter->force_reset_recovery && !list_empty(&adapter->rwi_list)) {
-               list_for_each_safe(entry, tmp_entry, &adapter->rwi_list)
-                       list_del(entry);
-       }
+       if (adapter->force_reset_recovery)
+               flush_reset_queue(adapter);
+
        rwi->reset_reason = reason;
        list_add_tail(&rwi->list, &adapter->rwi_list);
        netdev_dbg(adapter->netdev, "Scheduling reset (reason %s)\n",
@@ -5321,9 +5399,9 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
                        }
 
                        if (!completion_done(&adapter->init_done)) {
-                               complete(&adapter->init_done);
                                if (!adapter->init_done_rc)
                                        adapter->init_done_rc = -EAGAIN;
+                               complete(&adapter->init_done);
                        }
 
                        break;
@@ -5346,6 +5424,13 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
                        adapter->fw_done_rc = -EIO;
                        complete(&adapter->fw_done);
                }
+
+               /* if we got here during crq-init, retry crq-init */
+               if (!completion_done(&adapter->init_done)) {
+                       adapter->init_done_rc = -EAGAIN;
+                       complete(&adapter->init_done);
+               }
+
                if (!completion_done(&adapter->stats_done))
                        complete(&adapter->stats_done);
                if (test_bit(0, &adapter->resetting))
@@ -5662,10 +5747,6 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
 
        adapter->from_passive_init = false;
 
-       if (reset)
-               reinit_completion(&adapter->init_done);
-
-       adapter->init_done_rc = 0;
        rc = ibmvnic_send_crq_init(adapter);
        if (rc) {
                dev_err(dev, "Send crq init failed with error %d\n", rc);
@@ -5679,12 +5760,14 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
 
        if (adapter->init_done_rc) {
                release_crq_queue(adapter);
+               dev_err(dev, "CRQ-init failed, %d\n", adapter->init_done_rc);
                return adapter->init_done_rc;
        }
 
        if (adapter->from_passive_init) {
                adapter->state = VNIC_OPEN;
                adapter->from_passive_init = false;
+               dev_err(dev, "CRQ-init failed, passive-init\n");
                return -EINVAL;
        }
 
@@ -5724,6 +5807,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
        struct ibmvnic_adapter *adapter;
        struct net_device *netdev;
        unsigned char *mac_addr_p;
+       unsigned long flags;
        bool init_success;
        int rc;
 
@@ -5768,6 +5852,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
        spin_lock_init(&adapter->rwi_lock);
        spin_lock_init(&adapter->state_lock);
        mutex_init(&adapter->fw_lock);
+       init_completion(&adapter->probe_done);
        init_completion(&adapter->init_done);
        init_completion(&adapter->fw_done);
        init_completion(&adapter->reset_done);
@@ -5778,6 +5863,33 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
 
        init_success = false;
        do {
+               reinit_init_done(adapter);
+
+               /* clear any failovers we got in the previous pass
+                * since we are reinitializing the CRQ
+                */
+               adapter->failover_pending = false;
+
+               /* If we had already initialized CRQ, we may have one or
+                * more resets queued already. Discard those and release
+                * the CRQ before initializing the CRQ again.
+                */
+               release_crq_queue(adapter);
+
+               /* Since we are still in PROBING state, __ibmvnic_reset()
+                * will not access the ->rwi_list and since we released CRQ,
+                * we won't get _new_ transport events. But there maybe an
+                * ongoing ibmvnic_reset() call. So serialize access to
+                * rwi_list. If we win the race, ibvmnic_reset() could add
+                * a reset after we purged but thats ok - we just may end
+                * up with an extra reset (i.e similar to having two or more
+                * resets in the queue at once).
+                * CHECK.
+                */
+               spin_lock_irqsave(&adapter->rwi_lock, flags);
+               flush_reset_queue(adapter);
+               spin_unlock_irqrestore(&adapter->rwi_lock, flags);
+
                rc = init_crq_queue(adapter);
                if (rc) {
                        dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
@@ -5809,12 +5921,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
                goto ibmvnic_dev_file_err;
 
        netif_carrier_off(netdev);
-       rc = register_netdev(netdev);
-       if (rc) {
-               dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
-               goto ibmvnic_register_fail;
-       }
-       dev_info(&dev->dev, "ibmvnic registered\n");
 
        if (init_success) {
                adapter->state = VNIC_PROBED;
@@ -5827,6 +5933,16 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
 
        adapter->wait_for_reset = false;
        adapter->last_reset_time = jiffies;
+
+       rc = register_netdev(netdev);
+       if (rc) {
+               dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
+               goto ibmvnic_register_fail;
+       }
+       dev_info(&dev->dev, "ibmvnic registered\n");
+
+       complete(&adapter->probe_done);
+
        return 0;
 
 ibmvnic_register_fail:
@@ -5841,6 +5957,17 @@ ibmvnic_stats_fail:
 ibmvnic_init_fail:
        release_sub_crqs(adapter, 1);
        release_crq_queue(adapter);
+
+       /* cleanup worker thread after releasing CRQ so we don't get
+        * transport events (i.e new work items for the worker thread).
+        */
+       adapter->state = VNIC_REMOVING;
+       complete(&adapter->probe_done);
+       flush_work(&adapter->ibmvnic_reset);
+       flush_delayed_work(&adapter->ibmvnic_delayed_reset);
+
+       flush_reset_queue(adapter);
+
        mutex_destroy(&adapter->fw_lock);
        free_netdev(netdev);
 
@@ -5917,10 +6044,14 @@ static ssize_t failover_store(struct device *dev, struct device_attribute *attr,
                   be64_to_cpu(session_token));
        rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
                                H_SESSION_ERR_DETECTED, session_token, 0, 0);
-       if (rc)
+       if (rc) {
                netdev_err(netdev,
                           "H_VIOCTL initiated failover failed, rc %ld\n",
                           rc);
+               goto last_resort;
+       }
+
+       return count;
 
 last_resort:
        netdev_dbg(netdev, "Trying to send CRQ_CMD, the last resort\n");
index 4a7a56ff74ce16af8682808b9ae41c68e90a39b6..fa2d607a7b1b9712930267d96f1b644c1a1ddc98 100644 (file)
@@ -930,6 +930,7 @@ struct ibmvnic_adapter {
 
        struct ibmvnic_tx_pool *tx_pool;
        struct ibmvnic_tx_pool *tso_pool;
+       struct completion probe_done;
        struct completion init_done;
        int init_done_rc;
 
index bcf680e838113ddfd9d73a712fb94eac772ea343..13382df2f2eff4577128430ff55882a7434280d7 100644 (file)
@@ -630,6 +630,7 @@ struct e1000_phy_info {
        bool disable_polarity_correction;
        bool is_mdix;
        bool polarity_correction;
+       bool reset_disable;
        bool speed_downgraded;
        bool autoneg_wait_to_complete;
 };
index c908c84b86d222b5be4bbcc53a50106a92248fdd..d60e2016d03c6116062ca882b2d5142db26cebca 100644 (file)
@@ -2050,6 +2050,10 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
        bool blocked = false;
        int i = 0;
 
+       /* Check the PHY (LCD) reset flag */
+       if (hw->phy.reset_disable)
+               return true;
+
        while ((blocked = !(er32(FWSM) & E1000_ICH_FWSM_RSPCIPHY)) &&
               (i++ < 30))
                usleep_range(10000, 11000);
@@ -4136,9 +4140,9 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
                return ret_val;
 
        if (!(data & valid_csum_mask)) {
-               e_dbg("NVM Checksum Invalid\n");
+               e_dbg("NVM Checksum valid bit not set\n");
 
-               if (hw->mac.type < e1000_pch_cnp) {
+               if (hw->mac.type < e1000_pch_tgp) {
                        data |= valid_csum_mask;
                        ret_val = e1000_write_nvm(hw, word, 1, &data);
                        if (ret_val)
index 2504b11c3169fa6886403b163bb8705729ffda56..638a3ddd7ada8b3d9bae93e4c0c9e99527ef4cac 100644 (file)
 #define I217_CGFREG_ENABLE_MTA_RESET   0x0002
 #define I217_MEMPWR                    PHY_REG(772, 26)
 #define I217_MEMPWR_DISABLE_SMB_RELEASE        0x0010
+#define I217_MEMPWR_MOEM               0x1000
 
 /* Receive Address Initial CRC Calculation */
 #define E1000_PCH_RAICC(_n)    (0x05F50 + ((_n) * 4))
index a42aeb555f343400721993e95f6a7d31397f3649..c5bdef3ffe26c7c96dbfbc816a7107e1ade7141f 100644 (file)
@@ -6987,8 +6987,21 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
        struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct pci_dev *pdev = to_pci_dev(dev);
+       struct e1000_hw *hw = &adapter->hw;
+       u16 phy_data;
        int rc;
 
+       if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+           hw->mac.type >= e1000_pch_adp) {
+               /* Mask OEM Bits / Gig Disable / Restart AN (772_26[12] = 1) */
+               e1e_rphy(hw, I217_MEMPWR, &phy_data);
+               phy_data |= I217_MEMPWR_MOEM;
+               e1e_wphy(hw, I217_MEMPWR, phy_data);
+
+               /* Disable LCD reset */
+               hw->phy.reset_disable = true;
+       }
+
        e1000e_flush_lpic(pdev);
 
        e1000e_pm_freeze(dev);
@@ -7010,6 +7023,8 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
        struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct pci_dev *pdev = to_pci_dev(dev);
+       struct e1000_hw *hw = &adapter->hw;
+       u16 phy_data;
        int rc;
 
        /* Introduce S0ix implementation */
@@ -7020,6 +7035,17 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
        if (rc)
                return rc;
 
+       if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+           hw->mac.type >= e1000_pch_adp) {
+               /* Unmask OEM Bits / Gig Disable / Restart AN 772_26[12] = 0 */
+               e1e_rphy(hw, I217_MEMPWR, &phy_data);
+               phy_data &= ~I217_MEMPWR_MOEM;
+               e1e_wphy(hw, I217_MEMPWR, phy_data);
+
+               /* Enable LCD reset */
+               hw->phy.reset_disable = false;
+       }
+
        return e1000e_pm_thaw(dev);
 }
 
index 1e57cc8c47d7bbd7ee15e632c3b6ee097f18e191..9db5001297c7ec641dc00b5989424bb1941affab 100644 (file)
@@ -742,10 +742,8 @@ static void i40e_dbg_dump_vf(struct i40e_pf *pf, int vf_id)
                vsi = pf->vsi[vf->lan_vsi_idx];
                dev_info(&pf->pdev->dev, "vf %2d: VSI id=%d, seid=%d, qps=%d\n",
                         vf_id, vf->lan_vsi_id, vsi->seid, vf->num_queue_pairs);
-               dev_info(&pf->pdev->dev, "       num MDD=%lld, invalid msg=%lld, valid msg=%lld\n",
-                        vf->num_mdd_events,
-                        vf->num_invalid_msgs,
-                        vf->num_valid_msgs);
+               dev_info(&pf->pdev->dev, "       num MDD=%lld\n",
+                        vf->num_mdd_events);
        } else {
                dev_info(&pf->pdev->dev, "invalid VF id %d\n", vf_id);
        }
index 0c4b7dfb3b35d583e48adb670a875834ebe9b113..31b03fe78d3be5a6bd5e53d2e4aed39f8a0a4536 100644 (file)
@@ -5372,15 +5372,7 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
        /* There is no need to reset BW when mqprio mode is on.  */
        if (pf->flags & I40E_FLAG_TC_MQPRIO)
                return 0;
-
-       if (!vsi->mqprio_qopt.qopt.hw) {
-               if (pf->flags & I40E_FLAG_DCB_ENABLED)
-                       goto skip_reset;
-
-               if (IS_ENABLED(CONFIG_I40E_DCB) &&
-                   i40e_dcb_hw_get_num_tc(&pf->hw) == 1)
-                       goto skip_reset;
-
+       if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) {
                ret = i40e_set_bw_limit(vsi, vsi->seid, 0);
                if (ret)
                        dev_info(&pf->pdev->dev,
@@ -5388,8 +5380,6 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
                                 vsi->seid);
                return ret;
        }
-
-skip_reset:
        memset(&bw_data, 0, sizeof(bw_data));
        bw_data.tc_valid_bits = enabled_tc;
        for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
index dfdb6e786461a5d5eaf153f56a98b5a37aa8c27c..2606e8f0f19be4764d48ec0cbe28850e3735d5d3 100644 (file)
@@ -1917,19 +1917,17 @@ sriov_configure_out:
 /***********************virtual channel routines******************/
 
 /**
- * i40e_vc_send_msg_to_vf_ex
+ * i40e_vc_send_msg_to_vf
  * @vf: pointer to the VF info
  * @v_opcode: virtual channel opcode
  * @v_retval: virtual channel return value
  * @msg: pointer to the msg buffer
  * @msglen: msg length
- * @is_quiet: true for not printing unsuccessful return values, false otherwise
  *
  * send msg to VF
  **/
-static int i40e_vc_send_msg_to_vf_ex(struct i40e_vf *vf, u32 v_opcode,
-                                    u32 v_retval, u8 *msg, u16 msglen,
-                                    bool is_quiet)
+static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
+                                 u32 v_retval, u8 *msg, u16 msglen)
 {
        struct i40e_pf *pf;
        struct i40e_hw *hw;
@@ -1944,25 +1942,6 @@ static int i40e_vc_send_msg_to_vf_ex(struct i40e_vf *vf, u32 v_opcode,
        hw = &pf->hw;
        abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
 
-       /* single place to detect unsuccessful return values */
-       if (v_retval && !is_quiet) {
-               vf->num_invalid_msgs++;
-               dev_info(&pf->pdev->dev, "VF %d failed opcode %d, retval: %d\n",
-                        vf->vf_id, v_opcode, v_retval);
-               if (vf->num_invalid_msgs >
-                   I40E_DEFAULT_NUM_INVALID_MSGS_ALLOWED) {
-                       dev_err(&pf->pdev->dev,
-                               "Number of invalid messages exceeded for VF %d\n",
-                               vf->vf_id);
-                       dev_err(&pf->pdev->dev, "Use PF Control I/F to enable the VF\n");
-                       set_bit(I40E_VF_STATE_DISABLED, &vf->vf_states);
-               }
-       } else {
-               vf->num_valid_msgs++;
-               /* reset the invalid counter, if a valid message is received. */
-               vf->num_invalid_msgs = 0;
-       }
-
        aq_ret = i40e_aq_send_msg_to_vf(hw, abs_vf_id,  v_opcode, v_retval,
                                        msg, msglen, NULL);
        if (aq_ret) {
@@ -1975,23 +1954,6 @@ static int i40e_vc_send_msg_to_vf_ex(struct i40e_vf *vf, u32 v_opcode,
        return 0;
 }
 
-/**
- * i40e_vc_send_msg_to_vf
- * @vf: pointer to the VF info
- * @v_opcode: virtual channel opcode
- * @v_retval: virtual channel return value
- * @msg: pointer to the msg buffer
- * @msglen: msg length
- *
- * send msg to VF
- **/
-static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
-                                 u32 v_retval, u8 *msg, u16 msglen)
-{
-       return i40e_vc_send_msg_to_vf_ex(vf, v_opcode, v_retval,
-                                        msg, msglen, false);
-}
-
 /**
  * i40e_vc_send_resp_to_vf
  * @vf: pointer to the VF info
@@ -2822,7 +2784,6 @@ error_param:
  * i40e_check_vf_permission
  * @vf: pointer to the VF info
  * @al: MAC address list from virtchnl
- * @is_quiet: set true for printing msg without opcode info, false otherwise
  *
  * Check that the given list of MAC addresses is allowed. Will return -EPERM
  * if any address in the list is not valid. Checks the following conditions:
@@ -2837,8 +2798,7 @@ error_param:
  * addresses might not be accurate.
  **/
 static inline int i40e_check_vf_permission(struct i40e_vf *vf,
-                                          struct virtchnl_ether_addr_list *al,
-                                          bool *is_quiet)
+                                          struct virtchnl_ether_addr_list *al)
 {
        struct i40e_pf *pf = vf->pf;
        struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx];
@@ -2846,7 +2806,6 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
        int mac2add_cnt = 0;
        int i;
 
-       *is_quiet = false;
        for (i = 0; i < al->num_elements; i++) {
                struct i40e_mac_filter *f;
                u8 *addr = al->list[i].addr;
@@ -2870,7 +2829,6 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
                    !ether_addr_equal(addr, vf->default_lan_addr.addr)) {
                        dev_err(&pf->pdev->dev,
                                "VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n");
-                       *is_quiet = true;
                        return -EPERM;
                }
 
@@ -2921,7 +2879,6 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
            (struct virtchnl_ether_addr_list *)msg;
        struct i40e_pf *pf = vf->pf;
        struct i40e_vsi *vsi = NULL;
-       bool is_quiet = false;
        i40e_status ret = 0;
        int i;
 
@@ -2938,7 +2895,7 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
         */
        spin_lock_bh(&vsi->mac_filter_hash_lock);
 
-       ret = i40e_check_vf_permission(vf, al, &is_quiet);
+       ret = i40e_check_vf_permission(vf, al);
        if (ret) {
                spin_unlock_bh(&vsi->mac_filter_hash_lock);
                goto error_param;
@@ -2976,8 +2933,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
 
 error_param:
        /* send the response to the VF */
-       return i40e_vc_send_msg_to_vf_ex(vf, VIRTCHNL_OP_ADD_ETH_ADDR,
-                                      ret, NULL, 0, is_quiet);
+       return i40e_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_ETH_ADDR,
+                                     ret, NULL, 0);
 }
 
 /**
index 03c42fd0fea19326916d302d67a7585456dc0a7c..a554d0a0b09bd56fb9904defd0a390df877cfa89 100644 (file)
@@ -10,8 +10,6 @@
 
 #define I40E_VIRTCHNL_SUPPORTED_QTYPES 2
 
-#define I40E_DEFAULT_NUM_INVALID_MSGS_ALLOWED  10
-
 #define I40E_VLAN_PRIORITY_SHIFT       13
 #define I40E_VLAN_MASK                 0xFFF
 #define I40E_PRIORITY_MASK             0xE000
@@ -92,9 +90,6 @@ struct i40e_vf {
        u8 num_queue_pairs;     /* num of qps assigned to VF vsis */
        u8 num_req_queues;      /* num of requested qps */
        u64 num_mdd_events;     /* num of mdd events detected */
-       /* num of continuous malformed or invalid msgs detected */
-       u64 num_invalid_msgs;
-       u64 num_valid_msgs;     /* num of valid msgs detected */
 
        unsigned long vf_caps;  /* vf's adv. capabilities */
        unsigned long vf_states;        /* vf's runtime states */
index 59806d1f7e7953e20dcddf84778e0750aad6d5e7..4babe4705a5527c70ef2203ce04a8c6dd2f45041 100644 (file)
@@ -201,6 +201,10 @@ enum iavf_state_t {
        __IAVF_RUNNING,         /* opened, working */
 };
 
+enum iavf_critical_section_t {
+       __IAVF_IN_REMOVE_TASK,  /* device being removed */
+};
+
 #define IAVF_CLOUD_FIELD_OMAC          0x01
 #define IAVF_CLOUD_FIELD_IMAC          0x02
 #define IAVF_CLOUD_FIELD_IVLAN 0x04
@@ -246,7 +250,6 @@ struct iavf_adapter {
        struct list_head mac_filter_list;
        struct mutex crit_lock;
        struct mutex client_lock;
-       struct mutex remove_lock;
        /* Lock to protect accesses to MAC and VLAN lists */
        spinlock_t mac_vlan_list_lock;
        char misc_vector_name[IFNAMSIZ + 9];
@@ -284,6 +287,8 @@ struct iavf_adapter {
 #define IAVF_FLAG_LEGACY_RX                    BIT(15)
 #define IAVF_FLAG_REINIT_ITR_NEEDED            BIT(16)
 #define IAVF_FLAG_QUEUES_DISABLED              BIT(17)
+#define IAVF_FLAG_SETUP_NETDEV_FEATURES                BIT(18)
+#define IAVF_FLAG_REINIT_MSIX_NEEDED           BIT(20)
 /* duplicates for common code */
 #define IAVF_FLAG_DCB_ENABLED                  0
        /* flags for admin queue service task */
index 8125b91206150988e1ded404c7de85b663c4bb0a..0e178a0a59c5d9c65591a0e575e29c47d42f9554 100644 (file)
@@ -302,8 +302,9 @@ static irqreturn_t iavf_msix_aq(int irq, void *data)
        rd32(hw, IAVF_VFINT_ICR01);
        rd32(hw, IAVF_VFINT_ICR0_ENA1);
 
-       /* schedule work on the private workqueue */
-       queue_work(iavf_wq, &adapter->adminq_task);
+       if (adapter->state != __IAVF_REMOVE)
+               /* schedule work on the private workqueue */
+               queue_work(iavf_wq, &adapter->adminq_task);
 
        return IRQ_HANDLED;
 }
@@ -1136,8 +1137,7 @@ void iavf_down(struct iavf_adapter *adapter)
                rss->state = IAVF_ADV_RSS_DEL_REQUEST;
        spin_unlock_bh(&adapter->adv_rss_lock);
 
-       if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) &&
-           adapter->state != __IAVF_RESETTING) {
+       if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) {
                /* cancel any current operation */
                adapter->current_op = VIRTCHNL_OP_UNKNOWN;
                /* Schedule operations to close down the HW. Don't wait
@@ -2120,7 +2120,7 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter)
                        "Requested %d queues, but PF only gave us %d.\n",
                        num_req_queues,
                        adapter->vsi_res->num_queue_pairs);
-               adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
+               adapter->flags |= IAVF_FLAG_REINIT_MSIX_NEEDED;
                adapter->num_req_queues = adapter->vsi_res->num_queue_pairs;
                iavf_schedule_reset(adapter);
 
@@ -2374,17 +2374,22 @@ static void iavf_watchdog_task(struct work_struct *work)
        struct iavf_hw *hw = &adapter->hw;
        u32 reg_val;
 
-       if (!mutex_trylock(&adapter->crit_lock))
+       if (!mutex_trylock(&adapter->crit_lock)) {
+               if (adapter->state == __IAVF_REMOVE)
+                       return;
+
                goto restart_watchdog;
+       }
 
        if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
                iavf_change_state(adapter, __IAVF_COMM_FAILED);
 
-       if (adapter->flags & IAVF_FLAG_RESET_NEEDED &&
-           adapter->state != __IAVF_RESETTING) {
-               iavf_change_state(adapter, __IAVF_RESETTING);
+       if (adapter->flags & IAVF_FLAG_RESET_NEEDED) {
                adapter->aq_required = 0;
                adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+               mutex_unlock(&adapter->crit_lock);
+               queue_work(iavf_wq, &adapter->reset_task);
+               return;
        }
 
        switch (adapter->state) {
@@ -2419,6 +2424,15 @@ static void iavf_watchdog_task(struct work_struct *work)
                                   msecs_to_jiffies(1));
                return;
        case __IAVF_INIT_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+                       /* Do not update the state and do not reschedule
+                        * watchdog task, iavf_remove should handle this state
+                        * as it can loop forever
+                        */
+                       mutex_unlock(&adapter->crit_lock);
+                       return;
+               }
                if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) {
                        dev_err(&adapter->pdev->dev,
                                "Failed to communicate with PF; waiting before retry\n");
@@ -2435,6 +2449,17 @@ static void iavf_watchdog_task(struct work_struct *work)
                queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ);
                return;
        case __IAVF_COMM_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+                       /* Set state to __IAVF_INIT_FAILED and perform remove
+                        * steps. Remove IAVF_FLAG_PF_COMMS_FAILED so the task
+                        * doesn't bring the state back to __IAVF_COMM_FAILED.
+                        */
+                       iavf_change_state(adapter, __IAVF_INIT_FAILED);
+                       adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
+                       mutex_unlock(&adapter->crit_lock);
+                       return;
+               }
                reg_val = rd32(hw, IAVF_VFGEN_RSTAT) &
                          IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
                if (reg_val == VIRTCHNL_VFR_VFACTIVE ||
@@ -2507,7 +2532,8 @@ static void iavf_watchdog_task(struct work_struct *work)
        schedule_delayed_work(&adapter->client_task, msecs_to_jiffies(5));
        mutex_unlock(&adapter->crit_lock);
 restart_watchdog:
-       queue_work(iavf_wq, &adapter->adminq_task);
+       if (adapter->state >= __IAVF_DOWN)
+               queue_work(iavf_wq, &adapter->adminq_task);
        if (adapter->aq_required)
                queue_delayed_work(iavf_wq, &adapter->watchdog_task,
                                   msecs_to_jiffies(20));
@@ -2515,6 +2541,13 @@ restart_watchdog:
                queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ * 2);
 }
 
+/**
+ * iavf_disable_vf - disable VF
+ * @adapter: board private structure
+ *
+ * Set communication failed flag and free all resources.
+ * NOTE: This function is expected to be called with crit_lock being held.
+ **/
 static void iavf_disable_vf(struct iavf_adapter *adapter)
 {
        struct iavf_mac_filter *f, *ftmp;
@@ -2569,7 +2602,6 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
        memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
        iavf_shutdown_adminq(&adapter->hw);
        adapter->netdev->flags &= ~IFF_UP;
-       mutex_unlock(&adapter->crit_lock);
        adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
        iavf_change_state(adapter, __IAVF_DOWN);
        wake_up(&adapter->down_waitqueue);
@@ -2601,13 +2633,13 @@ static void iavf_reset_task(struct work_struct *work)
        /* When device is being removed it doesn't make sense to run the reset
         * task, just return in such a case.
         */
-       if (mutex_is_locked(&adapter->remove_lock))
-               return;
+       if (!mutex_trylock(&adapter->crit_lock)) {
+               if (adapter->state != __IAVF_REMOVE)
+                       queue_work(iavf_wq, &adapter->reset_task);
 
-       if (iavf_lock_timeout(&adapter->crit_lock, 200)) {
-               schedule_work(&adapter->reset_task);
                return;
        }
+
        while (!mutex_trylock(&adapter->client_lock))
                usleep_range(500, 1000);
        if (CLIENT_ENABLED(adapter)) {
@@ -2662,6 +2694,7 @@ static void iavf_reset_task(struct work_struct *work)
                        reg_val);
                iavf_disable_vf(adapter);
                mutex_unlock(&adapter->client_lock);
+               mutex_unlock(&adapter->crit_lock);
                return; /* Do not attempt to reinit. It's dead, Jim. */
        }
 
@@ -2670,8 +2703,7 @@ continue_reset:
         * ndo_open() returning, so we can't assume it means all our open
         * tasks have finished, since we're not holding the rtnl_lock here.
         */
-       running = ((adapter->state == __IAVF_RUNNING) ||
-                  (adapter->state == __IAVF_RESETTING));
+       running = adapter->state == __IAVF_RUNNING;
 
        if (running) {
                netdev->flags &= ~IFF_UP;
@@ -2701,7 +2733,8 @@ continue_reset:
                         err);
        adapter->aq_required = 0;
 
-       if (adapter->flags & IAVF_FLAG_REINIT_ITR_NEEDED) {
+       if ((adapter->flags & IAVF_FLAG_REINIT_MSIX_NEEDED) ||
+           (adapter->flags & IAVF_FLAG_REINIT_ITR_NEEDED)) {
                err = iavf_reinit_interrupt_scheme(adapter);
                if (err)
                        goto reset_err;
@@ -2773,12 +2806,13 @@ continue_reset:
                if (err)
                        goto reset_err;
 
-               if (adapter->flags & IAVF_FLAG_REINIT_ITR_NEEDED) {
+               if ((adapter->flags & IAVF_FLAG_REINIT_MSIX_NEEDED) ||
+                   (adapter->flags & IAVF_FLAG_REINIT_ITR_NEEDED)) {
                        err = iavf_request_traffic_irqs(adapter, netdev->name);
                        if (err)
                                goto reset_err;
 
-                       adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
+                       adapter->flags &= ~IAVF_FLAG_REINIT_MSIX_NEEDED;
                }
 
                iavf_configure(adapter);
@@ -2793,6 +2827,9 @@ continue_reset:
                iavf_change_state(adapter, __IAVF_DOWN);
                wake_up(&adapter->down_waitqueue);
        }
+
+       adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
+
        mutex_unlock(&adapter->client_lock);
        mutex_unlock(&adapter->crit_lock);
 
@@ -2826,13 +2863,19 @@ static void iavf_adminq_task(struct work_struct *work)
        if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
                goto out;
 
+       if (!mutex_trylock(&adapter->crit_lock)) {
+               if (adapter->state == __IAVF_REMOVE)
+                       return;
+
+               queue_work(iavf_wq, &adapter->adminq_task);
+               goto out;
+       }
+
        event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
        event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
        if (!event.msg_buf)
                goto out;
 
-       if (iavf_lock_timeout(&adapter->crit_lock, 200))
-               goto freedom;
        do {
                ret = iavf_clean_arq_element(hw, &event, &pending);
                v_op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
@@ -2848,6 +2891,24 @@ static void iavf_adminq_task(struct work_struct *work)
        } while (pending);
        mutex_unlock(&adapter->crit_lock);
 
+       if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES)) {
+               if (adapter->netdev_registered ||
+                   !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) {
+                       struct net_device *netdev = adapter->netdev;
+
+                       rtnl_lock();
+                       netdev_update_features(netdev);
+                       rtnl_unlock();
+                       /* Request VLAN offload settings */
+                       if (VLAN_V2_ALLOWED(adapter))
+                               iavf_set_vlan_offload_features
+                                       (adapter, 0, netdev->features);
+
+                       iavf_set_queue_vlan_tag_loc(adapter);
+               }
+
+               adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES;
+       }
        if ((adapter->flags &
             (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) ||
            adapter->state == __IAVF_RESETTING)
@@ -3800,11 +3861,12 @@ static int iavf_close(struct net_device *netdev)
        struct iavf_adapter *adapter = netdev_priv(netdev);
        int status;
 
-       if (adapter->state <= __IAVF_DOWN_PENDING)
-               return 0;
+       mutex_lock(&adapter->crit_lock);
 
-       while (!mutex_trylock(&adapter->crit_lock))
-               usleep_range(500, 1000);
+       if (adapter->state <= __IAVF_DOWN_PENDING) {
+               mutex_unlock(&adapter->crit_lock);
+               return 0;
+       }
 
        set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
        if (CLIENT_ENABLED(adapter))
@@ -3853,8 +3915,11 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu)
                iavf_notify_client_l2_params(&adapter->vsi);
                adapter->flags |= IAVF_FLAG_SERVICE_CLIENT_REQUESTED;
        }
-       adapter->flags |= IAVF_FLAG_RESET_NEEDED;
-       queue_work(iavf_wq, &adapter->reset_task);
+
+       if (netif_running(netdev)) {
+               adapter->flags |= IAVF_FLAG_RESET_NEEDED;
+               queue_work(iavf_wq, &adapter->reset_task);
+       }
 
        return 0;
 }
@@ -4431,7 +4496,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         */
        mutex_init(&adapter->crit_lock);
        mutex_init(&adapter->client_lock);
-       mutex_init(&adapter->remove_lock);
        mutex_init(&hw->aq.asq_mutex);
        mutex_init(&hw->aq.arq_mutex);
 
@@ -4547,7 +4611,6 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
 static void iavf_remove(struct pci_dev *pdev)
 {
        struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
-       enum iavf_state_t prev_state = adapter->last_state;
        struct net_device *netdev = adapter->netdev;
        struct iavf_fdir_fltr *fdir, *fdirtmp;
        struct iavf_vlan_filter *vlf, *vlftmp;
@@ -4556,14 +4619,37 @@ static void iavf_remove(struct pci_dev *pdev)
        struct iavf_cloud_filter *cf, *cftmp;
        struct iavf_hw *hw = &adapter->hw;
        int err;
-       /* Indicate we are in remove and not to run reset_task */
-       mutex_lock(&adapter->remove_lock);
-       cancel_work_sync(&adapter->reset_task);
+
+       /* When reboot/shutdown is in progress no need to do anything
+        * as the adapter is already REMOVE state that was set during
+        * iavf_shutdown() callback.
+        */
+       if (adapter->state == __IAVF_REMOVE)
+               return;
+
+       set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
+       /* Wait until port initialization is complete.
+        * There are flows where register/unregister netdev may race.
+        */
+       while (1) {
+               mutex_lock(&adapter->crit_lock);
+               if (adapter->state == __IAVF_RUNNING ||
+                   adapter->state == __IAVF_DOWN ||
+                   adapter->state == __IAVF_INIT_FAILED) {
+                       mutex_unlock(&adapter->crit_lock);
+                       break;
+               }
+
+               mutex_unlock(&adapter->crit_lock);
+               usleep_range(500, 1000);
+       }
        cancel_delayed_work_sync(&adapter->watchdog_task);
-       cancel_delayed_work_sync(&adapter->client_task);
+
        if (adapter->netdev_registered) {
-               unregister_netdev(netdev);
+               rtnl_lock();
+               unregister_netdevice(netdev);
                adapter->netdev_registered = false;
+               rtnl_unlock();
        }
        if (CLIENT_ALLOWED(adapter)) {
                err = iavf_lan_del_device(adapter);
@@ -4572,6 +4658,10 @@ static void iavf_remove(struct pci_dev *pdev)
                                 err);
        }
 
+       mutex_lock(&adapter->crit_lock);
+       dev_info(&adapter->pdev->dev, "Remove device\n");
+       iavf_change_state(adapter, __IAVF_REMOVE);
+
        iavf_request_reset(adapter);
        msleep(50);
        /* If the FW isn't responding, kick it once, but only once. */
@@ -4579,37 +4669,24 @@ static void iavf_remove(struct pci_dev *pdev)
                iavf_request_reset(adapter);
                msleep(50);
        }
-       if (iavf_lock_timeout(&adapter->crit_lock, 5000))
-               dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__);
 
-       dev_info(&adapter->pdev->dev, "Removing device\n");
+       iavf_misc_irq_disable(adapter);
        /* Shut down all the garbage mashers on the detention level */
-       iavf_change_state(adapter, __IAVF_REMOVE);
+       cancel_work_sync(&adapter->reset_task);
+       cancel_delayed_work_sync(&adapter->watchdog_task);
+       cancel_work_sync(&adapter->adminq_task);
+       cancel_delayed_work_sync(&adapter->client_task);
+
        adapter->aq_required = 0;
        adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
 
        iavf_free_all_tx_resources(adapter);
        iavf_free_all_rx_resources(adapter);
-       iavf_misc_irq_disable(adapter);
        iavf_free_misc_irq(adapter);
 
-       /* In case we enter iavf_remove from erroneous state, free traffic irqs
-        * here, so as to not cause a kernel crash, when calling
-        * iavf_reset_interrupt_capability.
-        */
-       if ((adapter->last_state == __IAVF_RESETTING &&
-            prev_state != __IAVF_DOWN) ||
-           (adapter->last_state == __IAVF_RUNNING &&
-            !(netdev->flags & IFF_UP)))
-               iavf_free_traffic_irqs(adapter);
-
        iavf_reset_interrupt_capability(adapter);
        iavf_free_q_vectors(adapter);
 
-       cancel_delayed_work_sync(&adapter->watchdog_task);
-
-       cancel_work_sync(&adapter->adminq_task);
-
        iavf_free_rss(adapter);
 
        if (hw->aq.asq.count)
@@ -4621,8 +4698,6 @@ static void iavf_remove(struct pci_dev *pdev)
        mutex_destroy(&adapter->client_lock);
        mutex_unlock(&adapter->crit_lock);
        mutex_destroy(&adapter->crit_lock);
-       mutex_unlock(&adapter->remove_lock);
-       mutex_destroy(&adapter->remove_lock);
 
        iounmap(hw->hw_addr);
        pci_release_regions(pdev);
index 5ee1d118fd30f2b73232481de0d2651e84cb9367..5263cefe46f5f291bb2f2a5dc842b035c3d64328 100644 (file)
@@ -1834,6 +1834,22 @@ void iavf_request_reset(struct iavf_adapter *adapter)
        adapter->current_op = VIRTCHNL_OP_UNKNOWN;
 }
 
+/**
+ * iavf_netdev_features_vlan_strip_set - update vlan strip status
+ * @netdev: ptr to netdev being adjusted
+ * @enable: enable or disable vlan strip
+ *
+ * Helper function to change vlan strip status in netdev->features.
+ */
+static void iavf_netdev_features_vlan_strip_set(struct net_device *netdev,
+                                               const bool enable)
+{
+       if (enable)
+               netdev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+       else
+               netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+}
+
 /**
  * iavf_virtchnl_completion
  * @adapter: adapter structure
@@ -2057,8 +2073,18 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
                        }
                        break;
                case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
+                       dev_warn(&adapter->pdev->dev, "Changing VLAN Stripping is not allowed when Port VLAN is configured\n");
+                       /* Vlan stripping could not be enabled by ethtool.
+                        * Disable it in netdev->features.
+                        */
+                       iavf_netdev_features_vlan_strip_set(netdev, false);
+                       break;
                case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
                        dev_warn(&adapter->pdev->dev, "Changing VLAN Stripping is not allowed when Port VLAN is configured\n");
+                       /* Vlan stripping could not be disabled by ethtool.
+                        * Enable it in netdev->features.
+                        */
+                       iavf_netdev_features_vlan_strip_set(netdev, true);
                        break;
                default:
                        dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
@@ -2146,29 +2172,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
                                     sizeof(adapter->vlan_v2_caps)));
 
                iavf_process_config(adapter);
-
-               /* unlock crit_lock before acquiring rtnl_lock as other
-                * processes holding rtnl_lock could be waiting for the same
-                * crit_lock
-                */
-               mutex_unlock(&adapter->crit_lock);
-               /* VLAN capabilities can change during VFR, so make sure to
-                * update the netdev features with the new capabilities
-                */
-               rtnl_lock();
-               netdev_update_features(netdev);
-               rtnl_unlock();
-               if (iavf_lock_timeout(&adapter->crit_lock, 10000))
-                       dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n",
-                                __FUNCTION__);
-
-               /* Request VLAN offload settings */
-               if (VLAN_V2_ALLOWED(adapter))
-                       iavf_set_vlan_offload_features(adapter, 0,
-                                                      netdev->features);
-
-               iavf_set_queue_vlan_tag_loc(adapter);
-
+               adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES;
                }
                break;
        case VIRTCHNL_OP_ENABLE_QUEUES:
@@ -2334,6 +2338,20 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
                spin_unlock_bh(&adapter->adv_rss_lock);
                }
                break;
+       case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
+               /* PF enabled vlan strip on this VF.
+                * Update netdev->features if needed to be in sync with ethtool.
+                */
+               if (!v_retval)
+                       iavf_netdev_features_vlan_strip_set(netdev, true);
+               break;
+       case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
+               /* PF disabled vlan strip on this VF.
+                * Update netdev->features if needed to be in sync with ethtool.
+                */
+               if (!v_retval)
+                       iavf_netdev_features_vlan_strip_set(netdev, false);
+               break;
        default:
                if (adapter->current_op && (v_opcode != adapter->current_op))
                        dev_warn(&adapter->pdev->dev, "Expected response %d from PF, received %d\n",
index a9fa701aaa951958f2432e2bb2ff0080b3c71306..bea1d1e39fa27c75da0bf11634efdfeb69901cdc 100644 (file)
@@ -280,7 +280,6 @@ enum ice_pf_state {
        ICE_VFLR_EVENT_PENDING,
        ICE_FLTR_OVERFLOW_PROMISC,
        ICE_VF_DIS,
-       ICE_VF_DEINIT_IN_PROGRESS,
        ICE_CFG_BUSY,
        ICE_SERVICE_SCHED,
        ICE_SERVICE_DIS,
@@ -484,6 +483,7 @@ enum ice_pf_flags {
        ICE_FLAG_MDD_AUTO_RESET_VF,
        ICE_FLAG_LINK_LENIENT_MODE_ENA,
        ICE_FLAG_PLUG_AUX_DEV,
+       ICE_FLAG_MTU_CHANGED,
        ICE_PF_FLAGS_NBITS              /* must be last */
 };
 
@@ -898,7 +898,16 @@ static inline void ice_set_rdma_cap(struct ice_pf *pf)
  */
 static inline void ice_clear_rdma_cap(struct ice_pf *pf)
 {
-       ice_unplug_aux_dev(pf);
+       /* We can directly unplug aux device here only if the flag bit
+        * ICE_FLAG_PLUG_AUX_DEV is not set because ice_unplug_aux_dev()
+        * could race with ice_plug_aux_dev() called from
+        * ice_service_task(). In this case we only clear that bit now and
+        * aux device will be unplugged later once ice_plug_aux_device()
+        * called from ice_service_task() finishes (see ice_service_task()).
+        */
+       if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
+               ice_unplug_aux_dev(pf);
+
        clear_bit(ICE_FLAG_RDMA_ENA, pf->flags);
        clear_bit(ICE_FLAG_AUX_ENA, pf->flags);
 }
index a6d7d3eff186841766f53ed7998c2852ed32ec51..e2af99a763ed537b41bcf105cbdb8487139caa14 100644 (file)
@@ -3340,7 +3340,7 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
 
        if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(hw) &&
            !ice_fw_supports_report_dflt_cfg(hw)) {
-               struct ice_link_default_override_tlv tlv;
+               struct ice_link_default_override_tlv tlv = { 0 };
 
                status = ice_get_link_default_override(&tlv, pi);
                if (status)
index 864692b157b6f8901f8d6b6808499bd51331e842..73edc24d81d54613c5793b1d0747783ac6b09943 100644 (file)
@@ -44,6 +44,7 @@ ice_eswitch_add_vf_mac_rule(struct ice_pf *pf, struct ice_vf *vf, const u8 *mac)
                                       ctrl_vsi->rxq_map[vf->vf_id];
        rule_info.flags_info.act |= ICE_SINGLE_ACT_LB_ENABLE;
        rule_info.flags_info.act_valid = true;
+       rule_info.tun_type = ICE_SW_TUN_AND_NON_TUN;
 
        err = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info,
                               vf->repr->mac_rule);
index e2e3ef7fba7fc217768548f235a71f47c6c729cf..a5dc9824e255e820b2748606735dcb341f20589a 100644 (file)
@@ -2298,7 +2298,7 @@ ice_set_link_ksettings(struct net_device *netdev,
        if (err)
                goto done;
 
-       curr_link_speed = pi->phy.link_info.link_speed;
+       curr_link_speed = pi->phy.curr_user_speed_req;
        adv_link_speed = ice_ksettings_find_adv_link_speed(ks);
 
        /* If speed didn't get set, set it to what it currently is.
index 17a9bb461dc3a33961915b4ddb86f231aefca2ec..b7e8744b0c0a68d605706567ec14bf41062d4f9b 100644 (file)
@@ -1799,7 +1799,9 @@ static void ice_handle_mdd_event(struct ice_pf *pf)
                                 * reset, so print the event prior to reset.
                                 */
                                ice_print_vf_rx_mdd_event(vf);
+                               mutex_lock(&pf->vf[i].cfg_lock);
                                ice_reset_vf(&pf->vf[i], false);
+                               mutex_unlock(&pf->vf[i].cfg_lock);
                        }
                }
        }
@@ -2253,9 +2255,30 @@ static void ice_service_task(struct work_struct *work)
                return;
        }
 
-       if (test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
+       if (test_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags)) {
+               /* Plug aux device per request */
                ice_plug_aux_dev(pf);
 
+               /* Mark plugging as done but check whether unplug was
+                * requested during ice_plug_aux_dev() call
+                * (e.g. from ice_clear_rdma_cap()) and if so then
+                * plug aux device.
+                */
+               if (!test_and_clear_bit(ICE_FLAG_PLUG_AUX_DEV, pf->flags))
+                       ice_unplug_aux_dev(pf);
+       }
+
+       if (test_and_clear_bit(ICE_FLAG_MTU_CHANGED, pf->flags)) {
+               struct iidc_event *event;
+
+               event = kzalloc(sizeof(*event), GFP_KERNEL);
+               if (event) {
+                       set_bit(IIDC_EVENT_AFTER_MTU_CHANGE, event->type);
+                       ice_send_event_to_aux(pf, event);
+                       kfree(event);
+               }
+       }
+
        ice_clean_adminq_subtask(pf);
        ice_check_media_subtask(pf);
        ice_check_for_hang_subtask(pf);
@@ -3021,7 +3044,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
                struct iidc_event *event;
 
                ena_mask &= ~ICE_AUX_CRIT_ERR;
-               event = kzalloc(sizeof(*event), GFP_KERNEL);
+               event = kzalloc(sizeof(*event), GFP_ATOMIC);
                if (event) {
                        set_bit(IIDC_EVENT_CRIT_ERR, event->type);
                        /* report the entire OICR value to AUX driver */
@@ -4857,7 +4880,6 @@ static void ice_remove(struct pci_dev *pdev)
        ice_devlink_unregister_params(pf);
        set_bit(ICE_DOWN, pf->state);
 
-       mutex_destroy(&(&pf->hw)->fdir_fltr_lock);
        ice_deinit_lag(pf);
        if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
                ice_ptp_release(pf);
@@ -4865,6 +4887,7 @@ static void ice_remove(struct pci_dev *pdev)
                ice_remove_arfs(pf);
        ice_setup_mc_magic_wake(pf);
        ice_vsi_release_all(pf);
+       mutex_destroy(&(&pf->hw)->fdir_fltr_lock);
        ice_set_wake(pf);
        ice_free_irq_msix_misc(pf);
        ice_for_each_vsi(pf, i) {
@@ -5939,8 +5962,9 @@ ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi,
                u64 pkts = 0, bytes = 0;
 
                ring = READ_ONCE(rings[i]);
-               if (ring)
-                       ice_fetch_u64_stats_per_ring(&ring->syncp, ring->stats, &pkts, &bytes);
+               if (!ring)
+                       continue;
+               ice_fetch_u64_stats_per_ring(&ring->syncp, ring->stats, &pkts, &bytes);
                vsi_stats->tx_packets += pkts;
                vsi_stats->tx_bytes += bytes;
                vsi->tx_restart += ring->tx_stats.restart_q;
@@ -6820,7 +6844,6 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
        struct ice_netdev_priv *np = netdev_priv(netdev);
        struct ice_vsi *vsi = np->vsi;
        struct ice_pf *pf = vsi->back;
-       struct iidc_event *event;
        u8 count = 0;
        int err = 0;
 
@@ -6855,14 +6878,6 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
                return -EBUSY;
        }
 
-       event = kzalloc(sizeof(*event), GFP_KERNEL);
-       if (!event)
-               return -ENOMEM;
-
-       set_bit(IIDC_EVENT_BEFORE_MTU_CHANGE, event->type);
-       ice_send_event_to_aux(pf, event);
-       clear_bit(IIDC_EVENT_BEFORE_MTU_CHANGE, event->type);
-
        netdev->mtu = (unsigned int)new_mtu;
 
        /* if VSI is up, bring it down and then back up */
@@ -6870,21 +6885,18 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
                err = ice_down(vsi);
                if (err) {
                        netdev_err(netdev, "change MTU if_down err %d\n", err);
-                       goto event_after;
+                       return err;
                }
 
                err = ice_up(vsi);
                if (err) {
                        netdev_err(netdev, "change MTU if_up err %d\n", err);
-                       goto event_after;
+                       return err;
                }
        }
 
        netdev_dbg(netdev, "changed MTU to %d\n", new_mtu);
-event_after:
-       set_bit(IIDC_EVENT_AFTER_MTU_CHANGE, event->type);
-       ice_send_event_to_aux(pf, event);
-       kfree(event);
+       set_bit(ICE_FLAG_MTU_CHANGED, pf->flags);
 
        return err;
 }
index dc1b0e9e6df5fd4e20dad7f5a63e4503259b27f0..695b6dd61dc27e091cd5cd55bce6fa8fb58579fc 100644 (file)
@@ -47,6 +47,7 @@ enum ice_protocol_type {
 
 enum ice_sw_tunnel_type {
        ICE_NON_TUN = 0,
+       ICE_SW_TUN_AND_NON_TUN,
        ICE_SW_TUN_VXLAN,
        ICE_SW_TUN_GENEVE,
        ICE_SW_TUN_NVGRE,
index ae291d442539710d63e7dede50aea411fbc88ade..000c39d163a28e521c9a771b2824c3a05021a8e9 100644 (file)
@@ -1533,9 +1533,12 @@ exit:
 static int ice_ptp_adjtime_nonatomic(struct ptp_clock_info *info, s64 delta)
 {
        struct timespec64 now, then;
+       int ret;
 
        then = ns_to_timespec64(delta);
-       ice_ptp_gettimex64(info, &now, NULL);
+       ret = ice_ptp_gettimex64(info, &now, NULL);
+       if (ret)
+               return ret;
        now = timespec64_add(now, then);
 
        return ice_ptp_settime64(info, (const struct timespec64 *)&now);
index 11ae0bee3590fe35cbd8a0ad028b74effaaedb67..475ec2afa210b1e799baa760d9de4bf54bcf96be 100644 (file)
@@ -4537,6 +4537,7 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
        case ICE_SW_TUN_NVGRE:
                prof_type = ICE_PROF_TUN_GRE;
                break;
+       case ICE_SW_TUN_AND_NON_TUN:
        default:
                prof_type = ICE_PROF_ALL;
                break;
@@ -5305,7 +5306,8 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
        if (status)
                goto err_ice_add_adv_rule;
 
-       if (rinfo->tun_type != ICE_NON_TUN) {
+       if (rinfo->tun_type != ICE_NON_TUN &&
+           rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
                status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
                                                 s_rule->pdata.lkup_tx_rx.hdr,
                                                 pkt_offsets);
index e8aab664270ac653e081ced5eab228d9b7941edd..65cf32eb404665acc09e8216378ed5ba43cda8c7 100644 (file)
@@ -709,7 +709,7 @@ ice_tc_set_port(struct flow_match_ports match,
                        fltr->flags |= ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT;
                else
                        fltr->flags |= ICE_TC_FLWR_FIELD_DEST_L4_PORT;
-               fltr->flags |= ICE_TC_FLWR_FIELD_DEST_L4_PORT;
+
                headers->l4_key.dst_port = match.key->dst;
                headers->l4_mask.dst_port = match.mask->dst;
        }
@@ -718,7 +718,7 @@ ice_tc_set_port(struct flow_match_ports match,
                        fltr->flags |= ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT;
                else
                        fltr->flags |= ICE_TC_FLWR_FIELD_SRC_L4_PORT;
-               fltr->flags |= ICE_TC_FLWR_FIELD_SRC_L4_PORT;
+
                headers->l4_key.src_port = match.key->src;
                headers->l4_mask.src_port = match.mask->src;
        }
index 39b80124d2827243f06395d39d54be642436b7af..1be3cd4b2bef73fa5fda7c12d202647f22092f8f 100644 (file)
@@ -500,8 +500,6 @@ void ice_free_vfs(struct ice_pf *pf)
        struct ice_hw *hw = &pf->hw;
        unsigned int tmp, i;
 
-       set_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state);
-
        if (!pf->vf)
                return;
 
@@ -519,22 +517,26 @@ void ice_free_vfs(struct ice_pf *pf)
        else
                dev_warn(dev, "VFs are assigned - not disabling SR-IOV\n");
 
-       /* Avoid wait time by stopping all VFs at the same time */
-       ice_for_each_vf(pf, i)
-               ice_dis_vf_qs(&pf->vf[i]);
-
        tmp = pf->num_alloc_vfs;
        pf->num_qps_per_vf = 0;
        pf->num_alloc_vfs = 0;
        for (i = 0; i < tmp; i++) {
-               if (test_bit(ICE_VF_STATE_INIT, pf->vf[i].vf_states)) {
+               struct ice_vf *vf = &pf->vf[i];
+
+               mutex_lock(&vf->cfg_lock);
+
+               ice_dis_vf_qs(vf);
+
+               if (test_bit(ICE_VF_STATE_INIT, vf->vf_states)) {
                        /* disable VF qp mappings and set VF disable state */
-                       ice_dis_vf_mappings(&pf->vf[i]);
-                       set_bit(ICE_VF_STATE_DIS, pf->vf[i].vf_states);
-                       ice_free_vf_res(&pf->vf[i]);
+                       ice_dis_vf_mappings(vf);
+                       set_bit(ICE_VF_STATE_DIS, vf->vf_states);
+                       ice_free_vf_res(vf);
                }
 
-               mutex_destroy(&pf->vf[i].cfg_lock);
+               mutex_unlock(&vf->cfg_lock);
+
+               mutex_destroy(&vf->cfg_lock);
        }
 
        if (ice_sriov_free_msix_res(pf))
@@ -570,7 +572,6 @@ void ice_free_vfs(struct ice_pf *pf)
                                i);
 
        clear_bit(ICE_VF_DIS, pf->state);
-       clear_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state);
        clear_bit(ICE_FLAG_SRIOV_ENA, pf->flags);
 }
 
@@ -1498,6 +1499,8 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr)
        ice_for_each_vf(pf, v) {
                vf = &pf->vf[v];
 
+               mutex_lock(&vf->cfg_lock);
+
                vf->driver_caps = 0;
                ice_vc_set_default_allowlist(vf);
 
@@ -1512,6 +1515,8 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr)
                ice_vf_pre_vsi_rebuild(vf);
                ice_vf_rebuild_vsi(vf);
                ice_vf_post_vsi_rebuild(vf);
+
+               mutex_unlock(&vf->cfg_lock);
        }
 
        if (ice_is_eswitch_mode_switchdev(pf))
@@ -1562,6 +1567,8 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
        u32 reg;
        int i;
 
+       lockdep_assert_held(&vf->cfg_lock);
+
        dev = ice_pf_to_dev(pf);
 
        if (test_bit(ICE_VF_RESETS_DISABLED, pf->state)) {
@@ -2061,9 +2068,12 @@ void ice_process_vflr_event(struct ice_pf *pf)
                bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32;
                /* read GLGEN_VFLRSTAT register to find out the flr VFs */
                reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx));
-               if (reg & BIT(bit_idx))
+               if (reg & BIT(bit_idx)) {
                        /* GLGEN_VFLRSTAT bit will be cleared in ice_reset_vf */
+                       mutex_lock(&vf->cfg_lock);
                        ice_reset_vf(vf, true);
+                       mutex_unlock(&vf->cfg_lock);
+               }
        }
 }
 
@@ -2140,7 +2150,9 @@ ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event)
        if (!vf)
                return;
 
+       mutex_lock(&vf->cfg_lock);
        ice_vc_reset_vf(vf);
+       mutex_unlock(&vf->cfg_lock);
 }
 
 /**
@@ -2170,24 +2182,6 @@ ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode,
 
        dev = ice_pf_to_dev(pf);
 
-       /* single place to detect unsuccessful return values */
-       if (v_retval) {
-               vf->num_inval_msgs++;
-               dev_info(dev, "VF %d failed opcode %d, retval: %d\n", vf->vf_id,
-                        v_opcode, v_retval);
-               if (vf->num_inval_msgs > ICE_DFLT_NUM_INVAL_MSGS_ALLOWED) {
-                       dev_err(dev, "Number of invalid messages exceeded for VF %d\n",
-                               vf->vf_id);
-                       dev_err(dev, "Use PF Control I/F to enable the VF\n");
-                       set_bit(ICE_VF_STATE_DIS, vf->vf_states);
-                       return -EIO;
-               }
-       } else {
-               vf->num_valid_msgs++;
-               /* reset the invalid counter, if a valid message is received. */
-               vf->num_inval_msgs = 0;
-       }
-
        aq_ret = ice_aq_send_msg_to_vf(&pf->hw, vf->vf_id, v_opcode, v_retval,
                                       msg, msglen, NULL);
        if (aq_ret && pf->hw.mailboxq.sq_last_status != ICE_AQ_RC_ENOSYS) {
@@ -4625,10 +4619,6 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
        struct device *dev;
        int err = 0;
 
-       /* if de-init is underway, don't process messages from VF */
-       if (test_bit(ICE_VF_DEINIT_IN_PROGRESS, pf->state))
-               return;
-
        dev = ice_pf_to_dev(pf);
        if (ice_validate_vf_id(pf, vf_id)) {
                err = -EINVAL;
index 752487a1bdd60bbfdd308f3e171e95f21396d455..8f27255cc0cca9000777b22f145e64960ca1e9b8 100644 (file)
@@ -14,7 +14,6 @@
 #define ICE_MAX_MACADDR_PER_VF         18
 
 /* Malicious Driver Detection */
-#define ICE_DFLT_NUM_INVAL_MSGS_ALLOWED                10
 #define ICE_MDD_EVENTS_THRESHOLD               30
 
 /* Static VF transaction/status register def */
@@ -134,8 +133,6 @@ struct ice_vf {
        unsigned int max_tx_rate;       /* Maximum Tx bandwidth limit in Mbps */
        DECLARE_BITMAP(vf_states, ICE_VF_STATES_NBITS); /* VF runtime states */
 
-       u64 num_inval_msgs;             /* number of continuous invalid msgs */
-       u64 num_valid_msgs;             /* number of valid msgs detected */
        unsigned long vf_caps;          /* VF's adv. capabilities */
        u8 num_req_qs;                  /* num of queue pairs requested by VF */
        u16 num_mac;
index 5cad31c3c7b09454da34129ddf51a51808c0e389..40dbf4b43234546634a3f8f04243fc651ea1f2e7 100644 (file)
@@ -746,8 +746,6 @@ s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data)
                if (ret_val)
                        return ret_val;
                ret_val = igc_write_phy_reg_mdic(hw, offset, data);
-               if (ret_val)
-                       return ret_val;
                hw->phy.ops.release(hw);
        } else {
                ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr,
@@ -779,8 +777,6 @@ s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data)
                if (ret_val)
                        return ret_val;
                ret_val = igc_read_phy_reg_mdic(hw, offset, data);
-               if (ret_val)
-                       return ret_val;
                hw->phy.ops.release(hw);
        } else {
                ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr,
index b3fd8e5cd85b4f3b47b643d1895eac049f20c1b8..6a5e9cf6b5dac4d1b887d05068f9fa1effe49754 100644 (file)
@@ -390,12 +390,14 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget)
        u32 cmd_type;
 
        while (budget-- > 0) {
-               if (unlikely(!ixgbe_desc_unused(xdp_ring)) ||
-                   !netif_carrier_ok(xdp_ring->netdev)) {
+               if (unlikely(!ixgbe_desc_unused(xdp_ring))) {
                        work_done = false;
                        break;
                }
 
+               if (!netif_carrier_ok(xdp_ring->netdev))
+                       break;
+
                if (!xsk_tx_peek_desc(pool, &desc))
                        break;
 
index 41d11137cde0c4ce397d29c920756a9e37034b25..5712c3e94be813eecb668d97be06385983e78a72 100644 (file)
@@ -260,9 +260,9 @@ static int xrx200_hw_receive(struct xrx200_chan *ch)
 
        if (ctl & LTQ_DMA_EOP) {
                ch->skb_head->protocol = eth_type_trans(ch->skb_head, net_dev);
-               netif_receive_skb(ch->skb_head);
                net_dev->stats.rx_packets++;
                net_dev->stats.rx_bytes += ch->skb_head->len;
+               netif_receive_skb(ch->skb_head);
                ch->skb_head = NULL;
                ch->skb_tail = NULL;
                ret = XRX200_DMA_PACKET_COMPLETE;
index 105247582684de01b1ac0743dfd12c41a93af193..143ca8be5eb595f77fb0d23177d74be80d89d847 100644 (file)
@@ -2704,6 +2704,16 @@ MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids);
 
 static struct platform_device *port_platdev[3];
 
+static void mv643xx_eth_shared_of_remove(void)
+{
+       int n;
+
+       for (n = 0; n < 3; n++) {
+               platform_device_del(port_platdev[n]);
+               port_platdev[n] = NULL;
+       }
+}
+
 static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
                                          struct device_node *pnp)
 {
@@ -2740,7 +2750,9 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
                return -EINVAL;
        }
 
-       of_get_mac_address(pnp, ppd.mac_addr);
+       ret = of_get_mac_address(pnp, ppd.mac_addr);
+       if (ret)
+               return ret;
 
        mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size);
        mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr);
@@ -2804,21 +2816,13 @@ static int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
                ret = mv643xx_eth_shared_of_add_port(pdev, pnp);
                if (ret) {
                        of_node_put(pnp);
+                       mv643xx_eth_shared_of_remove();
                        return ret;
                }
        }
        return 0;
 }
 
-static void mv643xx_eth_shared_of_remove(void)
-{
-       int n;
-
-       for (n = 0; n < 3; n++) {
-               platform_device_del(port_platdev[n]);
-               port_platdev[n] = NULL;
-       }
-}
 #else
 static inline int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
 {
index 7cdbf8b8bbf6c5cc533129f50e70053003e53859..1a835b48791beb79499296fb560c8d165d7a5acc 100644 (file)
@@ -6870,6 +6870,9 @@ static int mvpp2_port_probe(struct platform_device *pdev,
        dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
        dev->dev.of_node = port_node;
 
+       port->pcs_gmac.ops = &mvpp2_phylink_gmac_pcs_ops;
+       port->pcs_xlg.ops = &mvpp2_phylink_xlg_pcs_ops;
+
        if (!mvpp2_use_acpi_compat_mode(port_fwnode)) {
                port->phylink_config.dev = &dev->dev;
                port->phylink_config.type = PHYLINK_NETDEV;
@@ -6940,9 +6943,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
                                  port->phylink_config.supported_interfaces);
                }
 
-               port->pcs_gmac.ops = &mvpp2_phylink_gmac_pcs_ops;
-               port->pcs_xlg.ops = &mvpp2_phylink_xlg_pcs_ops;
-
                phylink = phylink_create(&port->phylink_config, port_fwnode,
                                         phy_mode, &mvpp2_phylink_ops);
                if (IS_ERR(phylink)) {
index cad93f747d0cc69df5165bd5379226f41ccf569f..73cd0a4b729142dd8738f4f7403dbe6ca4c75172 100644 (file)
@@ -554,6 +554,7 @@ static int prestera_switch_set_base_mac_addr(struct prestera_switch *sw)
                dev_info(prestera_dev(sw), "using random base mac address\n");
        }
        of_node_put(base_mac_np);
+       of_node_put(np);
 
        return prestera_hw_switch_mac_set(sw, sw->base_mac);
 }
index 17fe0580965331623055940f46c4578e585abad7..3eacd873992940255bd4ac786d0242bdb592a4d5 100644 (file)
@@ -131,11 +131,8 @@ static int cmd_alloc_index(struct mlx5_cmd *cmd)
 
 static void cmd_free_index(struct mlx5_cmd *cmd, int idx)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&cmd->alloc_lock, flags);
+       lockdep_assert_held(&cmd->alloc_lock);
        set_bit(idx, &cmd->bitmask);
-       spin_unlock_irqrestore(&cmd->alloc_lock, flags);
 }
 
 static void cmd_ent_get(struct mlx5_cmd_work_ent *ent)
@@ -145,17 +142,21 @@ static void cmd_ent_get(struct mlx5_cmd_work_ent *ent)
 
 static void cmd_ent_put(struct mlx5_cmd_work_ent *ent)
 {
+       struct mlx5_cmd *cmd = ent->cmd;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cmd->alloc_lock, flags);
        if (!refcount_dec_and_test(&ent->refcnt))
-               return;
+               goto out;
 
        if (ent->idx >= 0) {
-               struct mlx5_cmd *cmd = ent->cmd;
-
                cmd_free_index(cmd, ent->idx);
                up(ent->page_queue ? &cmd->pages_sem : &cmd->sem);
        }
 
        cmd_free_ent(ent);
+out:
+       spin_unlock_irqrestore(&cmd->alloc_lock, flags);
 }
 
 static struct mlx5_cmd_layout *get_inst(struct mlx5_cmd *cmd, int idx)
index 26efa33de56fbfc98df1d41ef9c6d956c1e8f6f8..9cc844bd00f59cea9f47f4876e2985ec10249e22 100644 (file)
@@ -16,11 +16,13 @@ struct mlx5e_tc_act_parse_state {
        unsigned int num_actions;
        struct mlx5e_tc_flow *flow;
        struct netlink_ext_ack *extack;
+       bool ct_clear;
        bool encap;
        bool decap;
        bool mpls_push;
        bool ptype_host;
        const struct ip_tunnel_info *tun_info;
+       struct mlx5e_mpls_info mpls_info;
        struct pedit_headers_action hdrs[__PEDIT_CMD_MAX];
        int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS];
        int if_count;
index 06ec30cdb269e2c9815400fa0ef7eb418d7a05d7..58cc33f1363d23ff576d91c9e16e9a9ad7bce00f 100644 (file)
@@ -27,8 +27,13 @@ tc_act_parse_ct(struct mlx5e_tc_act_parse_state *parse_state,
                struct mlx5e_priv *priv,
                struct mlx5_flow_attr *attr)
 {
+       bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR;
        int err;
 
+       /* It's redundant to do ct clear more than once. */
+       if (clear_action && parse_state->ct_clear)
+               return 0;
+
        err = mlx5_tc_ct_parse_action(parse_state->ct_priv, attr,
                                      &attr->parse_attr->mod_hdr_acts,
                                      act, parse_state->extack);
@@ -40,6 +45,8 @@ tc_act_parse_ct(struct mlx5e_tc_act_parse_state *parse_state,
        if (mlx5e_is_eswitch_flow(parse_state->flow))
                attr->esw_attr->split_count = attr->esw_attr->out_count;
 
+       parse_state->ct_clear = clear_action;
+
        return 0;
 }
 
index c614fc7fdc9c9f632471a4eb22673962a53a925f..2e615e0ba972b2e5b4bb1c74319c2821df36c5cf 100644 (file)
@@ -177,6 +177,12 @@ parse_mirred_encap(struct mlx5e_tc_act_parse_state *parse_state,
                return -ENOMEM;
 
        parse_state->encap = false;
+
+       if (parse_state->mpls_push) {
+               memcpy(&parse_attr->mpls_info[esw_attr->out_count],
+                      &parse_state->mpls_info, sizeof(parse_state->mpls_info));
+               parse_state->mpls_push = false;
+       }
        esw_attr->dests[esw_attr->out_count].flags |= MLX5_ESW_DEST_ENCAP;
        esw_attr->out_count++;
        /* attr->dests[].rep is resolved when we handle encap */
index 784fc4f68b1e41c7ee64f43fe88a0f515a2a20de..89ca88c78840d5cfd72b7a7bc213755d99d2b468 100644 (file)
@@ -22,6 +22,16 @@ tc_act_can_offload_mpls_push(struct mlx5e_tc_act_parse_state *parse_state,
        return true;
 }
 
+static void
+copy_mpls_info(struct mlx5e_mpls_info *mpls_info,
+              const struct flow_action_entry *act)
+{
+       mpls_info->label = act->mpls_push.label;
+       mpls_info->tc = act->mpls_push.tc;
+       mpls_info->bos = act->mpls_push.bos;
+       mpls_info->ttl = act->mpls_push.ttl;
+}
+
 static int
 tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state,
                       const struct flow_action_entry *act,
@@ -29,6 +39,7 @@ tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state,
                       struct mlx5_flow_attr *attr)
 {
        parse_state->mpls_push = true;
+       copy_mpls_info(&parse_state->mpls_info, act);
 
        return 0;
 }
index f832c26ff2c3e01e56163bfb032138e0a30c1b77..70b40ae384e42b8fb9c5679faf1a9a9099537a06 100644 (file)
@@ -35,6 +35,7 @@ enum {
 
 struct mlx5e_tc_flow_parse_attr {
        const struct ip_tunnel_info *tun_info[MLX5_MAX_FLOW_FWD_VPORTS];
+       struct mlx5e_mpls_info mpls_info[MLX5_MAX_FLOW_FWD_VPORTS];
        struct net_device *filter_dev;
        struct mlx5_flow_spec spec;
        struct mlx5e_tc_mod_hdr_acts mod_hdr_acts;
index 9918ed8c059b6b48347eb38e2256d3fdf4e30648..d39d0dae22fcee1a7013129915b6be73eaee3f2a 100644 (file)
@@ -750,6 +750,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
        struct mlx5e_tc_flow_parse_attr *parse_attr;
        struct mlx5_flow_attr *attr = flow->attr;
        const struct ip_tunnel_info *tun_info;
+       const struct mlx5e_mpls_info *mpls_info;
        unsigned long tbl_time_before = 0;
        struct mlx5e_encap_entry *e;
        struct mlx5e_encap_key key;
@@ -760,6 +761,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
 
        parse_attr = attr->parse_attr;
        tun_info = parse_attr->tun_info[out_index];
+       mpls_info = &parse_attr->mpls_info[out_index];
        family = ip_tunnel_info_af(tun_info);
        key.ip_tun_key = &tun_info->key;
        key.tc_tunnel = mlx5e_get_tc_tun(mirred_dev);
@@ -810,6 +812,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
                goto out_err_init;
        }
        e->tun_info = tun_info;
+       memcpy(&e->mpls_info, mpls_info, sizeof(*mpls_info));
        err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack);
        if (err)
                goto out_err_init;
index 60952b33b5688835ddd5bfdddc2a0e30fa56fd5f..c5b1617d556fe0df9e07d4df118c595a4237edcf 100644 (file)
@@ -30,16 +30,15 @@ static int generate_ip_tun_hdr(char buf[],
                               struct mlx5e_encap_entry *r)
 {
        const struct ip_tunnel_key *tun_key = &r->tun_info->key;
+       const struct mlx5e_mpls_info *mpls_info = &r->mpls_info;
        struct udphdr *udp = (struct udphdr *)(buf);
        struct mpls_shim_hdr *mpls;
-       u32 tun_id;
 
-       tun_id = be32_to_cpu(tunnel_id_to_key32(tun_key->tun_id));
        mpls = (struct mpls_shim_hdr *)(udp + 1);
        *ip_proto = IPPROTO_UDP;
 
        udp->dest = tun_key->tp_dst;
-       *mpls = mpls_entry_encode(tun_id, tun_key->ttl, tun_key->tos, true);
+       *mpls = mpls_entry_encode(mpls_info->label, mpls_info->ttl, mpls_info->tc, mpls_info->bos);
 
        return 0;
 }
@@ -60,37 +59,31 @@ static int parse_tunnel(struct mlx5e_priv *priv,
                        void *headers_v)
 {
        struct flow_rule *rule = flow_cls_offload_flow_rule(f);
-       struct flow_match_enc_keyid enc_keyid;
        struct flow_match_mpls match;
        void *misc2_c;
        void *misc2_v;
 
-       misc2_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
-                              misc_parameters_2);
-       misc2_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
-                              misc_parameters_2);
-
-       if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS))
-               return 0;
-
-       if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID))
-               return 0;
-
-       flow_rule_match_enc_keyid(rule, &enc_keyid);
-
-       if (!enc_keyid.mask->keyid)
-               return 0;
-
        if (!MLX5_CAP_ETH(priv->mdev, tunnel_stateless_mpls_over_udp) &&
            !(MLX5_CAP_GEN(priv->mdev, flex_parser_protocols) & MLX5_FLEX_PROTO_CW_MPLS_UDP))
                return -EOPNOTSUPP;
 
+       if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID))
+               return -EOPNOTSUPP;
+
+       if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS))
+               return 0;
+
        flow_rule_match_mpls(rule, &match);
 
        /* Only support matching the first LSE */
        if (match.mask->used_lses != 1)
                return -EOPNOTSUPP;
 
+       misc2_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+                              misc_parameters_2);
+       misc2_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
+                              misc_parameters_2);
+
        MLX5_SET(fte_match_set_misc2, misc2_c,
                 outer_first_mpls_over_udp.mpls_label,
                 match.mask->ls[0].mpls_label);
index da169b816665050aa4b88f53ff25f819a8c51bc1..d4239e3b3c88efcc2ed0b5f0d84eb82285032b20 100644 (file)
@@ -88,9 +88,6 @@ void mlx5e_tir_builder_build_packet_merge(struct mlx5e_tir_builder *builder,
                         (MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ - rough_max_l2_l3_hdr_sz) >> 8);
                MLX5_SET(tirc, tirc, lro_timeout_period_usecs, pkt_merge_param->timeout);
                break;
-       case MLX5E_PACKET_MERGE_SHAMPO:
-               MLX5_SET(tirc, tirc, packet_merge_mask, MLX5_TIRC_PACKET_MERGE_MASK_SHAMPO);
-               break;
        default:
                break;
        }
index 57d755db1cf5a92a434c6dec196e27863bfade93..6e80585d731fe7a0f8b6a2fb2fed0cca49cb93f7 100644 (file)
@@ -1792,7 +1792,7 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev,
                if (size_read < 0) {
                        netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n",
                                   __func__, size_read);
-                       return 0;
+                       return size_read;
                }
 
                i += size_read;
index bf80fb6124499fc4e6a0310ab92c91159b4ccbbb..3667f5ef5990f5254c90d4d8f01e03befcd5bf38 100644 (file)
@@ -3616,8 +3616,7 @@ static int set_feature_hw_gro(struct net_device *netdev, bool enable)
                goto out;
        }
 
-       err = mlx5e_safe_switch_params(priv, &new_params,
-                                      mlx5e_modify_tirs_packet_merge_ctx, NULL, reset);
+       err = mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, reset);
 out:
        mutex_unlock(&priv->state_lock);
        return err;
index b01dacb6f527c81f27688dd0c14763ceeb210a17..b3f7520dfd0845637dbde3bdba15fb82f3175cf7 100644 (file)
@@ -183,6 +183,13 @@ struct mlx5e_decap_entry {
        struct rcu_head rcu;
 };
 
+struct mlx5e_mpls_info {
+       u32             label;
+       u8              tc;
+       u8              bos;
+       u8              ttl;
+};
+
 struct mlx5e_encap_entry {
        /* attached neigh hash entry */
        struct mlx5e_neigh_hash_entry *nhe;
@@ -196,6 +203,7 @@ struct mlx5e_encap_entry {
        struct list_head route_list;
        struct mlx5_pkt_reformat *pkt_reformat;
        const struct ip_tunnel_info *tun_info;
+       struct mlx5e_mpls_info mpls_info;
        unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
 
        struct net_device *out_dev;
index ee0a8f5206e3a00df96c3edb5429b00dee36f28f..6530d7bd504533abcd9184b8b47b6eb459476936 100644 (file)
@@ -1349,7 +1349,8 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
        }
 
        /* True when explicitly set via priv flag, or XDP prog is loaded */
-       if (test_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &rq->state))
+       if (test_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &rq->state) ||
+           get_cqe_tls_offload(cqe))
                goto csum_unnecessary;
 
        /* CQE csum doesn't cover padding octets in short ethernet
index 8c9163d2c64684372c04a3e25aa6f43a5de0b7f2..08a75654f5f188ca96a04c3920416e3c9b0eab5f 100644 (file)
@@ -334,6 +334,7 @@ void mlx5e_self_test(struct net_device *ndev, struct ethtool_test *etest,
                netdev_info(ndev, "\t[%d] %s start..\n", i, st.name);
                buf[count] = st.st_func(priv);
                netdev_info(ndev, "\t[%d] %s end: result(%lld)\n", i, st.name, buf[count]);
+               count++;
        }
 
        mutex_unlock(&priv->state_lock);
index 26e326fe503ceaba24bfbc75f0b5ee41da4b01cd..00f1d16db45689d68cdd10c3c3bfacd4cc4ae02d 100644 (file)
@@ -1254,9 +1254,6 @@ static void fec_set_corrected_bits_total(struct mlx5e_priv *priv,
        u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
        int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
 
-       if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group))
-               return;
-
        MLX5_SET(ppcnt_reg, in, local_port, 1);
        MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_STATISTICAL_GROUP);
        if (mlx5_core_access_reg(mdev, in, sz, ppcnt_phy_statistical,
@@ -1272,6 +1269,9 @@ static void fec_set_corrected_bits_total(struct mlx5e_priv *priv,
 void mlx5e_stats_fec_get(struct mlx5e_priv *priv,
                         struct ethtool_fec_stats *fec_stats)
 {
+       if (!MLX5_CAP_PCAM_FEATURE(priv->mdev, ppcnt_statistical_group))
+               return;
+
        fec_set_corrected_bits_total(priv, fec_stats);
        fec_set_block_stats(priv, fec_stats);
 }
index 2022fa4a959850e929329b9c6c4255373339bc2c..b27532a9301e751ca4556ea2fe6d9ef21721cf55 100644 (file)
@@ -3204,6 +3204,18 @@ actions_match_supported(struct mlx5e_priv *priv,
                return false;
        }
 
+       if (!(~actions &
+             (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) {
+               NL_SET_ERR_MSG_MOD(extack, "Rule cannot support forward+drop action");
+               return false;
+       }
+
+       if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
+           actions & MLX5_FLOW_CONTEXT_ACTION_DROP) {
+               NL_SET_ERR_MSG_MOD(extack, "Drop with modify header action is not supported");
+               return false;
+       }
+
        if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
            !modify_header_match_supported(priv, &parse_attr->spec, flow_action,
                                           actions, ct_flow, ct_clear, extack))
index 11bbcd5f5b8b9c1c9bdf2a112982d6f271dd610b..694c540669550a2c6f37656932d1a414c97b1803 100644 (file)
@@ -697,7 +697,7 @@ void mlx5_esw_qos_vport_disable(struct mlx5_eswitch *esw, struct mlx5_vport *vpo
 }
 
 int mlx5_esw_qos_set_vport_rate(struct mlx5_eswitch *esw, struct mlx5_vport *vport,
-                               u32 min_rate, u32 max_rate)
+                               u32 max_rate, u32 min_rate)
 {
        int err;
 
index 9a7b25692505efd58127165bad66bcdee1f841f1..cfcd72bad9af66e9ae154aa9208edc5158882edd 100644 (file)
@@ -2838,10 +2838,6 @@ bool mlx5_esw_vport_match_metadata_supported(const struct mlx5_eswitch *esw)
        if (!MLX5_CAP_ESW_FLOWTABLE(esw->dev, flow_source))
                return false;
 
-       if (mlx5_core_is_ecpf_esw_manager(esw->dev) ||
-           mlx5_ecpf_vport_exists(esw->dev))
-               return false;
-
        return true;
 }
 
index b628917e38e465b80334555da31b2c04cb395544..537c82b9aa530e68c8943f994904593a6bcc41fc 100644 (file)
@@ -2074,6 +2074,8 @@ void mlx5_del_flow_rules(struct mlx5_flow_handle *handle)
                fte->node.del_hw_func = NULL;
                up_write_ref_node(&fte->node, false);
                tree_put_node(&fte->node, false);
+       } else {
+               up_write_ref_node(&fte->node, false);
        }
        kfree(handle);
 }
index 1ca01a5b6cdd803ed206685be19ddbcd12bcfe52..626aa60b6099b61641de67421611aeab348d3817 100644 (file)
@@ -126,6 +126,10 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
                return;
        }
 
+       /* Handle multipath entry with lower priority value */
+       if (mp->mfi && mp->mfi != fi && fi->fib_priority >= mp->mfi->fib_priority)
+               return;
+
        /* Handle add/replace event */
        nhs = fib_info_num_path(fi);
        if (nhs == 1) {
@@ -135,12 +139,13 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
                        int i = mlx5_lag_dev_get_netdev_idx(ldev, nh_dev);
 
                        if (i < 0)
-                               i = MLX5_LAG_NORMAL_AFFINITY;
-                       else
-                               ++i;
+                               return;
 
+                       i++;
                        mlx5_lag_set_port_affinity(ldev, i);
                }
+
+               mp->mfi = fi;
                return;
        }
 
index 2c774f367199d6846241abab218e11706aa76064..bba72b220cc3f4cbd99c2a3517bfb49ad3d8943e 100644 (file)
@@ -526,7 +526,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
 
        /* Check log_max_qp from HCA caps to set in current profile */
        if (prof->log_max_qp == LOG_MAX_SUPPORTED_QPS) {
-               prof->log_max_qp = MLX5_CAP_GEN_MAX(dev, log_max_qp);
+               prof->log_max_qp = min_t(u8, 17, MLX5_CAP_GEN_MAX(dev, log_max_qp));
        } else if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) {
                mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n",
                               prof->log_max_qp,
@@ -1840,10 +1840,12 @@ static const struct pci_device_id mlx5_core_pci_table[] = {
        { PCI_VDEVICE(MELLANOX, 0x101e), MLX5_PCI_DEV_IS_VF},   /* ConnectX Family mlx5Gen Virtual Function */
        { PCI_VDEVICE(MELLANOX, 0x101f) },                      /* ConnectX-6 LX */
        { PCI_VDEVICE(MELLANOX, 0x1021) },                      /* ConnectX-7 */
+       { PCI_VDEVICE(MELLANOX, 0x1023) },                      /* ConnectX-8 */
        { PCI_VDEVICE(MELLANOX, 0xa2d2) },                      /* BlueField integrated ConnectX-5 network controller */
        { PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF},   /* BlueField integrated ConnectX-5 network controller VF */
        { PCI_VDEVICE(MELLANOX, 0xa2d6) },                      /* BlueField-2 integrated ConnectX-6 Dx network controller */
        { PCI_VDEVICE(MELLANOX, 0xa2dc) },                      /* BlueField-3 integrated ConnectX-7 network controller */
+       { PCI_VDEVICE(MELLANOX, 0xa2df) },                      /* BlueField-4 integrated ConnectX-8 network controller */
        { 0, }
 };
 
index 7f6fd9c5e371b4af30b9cc78307c514fbf68a808..e289cfdbce07513d5f31af78e1f6ceec516d387d 100644 (file)
@@ -4,7 +4,6 @@
 #include "dr_types.h"
 
 #define DR_ICM_MODIFY_HDR_ALIGN_BASE 64
-#define DR_ICM_SYNC_THRESHOLD_POOL (64 * 1024 * 1024)
 
 struct mlx5dr_icm_pool {
        enum mlx5dr_icm_type icm_type;
@@ -136,37 +135,35 @@ static void dr_icm_pool_mr_destroy(struct mlx5dr_icm_mr *icm_mr)
        kvfree(icm_mr);
 }
 
-static int dr_icm_chunk_ste_init(struct mlx5dr_icm_chunk *chunk)
+static int dr_icm_buddy_get_ste_size(struct mlx5dr_icm_buddy_mem *buddy)
 {
-       chunk->ste_arr = kvzalloc(chunk->num_of_entries *
-                                 sizeof(chunk->ste_arr[0]), GFP_KERNEL);
-       if (!chunk->ste_arr)
-               return -ENOMEM;
-
-       chunk->hw_ste_arr = kvzalloc(chunk->num_of_entries *
-                                    DR_STE_SIZE_REDUCED, GFP_KERNEL);
-       if (!chunk->hw_ste_arr)
-               goto out_free_ste_arr;
-
-       chunk->miss_list = kvmalloc(chunk->num_of_entries *
-                                   sizeof(chunk->miss_list[0]), GFP_KERNEL);
-       if (!chunk->miss_list)
-               goto out_free_hw_ste_arr;
+       /* We support only one type of STE size, both for ConnectX-5 and later
+        * devices. Once the support for match STE which has a larger tag is
+        * added (32B instead of 16B), the STE size for devices later than
+        * ConnectX-5 needs to account for that.
+        */
+       return DR_STE_SIZE_REDUCED;
+}
 
-       return 0;
+static void dr_icm_chunk_ste_init(struct mlx5dr_icm_chunk *chunk, int offset)
+{
+       struct mlx5dr_icm_buddy_mem *buddy = chunk->buddy_mem;
+       int index = offset / DR_STE_SIZE;
 
-out_free_hw_ste_arr:
-       kvfree(chunk->hw_ste_arr);
-out_free_ste_arr:
-       kvfree(chunk->ste_arr);
-       return -ENOMEM;
+       chunk->ste_arr = &buddy->ste_arr[index];
+       chunk->miss_list = &buddy->miss_list[index];
+       chunk->hw_ste_arr = buddy->hw_ste_arr +
+                           index * dr_icm_buddy_get_ste_size(buddy);
 }
 
 static void dr_icm_chunk_ste_cleanup(struct mlx5dr_icm_chunk *chunk)
 {
-       kvfree(chunk->miss_list);
-       kvfree(chunk->hw_ste_arr);
-       kvfree(chunk->ste_arr);
+       struct mlx5dr_icm_buddy_mem *buddy = chunk->buddy_mem;
+
+       memset(chunk->hw_ste_arr, 0,
+              chunk->num_of_entries * dr_icm_buddy_get_ste_size(buddy));
+       memset(chunk->ste_arr, 0,
+              chunk->num_of_entries * sizeof(chunk->ste_arr[0]));
 }
 
 static enum mlx5dr_icm_type
@@ -189,6 +186,44 @@ static void dr_icm_chunk_destroy(struct mlx5dr_icm_chunk *chunk,
        kvfree(chunk);
 }
 
+static int dr_icm_buddy_init_ste_cache(struct mlx5dr_icm_buddy_mem *buddy)
+{
+       int num_of_entries =
+               mlx5dr_icm_pool_chunk_size_to_entries(buddy->pool->max_log_chunk_sz);
+
+       buddy->ste_arr = kvcalloc(num_of_entries,
+                                 sizeof(struct mlx5dr_ste), GFP_KERNEL);
+       if (!buddy->ste_arr)
+               return -ENOMEM;
+
+       /* Preallocate full STE size on non-ConnectX-5 devices since
+        * we need to support both full and reduced with the same cache.
+        */
+       buddy->hw_ste_arr = kvcalloc(num_of_entries,
+                                    dr_icm_buddy_get_ste_size(buddy), GFP_KERNEL);
+       if (!buddy->hw_ste_arr)
+               goto free_ste_arr;
+
+       buddy->miss_list = kvmalloc(num_of_entries * sizeof(struct list_head), GFP_KERNEL);
+       if (!buddy->miss_list)
+               goto free_hw_ste_arr;
+
+       return 0;
+
+free_hw_ste_arr:
+       kvfree(buddy->hw_ste_arr);
+free_ste_arr:
+       kvfree(buddy->ste_arr);
+       return -ENOMEM;
+}
+
+static void dr_icm_buddy_cleanup_ste_cache(struct mlx5dr_icm_buddy_mem *buddy)
+{
+       kvfree(buddy->ste_arr);
+       kvfree(buddy->hw_ste_arr);
+       kvfree(buddy->miss_list);
+}
+
 static int dr_icm_buddy_create(struct mlx5dr_icm_pool *pool)
 {
        struct mlx5dr_icm_buddy_mem *buddy;
@@ -208,11 +243,19 @@ static int dr_icm_buddy_create(struct mlx5dr_icm_pool *pool)
        buddy->icm_mr = icm_mr;
        buddy->pool = pool;
 
+       if (pool->icm_type == DR_ICM_TYPE_STE) {
+               /* Reduce allocations by preallocating and reusing the STE structures */
+               if (dr_icm_buddy_init_ste_cache(buddy))
+                       goto err_cleanup_buddy;
+       }
+
        /* add it to the -start- of the list in order to search in it first */
        list_add(&buddy->list_node, &pool->buddy_mem_list);
 
        return 0;
 
+err_cleanup_buddy:
+       mlx5dr_buddy_cleanup(buddy);
 err_free_buddy:
        kvfree(buddy);
 free_mr:
@@ -234,6 +277,9 @@ static void dr_icm_buddy_destroy(struct mlx5dr_icm_buddy_mem *buddy)
 
        mlx5dr_buddy_cleanup(buddy);
 
+       if (buddy->pool->icm_type == DR_ICM_TYPE_STE)
+               dr_icm_buddy_cleanup_ste_cache(buddy);
+
        kvfree(buddy);
 }
 
@@ -261,34 +307,30 @@ dr_icm_chunk_create(struct mlx5dr_icm_pool *pool,
        chunk->byte_size =
                mlx5dr_icm_pool_chunk_size_to_byte(chunk_size, pool->icm_type);
        chunk->seg = seg;
+       chunk->buddy_mem = buddy_mem_pool;
 
-       if (pool->icm_type == DR_ICM_TYPE_STE && dr_icm_chunk_ste_init(chunk)) {
-               mlx5dr_err(pool->dmn,
-                          "Failed to init ste arrays (order: %d)\n",
-                          chunk_size);
-               goto out_free_chunk;
-       }
+       if (pool->icm_type == DR_ICM_TYPE_STE)
+               dr_icm_chunk_ste_init(chunk, offset);
 
        buddy_mem_pool->used_memory += chunk->byte_size;
-       chunk->buddy_mem = buddy_mem_pool;
        INIT_LIST_HEAD(&chunk->chunk_list);
 
        /* chunk now is part of the used_list */
        list_add_tail(&chunk->chunk_list, &buddy_mem_pool->used_list);
 
        return chunk;
-
-out_free_chunk:
-       kvfree(chunk);
-       return NULL;
 }
 
 static bool dr_icm_pool_is_sync_required(struct mlx5dr_icm_pool *pool)
 {
-       if (pool->hot_memory_size > DR_ICM_SYNC_THRESHOLD_POOL)
-               return true;
+       int allow_hot_size;
+
+       /* sync when hot memory reaches half of the pool size */
+       allow_hot_size =
+               mlx5dr_icm_pool_chunk_size_to_byte(pool->max_log_chunk_sz,
+                                                  pool->icm_type) / 2;
 
-       return false;
+       return pool->hot_memory_size > allow_hot_size;
 }
 
 static int dr_icm_pool_sync_all_buddy_pools(struct mlx5dr_icm_pool *pool)
index e87cf498c77bf37a1127eb1699d72349afccd5fe..38971fe1dfe1b5aa8176e87475f2c463d0bcbd6e 100644 (file)
@@ -13,18 +13,6 @@ static bool dr_mask_is_dmac_set(struct mlx5dr_match_spec *spec)
        return (spec->dmac_47_16 || spec->dmac_15_0);
 }
 
-static bool dr_mask_is_src_addr_set(struct mlx5dr_match_spec *spec)
-{
-       return (spec->src_ip_127_96 || spec->src_ip_95_64 ||
-               spec->src_ip_63_32 || spec->src_ip_31_0);
-}
-
-static bool dr_mask_is_dst_addr_set(struct mlx5dr_match_spec *spec)
-{
-       return (spec->dst_ip_127_96 || spec->dst_ip_95_64 ||
-               spec->dst_ip_63_32 || spec->dst_ip_31_0);
-}
-
 static bool dr_mask_is_l3_base_set(struct mlx5dr_match_spec *spec)
 {
        return (spec->ip_protocol || spec->frag || spec->tcp_flags ||
@@ -503,11 +491,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
                                                    &mask, inner, rx);
 
                if (outer_ipv == DR_RULE_IPV6) {
-                       if (dr_mask_is_dst_addr_set(&mask.outer))
+                       if (DR_MASK_IS_DST_IP_SET(&mask.outer))
                                mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
-                       if (dr_mask_is_src_addr_set(&mask.outer))
+                       if (DR_MASK_IS_SRC_IP_SET(&mask.outer))
                                mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
@@ -610,11 +598,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
                                                    &mask, inner, rx);
 
                if (inner_ipv == DR_RULE_IPV6) {
-                       if (dr_mask_is_dst_addr_set(&mask.inner))
+                       if (DR_MASK_IS_DST_IP_SET(&mask.inner))
                                mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
-                       if (dr_mask_is_src_addr_set(&mask.inner))
+                       if (DR_MASK_IS_SRC_IP_SET(&mask.inner))
                                mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
index 7e61742e58a0e2cf521e3568ce0acc263a63a5cf..187e29b409b6cfa23f36354fdb153dc770859820 100644 (file)
@@ -602,12 +602,34 @@ int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx,
                                                 used_hw_action_num);
 }
 
+static int dr_ste_build_pre_check_spec(struct mlx5dr_domain *dmn,
+                                      struct mlx5dr_match_spec *spec)
+{
+       if (spec->ip_version) {
+               if (spec->ip_version != 0xf) {
+                       mlx5dr_err(dmn,
+                                  "Partial ip_version mask with src/dst IP is not supported\n");
+                       return -EINVAL;
+               }
+       } else if (spec->ethertype != 0xffff &&
+                  (DR_MASK_IS_SRC_IP_SET(spec) || DR_MASK_IS_DST_IP_SET(spec))) {
+               mlx5dr_err(dmn,
+                          "Partial/no ethertype mask with src/dst IP is not supported\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
                               u8 match_criteria,
                               struct mlx5dr_match_param *mask,
                               struct mlx5dr_match_param *value)
 {
-       if (!value && (match_criteria & DR_MATCHER_CRITERIA_MISC)) {
+       if (value)
+               return 0;
+
+       if (match_criteria & DR_MATCHER_CRITERIA_MISC) {
                if (mask->misc.source_port && mask->misc.source_port != 0xffff) {
                        mlx5dr_err(dmn,
                                   "Partial mask source_port is not supported\n");
@@ -621,6 +643,14 @@ int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
                }
        }
 
+       if ((match_criteria & DR_MATCHER_CRITERIA_OUTER) &&
+           dr_ste_build_pre_check_spec(dmn, &mask->outer))
+               return -EINVAL;
+
+       if ((match_criteria & DR_MATCHER_CRITERIA_INNER) &&
+           dr_ste_build_pre_check_spec(dmn, &mask->inner))
+               return -EINVAL;
+
        return 0;
 }
 
index 1b3d484b99be19e2f2632da3f65cd0c1bb7a4e8e..55fcb751e24a43616c6c55c066936446c064fe3b 100644 (file)
@@ -798,6 +798,16 @@ struct mlx5dr_match_param {
                                       (_misc3)->icmpv4_code || \
                                       (_misc3)->icmpv4_header_data)
 
+#define DR_MASK_IS_SRC_IP_SET(_spec) ((_spec)->src_ip_127_96 || \
+                                     (_spec)->src_ip_95_64  || \
+                                     (_spec)->src_ip_63_32  || \
+                                     (_spec)->src_ip_31_0)
+
+#define DR_MASK_IS_DST_IP_SET(_spec) ((_spec)->dst_ip_127_96 || \
+                                     (_spec)->dst_ip_95_64  || \
+                                     (_spec)->dst_ip_63_32  || \
+                                     (_spec)->dst_ip_31_0)
+
 struct mlx5dr_esw_caps {
        u64 drop_icm_address_rx;
        u64 drop_icm_address_tx;
index a476da2424f8e39d22f6bcac1666a85d10d8b1e9..3f311462bedf3ee5ac3b26cb1bef249284626184 100644 (file)
@@ -233,7 +233,11 @@ static bool contain_vport_reformat_action(struct mlx5_flow_rule *dst)
                dst->dest_attr.vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID;
 }
 
-#define MLX5_FLOW_CONTEXT_ACTION_MAX  32
+/* We want to support a rule with 32 destinations, which means we need to
+ * account for 32 destinations plus usually a counter plus one more action
+ * for a multi-destination flow table.
+ */
+#define MLX5_FLOW_CONTEXT_ACTION_MAX  34
 static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
                                  struct mlx5_flow_table *ft,
                                  struct mlx5_flow_group *group,
@@ -403,9 +407,9 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
                        enum mlx5_flow_destination_type type = dst->dest_attr.type;
                        u32 id;
 
-                       if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX ||
-                           num_term_actions >= MLX5_FLOW_CONTEXT_ACTION_MAX) {
-                               err = -ENOSPC;
+                       if (fs_dr_num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX ||
+                           num_term_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) {
+                               err = -EOPNOTSUPP;
                                goto free_actions;
                        }
 
@@ -478,8 +482,9 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
                            MLX5_FLOW_DESTINATION_TYPE_COUNTER)
                                continue;
 
-                       if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) {
-                               err = -ENOSPC;
+                       if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX ||
+                           fs_dr_num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) {
+                               err = -EOPNOTSUPP;
                                goto free_actions;
                        }
 
@@ -499,14 +504,28 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
        params.match_sz = match_sz;
        params.match_buf = (u64 *)fte->val;
        if (num_term_actions == 1) {
-               if (term_actions->reformat)
+               if (term_actions->reformat) {
+                       if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) {
+                               err = -EOPNOTSUPP;
+                               goto free_actions;
+                       }
                        actions[num_actions++] = term_actions->reformat;
+               }
 
+               if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) {
+                       err = -EOPNOTSUPP;
+                       goto free_actions;
+               }
                actions[num_actions++] = term_actions->dest;
        } else if (num_term_actions > 1) {
                bool ignore_flow_level =
                        !!(fte->action.flags & FLOW_ACT_IGNORE_FLOW_LEVEL);
 
+               if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX ||
+                   fs_dr_num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) {
+                       err = -EOPNOTSUPP;
+                       goto free_actions;
+               }
                tmp_action = mlx5dr_action_create_mult_dest_tbl(domain,
                                                                term_actions,
                                                                num_term_actions,
index c7c93131b762b64de9d11d2f71e44491f627788e..dfa223415fe24fed05e7dfd1ae728ca7f4d3b835 100644 (file)
@@ -160,6 +160,11 @@ struct mlx5dr_icm_buddy_mem {
         * sync_ste command sets them free.
         */
        struct list_head        hot_list;
+
+       /* Memory optimisation */
+       struct mlx5dr_ste       *ste_arr;
+       struct list_head        *miss_list;
+       u8                      *hw_ste_arr;
 };
 
 int mlx5dr_buddy_init(struct mlx5dr_icm_buddy_mem *buddy,
index a1acc9b461f211e6ecb82d89ad9b2a5a0e782add..d40e18ce32935f61179e7e193a5d49dfc3c2f7db 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/phylink.h>
 #include <linux/hrtimer.h>
 
+#include "sparx5_main_regs.h"
+
 /* Target chip type */
 enum spx5_target_chiptype {
        SPX5_TARGET_CT_7546    = 0x7546,  /* SparX-5-64  Enterprise */
index 4ce490a25f332dfbfc1116281047037c68010512..8e56ffa1c4f7afe5f1ba2eb6d19c80e8c0a08c6d 100644 (file)
@@ -58,16 +58,6 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
        struct sparx5 *sparx5 = port->sparx5;
        int ret;
 
-       /* Make the port a member of the VLAN */
-       set_bit(port->portno, sparx5->vlan_mask[vid]);
-       ret = sparx5_vlant_set_mask(sparx5, vid);
-       if (ret)
-               return ret;
-
-       /* Default ingress vlan classification */
-       if (pvid)
-               port->pvid = vid;
-
        /* Untagged egress vlan classification */
        if (untagged && port->vid != vid) {
                if (port->vid) {
@@ -79,6 +69,16 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
                port->vid = vid;
        }
 
+       /* Make the port a member of the VLAN */
+       set_bit(port->portno, sparx5->vlan_mask[vid]);
+       ret = sparx5_vlant_set_mask(sparx5, vid);
+       if (ret)
+               return ret;
+
+       /* Default ingress vlan classification */
+       if (pvid)
+               port->pvid = vid;
+
        sparx5_vlan_port_apply(sparx5, port);
 
        return 0;
index 949858891973d4bd6c03406dcd087710839ac0e7..fdb4d7e7296c8a0bc5066417b591fa7fcfedb0a4 100644 (file)
@@ -60,6 +60,12 @@ static int ocelot_chain_to_block(int chain, bool ingress)
  */
 static int ocelot_chain_to_lookup(int chain)
 {
+       /* Backwards compatibility with older, single-chain tc-flower
+        * offload support in Ocelot
+        */
+       if (chain == 0)
+               return 0;
+
        return (chain / VCAP_LOOKUP) % 10;
 }
 
@@ -68,7 +74,15 @@ static int ocelot_chain_to_lookup(int chain)
  */
 static int ocelot_chain_to_pag(int chain)
 {
-       int lookup = ocelot_chain_to_lookup(chain);
+       int lookup;
+
+       /* Backwards compatibility with older, single-chain tc-flower
+        * offload support in Ocelot
+        */
+       if (chain == 0)
+               return 0;
+
+       lookup = ocelot_chain_to_lookup(chain);
 
        /* calculate PAG value as chain index relative to the first PAG */
        return chain - VCAP_IS2_CHAIN(lookup, 0);
index 0a326e04e6923351e2b9180144cfc504a3040c0b..cb43651ea9ba87a2222c79da34274399fdf33eb7 100644 (file)
@@ -922,8 +922,8 @@ nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev,
                          int port, bool mod)
 {
        struct nfp_flower_priv *priv = app->priv;
-       int ida_idx = NFP_MAX_MAC_INDEX, err;
        struct nfp_tun_offloaded_mac *entry;
+       int ida_idx = -1, err;
        u16 nfp_mac_idx = 0;
 
        entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr);
@@ -997,7 +997,7 @@ err_remove_hash:
 err_free_entry:
        kfree(entry);
 err_free_ida:
-       if (ida_idx != NFP_MAX_MAC_INDEX)
+       if (ida_idx != -1)
                ida_simple_remove(&priv->tun.mac_off_ids, ida_idx);
 
        return err;
index bc39558fe82be1e6e38e1a38b0c22b2f8ee50305..756f97dce85b2b4a5ed95667adeffe177b7b0984 100644 (file)
@@ -1471,6 +1471,7 @@ static int lpc_eth_drv_resume(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct netdata_local *pldat;
+       int ret;
 
        if (device_may_wakeup(&pdev->dev))
                disable_irq_wake(ndev->irq);
@@ -1480,7 +1481,9 @@ static int lpc_eth_drv_resume(struct platform_device *pdev)
                        pldat = netdev_priv(ndev);
 
                        /* Enable interface clock */
-                       clk_enable(pldat->clk);
+                       ret = clk_enable(pldat->clk);
+                       if (ret)
+                               return ret;
 
                        /* Reset and initialize */
                        __lpc_eth_reset(pldat);
index 8ac38828ba459796bfd426ff130530b83f1fa7c5..48cf4355bc47a59ec40c68624bfa8c92ba182bf6 100644 (file)
@@ -3806,11 +3806,11 @@ bool qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *p_disabled_vfs)
        return found;
 }
 
-static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
-                            u16 vfid,
-                            struct qed_mcp_link_params *p_params,
-                            struct qed_mcp_link_state *p_link,
-                            struct qed_mcp_link_capabilities *p_caps)
+static int qed_iov_get_link(struct qed_hwfn *p_hwfn,
+                           u16 vfid,
+                           struct qed_mcp_link_params *p_params,
+                           struct qed_mcp_link_state *p_link,
+                           struct qed_mcp_link_capabilities *p_caps)
 {
        struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
                                                       vfid,
@@ -3818,7 +3818,7 @@ static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
        struct qed_bulletin_content *p_bulletin;
 
        if (!p_vf)
-               return;
+               return -EINVAL;
 
        p_bulletin = p_vf->bulletin.p_virt;
 
@@ -3828,6 +3828,7 @@ static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
                __qed_vf_get_link_state(p_hwfn, p_link, p_bulletin);
        if (p_caps)
                __qed_vf_get_link_caps(p_hwfn, p_caps, p_bulletin);
+       return 0;
 }
 
 static int
@@ -4686,6 +4687,7 @@ static int qed_get_vf_config(struct qed_dev *cdev,
        struct qed_public_vf_info *vf_info;
        struct qed_mcp_link_state link;
        u32 tx_rate;
+       int ret;
 
        /* Sanitize request */
        if (IS_VF(cdev))
@@ -4699,7 +4701,9 @@ static int qed_get_vf_config(struct qed_dev *cdev,
 
        vf_info = qed_iov_get_public_vf_info(hwfn, vf_id, true);
 
-       qed_iov_get_link(hwfn, vf_id, NULL, &link, NULL);
+       ret = qed_iov_get_link(hwfn, vf_id, NULL, &link, NULL);
+       if (ret)
+               return ret;
 
        /* Fill information about VF */
        ivi->vf = vf_id;
index 597cd9cd57b54102b34c8abbdbb5a6c407a1059e..7b0e390c0b07dc970329046414642e01289bec22 100644 (file)
@@ -513,6 +513,9 @@ int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn)
                                                    p_iov->bulletin.size,
                                                    &p_iov->bulletin.phys,
                                                    GFP_KERNEL);
+       if (!p_iov->bulletin.p_virt)
+               goto free_pf2vf_reply;
+
        DP_VERBOSE(p_hwfn, QED_MSG_IOV,
                   "VF's bulletin Board [%p virt 0x%llx phys 0x%08x bytes]\n",
                   p_iov->bulletin.p_virt,
@@ -552,6 +555,10 @@ int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn)
 
        return rc;
 
+free_pf2vf_reply:
+       dma_free_coherent(&p_hwfn->cdev->pdev->dev,
+                         sizeof(union pfvf_tlvs),
+                         p_iov->pf2vf_reply, p_iov->pf2vf_reply_phys);
 free_vf2pf_request:
        dma_free_coherent(&p_hwfn->cdev->pdev->dev,
                          sizeof(union vfpf_tlvs),
index 32161a56726c1af89df1c538dec5b4cc318fcac4..2881f5b2b5f49fdabee66dd9662fd83ebb1787dc 100644 (file)
@@ -2285,18 +2285,18 @@ static int __init sxgbe_cmdline_opt(char *str)
        char *opt;
 
        if (!str || !*str)
-               return -EINVAL;
+               return 1;
        while ((opt = strsep(&str, ",")) != NULL) {
                if (!strncmp(opt, "eee_timer:", 10)) {
                        if (kstrtoint(opt + 10, 0, &eee_timer))
                                goto err;
                }
        }
-       return 0;
+       return 1;
 
 err:
        pr_err("%s: ERROR broken module parameter conversion\n", __func__);
-       return -EINVAL;
+       return 1;
 }
 
 __setup("sxgbeeth=", sxgbe_cmdline_opt);
index be6bfd6b7ec7576407f85ebb786eaed238f7d8be..50baf62b2cbc6808bad368e45d6e2efce7573f8c 100644 (file)
@@ -163,9 +163,9 @@ static void efx_mcdi_send_request(struct efx_nic *efx, unsigned cmd,
        /* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */
        spin_lock_bh(&mcdi->iface_lock);
        ++mcdi->seqno;
+       seqno = mcdi->seqno & SEQ_MASK;
        spin_unlock_bh(&mcdi->iface_lock);
 
-       seqno = mcdi->seqno & SEQ_MASK;
        xflags = 0;
        if (mcdi->mode == MCDI_MODE_EVENTS)
                xflags |= MCDI_HEADER_XFLAGS_EVREQ;
index bde76ea2deecf0ac927a1577a34a048efe2214a9..422e3225f476a85c1fff1aa945d46a1be3e7eebb 100644 (file)
@@ -2262,6 +2262,23 @@ static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan)
        stmmac_stop_tx(priv, priv->ioaddr, chan);
 }
 
+static void stmmac_enable_all_dma_irq(struct stmmac_priv *priv)
+{
+       u32 rx_channels_count = priv->plat->rx_queues_to_use;
+       u32 tx_channels_count = priv->plat->tx_queues_to_use;
+       u32 dma_csr_ch = max(rx_channels_count, tx_channels_count);
+       u32 chan;
+
+       for (chan = 0; chan < dma_csr_ch; chan++) {
+               struct stmmac_channel *ch = &priv->channel[chan];
+               unsigned long flags;
+
+               spin_lock_irqsave(&ch->lock, flags);
+               stmmac_enable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
+               spin_unlock_irqrestore(&ch->lock, flags);
+       }
+}
+
 /**
  * stmmac_start_all_dma - start all RX and TX DMA channels
  * @priv: driver private structure
@@ -2904,8 +2921,10 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
                stmmac_axi(priv, priv->ioaddr, priv->plat->axi);
 
        /* DMA CSR Channel configuration */
-       for (chan = 0; chan < dma_csr_ch; chan++)
+       for (chan = 0; chan < dma_csr_ch; chan++) {
                stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
+               stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
+       }
 
        /* DMA RX Channel Configuration */
        for (chan = 0; chan < rx_channels_count; chan++) {
@@ -3761,6 +3780,7 @@ static int stmmac_open(struct net_device *dev)
 
        stmmac_enable_all_queues(priv);
        netif_tx_start_all_queues(priv->dev);
+       stmmac_enable_all_dma_irq(priv);
 
        return 0;
 
@@ -6510,8 +6530,10 @@ int stmmac_xdp_open(struct net_device *dev)
        }
 
        /* DMA CSR Channel configuration */
-       for (chan = 0; chan < dma_csr_ch; chan++)
+       for (chan = 0; chan < dma_csr_ch; chan++) {
                stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
+               stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
+       }
 
        /* Adjust Split header */
        sph_en = (priv->hw->rx_csum > 0) && priv->sph;
@@ -6572,6 +6594,7 @@ int stmmac_xdp_open(struct net_device *dev)
        stmmac_enable_all_queues(priv);
        netif_carrier_on(dev);
        netif_tx_start_all_queues(dev);
+       stmmac_enable_all_dma_irq(priv);
 
        return 0;
 
@@ -7451,6 +7474,7 @@ int stmmac_resume(struct device *dev)
        stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw);
 
        stmmac_enable_all_queues(priv);
+       stmmac_enable_all_dma_irq(priv);
 
        mutex_unlock(&priv->lock);
        rtnl_unlock();
@@ -7467,7 +7491,7 @@ static int __init stmmac_cmdline_opt(char *str)
        char *opt;
 
        if (!str || !*str)
-               return -EINVAL;
+               return 1;
        while ((opt = strsep(&str, ",")) != NULL) {
                if (!strncmp(opt, "debug:", 6)) {
                        if (kstrtoint(opt + 6, 0, &debug))
@@ -7498,11 +7522,11 @@ static int __init stmmac_cmdline_opt(char *str)
                                goto err;
                }
        }
-       return 0;
+       return 1;
 
 err:
        pr_err("%s: ERROR broken module parameter conversion", __func__);
-       return -EINVAL;
+       return 1;
 }
 
 __setup("stmmaceth=", stmmac_cmdline_opt);
index ad9029ae684851ff93eae56dd101ae93ce4b35ad..77e5dffb558f4a15ee78cb34e45959bd3bbf472a 100644 (file)
@@ -3146,7 +3146,7 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
        if (err) {
                printk(KERN_ERR "happymeal(PCI): Cannot register net device, "
                       "aborting.\n");
-               goto err_out_iounmap;
+               goto err_out_free_coherent;
        }
 
        pci_set_drvdata(pdev, hp);
@@ -3179,6 +3179,10 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
 
        return 0;
 
+err_out_free_coherent:
+       dma_free_coherent(hp->dma_dev, PAGE_SIZE,
+                         hp->happy_block, hp->hblock_dvma);
+
 err_out_iounmap:
        iounmap(hp->gregs);
 
index dc70a6bfaa6a16d7d4d5e6514c58b93b72559adc..92ca739fac01028eb4f47091c5627e9e42c69dd9 100644 (file)
@@ -568,7 +568,9 @@ int cpts_register(struct cpts *cpts)
        for (i = 0; i < CPTS_MAX_EVENTS; i++)
                list_add(&cpts->pool_data[i].list, &cpts->pool);
 
-       clk_enable(cpts->refclk);
+       err = clk_enable(cpts->refclk);
+       if (err)
+               return err;
 
        cpts_write32(cpts, CPTS_EN, control);
        cpts_write32(cpts, TS_PEND_EN, int_enable);
index b900ab5aef2a8fa578c1649c0f1fee4fdfb415a7..64c7e26c3b75488f1ffd7dc6a33f308bea0299a6 100644 (file)
@@ -1433,6 +1433,8 @@ static int temac_probe(struct platform_device *pdev)
                lp->indirect_lock = devm_kmalloc(&pdev->dev,
                                                 sizeof(*lp->indirect_lock),
                                                 GFP_KERNEL);
+               if (!lp->indirect_lock)
+                       return -ENOMEM;
                spin_lock_init(lp->indirect_lock);
        }
 
index 519599480b15411c660fcbbfa6dc2e600fada179..77fa2cb03acaa99d71126a6d2c2d3d4729f4d534 100644 (file)
@@ -1183,7 +1183,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev)
        if (rc) {
                dev_err(dev,
                        "Cannot register network device, aborting\n");
-               goto error;
+               goto put_node;
        }
 
        dev_info(dev,
@@ -1191,6 +1191,8 @@ static int xemaclite_of_probe(struct platform_device *ofdev)
                 (unsigned long __force)ndev->mem_start, lp->base_addr, ndev->irq);
        return 0;
 
+put_node:
+       of_node_put(lp->phy_node);
 error:
        free_netdev(ndev);
        return rc;
index b1fc153125d9d3d37870858d45c13030915e1899..45c3c4a1101b7f9a20d2b3d79e986aa453d7a640 100644 (file)
@@ -668,11 +668,11 @@ static void sixpack_close(struct tty_struct *tty)
         */
        netif_stop_queue(sp->dev);
 
+       unregister_netdev(sp->dev);
+
        del_timer_sync(&sp->tx_t);
        del_timer_sync(&sp->resync_t);
 
-       unregister_netdev(sp->dev);
-
        /* Free all 6pack frame buffers after unreg. */
        kfree(sp->rbuff);
        kfree(sp->xbuff);
index 3646469433b1c3c28eba0fcb33725d89b9a5c71d..fde1c492ca02af30b9392c2eb9ab3a5ec27b766c 100644 (file)
@@ -1587,6 +1587,9 @@ static void netvsc_get_ethtool_stats(struct net_device *dev,
        pcpu_sum = kvmalloc_array(num_possible_cpus(),
                                  sizeof(struct netvsc_ethtool_pcpu_stats),
                                  GFP_KERNEL);
+       if (!pcpu_sum)
+               return;
+
        netvsc_get_pcpu_stats(dev, pcpu_sum);
        for_each_present_cpu(cpu) {
                struct netvsc_ethtool_pcpu_stats *this_sum = &pcpu_sum[cpu];
index d037682fb7adb8ab20e617fbc3053bd258b85e3c..6782c2cbf542fa683f48fa80ab5ffedd7cb52fe1 100644 (file)
@@ -2,7 +2,9 @@ config QCOM_IPA
        tristate "Qualcomm IPA support"
        depends on NET && QCOM_SMEM
        depends on ARCH_QCOM || COMPILE_TEST
+       depends on INTERCONNECT
        depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST)
+       depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
        select QCOM_MDT_LOADER if ARCH_QCOM
        select QCOM_SCM
        select QCOM_QMI_HELPERS
index 5f4cd24a0241d33f31450d7ee6a979ad34c5fa68..4eba5a91075c07cd52267a4c9401e367fde74dc8 100644 (file)
@@ -200,7 +200,11 @@ static int ipq_mdio_reset(struct mii_bus *bus)
        if (ret)
                return ret;
 
-       return clk_prepare_enable(priv->mdio_clk);
+       ret = clk_prepare_enable(priv->mdio_clk);
+       if (ret == 0)
+               mdelay(10);
+
+       return ret;
 }
 
 static int ipq4019_mdio_probe(struct platform_device *pdev)
index 7d2abaf2b2c9774ba074274302bb8bb7f81139ad..64fb76c1e3959836b05a4b4c294ad07ed9e4d510 100644 (file)
@@ -187,6 +187,13 @@ static const struct regmap_config mscc_miim_regmap_config = {
        .reg_stride     = 4,
 };
 
+static const struct regmap_config mscc_miim_phy_regmap_config = {
+       .reg_bits       = 32,
+       .val_bits       = 32,
+       .reg_stride     = 4,
+       .name           = "phy",
+};
+
 int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name,
                    struct regmap *mii_regmap, int status_offset)
 {
@@ -250,7 +257,7 @@ static int mscc_miim_probe(struct platform_device *pdev)
                }
 
                phy_regmap = devm_regmap_init_mmio(&pdev->dev, phy_regs,
-                                                  &mscc_miim_regmap_config);
+                                                  &mscc_miim_phy_regmap_config);
                if (IS_ERR(phy_regmap)) {
                        dev_err(&pdev->dev, "Unable to create phy register regmap\n");
                        return PTR_ERR(phy_regmap);
index 211b5476a6f516666e004ea03382eb716a5a2103..ce17b2af3218f0c0a64a4c1535af279791407b4e 100644 (file)
@@ -274,7 +274,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
                if (err < 0)
                        return err;
 
-               err = phy_write(phydev, MII_DP83822_MISR1, 0);
+               err = phy_write(phydev, MII_DP83822_MISR2, 0);
                if (err < 0)
                        return err;
 
index 2429db614b59ab4dfc91b4053edfebbff6effb8a..2702faf7b0f60210587af984367e6403c3ce5742 100644 (file)
@@ -1687,8 +1687,8 @@ static int marvell_suspend(struct phy_device *phydev)
        int err;
 
        /* Suspend the fiber mode first */
-       if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
-                              phydev->supported)) {
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                             phydev->supported)) {
                err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
                if (err < 0)
                        goto error;
@@ -1722,8 +1722,8 @@ static int marvell_resume(struct phy_device *phydev)
        int err;
 
        /* Resume the fiber mode first */
-       if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
-                              phydev->supported)) {
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                             phydev->supported)) {
                err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
                if (err < 0)
                        goto error;
index 7e7904fee1d976dfa1a4691961f8866f81bd9791..73f7962a37d335508b4a09e82d01132822c3b98f 100644 (file)
 #define  INTSRC_LINK_DOWN      BIT(4)
 #define  INTSRC_REMOTE_FAULT   BIT(5)
 #define  INTSRC_ANEG_COMPLETE  BIT(6)
+#define  INTSRC_ENERGY_DETECT  BIT(7)
 #define INTSRC_MASK    30
 
+#define INT_SOURCES (INTSRC_LINK_DOWN | INTSRC_ANEG_COMPLETE | \
+                    INTSRC_ENERGY_DETECT)
+
 #define BANK_ANALOG_DSP                0
 #define BANK_WOL               1
 #define BANK_BIST              3
@@ -200,7 +204,6 @@ static int meson_gxl_ack_interrupt(struct phy_device *phydev)
 
 static int meson_gxl_config_intr(struct phy_device *phydev)
 {
-       u16 val;
        int ret;
 
        if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
@@ -209,16 +212,9 @@ static int meson_gxl_config_intr(struct phy_device *phydev)
                if (ret)
                        return ret;
 
-               val = INTSRC_ANEG_PR
-                       | INTSRC_PARALLEL_FAULT
-                       | INTSRC_ANEG_LP_ACK
-                       | INTSRC_LINK_DOWN
-                       | INTSRC_REMOTE_FAULT
-                       | INTSRC_ANEG_COMPLETE;
-               ret = phy_write(phydev, INTSRC_MASK, val);
+               ret = phy_write(phydev, INTSRC_MASK, INT_SOURCES);
        } else {
-               val = 0;
-               ret = phy_write(phydev, INTSRC_MASK, val);
+               ret = phy_write(phydev, INTSRC_MASK, 0);
 
                /* Ack any pending IRQ */
                ret = meson_gxl_ack_interrupt(phydev);
@@ -237,10 +233,23 @@ static irqreturn_t meson_gxl_handle_interrupt(struct phy_device *phydev)
                return IRQ_NONE;
        }
 
+       irq_status &= INT_SOURCES;
+
        if (irq_status == 0)
                return IRQ_NONE;
 
-       phy_trigger_machine(phydev);
+       /* Aneg-complete interrupt is used for link-up detection */
+       if (phydev->autoneg == AUTONEG_ENABLE &&
+           irq_status == INTSRC_ENERGY_DETECT)
+               return IRQ_HANDLED;
+
+       /* Give PHY some time before MAC starts sending data. This works
+        * around an issue where network doesn't come up properly.
+        */
+       if (!(irq_status & INTSRC_LINK_DOWN))
+               phy_queue_state_machine(phydev, msecs_to_jiffies(100));
+       else
+               phy_trigger_machine(phydev);
 
        return IRQ_HANDLED;
 }
index ebfeeb3c67c1d94c5751f0d66cba5720324d32bd..7e3017e7a1c0324746f1e53a068a70eddacdbea3 100644 (file)
@@ -2685,3 +2685,6 @@ MODULE_DEVICE_TABLE(mdio, vsc85xx_tbl);
 MODULE_DESCRIPTION("Microsemi VSC85xx PHY driver");
 MODULE_AUTHOR("Nagaraju Lakkaraju");
 MODULE_LICENSE("Dual MIT/GPL");
+
+MODULE_FIRMWARE(MSCC_VSC8584_REVB_INT8051_FW);
+MODULE_FIRMWARE(MSCC_VSC8574_REVB_INT8051_FW);
index bc1e3dd67c04c9b81354a7b25342ce0cc8ca6ea5..a0f29482294d45dadf17d2aa49f364dbd08fd52a 100644 (file)
@@ -84,9 +84,10 @@ static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
        ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN
                 | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                 0, index, &buf, 4);
-       if (unlikely(ret < 0)) {
-               netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
-                           index, ret);
+       if (ret < 0) {
+               if (ret != -ENODEV)
+                       netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
+                                   index, ret);
                return ret;
        }
 
@@ -116,7 +117,7 @@ static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index,
        ret = fn(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, USB_DIR_OUT
                 | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                 0, index, &buf, 4);
-       if (unlikely(ret < 0))
+       if (ret < 0 && ret != -ENODEV)
                netdev_warn(dev->net, "Failed to write reg index 0x%08x: %d\n",
                            index, ret);
 
@@ -159,6 +160,9 @@ static int __must_check __smsc95xx_phy_wait_not_busy(struct usbnet *dev,
        do {
                ret = __smsc95xx_read_reg(dev, MII_ADDR, &val, in_pm);
                if (ret < 0) {
+                       /* Ignore -ENODEV error during disconnect() */
+                       if (ret == -ENODEV)
+                               return 0;
                        netdev_warn(dev->net, "Error reading MII_ACCESS\n");
                        return ret;
                }
@@ -194,7 +198,8 @@ static int __smsc95xx_mdio_read(struct usbnet *dev, int phy_id, int idx,
        addr = mii_address_cmd(phy_id, idx, MII_READ_ | MII_BUSY_);
        ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm);
        if (ret < 0) {
-               netdev_warn(dev->net, "Error writing MII_ADDR\n");
+               if (ret != -ENODEV)
+                       netdev_warn(dev->net, "Error writing MII_ADDR\n");
                goto done;
        }
 
@@ -206,7 +211,8 @@ static int __smsc95xx_mdio_read(struct usbnet *dev, int phy_id, int idx,
 
        ret = __smsc95xx_read_reg(dev, MII_DATA, &val, in_pm);
        if (ret < 0) {
-               netdev_warn(dev->net, "Error reading MII_DATA\n");
+               if (ret != -ENODEV)
+                       netdev_warn(dev->net, "Error reading MII_DATA\n");
                goto done;
        }
 
@@ -214,6 +220,10 @@ static int __smsc95xx_mdio_read(struct usbnet *dev, int phy_id, int idx,
 
 done:
        mutex_unlock(&dev->phy_mutex);
+
+       /* Ignore -ENODEV error during disconnect() */
+       if (ret == -ENODEV)
+               return 0;
        return ret;
 }
 
@@ -235,7 +245,8 @@ static void __smsc95xx_mdio_write(struct usbnet *dev, int phy_id,
        val = regval;
        ret = __smsc95xx_write_reg(dev, MII_DATA, val, in_pm);
        if (ret < 0) {
-               netdev_warn(dev->net, "Error writing MII_DATA\n");
+               if (ret != -ENODEV)
+                       netdev_warn(dev->net, "Error writing MII_DATA\n");
                goto done;
        }
 
@@ -243,7 +254,8 @@ static void __smsc95xx_mdio_write(struct usbnet *dev, int phy_id,
        addr = mii_address_cmd(phy_id, idx, MII_WRITE_ | MII_BUSY_);
        ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm);
        if (ret < 0) {
-               netdev_warn(dev->net, "Error writing MII_ADDR\n");
+               if (ret != -ENODEV)
+                       netdev_warn(dev->net, "Error writing MII_ADDR\n");
                goto done;
        }
 
index b658510cc9a42e1a0cab4d608a44fa078c2fdbf5..5a53e63d33a60995ea8023474e664f6fc14017a5 100644 (file)
@@ -413,7 +413,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
                /* ignore the CRC length */
                len = (skb->data[1] | (skb->data[2] << 8)) - 4;
 
-               if (len > ETH_FRAME_LEN)
+               if (len > ETH_FRAME_LEN || len > skb->len)
                        return 0;
 
                /* the last packet of current skb */
index 62c453a21e49e954adb5a469f3f4aa6a94428fcc..7c1c2658cb5f8c170e8c0944e9afba63a685d2bd 100644 (file)
@@ -2611,36 +2611,9 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
                ath10k_mac_handle_beacon(ar, skb);
 
        if (ieee80211_is_beacon(hdr->frame_control) ||
-           ieee80211_is_probe_resp(hdr->frame_control)) {
-               struct ieee80211_mgmt *mgmt = (void *)skb->data;
-               enum cfg80211_bss_frame_type ftype;
-               u8 *ies;
-               int ies_ch;
-
+           ieee80211_is_probe_resp(hdr->frame_control))
                status->boottime_ns = ktime_get_boottime_ns();
 
-               if (!ar->scan_channel)
-                       goto drop;
-
-               ies = mgmt->u.beacon.variable;
-
-               if (ieee80211_is_beacon(mgmt->frame_control))
-                       ftype = CFG80211_BSS_FTYPE_BEACON;
-               else
-                       ftype = CFG80211_BSS_FTYPE_PRESP;
-
-               ies_ch = cfg80211_get_ies_channel_number(mgmt->u.beacon.variable,
-                                                        skb_tail_pointer(skb) - ies,
-                                                        sband->band, ftype);
-
-               if (ies_ch > 0 && ies_ch != channel) {
-                       ath10k_dbg(ar, ATH10K_DBG_MGMT,
-                                  "channel mismatched ds channel %d scan channel %d\n",
-                                  ies_ch, channel);
-                       goto drop;
-               }
-       }
-
        ath10k_dbg(ar, ATH10K_DBG_MGMT,
                   "event mgmt rx skb %pK len %d ftype %02x stype %02x\n",
                   skb, skb->len,
@@ -2654,10 +2627,6 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
        ieee80211_rx_ni(ar->hw, skb);
 
        return 0;
-
-drop:
-       dev_kfree_skb(skb);
-       return 0;
 }
 
 static int freq_to_idx(struct ath10k *ar, int freq)
index 1364b0014488685dfbdfd79b8f2e6a2139eb26c4..208e73a16051938607957e988d33c3149f21264d 100644 (file)
@@ -5,3 +5,4 @@ obj-$(CONFIG_IPW2200) += ipw2x00/
 obj-$(CONFIG_IWLEGACY) += iwlegacy/
 
 obj-$(CONFIG_IWLWIFI)  += iwlwifi/
+obj-$(CONFIG_IWLMEI)   += iwlwifi/
index dd58c8f9aa1131999f8e08cecad86dfee9487e63..04addf964d839ba332b43f39e615513bd210ccb3 100644 (file)
@@ -553,8 +553,7 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
                        .has_he = true,
                        .he_cap_elem = {
                                .mac_cap_info[0] =
-                                       IEEE80211_HE_MAC_CAP0_HTC_HE |
-                                       IEEE80211_HE_MAC_CAP0_TWT_REQ,
+                                       IEEE80211_HE_MAC_CAP0_HTC_HE,
                                .mac_cap_info[1] =
                                        IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
                                        IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
index 63432c24eb592a91b4eefc5c48bd04361dae6415..445c94adb0768bce113167e681020d586f35f511 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
 #include <linux/vmalloc.h>
+#include <linux/err.h>
 #include <linux/ieee80211.h>
 #include <linux/netdevice.h>
 
@@ -1857,7 +1858,6 @@ void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
 void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)
 {
        struct dentry *bcast_dir __maybe_unused;
-       char buf[100];
 
        spin_lock_init(&mvm->drv_stats_lock);
 
@@ -1939,6 +1939,11 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)
         * Create a symlink with mac80211. It will be removed when mac80211
         * exists (before the opmode exists which removes the target.)
         */
-       snprintf(buf, 100, "../../%pd2", mvm->debugfs_dir->d_parent);
-       debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf);
+       if (!IS_ERR(mvm->debugfs_dir)) {
+               char buf[100];
+
+               snprintf(buf, 100, "../../%pd2", mvm->debugfs_dir->d_parent);
+               debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir,
+                                      buf);
+       }
 }
index 4ac599f6ad22a64c03e095d5cf0aed7acb5e2293..709a3df57b10ddfc3a1b270523b77e7be34a00a7 100644 (file)
@@ -226,7 +226,6 @@ static const u8 he_if_types_ext_capa_sta[] = {
         [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
         [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
         [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
-        [9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
 };
 
 static const struct wiphy_iftype_ext_capab he_iftypes_ext_capa[] = {
index 78450366312b12e8a207a61bb3c5c2ab8720fb1b..080a1587caa568f9c479051971946fcb4cd69b6b 100644 (file)
@@ -71,12 +71,13 @@ static int iwl_mvm_vendor_host_get_ownership(struct wiphy *wiphy,
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       int ret;
 
        mutex_lock(&mvm->mutex);
-       iwl_mvm_mei_get_ownership(mvm);
+       ret = iwl_mvm_mei_get_ownership(mvm);
        mutex_unlock(&mvm->mutex);
 
-       return 0;
+       return ret;
 }
 
 static const struct wiphy_vendor_command iwl_mvm_vendor_commands[] = {
index d24b7a7993aa0545b721675c2432061b718a3d45..990360d75cb6481936d2a7c5e1e5e63ee25a9db6 100644 (file)
@@ -256,6 +256,7 @@ static void backend_disconnect(struct backend_info *be)
                unsigned int queue_index;
 
                xen_unregister_watchers(vif);
+               xenbus_rm(XBT_NIL, be->dev->nodename, "hotplug-status");
 #ifdef CONFIG_DEBUG_FS
                xenvif_debugfs_delif(vif);
 #endif /* CONFIG_DEBUG_FS */
@@ -675,7 +676,6 @@ static void hotplug_status_changed(struct xenbus_watch *watch,
 
                /* Not interested in this watch anymore. */
                unregister_hotplug_status_watch(be);
-               xenbus_rm(XBT_NIL, be->dev->nodename, "hotplug-status");
        }
        kfree(str);
 }
@@ -824,15 +824,11 @@ static void connect(struct backend_info *be)
        xenvif_carrier_on(be->vif);
 
        unregister_hotplug_status_watch(be);
-       if (xenbus_exists(XBT_NIL, dev->nodename, "hotplug-status")) {
-               err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
-                                          NULL, hotplug_status_changed,
-                                          "%s/%s", dev->nodename,
-                                          "hotplug-status");
-               if (err)
-                       goto err;
+       err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, NULL,
+                                  hotplug_status_changed,
+                                  "%s/%s", dev->nodename, "hotplug-status");
+       if (!err)
                be->have_hotplug_status_watch = 1;
-       }
 
        netif_tx_wake_all_queues(be->vif->dev);
 
index 8b18246ad9992483faf94ff16471e40b0d39da21..daa4e6106aacc4004c4b02b2daf46fe969ee8d66 100644 (file)
@@ -424,14 +424,12 @@ static bool xennet_tx_buf_gc(struct netfront_queue *queue)
                        queue->tx_link[id] = TX_LINK_NONE;
                        skb = queue->tx_skbs[id];
                        queue->tx_skbs[id] = NULL;
-                       if (unlikely(gnttab_query_foreign_access(
-                               queue->grant_tx_ref[id]) != 0)) {
+                       if (unlikely(!gnttab_end_foreign_access_ref(
+                               queue->grant_tx_ref[id], GNTMAP_readonly))) {
                                dev_alert(dev,
                                          "Grant still in use by backend domain\n");
                                goto err;
                        }
-                       gnttab_end_foreign_access_ref(
-                               queue->grant_tx_ref[id], GNTMAP_readonly);
                        gnttab_release_grant_reference(
                                &queue->gref_tx_head, queue->grant_tx_ref[id]);
                        queue->grant_tx_ref[id] = GRANT_INVALID_REF;
@@ -842,6 +840,28 @@ static int xennet_close(struct net_device *dev)
        return 0;
 }
 
+static void xennet_destroy_queues(struct netfront_info *info)
+{
+       unsigned int i;
+
+       for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
+               struct netfront_queue *queue = &info->queues[i];
+
+               if (netif_running(info->netdev))
+                       napi_disable(&queue->napi);
+               netif_napi_del(&queue->napi);
+       }
+
+       kfree(info->queues);
+       info->queues = NULL;
+}
+
+static void xennet_uninit(struct net_device *dev)
+{
+       struct netfront_info *np = netdev_priv(dev);
+       xennet_destroy_queues(np);
+}
+
 static void xennet_set_rx_rsp_cons(struct netfront_queue *queue, RING_IDX val)
 {
        unsigned long flags;
@@ -968,7 +988,6 @@ static int xennet_get_responses(struct netfront_queue *queue,
        struct device *dev = &queue->info->netdev->dev;
        struct bpf_prog *xdp_prog;
        struct xdp_buff xdp;
-       unsigned long ret;
        int slots = 1;
        int err = 0;
        u32 verdict;
@@ -1010,8 +1029,13 @@ static int xennet_get_responses(struct netfront_queue *queue,
                        goto next;
                }
 
-               ret = gnttab_end_foreign_access_ref(ref, 0);
-               BUG_ON(!ret);
+               if (!gnttab_end_foreign_access_ref(ref, 0)) {
+                       dev_alert(dev,
+                                 "Grant still in use by backend domain\n");
+                       queue->info->broken = true;
+                       dev_alert(dev, "Disabled for further use\n");
+                       return -EINVAL;
+               }
 
                gnttab_release_grant_reference(&queue->gref_rx_head, ref);
 
@@ -1232,6 +1256,10 @@ static int xennet_poll(struct napi_struct *napi, int budget)
                                           &need_xdp_flush);
 
                if (unlikely(err)) {
+                       if (queue->info->broken) {
+                               spin_unlock(&queue->rx_lock);
+                               return 0;
+                       }
 err:
                        while ((skb = __skb_dequeue(&tmpq)))
                                __skb_queue_tail(&errq, skb);
@@ -1611,6 +1639,7 @@ static int xennet_xdp(struct net_device *dev, struct netdev_bpf *xdp)
 }
 
 static const struct net_device_ops xennet_netdev_ops = {
+       .ndo_uninit          = xennet_uninit,
        .ndo_open            = xennet_open,
        .ndo_stop            = xennet_close,
        .ndo_start_xmit      = xennet_start_xmit,
@@ -1895,7 +1924,7 @@ static int setup_netfront(struct xenbus_device *dev,
                        struct netfront_queue *queue, unsigned int feature_split_evtchn)
 {
        struct xen_netif_tx_sring *txs;
-       struct xen_netif_rx_sring *rxs;
+       struct xen_netif_rx_sring *rxs = NULL;
        grant_ref_t gref;
        int err;
 
@@ -1915,21 +1944,21 @@ static int setup_netfront(struct xenbus_device *dev,
 
        err = xenbus_grant_ring(dev, txs, 1, &gref);
        if (err < 0)
-               goto grant_tx_ring_fail;
+               goto fail;
        queue->tx_ring_ref = gref;
 
        rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH);
        if (!rxs) {
                err = -ENOMEM;
                xenbus_dev_fatal(dev, err, "allocating rx ring page");
-               goto alloc_rx_ring_fail;
+               goto fail;
        }
        SHARED_RING_INIT(rxs);
        FRONT_RING_INIT(&queue->rx, rxs, XEN_PAGE_SIZE);
 
        err = xenbus_grant_ring(dev, rxs, 1, &gref);
        if (err < 0)
-               goto grant_rx_ring_fail;
+               goto fail;
        queue->rx_ring_ref = gref;
 
        if (feature_split_evtchn)
@@ -1942,22 +1971,28 @@ static int setup_netfront(struct xenbus_device *dev,
                err = setup_netfront_single(queue);
 
        if (err)
-               goto alloc_evtchn_fail;
+               goto fail;
 
        return 0;
 
        /* If we fail to setup netfront, it is safe to just revoke access to
         * granted pages because backend is not accessing it at this point.
         */
-alloc_evtchn_fail:
-       gnttab_end_foreign_access_ref(queue->rx_ring_ref, 0);
-grant_rx_ring_fail:
-       free_page((unsigned long)rxs);
-alloc_rx_ring_fail:
-       gnttab_end_foreign_access_ref(queue->tx_ring_ref, 0);
-grant_tx_ring_fail:
-       free_page((unsigned long)txs);
-fail:
+ fail:
+       if (queue->rx_ring_ref != GRANT_INVALID_REF) {
+               gnttab_end_foreign_access(queue->rx_ring_ref, 0,
+                                         (unsigned long)rxs);
+               queue->rx_ring_ref = GRANT_INVALID_REF;
+       } else {
+               free_page((unsigned long)rxs);
+       }
+       if (queue->tx_ring_ref != GRANT_INVALID_REF) {
+               gnttab_end_foreign_access(queue->tx_ring_ref, 0,
+                                         (unsigned long)txs);
+               queue->tx_ring_ref = GRANT_INVALID_REF;
+       } else {
+               free_page((unsigned long)txs);
+       }
        return err;
 }
 
@@ -2103,22 +2138,6 @@ error:
        return err;
 }
 
-static void xennet_destroy_queues(struct netfront_info *info)
-{
-       unsigned int i;
-
-       for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
-               struct netfront_queue *queue = &info->queues[i];
-
-               if (netif_running(info->netdev))
-                       napi_disable(&queue->napi);
-               netif_napi_del(&queue->napi);
-       }
-
-       kfree(info->queues);
-       info->queues = NULL;
-}
-
 
 
 static int xennet_create_page_pool(struct netfront_queue *queue)
index d7db1a0e6be1253fce4f284ac360e7c5360dc1f5..00d8ea6dcb5dbad081bbd539fdea2689451a83fd 100644 (file)
@@ -1612,7 +1612,9 @@ free_nfc_dev:
        nfc_digital_free_device(dev->nfc_digital_dev);
 
 error:
+       usb_kill_urb(dev->in_urb);
        usb_free_urb(dev->in_urb);
+       usb_kill_urb(dev->out_urb);
        usb_free_urb(dev->out_urb);
        usb_put_dev(dev->udev);
 
index fede05151f6986db790f2566f79fcbebcf19eaaf..4081fc538ff45a7bcf6772ee07e177c91869c71c 100644 (file)
@@ -168,6 +168,18 @@ static enum ntb_topo gen4_ppd_topo(struct intel_ntb_dev *ndev, u32 ppd)
        return NTB_TOPO_NONE;
 }
 
+static enum ntb_topo spr_ppd_topo(struct intel_ntb_dev *ndev, u32 ppd)
+{
+       switch (ppd & SPR_PPD_TOPO_MASK) {
+       case SPR_PPD_TOPO_B2B_USD:
+               return NTB_TOPO_B2B_USD;
+       case SPR_PPD_TOPO_B2B_DSD:
+               return NTB_TOPO_B2B_DSD;
+       }
+
+       return NTB_TOPO_NONE;
+}
+
 int gen4_init_dev(struct intel_ntb_dev *ndev)
 {
        struct pci_dev *pdev = ndev->ntb.pdev;
@@ -183,7 +195,10 @@ int gen4_init_dev(struct intel_ntb_dev *ndev)
        }
 
        ppd1 = ioread32(ndev->self_mmio + GEN4_PPD1_OFFSET);
-       ndev->ntb.topo = gen4_ppd_topo(ndev, ppd1);
+       if (pdev_is_ICX(pdev))
+               ndev->ntb.topo = gen4_ppd_topo(ndev, ppd1);
+       else if (pdev_is_SPR(pdev))
+               ndev->ntb.topo = spr_ppd_topo(ndev, ppd1);
        dev_dbg(&pdev->dev, "ppd %#x topo %s\n", ppd1,
                ntb_topo_string(ndev->ntb.topo));
        if (ndev->ntb.topo == NTB_TOPO_NONE)
index 3fcd3fdce9edfbc6efe6b80d52cad7ed811c0d1d..f91323eaf5ce4693eb1ebd01e65c855ca1376948 100644 (file)
 #define GEN4_PPD_CLEAR_TRN             0x0001
 #define GEN4_PPD_LINKTRN               0x0008
 #define GEN4_PPD_CONN_MASK             0x0300
+#define SPR_PPD_CONN_MASK              0x0700
 #define GEN4_PPD_CONN_B2B              0x0200
 #define GEN4_PPD_DEV_MASK              0x1000
 #define GEN4_PPD_DEV_DSD               0x1000
 #define GEN4_PPD_DEV_USD               0x0000
+#define SPR_PPD_DEV_MASK               0x4000
+#define SPR_PPD_DEV_DSD                0x4000
+#define SPR_PPD_DEV_USD                0x0000
 #define GEN4_LINK_CTRL_LINK_DISABLE    0x0010
 
 #define GEN4_SLOTSTS                   0xb05a
 #define GEN4_PPD_TOPO_B2B_USD  (GEN4_PPD_CONN_B2B | GEN4_PPD_DEV_USD)
 #define GEN4_PPD_TOPO_B2B_DSD  (GEN4_PPD_CONN_B2B | GEN4_PPD_DEV_DSD)
 
+#define SPR_PPD_TOPO_MASK      (SPR_PPD_CONN_MASK | SPR_PPD_DEV_MASK)
+#define SPR_PPD_TOPO_B2B_USD   (GEN4_PPD_CONN_B2B | SPR_PPD_DEV_USD)
+#define SPR_PPD_TOPO_B2B_DSD   (GEN4_PPD_CONN_B2B | SPR_PPD_DEV_DSD)
+
 #define GEN4_DB_COUNT                  32
 #define GEN4_DB_LINK                   32
 #define GEN4_DB_LINK_BIT               BIT_ULL(GEN4_DB_LINK)
@@ -112,4 +120,12 @@ static inline int pdev_is_ICX(struct pci_dev *pdev)
        return 0;
 }
 
+static inline int pdev_is_SPR(struct pci_dev *pdev)
+{
+       if (pdev_is_gen4(pdev) &&
+           pdev->revision > PCI_DEVICE_REVISION_ICX_MAX)
+               return 1;
+       return 0;
+}
+
 #endif
index dd683cb58d091b87f186047a3bfd97837a053f0e..6295e55ef85e234044c88b6a3e65ef57b0380567 100644 (file)
@@ -33,7 +33,6 @@ int ntb_msi_init(struct ntb_dev *ntb,
 {
        phys_addr_t mw_phys_addr;
        resource_size_t mw_size;
-       size_t struct_size;
        int peer_widx;
        int peers;
        int ret;
@@ -43,9 +42,8 @@ int ntb_msi_init(struct ntb_dev *ntb,
        if (peers <= 0)
                return -EINVAL;
 
-       struct_size = sizeof(*ntb->msi) + sizeof(*ntb->msi->peer_mws) * peers;
-
-       ntb->msi = devm_kzalloc(&ntb->dev, struct_size, GFP_KERNEL);
+       ntb->msi = devm_kzalloc(&ntb->dev, struct_size(ntb->msi, peer_mws, peers),
+                               GFP_KERNEL);
        if (!ntb->msi)
                return -ENOMEM;
 
index 469f23186159c2c619e082a538b08b39f552af49..fd4720d37cc0bf0f0eaa25fe86a7b456d16e11fc 100644 (file)
@@ -1723,7 +1723,7 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
        return 0;
 }
 
-static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
 {
        struct nvme_ctrl *ctrl = ns->ctrl;
 
@@ -1739,7 +1739,8 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
 
        ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS);
        if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED))
-               return 0;
+               return;
+
        if (ctrl->ops->flags & NVME_F_FABRICS) {
                /*
                 * The NVMe over Fabrics specification only supports metadata as
@@ -1747,7 +1748,7 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
                 * remap the separate metadata buffer from the block layer.
                 */
                if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT)))
-                       return -EINVAL;
+                       return;
 
                ns->features |= NVME_NS_EXT_LBAS;
 
@@ -1774,8 +1775,6 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
                else
                        ns->features |= NVME_NS_METADATA_SUPPORTED;
        }
-
-       return 0;
 }
 
 static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
@@ -1916,9 +1915,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
        ns->lba_shift = id->lbaf[lbaf].ds;
        nvme_set_queue_limits(ns->ctrl, ns->queue);
 
-       ret = nvme_configure_metadata(ns, id);
-       if (ret)
-               goto out_unfreeze;
+       nvme_configure_metadata(ns, id);
        nvme_set_chunk_sectors(ns, id);
        nvme_update_disk_info(ns->disk, ns, id);
 
@@ -1934,7 +1931,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
        if (blk_queue_is_zoned(ns->queue)) {
                ret = nvme_revalidate_zones(ns);
                if (ret && !nvme_first_scan(ns->disk))
-                       goto out;
+                       return ret;
        }
 
        if (nvme_ns_head_multipath(ns->head)) {
@@ -1949,16 +1946,16 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
        return 0;
 
 out_unfreeze:
-       blk_mq_unfreeze_queue(ns->disk->queue);
-out:
        /*
         * If probing fails due an unsupported feature, hide the block device,
         * but still allow other access.
         */
        if (ret == -ENODEV) {
                ns->disk->flags |= GENHD_FL_HIDDEN;
+               set_bit(NVME_NS_READY, &ns->flags);
                ret = 0;
        }
+       blk_mq_unfreeze_queue(ns->disk->queue);
        return ret;
 }
 
index 891a36d02e7c7191471b66285d2c58da4ac53dd7..65e00c64a588b7d188629e716fe4b7c96383d10b 100644 (file)
@@ -44,6 +44,8 @@ struct nvme_tcp_request {
        u32                     data_len;
        u32                     pdu_len;
        u32                     pdu_sent;
+       u32                     h2cdata_left;
+       u32                     h2cdata_offset;
        u16                     ttag;
        __le16                  status;
        struct list_head        entry;
@@ -95,6 +97,7 @@ struct nvme_tcp_queue {
        struct nvme_tcp_request *request;
 
        int                     queue_size;
+       u32                     maxh2cdata;
        size_t                  cmnd_capsule_len;
        struct nvme_tcp_ctrl    *ctrl;
        unsigned long           flags;
@@ -572,23 +575,26 @@ static int nvme_tcp_handle_comp(struct nvme_tcp_queue *queue,
        return ret;
 }
 
-static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req,
-               struct nvme_tcp_r2t_pdu *pdu)
+static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req)
 {
        struct nvme_tcp_data_pdu *data = req->pdu;
        struct nvme_tcp_queue *queue = req->queue;
        struct request *rq = blk_mq_rq_from_pdu(req);
+       u32 h2cdata_sent = req->pdu_len;
        u8 hdgst = nvme_tcp_hdgst_len(queue);
        u8 ddgst = nvme_tcp_ddgst_len(queue);
 
        req->state = NVME_TCP_SEND_H2C_PDU;
        req->offset = 0;
-       req->pdu_len = le32_to_cpu(pdu->r2t_length);
+       req->pdu_len = min(req->h2cdata_left, queue->maxh2cdata);
        req->pdu_sent = 0;
+       req->h2cdata_left -= req->pdu_len;
+       req->h2cdata_offset += h2cdata_sent;
 
        memset(data, 0, sizeof(*data));
        data->hdr.type = nvme_tcp_h2c_data;
-       data->hdr.flags = NVME_TCP_F_DATA_LAST;
+       if (!req->h2cdata_left)
+               data->hdr.flags = NVME_TCP_F_DATA_LAST;
        if (queue->hdr_digest)
                data->hdr.flags |= NVME_TCP_F_HDGST;
        if (queue->data_digest)
@@ -597,9 +603,9 @@ static void nvme_tcp_setup_h2c_data_pdu(struct nvme_tcp_request *req,
        data->hdr.pdo = data->hdr.hlen + hdgst;
        data->hdr.plen =
                cpu_to_le32(data->hdr.hlen + hdgst + req->pdu_len + ddgst);
-       data->ttag = pdu->ttag;
+       data->ttag = req->ttag;
        data->command_id = nvme_cid(rq);
-       data->data_offset = pdu->r2t_offset;
+       data->data_offset = cpu_to_le32(req->h2cdata_offset);
        data->data_length = cpu_to_le32(req->pdu_len);
 }
 
@@ -609,6 +615,7 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue,
        struct nvme_tcp_request *req;
        struct request *rq;
        u32 r2t_length = le32_to_cpu(pdu->r2t_length);
+       u32 r2t_offset = le32_to_cpu(pdu->r2t_offset);
 
        rq = nvme_find_rq(nvme_tcp_tagset(queue), pdu->command_id);
        if (!rq) {
@@ -633,14 +640,19 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue,
                return -EPROTO;
        }
 
-       if (unlikely(le32_to_cpu(pdu->r2t_offset) < req->data_sent)) {
+       if (unlikely(r2t_offset < req->data_sent)) {
                dev_err(queue->ctrl->ctrl.device,
                        "req %d unexpected r2t offset %u (expected %zu)\n",
-                       rq->tag, le32_to_cpu(pdu->r2t_offset), req->data_sent);
+                       rq->tag, r2t_offset, req->data_sent);
                return -EPROTO;
        }
 
-       nvme_tcp_setup_h2c_data_pdu(req, pdu);
+       req->pdu_len = 0;
+       req->h2cdata_left = r2t_length;
+       req->h2cdata_offset = r2t_offset;
+       req->ttag = pdu->ttag;
+
+       nvme_tcp_setup_h2c_data_pdu(req);
        nvme_tcp_queue_request(req, false, true);
 
        return 0;
@@ -928,6 +940,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
 {
        struct nvme_tcp_queue *queue = req->queue;
        int req_data_len = req->data_len;
+       u32 h2cdata_left = req->h2cdata_left;
 
        while (true) {
                struct page *page = nvme_tcp_req_cur_page(req);
@@ -972,7 +985,10 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
                                req->state = NVME_TCP_SEND_DDGST;
                                req->offset = 0;
                        } else {
-                               nvme_tcp_done_send_req(queue);
+                               if (h2cdata_left)
+                                       nvme_tcp_setup_h2c_data_pdu(req);
+                               else
+                                       nvme_tcp_done_send_req(queue);
                        }
                        return 1;
                }
@@ -1030,9 +1046,14 @@ static int nvme_tcp_try_send_data_pdu(struct nvme_tcp_request *req)
        if (queue->hdr_digest && !req->offset)
                nvme_tcp_hdgst(queue->snd_hash, pdu, sizeof(*pdu));
 
-       ret = kernel_sendpage(queue->sock, virt_to_page(pdu),
-                       offset_in_page(pdu) + req->offset, len,
-                       MSG_DONTWAIT | MSG_MORE | MSG_SENDPAGE_NOTLAST);
+       if (!req->h2cdata_left)
+               ret = kernel_sendpage(queue->sock, virt_to_page(pdu),
+                               offset_in_page(pdu) + req->offset, len,
+                               MSG_DONTWAIT | MSG_MORE | MSG_SENDPAGE_NOTLAST);
+       else
+               ret = sock_no_sendpage(queue->sock, virt_to_page(pdu),
+                               offset_in_page(pdu) + req->offset, len,
+                               MSG_DONTWAIT | MSG_MORE);
        if (unlikely(ret <= 0))
                return ret;
 
@@ -1052,6 +1073,7 @@ static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req)
 {
        struct nvme_tcp_queue *queue = req->queue;
        size_t offset = req->offset;
+       u32 h2cdata_left = req->h2cdata_left;
        int ret;
        struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
        struct kvec iov = {
@@ -1069,7 +1091,10 @@ static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req)
                return ret;
 
        if (offset + ret == NVME_TCP_DIGEST_LENGTH) {
-               nvme_tcp_done_send_req(queue);
+               if (h2cdata_left)
+                       nvme_tcp_setup_h2c_data_pdu(req);
+               else
+                       nvme_tcp_done_send_req(queue);
                return 1;
        }
 
@@ -1261,6 +1286,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
        struct msghdr msg = {};
        struct kvec iov;
        bool ctrl_hdgst, ctrl_ddgst;
+       u32 maxh2cdata;
        int ret;
 
        icreq = kzalloc(sizeof(*icreq), GFP_KERNEL);
@@ -1344,6 +1370,14 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
                goto free_icresp;
        }
 
+       maxh2cdata = le32_to_cpu(icresp->maxdata);
+       if ((maxh2cdata % 4) || (maxh2cdata < NVME_TCP_MIN_MAXH2CDATA)) {
+               pr_err("queue %d: invalid maxh2cdata returned %u\n",
+                      nvme_tcp_queue_id(queue), maxh2cdata);
+               goto free_icresp;
+       }
+       queue->maxh2cdata = maxh2cdata;
+
        ret = 0;
 free_icresp:
        kfree(icresp);
@@ -2329,6 +2363,7 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns,
        req->data_sent = 0;
        req->pdu_len = 0;
        req->pdu_sent = 0;
+       req->h2cdata_left = 0;
        req->data_len = blk_rq_nr_phys_segments(rq) ?
                                blk_rq_payload_bytes(rq) : 0;
        req->curr_bio = rq->bio;
index 091a0ca16361cfd5f3cc733aa50eea879f0d75e3..496d775c677071ba97a2253c678da5fb972ace6b 100644 (file)
@@ -1233,44 +1233,6 @@ static ssize_t nvmet_subsys_attr_model_store(struct config_item *item,
 }
 CONFIGFS_ATTR(nvmet_subsys_, attr_model);
 
-static ssize_t nvmet_subsys_attr_discovery_nqn_show(struct config_item *item,
-                       char *page)
-{
-       return snprintf(page, PAGE_SIZE, "%s\n",
-                       nvmet_disc_subsys->subsysnqn);
-}
-
-static ssize_t nvmet_subsys_attr_discovery_nqn_store(struct config_item *item,
-                       const char *page, size_t count)
-{
-       struct nvmet_subsys *subsys = to_subsys(item);
-       char *subsysnqn;
-       int len;
-
-       len = strcspn(page, "\n");
-       if (!len)
-               return -EINVAL;
-
-       subsysnqn = kmemdup_nul(page, len, GFP_KERNEL);
-       if (!subsysnqn)
-               return -ENOMEM;
-
-       /*
-        * The discovery NQN must be different from subsystem NQN.
-        */
-       if (!strcmp(subsysnqn, subsys->subsysnqn)) {
-               kfree(subsysnqn);
-               return -EBUSY;
-       }
-       down_write(&nvmet_config_sem);
-       kfree(nvmet_disc_subsys->subsysnqn);
-       nvmet_disc_subsys->subsysnqn = subsysnqn;
-       up_write(&nvmet_config_sem);
-
-       return count;
-}
-CONFIGFS_ATTR(nvmet_subsys_, attr_discovery_nqn);
-
 #ifdef CONFIG_BLK_DEV_INTEGRITY
 static ssize_t nvmet_subsys_attr_pi_enable_show(struct config_item *item,
                                                char *page)
@@ -1300,7 +1262,6 @@ static struct configfs_attribute *nvmet_subsys_attrs[] = {
        &nvmet_subsys_attr_attr_cntlid_min,
        &nvmet_subsys_attr_attr_cntlid_max,
        &nvmet_subsys_attr_attr_model,
-       &nvmet_subsys_attr_attr_discovery_nqn,
 #ifdef CONFIG_BLK_DEV_INTEGRITY
        &nvmet_subsys_attr_attr_pi_enable,
 #endif
index 5119c687de683b45b6d74a3a6d3a98d0f4914e9a..626caf6f1e4b498ab0f6093ea5914d6be5e706be 100644 (file)
@@ -1493,8 +1493,7 @@ static struct nvmet_subsys *nvmet_find_get_subsys(struct nvmet_port *port,
        if (!port)
                return NULL;
 
-       if (!strcmp(NVME_DISC_SUBSYS_NAME, subsysnqn) ||
-           !strcmp(nvmet_disc_subsys->subsysnqn, subsysnqn)) {
+       if (!strcmp(NVME_DISC_SUBSYS_NAME, subsysnqn)) {
                if (!kref_get_unless_zero(&nvmet_disc_subsys->ref))
                        return NULL;
                return nvmet_disc_subsys;
index 23a38dcf0fc4dc8419fbb333e188339b3c7ba4d6..9fd1602b539d97a1c896aedbe29f068b25a689a9 100644 (file)
@@ -771,7 +771,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 
        if (config->wp_gpio)
                nvmem->wp_gpio = config->wp_gpio;
-       else
+       else if (!config->ignore_wp)
                nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp",
                                                    GPIOD_OUT_HIGH);
        if (IS_ERR(nvmem->wp_gpio)) {
index ad85ff6474ff1398c3eb93c7396371daca7c15dc..ec315b060cd50d26a6a2e559f5427f79646f2726 100644 (file)
@@ -648,8 +648,8 @@ void __init early_init_fdt_scan_reserved_mem(void)
        }
 
        fdt_scan_reserved_mem();
-       fdt_init_reserved_mem();
        fdt_reserve_elfcorehdr();
+       fdt_init_reserved_mem();
 }
 
 /**
index 70992103c07d772acf0c8c626279773c9b42e988..2c2fb161b57270b2fb95dfd7096591e4c32ccf71 100644 (file)
@@ -513,24 +513,24 @@ static void __init of_unittest_parse_phandle_with_args(void)
        memset(&args, 0, sizeof(args));
 
        EXPECT_BEGIN(KERN_INFO,
-                    "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
+                    "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");
 
        rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",
                                        "#phandle-cells", 1, &args);
 
        EXPECT_END(KERN_INFO,
-                  "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
+                  "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");
 
        unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
 
        EXPECT_BEGIN(KERN_INFO,
-                    "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
+                    "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");
 
        rc = of_count_phandle_with_args(np, "phandle-list-bad-args",
                                        "#phandle-cells");
 
        EXPECT_END(KERN_INFO,
-                  "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found -1");
+                  "OF: /testcase-data/phandle-tests/consumer-a: #phandle-cells = 3 found 1");
 
        unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
 }
@@ -670,12 +670,12 @@ static void __init of_unittest_parse_phandle_with_args_map(void)
        memset(&args, 0, sizeof(args));
 
        EXPECT_BEGIN(KERN_INFO,
-                    "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found -1");
+                    "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1");
 
        rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args",
                                            "phandle", 1, &args);
        EXPECT_END(KERN_INFO,
-                  "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found -1");
+                  "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1");
 
        unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
 }
@@ -1257,12 +1257,12 @@ static void __init of_unittest_platform_populate(void)
                unittest(pdev, "device 2 creation failed\n");
 
                EXPECT_BEGIN(KERN_INFO,
-                            "platform testcase-data:testcase-device2: IRQ index 0 not found");
+                            "platform testcase-data:testcase-device2: error -ENXIO: IRQ index 0 not found");
 
                irq = platform_get_irq(pdev, 0);
 
                EXPECT_END(KERN_INFO,
-                          "platform testcase-data:testcase-device2: IRQ index 0 not found");
+                          "platform testcase-data:testcase-device2: error -ENXIO: IRQ index 0 not found");
 
                unittest(irq < 0 && irq != -EPROBE_DEFER,
                         "device parsing error failed - %d\n", irq);
index 71258ea3d35f36f618c1f726654833303baa2929..f8e82c5e2d878bacf0c67c45697c1373920e7592 100644 (file)
@@ -1329,7 +1329,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
                 * indirectly via kernel emulated PCI bridge driver.
                 */
                mvebu_pcie_setup_hw(port);
-               mvebu_pcie_set_local_dev_nr(port, 0);
+               mvebu_pcie_set_local_dev_nr(port, 1);
+               mvebu_pcie_set_local_bus_nr(port, 0);
        }
 
        pcie->nports = i;
index cc166c6836387126aa8017e3951cb875a6f75ea8..eb05cceab964fd22b47cc44fef837b44e6d2f42d 100644 (file)
@@ -99,11 +99,13 @@ struct vmd_irq {
  * @srcu:      SRCU struct for local synchronization.
  * @count:     number of child IRQs assigned to this vector; used to track
  *             sharing.
+ * @virq:      The underlying VMD Linux interrupt number
  */
 struct vmd_irq_list {
        struct list_head        irq_list;
        struct srcu_struct      srcu;
        unsigned int            count;
+       unsigned int            virq;
 };
 
 struct vmd_dev {
@@ -253,7 +255,6 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
        struct msi_desc *desc = arg->desc;
        struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus);
        struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL);
-       unsigned int index, vector;
 
        if (!vmdirq)
                return -ENOMEM;
@@ -261,10 +262,8 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
        INIT_LIST_HEAD(&vmdirq->node);
        vmdirq->irq = vmd_next_irq(vmd, desc);
        vmdirq->virq = virq;
-       index = index_from_irqs(vmd, vmdirq->irq);
-       vector = pci_irq_vector(vmd->dev, index);
 
-       irq_domain_set_info(domain, virq, vector, info->chip, vmdirq,
+       irq_domain_set_info(domain, virq, vmdirq->irq->virq, info->chip, vmdirq,
                            handle_untracked_irq, vmd, NULL);
        return 0;
 }
@@ -685,7 +684,8 @@ static int vmd_alloc_irqs(struct vmd_dev *vmd)
                        return err;
 
                INIT_LIST_HEAD(&vmd->irqs[i].irq_list);
-               err = devm_request_irq(&dev->dev, pci_irq_vector(dev, i),
+               vmd->irqs[i].virq = pci_irq_vector(dev, i);
+               err = devm_request_irq(&dev->dev, vmd->irqs[i].virq,
                                       vmd_irq, IRQF_NO_THREAD,
                                       vmd->name, &vmd->irqs[i]);
                if (err)
@@ -969,7 +969,7 @@ static int vmd_suspend(struct device *dev)
        int i;
 
        for (i = 0; i < vmd->msix_count; i++)
-               devm_free_irq(dev, pci_irq_vector(pdev, i), &vmd->irqs[i]);
+               devm_free_irq(dev, vmd->irqs[i].virq, &vmd->irqs[i]);
 
        return 0;
 }
@@ -981,7 +981,7 @@ static int vmd_resume(struct device *dev)
        int err, i;
 
        for (i = 0; i < vmd->msix_count; i++) {
-               err = devm_request_irq(dev, pci_irq_vector(pdev, i),
+               err = devm_request_irq(dev, vmd->irqs[i].virq,
                                       vmd_irq, IRQF_NO_THREAD,
                                       vmd->name, &vmd->irqs[i]);
                if (err)
index d2dd6a6cda608ada20cee2f25acc2dda458027cb..65f7f6b0576c684a34c5ac14297cf6ca4d590b89 100644 (file)
@@ -5344,11 +5344,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags);
  */
 static void quirk_amd_harvest_no_ats(struct pci_dev *pdev)
 {
-       if ((pdev->device == 0x7312 && pdev->revision != 0x00) ||
-           (pdev->device == 0x7340 && pdev->revision != 0xc5) ||
-           (pdev->device == 0x7341 && pdev->revision != 0x00))
-               return;
-
        if (pdev->device == 0x15d8) {
                if (pdev->revision == 0xcf &&
                    pdev->subsystem_vendor == 0xea50 &&
@@ -5370,10 +5365,19 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_amd_harvest_no_ats);
 /* AMD Iceland dGPU */
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_ats);
 /* AMD Navi10 dGPU */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7310, quirk_amd_harvest_no_ats);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7318, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7319, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731a, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731b, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731e, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731f, quirk_amd_harvest_no_ats);
 /* AMD Navi14 dGPU */
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_ats);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats);
 /* AMD Raven platform iGPU */
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats);
 #endif /* CONFIG_PCI_ATS */
index e1a0c44bc686493ef6ec41252f96aa9d04648c56..d05ca6ebbb9da3e6e8fad500658639b5a997a941 100644 (file)
@@ -141,11 +141,25 @@ config ARM_DMC620_PMU
 
 config MARVELL_CN10K_TAD_PMU
        tristate "Marvell CN10K LLC-TAD PMU"
-       depends on ARM64 || (COMPILE_TEST && 64BIT)
+       depends on ARCH_THUNDER || (COMPILE_TEST && 64BIT)
        help
          Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
          performance monitors on CN10K family silicons.
 
+config APPLE_M1_CPU_PMU
+       bool "Apple M1 CPU PMU support"
+       depends on ARM_PMU && ARCH_APPLE
+       help
+         Provides support for the non-architectural CPU PMUs present on
+         the Apple M1 SoCs and derivatives.
+
 source "drivers/perf/hisilicon/Kconfig"
 
+config MARVELL_CN10K_DDR_PMU
+       tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
+       depends on ARM64 || (COMPILE_TEST && 64BIT)
+       help
+         Enable perf support for Marvell DDR Performance monitoring
+         event on CN10K platform.
+
 endmenu
index 2db5418d5b0aa6c71871deae5f690031e775fbbd..4f43080ec54ea986a53372647cd64d4f3f4cfc5e 100644 (file)
@@ -15,3 +15,5 @@ obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
 obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
+obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
+obj-$(CONFIG_APPLE_M1_CPU_PMU) += apple_m1_cpu_pmu.o
diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
new file mode 100644 (file)
index 0000000..979a7c2
--- /dev/null
@@ -0,0 +1,584 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CPU PMU driver for the Apple M1 and derivatives
+ *
+ * Copyright (C) 2021 Google LLC
+ *
+ * Author: Marc Zyngier <maz@kernel.org>
+ *
+ * Most of the information used in this driver was provided by the
+ * Asahi Linux project. The rest was experimentally discovered.
+ */
+
+#include <linux/of.h>
+#include <linux/perf/arm_pmu.h>
+#include <linux/platform_device.h>
+
+#include <asm/apple_m1_pmu.h>
+#include <asm/irq_regs.h>
+#include <asm/perf_event.h>
+
+#define M1_PMU_NR_COUNTERS             10
+
+#define M1_PMU_CFG_EVENT               GENMASK(7, 0)
+
+#define ANY_BUT_0_1                    GENMASK(9, 2)
+#define ONLY_2_TO_7                    GENMASK(7, 2)
+#define ONLY_2_4_6                     (BIT(2) | BIT(4) | BIT(6))
+#define ONLY_5_6_7                     (BIT(5) | BIT(6) | BIT(7))
+
+/*
+ * Description of the events we actually know about, as well as those with
+ * a specific counter affinity. Yes, this is a grand total of two known
+ * counters, and the rest is anybody's guess.
+ *
+ * Not all counters can count all events. Counters #0 and #1 are wired to
+ * count cycles and instructions respectively, and some events have
+ * bizarre mappings (every other counter, or even *one* counter). These
+ * restrictions equally apply to both P and E cores.
+ *
+ * It is worth noting that the PMUs attached to P and E cores are likely
+ * to be different because the underlying uarches are different. At the
+ * moment, we don't really need to distinguish between the two because we
+ * know next to nothing about the events themselves, and we already have
+ * per cpu-type PMU abstractions.
+ *
+ * If we eventually find out that the events are different across
+ * implementations, we'll have to introduce per cpu-type tables.
+ */
+enum m1_pmu_events {
+       M1_PMU_PERFCTR_UNKNOWN_01       = 0x01,
+       M1_PMU_PERFCTR_CPU_CYCLES       = 0x02,
+       M1_PMU_PERFCTR_INSTRUCTIONS     = 0x8c,
+       M1_PMU_PERFCTR_UNKNOWN_8d       = 0x8d,
+       M1_PMU_PERFCTR_UNKNOWN_8e       = 0x8e,
+       M1_PMU_PERFCTR_UNKNOWN_8f       = 0x8f,
+       M1_PMU_PERFCTR_UNKNOWN_90       = 0x90,
+       M1_PMU_PERFCTR_UNKNOWN_93       = 0x93,
+       M1_PMU_PERFCTR_UNKNOWN_94       = 0x94,
+       M1_PMU_PERFCTR_UNKNOWN_95       = 0x95,
+       M1_PMU_PERFCTR_UNKNOWN_96       = 0x96,
+       M1_PMU_PERFCTR_UNKNOWN_97       = 0x97,
+       M1_PMU_PERFCTR_UNKNOWN_98       = 0x98,
+       M1_PMU_PERFCTR_UNKNOWN_99       = 0x99,
+       M1_PMU_PERFCTR_UNKNOWN_9a       = 0x9a,
+       M1_PMU_PERFCTR_UNKNOWN_9b       = 0x9b,
+       M1_PMU_PERFCTR_UNKNOWN_9c       = 0x9c,
+       M1_PMU_PERFCTR_UNKNOWN_9f       = 0x9f,
+       M1_PMU_PERFCTR_UNKNOWN_bf       = 0xbf,
+       M1_PMU_PERFCTR_UNKNOWN_c0       = 0xc0,
+       M1_PMU_PERFCTR_UNKNOWN_c1       = 0xc1,
+       M1_PMU_PERFCTR_UNKNOWN_c4       = 0xc4,
+       M1_PMU_PERFCTR_UNKNOWN_c5       = 0xc5,
+       M1_PMU_PERFCTR_UNKNOWN_c6       = 0xc6,
+       M1_PMU_PERFCTR_UNKNOWN_c8       = 0xc8,
+       M1_PMU_PERFCTR_UNKNOWN_ca       = 0xca,
+       M1_PMU_PERFCTR_UNKNOWN_cb       = 0xcb,
+       M1_PMU_PERFCTR_UNKNOWN_f5       = 0xf5,
+       M1_PMU_PERFCTR_UNKNOWN_f6       = 0xf6,
+       M1_PMU_PERFCTR_UNKNOWN_f7       = 0xf7,
+       M1_PMU_PERFCTR_UNKNOWN_f8       = 0xf8,
+       M1_PMU_PERFCTR_UNKNOWN_fd       = 0xfd,
+       M1_PMU_PERFCTR_LAST             = M1_PMU_CFG_EVENT,
+
+       /*
+        * From this point onwards, these are not actual HW events,
+        * but attributes that get stored in hw->config_base.
+        */
+       M1_PMU_CFG_COUNT_USER           = BIT(8),
+       M1_PMU_CFG_COUNT_KERNEL         = BIT(9),
+};
+
+/*
+ * Per-event affinity table. Most events can be installed on counter
+ * 2-9, but there are a number of exceptions. Note that this table
+ * has been created experimentally, and I wouldn't be surprised if more
+ * counters had strange affinities.
+ */
+static const u16 m1_pmu_event_affinity[M1_PMU_PERFCTR_LAST + 1] = {
+       [0 ... M1_PMU_PERFCTR_LAST]     = ANY_BUT_0_1,
+       [M1_PMU_PERFCTR_UNKNOWN_01]     = BIT(7),
+       [M1_PMU_PERFCTR_CPU_CYCLES]     = ANY_BUT_0_1 | BIT(0),
+       [M1_PMU_PERFCTR_INSTRUCTIONS]   = BIT(7) | BIT(1),
+       [M1_PMU_PERFCTR_UNKNOWN_8d]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_8e]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_8f]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_90]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_93]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_94]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_95]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_96]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_97]     = BIT(7),
+       [M1_PMU_PERFCTR_UNKNOWN_98]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_99]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_9a]     = BIT(7),
+       [M1_PMU_PERFCTR_UNKNOWN_9b]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_9c]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_9f]     = BIT(7),
+       [M1_PMU_PERFCTR_UNKNOWN_bf]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_c0]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_c1]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_c4]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_c5]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_c6]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_c8]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_ca]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_cb]     = ONLY_5_6_7,
+       [M1_PMU_PERFCTR_UNKNOWN_f5]     = ONLY_2_4_6,
+       [M1_PMU_PERFCTR_UNKNOWN_f6]     = ONLY_2_4_6,
+       [M1_PMU_PERFCTR_UNKNOWN_f7]     = ONLY_2_4_6,
+       [M1_PMU_PERFCTR_UNKNOWN_f8]     = ONLY_2_TO_7,
+       [M1_PMU_PERFCTR_UNKNOWN_fd]     = ONLY_2_4_6,
+};
+
+static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
+       PERF_MAP_ALL_UNSUPPORTED,
+       [PERF_COUNT_HW_CPU_CYCLES]      = M1_PMU_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]    = M1_PMU_PERFCTR_INSTRUCTIONS,
+       /* No idea about the rest yet */
+};
+
+/* sysfs definitions */
+static ssize_t m1_pmu_events_sysfs_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *page)
+{
+       struct perf_pmu_events_attr *pmu_attr;
+
+       pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+
+       return sprintf(page, "event=0x%04llx\n", pmu_attr->id);
+}
+
+#define M1_PMU_EVENT_ATTR(name, config)                                        \
+       PMU_EVENT_ATTR_ID(name, m1_pmu_events_sysfs_show, config)
+
+static struct attribute *m1_pmu_event_attrs[] = {
+       M1_PMU_EVENT_ATTR(cycles, M1_PMU_PERFCTR_CPU_CYCLES),
+       M1_PMU_EVENT_ATTR(instructions, M1_PMU_PERFCTR_INSTRUCTIONS),
+       NULL,
+};
+
+static const struct attribute_group m1_pmu_events_attr_group = {
+       .name = "events",
+       .attrs = m1_pmu_event_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-7");
+
+static struct attribute *m1_pmu_format_attrs[] = {
+       &format_attr_event.attr,
+       NULL,
+};
+
+static const struct attribute_group m1_pmu_format_attr_group = {
+       .name = "format",
+       .attrs = m1_pmu_format_attrs,
+};
+
+/* Low level accessors. No synchronisation. */
+#define PMU_READ_COUNTER(_idx)                                         \
+       case _idx:      return read_sysreg_s(SYS_IMP_APL_PMC## _idx ##_EL1)
+
+#define PMU_WRITE_COUNTER(_val, _idx)                                  \
+       case _idx:                                                      \
+               write_sysreg_s(_val, SYS_IMP_APL_PMC## _idx ##_EL1);    \
+               return
+
+static u64 m1_pmu_read_hw_counter(unsigned int index)
+{
+       switch (index) {
+               PMU_READ_COUNTER(0);
+               PMU_READ_COUNTER(1);
+               PMU_READ_COUNTER(2);
+               PMU_READ_COUNTER(3);
+               PMU_READ_COUNTER(4);
+               PMU_READ_COUNTER(5);
+               PMU_READ_COUNTER(6);
+               PMU_READ_COUNTER(7);
+               PMU_READ_COUNTER(8);
+               PMU_READ_COUNTER(9);
+       }
+
+       BUG();
+}
+
+static void m1_pmu_write_hw_counter(u64 val, unsigned int index)
+{
+       switch (index) {
+               PMU_WRITE_COUNTER(val, 0);
+               PMU_WRITE_COUNTER(val, 1);
+               PMU_WRITE_COUNTER(val, 2);
+               PMU_WRITE_COUNTER(val, 3);
+               PMU_WRITE_COUNTER(val, 4);
+               PMU_WRITE_COUNTER(val, 5);
+               PMU_WRITE_COUNTER(val, 6);
+               PMU_WRITE_COUNTER(val, 7);
+               PMU_WRITE_COUNTER(val, 8);
+               PMU_WRITE_COUNTER(val, 9);
+       }
+
+       BUG();
+}
+
+#define get_bit_offset(index, mask)    (__ffs(mask) + (index))
+
+static void __m1_pmu_enable_counter(unsigned int index, bool en)
+{
+       u64 val, bit;
+
+       switch (index) {
+       case 0 ... 7:
+               bit = BIT(get_bit_offset(index, PMCR0_CNT_ENABLE_0_7));
+               break;
+       case 8 ... 9:
+               bit = BIT(get_bit_offset(index - 8, PMCR0_CNT_ENABLE_8_9));
+               break;
+       default:
+               BUG();
+       }
+
+       val = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+
+       if (en)
+               val |= bit;
+       else
+               val &= ~bit;
+
+       write_sysreg_s(val, SYS_IMP_APL_PMCR0_EL1);
+}
+
+static void m1_pmu_enable_counter(unsigned int index)
+{
+       __m1_pmu_enable_counter(index, true);
+}
+
+static void m1_pmu_disable_counter(unsigned int index)
+{
+       __m1_pmu_enable_counter(index, false);
+}
+
+static void __m1_pmu_enable_counter_interrupt(unsigned int index, bool en)
+{
+       u64 val, bit;
+
+       switch (index) {
+       case 0 ... 7:
+               bit = BIT(get_bit_offset(index, PMCR0_PMI_ENABLE_0_7));
+               break;
+       case 8 ... 9:
+               bit = BIT(get_bit_offset(index - 8, PMCR0_PMI_ENABLE_8_9));
+               break;
+       default:
+               BUG();
+       }
+
+       val = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+
+       if (en)
+               val |= bit;
+       else
+               val &= ~bit;
+
+       write_sysreg_s(val, SYS_IMP_APL_PMCR0_EL1);
+}
+
+static void m1_pmu_enable_counter_interrupt(unsigned int index)
+{
+       __m1_pmu_enable_counter_interrupt(index, true);
+}
+
+static void m1_pmu_disable_counter_interrupt(unsigned int index)
+{
+       __m1_pmu_enable_counter_interrupt(index, false);
+}
+
+static void m1_pmu_configure_counter(unsigned int index, u8 event,
+                                    bool user, bool kernel)
+{
+       u64 val, user_bit, kernel_bit;
+       int shift;
+
+       switch (index) {
+       case 0 ... 7:
+               user_bit = BIT(get_bit_offset(index, PMCR1_COUNT_A64_EL0_0_7));
+               kernel_bit = BIT(get_bit_offset(index, PMCR1_COUNT_A64_EL1_0_7));
+               break;
+       case 8 ... 9:
+               user_bit = BIT(get_bit_offset(index - 8, PMCR1_COUNT_A64_EL0_8_9));
+               kernel_bit = BIT(get_bit_offset(index - 8, PMCR1_COUNT_A64_EL1_8_9));
+               break;
+       default:
+               BUG();
+       }
+
+       val = read_sysreg_s(SYS_IMP_APL_PMCR1_EL1);
+
+       if (user)
+               val |= user_bit;
+       else
+               val &= ~user_bit;
+
+       if (kernel)
+               val |= kernel_bit;
+       else
+               val &= ~kernel_bit;
+
+       write_sysreg_s(val, SYS_IMP_APL_PMCR1_EL1);
+
+       /*
+        * Counters 0 and 1 have fixed events. For anything else,
+        * place the event at the expected location in the relevant
+        * register (PMESR0 holds the event configuration for counters
+        * 2-5, resp. PMESR1 for counters 6-9).
+        */
+       switch (index) {
+       case 0 ... 1:
+               break;
+       case 2 ... 5:
+               shift = (index - 2) * 8;
+               val = read_sysreg_s(SYS_IMP_APL_PMESR0_EL1);
+               val &= ~((u64)0xff << shift);
+               val |= (u64)event << shift;
+               write_sysreg_s(val, SYS_IMP_APL_PMESR0_EL1);
+               break;
+       case 6 ... 9:
+               shift = (index - 6) * 8;
+               val = read_sysreg_s(SYS_IMP_APL_PMESR1_EL1);
+               val &= ~((u64)0xff << shift);
+               val |= (u64)event << shift;
+               write_sysreg_s(val, SYS_IMP_APL_PMESR1_EL1);
+               break;
+       }
+}
+
+/* arm_pmu backend */
+static void m1_pmu_enable_event(struct perf_event *event)
+{
+       bool user, kernel;
+       u8 evt;
+
+       evt = event->hw.config_base & M1_PMU_CFG_EVENT;
+       user = event->hw.config_base & M1_PMU_CFG_COUNT_USER;
+       kernel = event->hw.config_base & M1_PMU_CFG_COUNT_KERNEL;
+
+       m1_pmu_disable_counter_interrupt(event->hw.idx);
+       m1_pmu_disable_counter(event->hw.idx);
+       isb();
+
+       m1_pmu_configure_counter(event->hw.idx, evt, user, kernel);
+       m1_pmu_enable_counter(event->hw.idx);
+       m1_pmu_enable_counter_interrupt(event->hw.idx);
+       isb();
+}
+
+static void m1_pmu_disable_event(struct perf_event *event)
+{
+       m1_pmu_disable_counter_interrupt(event->hw.idx);
+       m1_pmu_disable_counter(event->hw.idx);
+       isb();
+}
+
+static irqreturn_t m1_pmu_handle_irq(struct arm_pmu *cpu_pmu)
+{
+       struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
+       struct pt_regs *regs;
+       u64 overflow, state;
+       int idx;
+
+       overflow = read_sysreg_s(SYS_IMP_APL_PMSR_EL1);
+       if (!overflow) {
+               /* Spurious interrupt? */
+               state = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+               state &= ~PMCR0_IACT;
+               write_sysreg_s(state, SYS_IMP_APL_PMCR0_EL1);
+               isb();
+               return IRQ_NONE;
+       }
+
+       cpu_pmu->stop(cpu_pmu);
+
+       regs = get_irq_regs();
+
+       for (idx = 0; idx < cpu_pmu->num_events; idx++) {
+               struct perf_event *event = cpuc->events[idx];
+               struct perf_sample_data data;
+
+               if (!event)
+                       continue;
+
+               armpmu_event_update(event);
+               perf_sample_data_init(&data, 0, event->hw.last_period);
+               if (!armpmu_event_set_period(event))
+                       continue;
+
+               if (perf_event_overflow(event, &data, regs))
+                       m1_pmu_disable_event(event);
+       }
+
+       cpu_pmu->start(cpu_pmu);
+
+       return IRQ_HANDLED;
+}
+
+static u64 m1_pmu_read_counter(struct perf_event *event)
+{
+       return m1_pmu_read_hw_counter(event->hw.idx);
+}
+
+static void m1_pmu_write_counter(struct perf_event *event, u64 value)
+{
+       m1_pmu_write_hw_counter(value, event->hw.idx);
+       isb();
+}
+
+static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+                               struct perf_event *event)
+{
+       unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
+       unsigned long affinity = m1_pmu_event_affinity[evtype];
+       int idx;
+
+       /*
+        * Place the event on the first free counter that can count
+        * this event.
+        *
+        * We could do a better job if we had a view of all the events
+        * counting on the PMU at any given time, and by placing the
+        * most constraining events first.
+        */
+       for_each_set_bit(idx, &affinity, M1_PMU_NR_COUNTERS) {
+               if (!test_and_set_bit(idx, cpuc->used_mask))
+                       return idx;
+       }
+
+       return -EAGAIN;
+}
+
+static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
+                                  struct perf_event *event)
+{
+       clear_bit(event->hw.idx, cpuc->used_mask);
+}
+
+static void __m1_pmu_set_mode(u8 mode)
+{
+       u64 val;
+
+       val = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+       val &= ~(PMCR0_IMODE | PMCR0_IACT);
+       val |= FIELD_PREP(PMCR0_IMODE, mode);
+       write_sysreg_s(val, SYS_IMP_APL_PMCR0_EL1);
+       isb();
+}
+
+static void m1_pmu_start(struct arm_pmu *cpu_pmu)
+{
+       __m1_pmu_set_mode(PMCR0_IMODE_FIQ);
+}
+
+static void m1_pmu_stop(struct arm_pmu *cpu_pmu)
+{
+       __m1_pmu_set_mode(PMCR0_IMODE_OFF);
+}
+
+static int m1_pmu_map_event(struct perf_event *event)
+{
+       /*
+        * Although the counters are 48bit wide, bit 47 is what
+        * triggers the overflow interrupt. Advertise the counters
+        * being 47bit wide to mimick the behaviour of the ARM PMU.
+        */
+       event->hw.flags |= ARMPMU_EVT_47BIT;
+       return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT);
+}
+
+static void m1_pmu_reset(void *info)
+{
+       int i;
+
+       __m1_pmu_set_mode(PMCR0_IMODE_OFF);
+
+       for (i = 0; i < M1_PMU_NR_COUNTERS; i++) {
+               m1_pmu_disable_counter(i);
+               m1_pmu_disable_counter_interrupt(i);
+               m1_pmu_write_hw_counter(0, i);
+       }
+
+       isb();
+}
+
+static int m1_pmu_set_event_filter(struct hw_perf_event *event,
+                                  struct perf_event_attr *attr)
+{
+       unsigned long config_base = 0;
+
+       if (!attr->exclude_guest)
+               return -EINVAL;
+       if (!attr->exclude_kernel)
+               config_base |= M1_PMU_CFG_COUNT_KERNEL;
+       if (!attr->exclude_user)
+               config_base |= M1_PMU_CFG_COUNT_USER;
+
+       event->config_base = config_base;
+
+       return 0;
+}
+
+static int m1_pmu_init(struct arm_pmu *cpu_pmu)
+{
+       cpu_pmu->handle_irq       = m1_pmu_handle_irq;
+       cpu_pmu->enable           = m1_pmu_enable_event;
+       cpu_pmu->disable          = m1_pmu_disable_event;
+       cpu_pmu->read_counter     = m1_pmu_read_counter;
+       cpu_pmu->write_counter    = m1_pmu_write_counter;
+       cpu_pmu->get_event_idx    = m1_pmu_get_event_idx;
+       cpu_pmu->clear_event_idx  = m1_pmu_clear_event_idx;
+       cpu_pmu->start            = m1_pmu_start;
+       cpu_pmu->stop             = m1_pmu_stop;
+       cpu_pmu->map_event        = m1_pmu_map_event;
+       cpu_pmu->reset            = m1_pmu_reset;
+       cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
+
+       cpu_pmu->num_events       = M1_PMU_NR_COUNTERS;
+       cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+       cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
+       return 0;
+}
+
+/* Device driver gunk */
+static int m1_pmu_ice_init(struct arm_pmu *cpu_pmu)
+{
+       cpu_pmu->name = "apple_icestorm_pmu";
+       return m1_pmu_init(cpu_pmu);
+}
+
+static int m1_pmu_fire_init(struct arm_pmu *cpu_pmu)
+{
+       cpu_pmu->name = "apple_firestorm_pmu";
+       return m1_pmu_init(cpu_pmu);
+}
+
+static const struct of_device_id m1_pmu_of_device_ids[] = {
+       { .compatible = "apple,icestorm-pmu",   .data = m1_pmu_ice_init, },
+       { .compatible = "apple,firestorm-pmu",  .data = m1_pmu_fire_init, },
+       { },
+};
+MODULE_DEVICE_TABLE(of, m1_pmu_of_device_ids);
+
+static int m1_pmu_device_probe(struct platform_device *pdev)
+{
+       return arm_pmu_device_probe(pdev, m1_pmu_of_device_ids, NULL);
+}
+
+static struct platform_driver m1_pmu_driver = {
+       .driver         = {
+               .name                   = "apple-m1-cpu-pmu",
+               .of_match_table         = m1_pmu_of_device_ids,
+               .suppress_bind_attrs    = true,
+       },
+       .probe          = m1_pmu_device_probe,
+};
+
+module_platform_driver(m1_pmu_driver);
+MODULE_LICENSE("GPL v2");
index 54aca3a62814719804e05df7700134bcd2adaaf1..96e09fa4090954f98bb4493610c138ad81c70c60 100644 (file)
@@ -1096,7 +1096,7 @@ static void cci_pmu_enable(struct pmu *pmu)
 {
        struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
        struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
-       int enabled = bitmap_weight(hw_events->used_mask, cci_pmu->num_cntrs);
+       bool enabled = !bitmap_empty(hw_events->used_mask, cci_pmu->num_cntrs);
        unsigned long flags;
 
        if (!enabled)
index a96c316045459bf91e1838192a75745024bb91d8..40b352e8aa7f7eff89f6cfd437801364c500fa6b 100644 (file)
@@ -1460,8 +1460,7 @@ static irqreturn_t arm_ccn_irq_handler(int irq, void *dev_id)
 static int arm_ccn_probe(struct platform_device *pdev)
 {
        struct arm_ccn *ccn;
-       struct resource *res;
-       unsigned int irq;
+       int irq;
        int err;
 
        ccn = devm_kzalloc(&pdev->dev, sizeof(*ccn), GFP_KERNEL);
@@ -1474,10 +1473,9 @@ static int arm_ccn_probe(struct platform_device *pdev)
        if (IS_ERR(ccn->base))
                return PTR_ERR(ccn->base);
 
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!res)
-               return -EINVAL;
-       irq = res->start;
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
 
        /* Check if we can use the interrupt */
        writel(CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE,
index 0e48adce57ef3c4d37bb7853496295a7a5e11279..9c1d82be7a2feea0f9cecf92741446bf644cf35a 100644 (file)
 #define CMN_DTM_WPn(n)                 (0x1A0 + (n) * 0x18)
 #define CMN_DTM_WPn_CONFIG(n)          (CMN_DTM_WPn(n) + 0x00)
 #define CMN_DTM_WPn_CONFIG_WP_DEV_SEL2 GENMASK_ULL(18,17)
-#define CMN_DTM_WPn_CONFIG_WP_COMBINE  BIT(6)
-#define CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE        BIT(5)
-#define CMN_DTM_WPn_CONFIG_WP_GRP      BIT(4)
+#define CMN_DTM_WPn_CONFIG_WP_COMBINE  BIT(9)
+#define CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE        BIT(8)
+#define CMN600_WPn_CONFIG_WP_COMBINE   BIT(6)
+#define CMN600_WPn_CONFIG_WP_EXCLUSIVE BIT(5)
+#define CMN_DTM_WPn_CONFIG_WP_GRP      GENMASK_ULL(5, 4)
 #define CMN_DTM_WPn_CONFIG_WP_CHN_SEL  GENMASK_ULL(3, 1)
 #define CMN_DTM_WPn_CONFIG_WP_DEV_SEL  BIT(0)
 #define CMN_DTM_WPn_VAL(n)             (CMN_DTM_WPn(n) + 0x08)
 #define CMN_CONFIG_WP_COMBINE          GENMASK_ULL(27, 24)
 #define CMN_CONFIG_WP_DEV_SEL          GENMASK_ULL(50, 48)
 #define CMN_CONFIG_WP_CHN_SEL          GENMASK_ULL(55, 51)
+/* Note that we don't yet support the tertiary match group on newer IPs */
 #define CMN_CONFIG_WP_GRP              BIT_ULL(56)
 #define CMN_CONFIG_WP_EXCLUSIVE                BIT_ULL(57)
 #define CMN_CONFIG1_WP_VAL             GENMASK_ULL(63, 0)
@@ -353,7 +356,7 @@ static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn,
        return NULL;
 }
 
-struct dentry *arm_cmn_debugfs;
+static struct dentry *arm_cmn_debugfs;
 
 #ifdef CONFIG_DEBUG_FS
 static const char *arm_cmn_device_type(u8 type)
@@ -595,6 +598,9 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
                if ((intf & 4) && !(cmn->ports_used & BIT(intf & 3)))
                        return 0;
 
+               if (chan == 4 && cmn->model == CMN600)
+                       return 0;
+
                if ((chan == 5 && cmn->rsp_vc_num < 2) ||
                    (chan == 6 && cmn->dat_vc_num < 2))
                        return 0;
@@ -905,15 +911,18 @@ static u32 arm_cmn_wp_config(struct perf_event *event)
        u32 grp = CMN_EVENT_WP_GRP(event);
        u32 exc = CMN_EVENT_WP_EXCLUSIVE(event);
        u32 combine = CMN_EVENT_WP_COMBINE(event);
+       bool is_cmn600 = to_cmn(event->pmu)->model == CMN600;
 
        config = FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL, dev) |
                 FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_CHN_SEL, chn) |
                 FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_GRP, grp) |
-                FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE, exc) |
                 FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL2, dev >> 1);
+       if (exc)
+               config |= is_cmn600 ? CMN600_WPn_CONFIG_WP_EXCLUSIVE :
+                                     CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE;
        if (combine && !grp)
-               config |= CMN_DTM_WPn_CONFIG_WP_COMBINE;
-
+               config |= is_cmn600 ? CMN600_WPn_CONFIG_WP_COMBINE :
+                                     CMN_DTM_WPn_CONFIG_WP_COMBINE;
        return config;
 }
 
index 295cc7952d0edf9d622727357d1c3d607ac4aa0b..9694370651fa8bc3bd19b91df020240f8144887e 100644 (file)
@@ -109,6 +109,8 @@ static inline u64 arm_pmu_event_max_period(struct perf_event *event)
 {
        if (event->hw.flags & ARMPMU_EVT_64BIT)
                return GENMASK_ULL(63, 0);
+       else if (event->hw.flags & ARMPMU_EVT_47BIT)
+               return GENMASK_ULL(46, 0);
        else
                return GENMASK_ULL(31, 0);
 }
@@ -524,7 +526,7 @@ static void armpmu_enable(struct pmu *pmu)
 {
        struct arm_pmu *armpmu = to_arm_pmu(pmu);
        struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
-       int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+       bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events);
 
        /* For task-bound events we may be called on other CPUs */
        if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus))
@@ -785,7 +787,7 @@ static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd,
 {
        struct arm_pmu *armpmu = container_of(b, struct arm_pmu, cpu_pm_nb);
        struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
-       int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+       bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events);
 
        if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus))
                return NOTIFY_DONE;
index a738aeab5c04985f1fe6b7cf4b21eeb312d50511..358e4e284a62905e64bfba49e58260005afb8761 100644 (file)
@@ -393,7 +393,7 @@ EXPORT_SYMBOL_GPL(hisi_uncore_pmu_read);
 void hisi_uncore_pmu_enable(struct pmu *pmu)
 {
        struct hisi_pmu *hisi_pmu = to_hisi_pmu(pmu);
-       int enabled = bitmap_weight(hisi_pmu->pmu_events.used_mask,
+       bool enabled = !bitmap_empty(hisi_pmu->pmu_events.used_mask,
                                    hisi_pmu->num_counters);
 
        if (!enabled)
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
new file mode 100644 (file)
index 0000000..665b382
--- /dev/null
@@ -0,0 +1,758 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
+ *
+ * Copyright (C) 2021 Marvell.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/perf_event.h>
+#include <linux/hrtimer.h>
+
+/* Performance Counters Operating Mode Control Registers */
+#define DDRC_PERF_CNT_OP_MODE_CTRL     0x8020
+#define OP_MODE_CTRL_VAL_MANNUAL       0x1
+
+/* Performance Counters Start Operation Control Registers */
+#define DDRC_PERF_CNT_START_OP_CTRL    0x8028
+#define START_OP_CTRL_VAL_START                0x1ULL
+#define START_OP_CTRL_VAL_ACTIVE       0x2
+
+/* Performance Counters End Operation Control Registers */
+#define DDRC_PERF_CNT_END_OP_CTRL      0x8030
+#define END_OP_CTRL_VAL_END            0x1ULL
+
+/* Performance Counters End Status Registers */
+#define DDRC_PERF_CNT_END_STATUS               0x8038
+#define END_STATUS_VAL_END_TIMER_MODE_END      0x1
+
+/* Performance Counters Configuration Registers */
+#define DDRC_PERF_CFG_BASE             0x8040
+
+/* 8 Generic event counter + 2 fixed event counters */
+#define DDRC_PERF_NUM_GEN_COUNTERS     8
+#define DDRC_PERF_NUM_FIX_COUNTERS     2
+#define DDRC_PERF_READ_COUNTER_IDX     DDRC_PERF_NUM_GEN_COUNTERS
+#define DDRC_PERF_WRITE_COUNTER_IDX    (DDRC_PERF_NUM_GEN_COUNTERS + 1)
+#define DDRC_PERF_NUM_COUNTERS         (DDRC_PERF_NUM_GEN_COUNTERS + \
+                                        DDRC_PERF_NUM_FIX_COUNTERS)
+
+/* Generic event counter registers */
+#define DDRC_PERF_CFG(n)               (DDRC_PERF_CFG_BASE + 8 * (n))
+#define EVENT_ENABLE                   BIT_ULL(63)
+
+/* Two dedicated event counters for DDR reads and writes */
+#define EVENT_DDR_READS                        101
+#define EVENT_DDR_WRITES               100
+
+/*
+ * programmable events IDs in programmable event counters.
+ * DO NOT change these event-id numbers, they are used to
+ * program event bitmap in h/w.
+ */
+#define EVENT_OP_IS_ZQLATCH                    55
+#define EVENT_OP_IS_ZQSTART                    54
+#define EVENT_OP_IS_TCR_MRR                    53
+#define EVENT_OP_IS_DQSOSC_MRR                 52
+#define EVENT_OP_IS_DQSOSC_MPC                 51
+#define EVENT_VISIBLE_WIN_LIMIT_REACHED_WR     50
+#define EVENT_VISIBLE_WIN_LIMIT_REACHED_RD     49
+#define EVENT_BSM_STARVATION                   48
+#define EVENT_BSM_ALLOC                                47
+#define EVENT_LPR_REQ_WITH_NOCREDIT            46
+#define EVENT_HPR_REQ_WITH_NOCREDIT            45
+#define EVENT_OP_IS_ZQCS                       44
+#define EVENT_OP_IS_ZQCL                       43
+#define EVENT_OP_IS_LOAD_MODE                  42
+#define EVENT_OP_IS_SPEC_REF                   41
+#define EVENT_OP_IS_CRIT_REF                   40
+#define EVENT_OP_IS_REFRESH                    39
+#define EVENT_OP_IS_ENTER_MPSM                 35
+#define EVENT_OP_IS_ENTER_POWERDOWN            31
+#define EVENT_OP_IS_ENTER_SELFREF              27
+#define EVENT_WAW_HAZARD                       26
+#define EVENT_RAW_HAZARD                       25
+#define EVENT_WAR_HAZARD                       24
+#define EVENT_WRITE_COMBINE                    23
+#define EVENT_RDWR_TRANSITIONS                 22
+#define EVENT_PRECHARGE_FOR_OTHER              21
+#define EVENT_PRECHARGE_FOR_RDWR               20
+#define EVENT_OP_IS_PRECHARGE                  19
+#define EVENT_OP_IS_MWR                                18
+#define EVENT_OP_IS_WR                         17
+#define EVENT_OP_IS_RD                         16
+#define EVENT_OP_IS_RD_ACTIVATE                        15
+#define EVENT_OP_IS_RD_OR_WR                   14
+#define EVENT_OP_IS_ACTIVATE                   13
+#define EVENT_WR_XACT_WHEN_CRITICAL            12
+#define EVENT_LPR_XACT_WHEN_CRITICAL           11
+#define EVENT_HPR_XACT_WHEN_CRITICAL           10
+#define EVENT_DFI_RD_DATA_CYCLES               9
+#define EVENT_DFI_WR_DATA_CYCLES               8
+#define EVENT_ACT_BYPASS                       7
+#define EVENT_READ_BYPASS                      6
+#define EVENT_HIF_HI_PRI_RD                    5
+#define EVENT_HIF_RMW                          4
+#define EVENT_HIF_RD                           3
+#define EVENT_HIF_WR                           2
+#define EVENT_HIF_RD_OR_WR                     1
+
+/* Event counter value registers */
+#define DDRC_PERF_CNT_VALUE_BASE               0x8080
+#define DDRC_PERF_CNT_VALUE(n) (DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
+
+/* Fixed event counter enable/disable register */
+#define DDRC_PERF_CNT_FREERUN_EN       0x80C0
+#define DDRC_PERF_FREERUN_WRITE_EN     0x1
+#define DDRC_PERF_FREERUN_READ_EN      0x2
+
+/* Fixed event counter control register */
+#define DDRC_PERF_CNT_FREERUN_CTRL     0x80C8
+#define DDRC_FREERUN_WRITE_CNT_CLR     0x1
+#define DDRC_FREERUN_READ_CNT_CLR      0x2
+
+/* Fixed event counter value register */
+#define DDRC_PERF_CNT_VALUE_WR_OP      0x80D0
+#define DDRC_PERF_CNT_VALUE_RD_OP      0x80D8
+#define DDRC_PERF_CNT_VALUE_OVERFLOW   BIT_ULL(48)
+#define DDRC_PERF_CNT_MAX_VALUE                GENMASK_ULL(48, 0)
+
+struct cn10k_ddr_pmu {
+       struct pmu pmu;
+       void __iomem *base;
+       unsigned int cpu;
+       struct  device *dev;
+       int active_events;
+       struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
+       struct hrtimer hrtimer;
+       struct hlist_node node;
+};
+
+#define to_cn10k_ddr_pmu(p)    container_of(p, struct cn10k_ddr_pmu, pmu)
+
+static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *page)
+{
+       struct perf_pmu_events_attr *pmu_attr;
+
+       pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+       return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
+
+}
+
+#define CN10K_DDR_PMU_EVENT_ATTR(_name, _id)                                \
+       PMU_EVENT_ATTR_ID(_name, cn10k_ddr_pmu_event_show, _id)
+
+static struct attribute *cn10k_ddr_perf_events_attrs[] = {
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access, EVENT_HIF_RD_OR_WR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access, EVENT_HIF_RMW),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess, EVENT_HIF_HI_PRI_RD),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access, EVENT_READ_BYPASS),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access, EVENT_ACT_BYPASS),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_wr_data_access, EVENT_DFI_WR_DATA_CYCLES),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_rd_data_access, EVENT_DFI_RD_DATA_CYCLES),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
+                                       EVENT_HPR_XACT_WHEN_CRITICAL),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
+                                       EVENT_LPR_XACT_WHEN_CRITICAL),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
+                                       EVENT_WR_XACT_WHEN_CRITICAL),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access, EVENT_OP_IS_ACTIVATE),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access, EVENT_OP_IS_RD_OR_WR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access, EVENT_OP_IS_RD_ACTIVATE),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge, EVENT_OP_IS_PRECHARGE),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr, EVENT_PRECHARGE_FOR_RDWR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
+                                       EVENT_PRECHARGE_FOR_OTHER),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions, EVENT_RDWR_TRANSITIONS),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine, EVENT_WRITE_COMBINE),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard, EVENT_WAR_HAZARD),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard, EVENT_RAW_HAZARD),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard, EVENT_WAW_HAZARD),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref, EVENT_OP_IS_ENTER_SELFREF),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown, EVENT_OP_IS_ENTER_POWERDOWN),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_mpsm, EVENT_OP_IS_ENTER_MPSM),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode, EVENT_OP_IS_LOAD_MODE),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_zqcl, EVENT_OP_IS_ZQCL),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_wr_access, EVENT_OP_IS_ZQCS),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_hpr_req_with_nocredit,
+                                       EVENT_HPR_REQ_WITH_NOCREDIT),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_lpr_req_with_nocredit,
+                                       EVENT_LPR_REQ_WITH_NOCREDIT),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_alloc, EVENT_BSM_ALLOC),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_starvation, EVENT_BSM_STARVATION),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
+                                       EVENT_VISIBLE_WIN_LIMIT_REACHED_RD),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
+                                       EVENT_VISIBLE_WIN_LIMIT_REACHED_WR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc, EVENT_OP_IS_DQSOSC_MPC),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr, EVENT_OP_IS_DQSOSC_MRR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_OP_IS_TCR_MRR),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_OP_IS_ZQSTART),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_OP_IS_ZQLATCH),
+       /* Free run event counters */
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
+       CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
+       NULL
+};
+
+static struct attribute_group cn10k_ddr_perf_events_attr_group = {
+       .name = "events",
+       .attrs = cn10k_ddr_perf_events_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-8");
+
+static struct attribute *cn10k_ddr_perf_format_attrs[] = {
+       &format_attr_event.attr,
+       NULL,
+};
+
+static struct attribute_group cn10k_ddr_perf_format_attr_group = {
+       .name = "format",
+       .attrs = cn10k_ddr_perf_format_attrs,
+};
+
+static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
+                                          struct device_attribute *attr,
+                                          char *buf)
+{
+       struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
+
+       return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
+}
+
+static struct device_attribute cn10k_ddr_perf_cpumask_attr =
+       __ATTR(cpumask, 0444, cn10k_ddr_perf_cpumask_show, NULL);
+
+static struct attribute *cn10k_ddr_perf_cpumask_attrs[] = {
+       &cn10k_ddr_perf_cpumask_attr.attr,
+       NULL,
+};
+
+static struct attribute_group cn10k_ddr_perf_cpumask_attr_group = {
+       .attrs = cn10k_ddr_perf_cpumask_attrs,
+};
+
+static const struct attribute_group *cn10k_attr_groups[] = {
+       &cn10k_ddr_perf_events_attr_group,
+       &cn10k_ddr_perf_format_attr_group,
+       &cn10k_ddr_perf_cpumask_attr_group,
+       NULL,
+};
+
+/* Default poll timeout is 100 sec, which is very sufficient for
+ * 48 bit counter incremented max at 5.6 GT/s, which may take many
+ * hours to overflow.
+ */
+static unsigned long cn10k_ddr_pmu_poll_period_sec = 100;
+module_param_named(poll_period_sec, cn10k_ddr_pmu_poll_period_sec, ulong, 0644);
+
+static ktime_t cn10k_ddr_pmu_timer_period(void)
+{
+       return ms_to_ktime((u64)cn10k_ddr_pmu_poll_period_sec * USEC_PER_SEC);
+}
+
+static int ddr_perf_get_event_bitmap(int eventid, u64 *event_bitmap)
+{
+       switch (eventid) {
+       case EVENT_HIF_RD_OR_WR ... EVENT_WAW_HAZARD:
+       case EVENT_OP_IS_REFRESH ... EVENT_OP_IS_ZQLATCH:
+               *event_bitmap = (1ULL << (eventid - 1));
+               break;
+       case EVENT_OP_IS_ENTER_SELFREF:
+       case EVENT_OP_IS_ENTER_POWERDOWN:
+       case EVENT_OP_IS_ENTER_MPSM:
+               *event_bitmap = (0xFULL << (eventid - 1));
+               break;
+       default:
+               pr_err("%s Invalid eventid %d\n", __func__, eventid);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int cn10k_ddr_perf_alloc_counter(struct cn10k_ddr_pmu *pmu,
+                                       struct perf_event *event)
+{
+       u8 config = event->attr.config;
+       int i;
+
+       /* DDR read free-run counter index */
+       if (config == EVENT_DDR_READS) {
+               pmu->events[DDRC_PERF_READ_COUNTER_IDX] = event;
+               return DDRC_PERF_READ_COUNTER_IDX;
+       }
+
+       /* DDR write free-run counter index */
+       if (config == EVENT_DDR_WRITES) {
+               pmu->events[DDRC_PERF_WRITE_COUNTER_IDX] = event;
+               return DDRC_PERF_WRITE_COUNTER_IDX;
+       }
+
+       /* Allocate DDR generic counters */
+       for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+               if (pmu->events[i] == NULL) {
+                       pmu->events[i] = event;
+                       return i;
+               }
+       }
+
+       return -ENOENT;
+}
+
+static void cn10k_ddr_perf_free_counter(struct cn10k_ddr_pmu *pmu, int counter)
+{
+       pmu->events[counter] = NULL;
+}
+
+static int cn10k_ddr_perf_event_init(struct perf_event *event)
+{
+       struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+       struct hw_perf_event *hwc = &event->hw;
+
+       if (event->attr.type != event->pmu->type)
+               return -ENOENT;
+
+       if (is_sampling_event(event)) {
+               dev_info(pmu->dev, "Sampling not supported!\n");
+               return -EOPNOTSUPP;
+       }
+
+       if (event->cpu < 0) {
+               dev_warn(pmu->dev, "Can't provide per-task data!\n");
+               return -EOPNOTSUPP;
+       }
+
+       /*  We must NOT create groups containing mixed PMUs */
+       if (event->group_leader->pmu != event->pmu &&
+           !is_software_event(event->group_leader))
+               return -EINVAL;
+
+       /* Set ownership of event to one CPU, same event can not be observed
+        * on multiple cpus at same time.
+        */
+       event->cpu = pmu->cpu;
+       hwc->idx = -1;
+       return 0;
+}
+
+static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
+                                         int counter, bool enable)
+{
+       u32 reg;
+       u64 val;
+
+       if (counter > DDRC_PERF_NUM_COUNTERS) {
+               pr_err("Error: unsupported counter %d\n", counter);
+               return;
+       }
+
+       if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
+               reg = DDRC_PERF_CFG(counter);
+               val = readq_relaxed(pmu->base + reg);
+
+               if (enable)
+                       val |= EVENT_ENABLE;
+               else
+                       val &= ~EVENT_ENABLE;
+
+               writeq_relaxed(val, pmu->base + reg);
+       } else {
+               val = readq_relaxed(pmu->base + DDRC_PERF_CNT_FREERUN_EN);
+               if (enable) {
+                       if (counter == DDRC_PERF_READ_COUNTER_IDX)
+                               val |= DDRC_PERF_FREERUN_READ_EN;
+                       else
+                               val |= DDRC_PERF_FREERUN_WRITE_EN;
+               } else {
+                       if (counter == DDRC_PERF_READ_COUNTER_IDX)
+                               val &= ~DDRC_PERF_FREERUN_READ_EN;
+                       else
+                               val &= ~DDRC_PERF_FREERUN_WRITE_EN;
+               }
+               writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_EN);
+       }
+}
+
+static u64 cn10k_ddr_perf_read_counter(struct cn10k_ddr_pmu *pmu, int counter)
+{
+       u64 val;
+
+       if (counter == DDRC_PERF_READ_COUNTER_IDX)
+               return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_RD_OP);
+
+       if (counter == DDRC_PERF_WRITE_COUNTER_IDX)
+               return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_WR_OP);
+
+       val = readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE(counter));
+       return val;
+}
+
+static void cn10k_ddr_perf_event_update(struct perf_event *event)
+{
+       struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+       struct hw_perf_event *hwc = &event->hw;
+       u64 prev_count, new_count, mask;
+
+       do {
+               prev_count = local64_read(&hwc->prev_count);
+               new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+       } while (local64_xchg(&hwc->prev_count, new_count) != prev_count);
+
+       mask = DDRC_PERF_CNT_MAX_VALUE;
+
+       local64_add((new_count - prev_count) & mask, &event->count);
+}
+
+static void cn10k_ddr_perf_event_start(struct perf_event *event, int flags)
+{
+       struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+       struct hw_perf_event *hwc = &event->hw;
+       int counter = hwc->idx;
+
+       local64_set(&hwc->prev_count, 0);
+
+       cn10k_ddr_perf_counter_enable(pmu, counter, true);
+
+       hwc->state = 0;
+}
+
+static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
+{
+       struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+       struct hw_perf_event *hwc = &event->hw;
+       u8 config = event->attr.config;
+       int counter, ret;
+       u32 reg_offset;
+       u64 val;
+
+       counter = cn10k_ddr_perf_alloc_counter(pmu, event);
+       if (counter < 0)
+               return -EAGAIN;
+
+       pmu->active_events++;
+       hwc->idx = counter;
+
+       if (pmu->active_events == 1)
+               hrtimer_start(&pmu->hrtimer, cn10k_ddr_pmu_timer_period(),
+                             HRTIMER_MODE_REL_PINNED);
+
+       if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
+               /* Generic counters, configure event id */
+               reg_offset = DDRC_PERF_CFG(counter);
+               ret = ddr_perf_get_event_bitmap(config, &val);
+               if (ret)
+                       return ret;
+
+               writeq_relaxed(val, pmu->base + reg_offset);
+       } else {
+               /* fixed event counter, clear counter value */
+               if (counter == DDRC_PERF_READ_COUNTER_IDX)
+                       val = DDRC_FREERUN_READ_CNT_CLR;
+               else
+                       val = DDRC_FREERUN_WRITE_CNT_CLR;
+
+               writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_CTRL);
+       }
+
+       hwc->state |= PERF_HES_STOPPED;
+
+       if (flags & PERF_EF_START)
+               cn10k_ddr_perf_event_start(event, flags);
+
+       return 0;
+}
+
+static void cn10k_ddr_perf_event_stop(struct perf_event *event, int flags)
+{
+       struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+       struct hw_perf_event *hwc = &event->hw;
+       int counter = hwc->idx;
+
+       cn10k_ddr_perf_counter_enable(pmu, counter, false);
+
+       if (flags & PERF_EF_UPDATE)
+               cn10k_ddr_perf_event_update(event);
+
+       hwc->state |= PERF_HES_STOPPED;
+}
+
+static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
+{
+       struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+       struct hw_perf_event *hwc = &event->hw;
+       int counter = hwc->idx;
+
+       cn10k_ddr_perf_event_stop(event, PERF_EF_UPDATE);
+
+       cn10k_ddr_perf_free_counter(pmu, counter);
+       pmu->active_events--;
+       hwc->idx = -1;
+
+       /* Cancel timer when no events to capture */
+       if (pmu->active_events == 0)
+               hrtimer_cancel(&pmu->hrtimer);
+}
+
+static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
+{
+       struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
+
+       writeq_relaxed(START_OP_CTRL_VAL_START, ddr_pmu->base +
+                      DDRC_PERF_CNT_START_OP_CTRL);
+}
+
+static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
+{
+       struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
+
+       writeq_relaxed(END_OP_CTRL_VAL_END, ddr_pmu->base +
+                      DDRC_PERF_CNT_END_OP_CTRL);
+}
+
+static void cn10k_ddr_perf_event_update_all(struct cn10k_ddr_pmu *pmu)
+{
+       struct hw_perf_event *hwc;
+       int i;
+
+       for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+               if (pmu->events[i] == NULL)
+                       continue;
+
+               cn10k_ddr_perf_event_update(pmu->events[i]);
+       }
+
+       /* Reset previous count as h/w counter are reset */
+       for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+               if (pmu->events[i] == NULL)
+                       continue;
+
+               hwc = &pmu->events[i]->hw;
+               local64_set(&hwc->prev_count, 0);
+       }
+}
+
+static irqreturn_t cn10k_ddr_pmu_overflow_handler(struct cn10k_ddr_pmu *pmu)
+{
+       struct perf_event *event;
+       struct hw_perf_event *hwc;
+       u64 prev_count, new_count;
+       u64 value;
+       int i;
+
+       event = pmu->events[DDRC_PERF_READ_COUNTER_IDX];
+       if (event) {
+               hwc = &event->hw;
+               prev_count = local64_read(&hwc->prev_count);
+               new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+
+               /* Overflow condition is when new count less than
+                * previous count
+                */
+               if (new_count < prev_count)
+                       cn10k_ddr_perf_event_update(event);
+       }
+
+       event = pmu->events[DDRC_PERF_WRITE_COUNTER_IDX];
+       if (event) {
+               hwc = &event->hw;
+               prev_count = local64_read(&hwc->prev_count);
+               new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+
+               /* Overflow condition is when new count less than
+                * previous count
+                */
+               if (new_count < prev_count)
+                       cn10k_ddr_perf_event_update(event);
+       }
+
+       for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+               if (pmu->events[i] == NULL)
+                       continue;
+
+               value = cn10k_ddr_perf_read_counter(pmu, i);
+               if (value == DDRC_PERF_CNT_MAX_VALUE) {
+                       pr_info("Counter-(%d) reached max value\n", i);
+                       cn10k_ddr_perf_event_update_all(pmu);
+                       cn10k_ddr_perf_pmu_disable(&pmu->pmu);
+                       cn10k_ddr_perf_pmu_enable(&pmu->pmu);
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+static enum hrtimer_restart cn10k_ddr_pmu_timer_handler(struct hrtimer *hrtimer)
+{
+       struct cn10k_ddr_pmu *pmu = container_of(hrtimer, struct cn10k_ddr_pmu,
+                                                hrtimer);
+       unsigned long flags;
+
+       local_irq_save(flags);
+       cn10k_ddr_pmu_overflow_handler(pmu);
+       local_irq_restore(flags);
+
+       hrtimer_forward_now(hrtimer, cn10k_ddr_pmu_timer_period());
+       return HRTIMER_RESTART;
+}
+
+static int cn10k_ddr_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+       struct cn10k_ddr_pmu *pmu = hlist_entry_safe(node, struct cn10k_ddr_pmu,
+                                                    node);
+       unsigned int target;
+
+       if (cpu != pmu->cpu)
+               return 0;
+
+       target = cpumask_any_but(cpu_online_mask, cpu);
+       if (target >= nr_cpu_ids)
+               return 0;
+
+       perf_pmu_migrate_context(&pmu->pmu, cpu, target);
+       pmu->cpu = target;
+       return 0;
+}
+
+static int cn10k_ddr_perf_probe(struct platform_device *pdev)
+{
+       struct cn10k_ddr_pmu *ddr_pmu;
+       struct resource *res;
+       void __iomem *base;
+       char *name;
+       int ret;
+
+       ddr_pmu = devm_kzalloc(&pdev->dev, sizeof(*ddr_pmu), GFP_KERNEL);
+       if (!ddr_pmu)
+               return -ENOMEM;
+
+       ddr_pmu->dev = &pdev->dev;
+       platform_set_drvdata(pdev, ddr_pmu);
+
+       base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       ddr_pmu->base = base;
+
+       /* Setup the PMU counter to work in manual mode */
+       writeq_relaxed(OP_MODE_CTRL_VAL_MANNUAL, ddr_pmu->base +
+                      DDRC_PERF_CNT_OP_MODE_CTRL);
+
+       ddr_pmu->pmu = (struct pmu) {
+               .module       = THIS_MODULE,
+               .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+               .task_ctx_nr = perf_invalid_context,
+               .attr_groups = cn10k_attr_groups,
+               .event_init  = cn10k_ddr_perf_event_init,
+               .add         = cn10k_ddr_perf_event_add,
+               .del         = cn10k_ddr_perf_event_del,
+               .start       = cn10k_ddr_perf_event_start,
+               .stop        = cn10k_ddr_perf_event_stop,
+               .read        = cn10k_ddr_perf_event_update,
+               .pmu_enable  = cn10k_ddr_perf_pmu_enable,
+               .pmu_disable = cn10k_ddr_perf_pmu_disable,
+       };
+
+       /* Choose this cpu to collect perf data */
+       ddr_pmu->cpu = raw_smp_processor_id();
+
+       name = devm_kasprintf(ddr_pmu->dev, GFP_KERNEL, "mrvl_ddr_pmu_%llx",
+                             res->start);
+       if (!name)
+               return -ENOMEM;
+
+       hrtimer_init(&ddr_pmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       ddr_pmu->hrtimer.function = cn10k_ddr_pmu_timer_handler;
+
+       cpuhp_state_add_instance_nocalls(
+                               CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+                               &ddr_pmu->node);
+
+       ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
+       if (ret)
+               goto error;
+
+       pr_info("CN10K DDR PMU Driver for ddrc@%llx\n", res->start);
+       return 0;
+error:
+       cpuhp_state_remove_instance_nocalls(
+                               CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+                               &ddr_pmu->node);
+       return ret;
+}
+
+static int cn10k_ddr_perf_remove(struct platform_device *pdev)
+{
+       struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
+
+       cpuhp_state_remove_instance_nocalls(
+                               CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+                               &ddr_pmu->node);
+
+       perf_pmu_unregister(&ddr_pmu->pmu);
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
+       { .compatible = "marvell,cn10k-ddr-pmu", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
+#endif
+
+static struct platform_driver cn10k_ddr_pmu_driver = {
+       .driver = {
+               .name   = "cn10k-ddr-pmu",
+               .of_match_table = of_match_ptr(cn10k_ddr_pmu_of_match),
+               .suppress_bind_attrs = true,
+       },
+       .probe          = cn10k_ddr_perf_probe,
+       .remove         = cn10k_ddr_perf_remove,
+};
+
+static int __init cn10k_ddr_pmu_init(void)
+{
+       int ret;
+
+       ret = cpuhp_setup_state_multi(
+                               CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+                               "perf/marvell/cn10k/ddr:online", NULL,
+                               cn10k_ddr_pmu_offline_cpu);
+       if (ret)
+               return ret;
+
+       ret = platform_driver_register(&cn10k_ddr_pmu_driver);
+       if (ret)
+               cpuhp_remove_multi_state(
+                               CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
+       return ret;
+}
+
+static void __exit cn10k_ddr_pmu_exit(void)
+{
+       platform_driver_unregister(&cn10k_ddr_pmu_driver);
+       cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
+}
+
+module_init(cn10k_ddr_pmu_init);
+module_exit(cn10k_ddr_pmu_exit);
+
+MODULE_AUTHOR("Bharat Bhushan <bbhushan2@marvell.com>");
+MODULE_LICENSE("GPL v2");
index 7f4d292658e3216dfcfcafe4f5780383d0f03f38..ee67305f822d08a08e29dcd6a7c69a2dfd82fa1a 100644 (file)
@@ -368,10 +368,12 @@ static int tad_pmu_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
 static const struct of_device_id tad_pmu_of_match[] = {
        { .compatible = "marvell,cn10k-tad-pmu", },
        {},
 };
+#endif
 
 static struct platform_driver tad_pmu_driver = {
        .driver         = {
index 05378c0fd8f32ff10b21ade929ef575780a6a014..1edb9c03704fd9aea0d9e51e672e139ed4ce17f2 100644 (file)
@@ -887,13 +887,11 @@ static struct tx2_uncore_pmu *tx2_uncore_pmu_init_dev(struct device *dev,
 static acpi_status tx2_uncore_pmu_add(acpi_handle handle, u32 level,
                                    void *data, void **return_value)
 {
+       struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
        struct tx2_uncore_pmu *tx2_pmu;
-       struct acpi_device *adev;
        enum tx2_uncore_type type;
 
-       if (acpi_bus_get_device(handle, &adev))
-               return AE_OK;
-       if (acpi_bus_get_status(adev) || !adev->status.present)
+       if (!adev || acpi_bus_get_status(adev) || !adev->status.present)
                return AE_OK;
 
        type = get_tx2_pmu_type(adev);
index 2b6d476bd21373bf8aeb7e4f2337f487b82eb678..0c32dffc7edefda0e17abb48d5c0dd6907ea1add 100644 (file)
@@ -867,7 +867,7 @@ static void xgene_perf_pmu_enable(struct pmu *pmu)
 {
        struct xgene_pmu_dev *pmu_dev = to_pmu_dev(pmu);
        struct xgene_pmu *xgene_pmu = pmu_dev->parent;
-       int enabled = bitmap_weight(pmu_dev->cntr_assign_mask,
+       bool enabled = !bitmap_empty(pmu_dev->cntr_assign_mask,
                        pmu_dev->max_counters);
 
        if (!enabled)
@@ -1549,14 +1549,12 @@ static const struct acpi_device_id *xgene_pmu_acpi_match_type(
 static acpi_status acpi_pmu_dev_add(acpi_handle handle, u32 level,
                                    void *data, void **return_value)
 {
+       struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
        const struct acpi_device_id *acpi_id;
        struct xgene_pmu *xgene_pmu = data;
        struct xgene_pmu_dev_ctx *ctx;
-       struct acpi_device *adev;
 
-       if (acpi_bus_get_device(handle, &adev))
-               return AE_OK;
-       if (acpi_bus_get_status(adev) || !adev->status.present)
+       if (!adev || acpi_bus_get_status(adev) || !adev->status.present)
                return AE_OK;
 
        acpi_id = xgene_pmu_acpi_match_type(xgene_pmu_acpi_type_match, adev);
index 0bcd19597e4adad2f4f439d03aeb37d377e4bfb8..3ddaeffc04150afab70e612e09e44c52368d3717 100644 (file)
@@ -749,7 +749,6 @@ static const struct acpi_device_id tgl_pinctrl_acpi_match[] = {
        { "INT34C5", (kernel_ulong_t)&tgllp_soc_data },
        { "INT34C6", (kernel_ulong_t)&tglh_soc_data },
        { "INTC1055", (kernel_ulong_t)&tgllp_soc_data },
-       { "INTC1057", (kernel_ulong_t)&tgllp_soc_data },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match);
index 49e32684dbb25848c8a9048aeb481a2c7f86246a..ecab6bf63dc6d330d9f6b667f459a9d31fe0882c 100644 (file)
@@ -482,7 +482,7 @@ static int k210_pinconf_get_drive(unsigned int max_strength_ua)
 {
        int i;
 
-       for (i = K210_PC_DRIVE_MAX; i; i--) {
+       for (i = K210_PC_DRIVE_MAX; i >= 0; i--) {
                if (k210_pinconf_drive_strength[i] <= max_strength_ua)
                        return i;
        }
@@ -527,7 +527,7 @@ static int k210_pinconf_set_param(struct pinctrl_dev *pctldev,
        case PIN_CONFIG_BIAS_PULL_UP:
                if (!arg)
                        return -EINVAL;
-               val |= K210_PC_PD;
+               val |= K210_PC_PU;
                break;
        case PIN_CONFIG_DRIVE_STRENGTH:
                arg *= 1000;
index 0b912152a405a23e261be07107100b800213e50f..266da41a616265382d8a17c62a21676606eea5a1 100644 (file)
@@ -1164,6 +1164,7 @@ static int starfive_irq_set_type(struct irq_data *d, unsigned int trigger)
 }
 
 static struct irq_chip starfive_irq_chip = {
+       .name = "StarFive GPIO",
        .irq_ack = starfive_irq_ack,
        .irq_mask = starfive_irq_mask,
        .irq_mask_ack = starfive_irq_mask_ack,
@@ -1308,7 +1309,6 @@ static int starfive_probe(struct platform_device *pdev)
        sfp->gc.ngpio = NR_GPIOS;
 
        starfive_irq_chip.parent_device = dev;
-       starfive_irq_chip.name = sfp->gc.label;
 
        sfp->gc.irq.chip = &starfive_irq_chip;
        sfp->gc.irq.parent_handler = starfive_gpio_irq_handler;
index 80d6750c74a60e3cde2e7a6918e145fac42fe37f..1f401377ff600800c4d18061d9d143bc2cfc4c55 100644 (file)
 #include "../core.h"
 #include "pinctrl-sunxi.h"
 
+/*
+ * These lock classes tell lockdep that GPIO IRQs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key sunxi_pinctrl_irq_lock_class;
+static struct lock_class_key sunxi_pinctrl_irq_request_class;
+
 static struct irq_chip sunxi_pinctrl_edge_irq_chip;
 static struct irq_chip sunxi_pinctrl_level_irq_chip;
 
@@ -837,7 +844,8 @@ static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
 {
        struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
 
-       return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, offset, true);
+       return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL,
+                                           chip->base + offset, true);
 }
 
 static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -890,7 +898,8 @@ static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
        struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
 
        sunxi_pinctrl_gpio_set(chip, offset, value);
-       return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, offset, false);
+       return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL,
+                                           chip->base + offset, false);
 }
 
 static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
@@ -1555,6 +1564,8 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
        for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
                int irqno = irq_create_mapping(pctl->domain, i);
 
+               irq_set_lockdep_class(irqno, &sunxi_pinctrl_irq_lock_class,
+                                     &sunxi_pinctrl_irq_request_class);
                irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
                                         handle_edge_irq);
                irq_set_chip_data(irqno, pctl);
index abac3eec565e873ef5d05b0976f16a5d6ce054cc..444ec81ba02d78cc88666a392eaf8569a425be0b 100644 (file)
@@ -232,14 +232,21 @@ static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix)
        }
        bix->last_full_charg_capacity = ret;
 
-       /* get serial number */
+       /*
+        * Get serial number, on some devices (with unofficial replacement
+        * battery?) reading any of the serial number range addresses gets
+        * nacked in this case just leave the serial number empty.
+        */
        ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO,
                                            sizeof(buf), buf);
-       if (ret != sizeof(buf)) {
+       if (ret == -EREMOTEIO) {
+               /* no serial number available */
+       } else if (ret != sizeof(buf)) {
                dev_err(&client->dev, "Error reading serial no: %d\n", ret);
                return ret;
+       } else {
+               snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
        }
-       snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
 
        /* get cycle count */
        ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);
index 4c72ba68b315bbeea909a25f46d278e63efb9ea1..b1103f85a85a0dd4d791000e6ef74cd8e3b8af69 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos.h>
 #include <linux/rtc.h>
 #include <linux/suspend.h>
 #include <linux/seq_file.h>
@@ -85,6 +86,9 @@
 #define PMC_MSG_DELAY_MIN_US           50
 #define RESPONSE_REGISTER_LOOP_MAX     20000
 
+/* QoS request for letting CPUs in idle states, but not the deepest */
+#define AMD_PMC_MAX_IDLE_STATE_LATENCY 3
+
 #define SOC_SUBSYSTEM_IP_MAX   12
 #define DELAY_MIN_US           2000
 #define DELAY_MAX_US           3000
@@ -131,6 +135,7 @@ struct amd_pmc_dev {
        struct device *dev;
        struct pci_dev *rdev;
        struct mutex lock; /* generic mutex lock */
+       struct pm_qos_request amd_pmc_pm_qos_req;
 #if IS_ENABLED(CONFIG_DEBUG_FS)
        struct dentry *dbgfs_dir;
 #endif /* CONFIG_DEBUG_FS */
@@ -521,6 +526,14 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
        rc = rtc_alarm_irq_enable(rtc_device, 0);
        dev_dbg(pdev->dev, "wakeup timer programmed for %lld seconds\n", duration);
 
+       /*
+        * Prevent CPUs from getting into deep idle states while sending OS_HINT
+        * which is otherwise generally safe to send when at least one of the CPUs
+        * is not in deep idle states.
+        */
+       cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req, AMD_PMC_MAX_IDLE_STATE_LATENCY);
+       wake_up_all_idle_cpus();
+
        return rc;
 }
 
@@ -538,24 +551,31 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev)
        /* Activate CZN specific RTC functionality */
        if (pdev->cpu_id == AMD_CPU_ID_CZN) {
                rc = amd_pmc_verify_czn_rtc(pdev, &arg);
-               if (rc < 0)
-                       return rc;
+               if (rc)
+                       goto fail;
        }
 
        /* Dump the IdleMask before we send hint to SMU */
        amd_pmc_idlemask_read(pdev, dev, NULL);
        msg = amd_pmc_get_os_hint(pdev);
        rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0);
-       if (rc)
+       if (rc) {
                dev_err(pdev->dev, "suspend failed\n");
+               goto fail;
+       }
 
        if (enable_stb)
                rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF);
-       if (rc) {
+       if (rc) {
                dev_err(pdev->dev, "error writing to STB\n");
-               return rc;
+               goto fail;
        }
 
+       return 0;
+fail:
+       if (pdev->cpu_id == AMD_CPU_ID_CZN)
+               cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req,
+                                               PM_QOS_DEFAULT_VALUE);
        return rc;
 }
 
@@ -579,12 +599,15 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
        /* Write data incremented by 1 to distinguish in stb_read */
        if (enable_stb)
                rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF + 1);
-       if (rc) {
+       if (rc)
                dev_err(pdev->dev, "error writing to STB\n");
-               return rc;
-       }
 
-       return 0;
+       /* Restore the QoS request back to defaults if it was set */
+       if (pdev->cpu_id == AMD_CPU_ID_CZN)
+               cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req,
+                                               PM_QOS_DEFAULT_VALUE);
+
+       return rc;
 }
 
 static const struct dev_pm_ops amd_pmc_pm_ops = {
@@ -722,6 +745,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
        amd_pmc_get_smu_version(dev);
        platform_set_drvdata(pdev, dev);
        amd_pmc_dbgfs_register(dev);
+       cpu_latency_qos_add_request(&dev->amd_pmc_pm_qos_req, PM_QOS_DEFAULT_VALUE);
        return 0;
 
 err_pci_dev_put:
index a3b83b22a3b13dbdb8a7fce55287bb7bf971a25b..2104a2621e5070e1c963576b77e29c7afff06e4d 100644 (file)
@@ -2223,7 +2223,7 @@ static int fan_curve_check_present(struct asus_wmi *asus, bool *available,
 
        err = fan_curve_get_factory_default(asus, fan_dev);
        if (err) {
-               if (err == -ENODEV)
+               if (err == -ENODEV || err == -ENODATA)
                        return 0;
                return err;
        }
index f93d437fd19281145c9aebb59e7a5a28b82951a9..525f09a3b5ff7427c76f6bf200c11cb2e35f38a6 100644 (file)
@@ -100,7 +100,8 @@ static struct gpiod_lookup_table surface_go_tps68470_gpios = {
        .dev_id = "i2c-INT347A:00",
        .table = {
                GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW),
-               GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW)
+               GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW),
+               { }
        }
 };
 
index bd045486b933fd26d345cf93abcdebdeb6fa2660..3424b080db7729b257b1b67cd00e8c39fc5f0833 100644 (file)
@@ -8703,6 +8703,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
        TPACPI_Q_LNV3('N', '4', '0', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (4nd gen) */
        TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL),  /* P15 (1st gen) / P15v (1st gen) */
        TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL),  /* X1 Carbon (9th gen) */
+       TPACPI_Q_LNV3('N', '3', '7', TPACPI_FAN_2CTL),  /* T15g (2nd gen) */
        TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */
 };
 
index 0f1b5a7d2a89c1101cfd64f90783d777cd323d4c..17ad5f0d13b2a1e1030de84318dbc26009a6c9c1 100644 (file)
@@ -607,7 +607,7 @@ ptp_ocp_settime(struct ptp_clock_info *ptp_info, const struct timespec64 *ts)
 }
 
 static void
-__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
+__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u32 adj_val)
 {
        u32 select, ctrl;
 
@@ -615,7 +615,7 @@ __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
        iowrite32(OCP_SELECT_CLK_REG, &bp->reg->select);
 
        iowrite32(adj_val, &bp->reg->offset_ns);
-       iowrite32(adj_val & 0x7f, &bp->reg->offset_window_ns);
+       iowrite32(NSEC_PER_SEC, &bp->reg->offset_window_ns);
 
        ctrl = OCP_CTRL_ADJUST_OFFSET | OCP_CTRL_ENABLE;
        iowrite32(ctrl, &bp->reg->ctrl);
@@ -624,6 +624,22 @@ __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
        iowrite32(select >> 16, &bp->reg->select);
 }
 
+static void
+ptp_ocp_adjtime_coarse(struct ptp_ocp *bp, u64 delta_ns)
+{
+       struct timespec64 ts;
+       unsigned long flags;
+       int err;
+
+       spin_lock_irqsave(&bp->lock, flags);
+       err = __ptp_ocp_gettime_locked(bp, &ts, NULL);
+       if (likely(!err)) {
+               timespec64_add_ns(&ts, delta_ns);
+               __ptp_ocp_settime_locked(bp, &ts);
+       }
+       spin_unlock_irqrestore(&bp->lock, flags);
+}
+
 static int
 ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
 {
@@ -631,6 +647,11 @@ ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
        unsigned long flags;
        u32 adj_ns, sign;
 
+       if (delta_ns > NSEC_PER_SEC || -delta_ns > NSEC_PER_SEC) {
+               ptp_ocp_adjtime_coarse(bp, delta_ns);
+               return 0;
+       }
+
        sign = delta_ns < 0 ? BIT(31) : 0;
        adj_ns = sign ? -delta_ns : delta_ns;
 
index 6f21223a488e55a65986c25e71fc7bbe189f3d69..eb9df485bd8aafcdcf15107aad88e2115c9cfa48 100644 (file)
@@ -87,16 +87,16 @@ static struct da9121_range da9121_3A_1phase_current = {
 };
 
 static struct da9121_range da914x_40A_4phase_current = {
-       .val_min = 14000000,
-       .val_max = 80000000,
-       .val_stp =  2000000,
+       .val_min = 26000000,
+       .val_max = 78000000,
+       .val_stp =  4000000,
        .reg_min = 1,
        .reg_max = 14,
 };
 
 static struct da9121_range da914x_20A_2phase_current = {
-       .val_min =  7000000,
-       .val_max = 40000000,
+       .val_min = 13000000,
+       .val_max = 39000000,
        .val_stp =  2000000,
        .reg_min = 1,
        .reg_max = 14,
@@ -561,7 +561,7 @@ static const struct regulator_desc da9217_reg = {
 };
 
 #define DA914X_MIN_MV          500
-#define DA914X_MAX_MV          1000
+#define DA914X_MAX_MV          1300
 #define DA914X_STEP_MV         10
 #define DA914X_MIN_SEL         (DA914X_MIN_MV / DA914X_STEP_MV)
 #define DA914X_N_VOLTAGES      (((DA914X_MAX_MV - DA914X_MIN_MV) / DA914X_STEP_MV) \
@@ -585,10 +585,6 @@ static const struct regulator_desc da9141_reg = {
        .vsel_mask = DA9121_MASK_BUCK_BUCKx_5_CHx_A_VOUT,
        .enable_reg = DA9121_REG_BUCK_BUCK1_0,
        .enable_mask = DA9121_MASK_BUCK_BUCKx_0_CHx_EN,
-       /* Default value of BUCK_BUCK1_0.CH1_SRC_DVC_UP */
-       .ramp_delay = 20000,
-       /* tBUCK_EN */
-       .enable_time = 20,
 };
 
 static const struct regulator_desc da9142_reg = {
index 88c549f257dbf7e74df28251c32f658ff0c6454a..40a52feb315da40114ffc6d2c33f6a1c85c8884f 100644 (file)
@@ -986,8 +986,6 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
        CMD_SP(sc) = NULL;
        CMD_FLAGS(sc) |= FNIC_IO_DONE;
 
-       spin_unlock_irqrestore(io_lock, flags);
-
        if (hdr_status != FCPIO_SUCCESS) {
                atomic64_inc(&fnic_stats->io_stats.io_failures);
                shost_printk(KERN_ERR, fnic->lport->host, "hdr status = %s\n",
@@ -996,8 +994,6 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
 
        fnic_release_ioreq_buf(fnic, io_req, sc);
 
-       mempool_free(io_req, fnic->io_req_pool);
-
        cmd_trace = ((u64)hdr_status << 56) |
                  (u64)icmnd_cmpl->scsi_status << 48 |
                  (u64)icmnd_cmpl->flags << 40 | (u64)sc->cmnd[0] << 32 |
@@ -1021,6 +1017,12 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
        } else
                fnic->lport->host_stats.fcp_control_requests++;
 
+       /* Call SCSI completion function to complete the IO */
+       scsi_done(sc);
+       spin_unlock_irqrestore(io_lock, flags);
+
+       mempool_free(io_req, fnic->io_req_pool);
+
        atomic64_dec(&fnic_stats->io_stats.active_ios);
        if (atomic64_read(&fnic->io_cmpl_skip))
                atomic64_dec(&fnic->io_cmpl_skip);
@@ -1049,9 +1051,6 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
                if(io_duration_time > atomic64_read(&fnic_stats->io_stats.current_max_io_time))
                        atomic64_set(&fnic_stats->io_stats.current_max_io_time, io_duration_time);
        }
-
-       /* Call SCSI completion function to complete the IO */
-       scsi_done(sc);
 }
 
 /* fnic_fcpio_itmf_cmpl_handler
index 511726f92d9a5b768a748d5cc92b48b76b581bda..76229b839560a27d3d1a6b06dd8db127c21d2d20 100644 (file)
@@ -2011,9 +2011,10 @@ mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll)
                                enable_irq(reply_q->os_irq);
                        }
                }
+
+               if (poll)
+                       _base_process_reply_queue(reply_q);
        }
-       if (poll)
-               _base_process_reply_queue(reply_q);
 }
 
 /**
index 12c10a5e3d93a3b8b71d955d6a541aa6914834e3..7f421600cb66df5e3d38b03a34f4e2520850dfc7 100644 (file)
@@ -233,12 +233,11 @@ static void scsifront_gnttab_done(struct vscsifrnt_info *info,
                return;
 
        for (i = 0; i < shadow->nr_grants; i++) {
-               if (unlikely(gnttab_query_foreign_access(shadow->gref[i]))) {
+               if (unlikely(!gnttab_try_end_foreign_access(shadow->gref[i]))) {
                        shost_printk(KERN_ALERT, info->host, KBUILD_MODNAME
                                     "grant still in use by backend\n");
                        BUG();
                }
-               gnttab_end_foreign_access(shadow->gref[i], 0, 0UL);
        }
 
        kfree(shadow->sg);
index 072473a16f4de638511ce5a172c9f0b3bfa47fa7..5ed2fc1c53a0e077773b0290746cbbcc0bdd11e2 100644 (file)
@@ -28,7 +28,6 @@ struct fsl_soc_die_attr {
 static struct guts *guts;
 static struct soc_device_attribute soc_dev_attr;
 static struct soc_device *soc_dev;
-static struct device_node *root;
 
 
 /* SoC die attribute definition for QorIQ platform */
@@ -138,7 +137,7 @@ static u32 fsl_guts_get_svr(void)
 
 static int fsl_guts_probe(struct platform_device *pdev)
 {
-       struct device_node *np = pdev->dev.of_node;
+       struct device_node *root, *np = pdev->dev.of_node;
        struct device *dev = &pdev->dev;
        const struct fsl_soc_die_attr *soc_die;
        const char *machine;
@@ -159,8 +158,14 @@ static int fsl_guts_probe(struct platform_device *pdev)
        root = of_find_node_by_path("/");
        if (of_property_read_string(root, "model", &machine))
                of_property_read_string_index(root, "compatible", 0, &machine);
-       if (machine)
-               soc_dev_attr.machine = machine;
+       if (machine) {
+               soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+               if (!soc_dev_attr.machine) {
+                       of_node_put(root);
+                       return -ENOMEM;
+               }
+       }
+       of_node_put(root);
 
        svr = fsl_guts_get_svr();
        soc_die = fsl_soc_die_match(svr, fsl_soc_die);
@@ -195,7 +200,6 @@ static int fsl_guts_probe(struct platform_device *pdev)
 static int fsl_guts_remove(struct platform_device *dev)
 {
        soc_device_unregister(soc_dev);
-       of_node_put(root);
        return 0;
 }
 
index 4d38c80f8be81ac0fe3e29b5ab6f106e37cc3709..b3c226eb5292f65dc4ba1f9d5b523986c5c3f668 100644 (file)
@@ -147,7 +147,7 @@ EXPORT_SYMBOL(qe_issue_cmd);
  * memory mapped space.
  * The BRG clock is the QE clock divided by 2.
  * It was set up long ago during the initial boot phase and is
- * is given to us.
+ * given to us.
  * Baud rate clocks are zero-based in the driver code (as that maps
  * to port numbers). Documentation uses 1-based numbering.
  */
@@ -421,7 +421,7 @@ static void qe_upload_microcode(const void *base,
 
        for (i = 0; i < be32_to_cpu(ucode->count); i++)
                iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata);
-       
+
        /* Set I-RAM Ready Register */
        iowrite32be(QE_IRAM_READY, &qe_immr->iram.iready);
 }
index e277c827bdf336f4789ff438a8413b235fc1ca1e..a5e2d0e5ab511fae5f929a8434fb499f0ea6d53a 100644 (file)
@@ -35,6 +35,8 @@ int par_io_init(struct device_node *np)
        if (ret)
                return ret;
        par_io = ioremap(res.start, resource_size(&res));
+       if (!par_io)
+               return -ENOMEM;
 
        if (!of_property_read_u32(np, "num-ports", &num_ports))
                num_par_io_ports = num_ports;
index 3e59d479d001e99c15a46303ff862063339462cd..3cb123016b3ec5ee0b939054eb8eddafa8595349 100644 (file)
@@ -382,7 +382,8 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
        return 0;
 
 out_clk_disable:
-       clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
+       if (!domain->keep_clocks)
+               clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
 
        return ret;
 }
index 6f0a57044a7bdfb5141eb675943b19ef7a04b802..6aae0b12b6ff907cc8a3d4b3ec4ad73b20091681 100644 (file)
@@ -53,7 +53,8 @@ static const struct mtk_mmsys_routes mmsys_mt8192_routing_table[] = {
                MT8192_AAL0_SEL_IN_CCORR0
        }, {
                DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
-               MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0
+               MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0,
+               MT8192_DSI0_SEL_IN_DITHER0
        }, {
                DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
                MT8192_DISP_RDMA0_SOUT_SEL, MT8192_RDMA0_SOUT_COLOR0,
index 2746d05936d37b3381fc78ace94d749176bd97c5..0fb3631e734610a6b40c2202dd4f1e92601c0f4f 100644 (file)
@@ -204,7 +204,7 @@ module_platform_driver(exynos_chipid_driver);
 
 MODULE_DESCRIPTION("Samsung Exynos ChipID controller and ASV driver");
 MODULE_AUTHOR("Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>");
-MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>");
+MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
 MODULE_AUTHOR("Pankaj Dubey <pankaj.dubey@samsung.com>");
 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
 MODULE_LICENSE("GPL");
index 553b6b9d02222ba835f468ec32acdd3ccd60155c..c6a1bb09be056683a47cce906bf5f02730172c80 100644 (file)
@@ -585,6 +585,12 @@ static int rockchip_spi_slave_abort(struct spi_controller *ctlr)
 {
        struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
 
+       if (atomic_read(&rs->state) & RXDMA)
+               dmaengine_terminate_sync(ctlr->dma_rx);
+       if (atomic_read(&rs->state) & TXDMA)
+               dmaengine_terminate_sync(ctlr->dma_tx);
+       atomic_set(&rs->state, 0);
+       spi_enable_chip(rs, false);
        rs->slave_abort = true;
        spi_finalize_current_transfer(ctlr);
 
@@ -654,7 +660,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
        struct spi_controller *ctlr;
        struct resource *mem;
        struct device_node *np = pdev->dev.of_node;
-       u32 rsd_nsecs;
+       u32 rsd_nsecs, num_cs;
        bool slave_mode;
 
        slave_mode = of_property_read_bool(np, "spi-slave");
@@ -764,8 +770,9 @@ static int rockchip_spi_probe(struct platform_device *pdev)
                 * rk spi0 has two native cs, spi1..5 one cs only
                 * if num-cs is missing in the dts, default to 1
                 */
-               if (of_property_read_u16(np, "num-cs", &ctlr->num_chipselect))
-                       ctlr->num_chipselect = 1;
+               if (of_property_read_u32(np, "num-cs", &num_cs))
+                       num_cs = 1;
+               ctlr->num_chipselect = num_cs;
                ctlr->use_gpio_descriptors = true;
        }
        ctlr->dev.of_node = pdev->dev.of_node;
index cfa222c9bd5e74f7794e74621cfc85359ccac477..78f31b61a2aac47e10762c04f97fb3e5e125a999 100644 (file)
@@ -570,6 +570,9 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
 
        if (op->dummy.nbytes) {
                tmpbuf = kzalloc(op->dummy.nbytes, GFP_KERNEL);
+               if (!tmpbuf)
+                       return -ENOMEM;
+
                memset(tmpbuf, 0xff, op->dummy.nbytes);
                reinit_completion(&xqspi->data_completion);
                xqspi->txbuf = tmpbuf;
index 4599b121d74423d573a9c275b24b19b2f58890b4..d96082dc3340dbc744b1cf83321ff5b68fdc5ad6 100644 (file)
@@ -1019,10 +1019,10 @@ int spi_map_buf(struct spi_controller *ctlr, struct device *dev,
        int i, ret;
 
        if (vmalloced_buf || kmap_buf) {
-               desc_len = min_t(int, max_seg_size, PAGE_SIZE);
+               desc_len = min_t(unsigned int, max_seg_size, PAGE_SIZE);
                sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len);
        } else if (virt_addr_valid(buf)) {
-               desc_len = min_t(int, max_seg_size, ctlr->max_dma_len);
+               desc_len = min_t(unsigned int, max_seg_size, ctlr->max_dma_len);
                sgs = DIV_ROUND_UP(len, desc_len);
        } else {
                return -EINVAL;
index abe9395a0aefda9e98fb0bdba4032ff0abf00673..861a154144e6616ed8854c272e9d718211341d0d 100644 (file)
@@ -144,6 +144,8 @@ static int init_display(struct fbtft_par *par)
 {
        int rc;
 
+       par->fbtftops.reset(par);
+
        rc = init_tearing_effect_line(par);
        if (rc)
                return rc;
index 493ed4821515be7fe596f53f389d0b6cb6b6ba27..0d8d8fed283d037a3691b0a4b2ce9358c378a16e 100644 (file)
@@ -76,14 +76,15 @@ static void tx_complete(void *arg)
 
 static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type)
 {
-       int ret;
+       int ret, len;
 
+       len = skb->len + ETH_HLEN;
        ret = netif_rx_ni(skb);
        if (ret == NET_RX_DROP) {
                nic->stats.rx_dropped++;
        } else {
                nic->stats.rx_packets++;
-               nic->stats.rx_bytes += skb->len + ETH_HLEN;
+               nic->stats.rx_bytes += len;
        }
 
        return 0;
index 0f82f5031c4349bfd9c8f5b89ff945fb4c95484a..49a3f45cb771b8da4c1492e0c92a5e7f0736e488 100644 (file)
@@ -5907,6 +5907,7 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
        struct sta_info *psta_bmc;
        struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
        struct xmit_frame *pxmitframe = NULL;
+       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
        struct sta_priv  *pstapriv = &padapter->stapriv;
 
        /* for BC/MC Frames */
@@ -5917,7 +5918,8 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
        if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) {
                msleep(10);/*  10ms, ATIM(HIQ) Windows */
 
-               spin_lock_bh(&psta_bmc->sleep_q.lock);
+               /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
+               spin_lock_bh(&pxmitpriv->lock);
 
                xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
                list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
@@ -5940,7 +5942,8 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
                        rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
                }
 
-               spin_unlock_bh(&psta_bmc->sleep_q.lock);
+               /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
+               spin_unlock_bh(&pxmitpriv->lock);
 
                /* check hi queue and bmc_sleepq */
                rtw_chk_hi_queue_cmd(padapter);
index 41bfca549c641806f0db58bd7eba2249d1dc34ad..105fe0e3482a2bf05399ff64899b2eb1f7b0d96d 100644 (file)
@@ -957,8 +957,10 @@ static signed int validate_recv_ctrl_frame(struct adapter *padapter, union recv_
                if ((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) {
                        struct list_head        *xmitframe_plist, *xmitframe_phead;
                        struct xmit_frame *pxmitframe = NULL;
+                       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 
-                       spin_lock_bh(&psta->sleep_q.lock);
+                       /* spin_lock_bh(&psta->sleep_q.lock); */
+                       spin_lock_bh(&pxmitpriv->lock);
 
                        xmitframe_phead = get_list_head(&psta->sleep_q);
                        xmitframe_plist = get_next(xmitframe_phead);
@@ -989,10 +991,12 @@ static signed int validate_recv_ctrl_frame(struct adapter *padapter, union recv_
                                        update_beacon(padapter, WLAN_EID_TIM, NULL, true);
                                }
 
-                               spin_unlock_bh(&psta->sleep_q.lock);
+                               /* spin_unlock_bh(&psta->sleep_q.lock); */
+                               spin_unlock_bh(&pxmitpriv->lock);
 
                        } else {
-                               spin_unlock_bh(&psta->sleep_q.lock);
+                               /* spin_unlock_bh(&psta->sleep_q.lock); */
+                               spin_unlock_bh(&pxmitpriv->lock);
 
                                if (pstapriv->tim_bitmap&BIT(psta->aid)) {
                                        if (psta->sleepq_len == 0) {
index 0c9ea1520fd059e1d62d5fcaeee55938bf0a4075..beb11d89db1866c2dfbf18d3f35f765a8f2aaec1 100644 (file)
@@ -293,48 +293,46 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
 
        /* list_del_init(&psta->wakeup_list); */
 
-       spin_lock_bh(&psta->sleep_q.lock);
+       spin_lock_bh(&pxmitpriv->lock);
+
        rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
        psta->sleepq_len = 0;
-       spin_unlock_bh(&psta->sleep_q.lock);
-
-       spin_lock_bh(&pxmitpriv->lock);
 
        /* vo */
-       spin_lock_bh(&pstaxmitpriv->vo_q.sta_pending.lock);
+       /* spin_lock_bh(&(pxmitpriv->vo_pending.lock)); */
        rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
        list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
        phwxmit = pxmitpriv->hwxmits;
        phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt;
        pstaxmitpriv->vo_q.qcnt = 0;
-       spin_unlock_bh(&pstaxmitpriv->vo_q.sta_pending.lock);
+       /* spin_unlock_bh(&(pxmitpriv->vo_pending.lock)); */
 
        /* vi */
-       spin_lock_bh(&pstaxmitpriv->vi_q.sta_pending.lock);
+       /* spin_lock_bh(&(pxmitpriv->vi_pending.lock)); */
        rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
        list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
        phwxmit = pxmitpriv->hwxmits+1;
        phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt;
        pstaxmitpriv->vi_q.qcnt = 0;
-       spin_unlock_bh(&pstaxmitpriv->vi_q.sta_pending.lock);
+       /* spin_unlock_bh(&(pxmitpriv->vi_pending.lock)); */
 
        /* be */
-       spin_lock_bh(&pstaxmitpriv->be_q.sta_pending.lock);
+       /* spin_lock_bh(&(pxmitpriv->be_pending.lock)); */
        rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
        list_del_init(&(pstaxmitpriv->be_q.tx_pending));
        phwxmit = pxmitpriv->hwxmits+2;
        phwxmit->accnt -= pstaxmitpriv->be_q.qcnt;
        pstaxmitpriv->be_q.qcnt = 0;
-       spin_unlock_bh(&pstaxmitpriv->be_q.sta_pending.lock);
+       /* spin_unlock_bh(&(pxmitpriv->be_pending.lock)); */
 
        /* bk */
-       spin_lock_bh(&pstaxmitpriv->bk_q.sta_pending.lock);
+       /* spin_lock_bh(&(pxmitpriv->bk_pending.lock)); */
        rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
        list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
        phwxmit = pxmitpriv->hwxmits+3;
        phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt;
        pstaxmitpriv->bk_q.qcnt = 0;
-       spin_unlock_bh(&pstaxmitpriv->bk_q.sta_pending.lock);
+       /* spin_unlock_bh(&(pxmitpriv->bk_pending.lock)); */
 
        spin_unlock_bh(&pxmitpriv->lock);
 
index 13b8bd5ffabc4c27cb28fd7aa5fae94528f6a526..f466bfd248fb683a76470807b8ada07f6a2ed027 100644 (file)
@@ -1734,12 +1734,15 @@ void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pfram
        struct list_head *plist, *phead, *tmp;
        struct  xmit_frame      *pxmitframe;
 
+       spin_lock_bh(&pframequeue->lock);
+
        phead = get_list_head(pframequeue);
        list_for_each_safe(plist, tmp, phead) {
                pxmitframe = list_entry(plist, struct xmit_frame, list);
 
                rtw_free_xmitframe(pxmitpriv, pxmitframe);
        }
+       spin_unlock_bh(&pframequeue->lock);
 }
 
 s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe)
@@ -1794,7 +1797,6 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
        struct sta_info *psta;
        struct tx_servq *ptxservq;
        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
-       struct xmit_priv *xmit_priv = &padapter->xmitpriv;
        struct hw_xmit  *phwxmits =  padapter->xmitpriv.hwxmits;
        signed int res = _SUCCESS;
 
@@ -1812,14 +1814,12 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
 
        ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
 
-       spin_lock_bh(&xmit_priv->lock);
        if (list_empty(&ptxservq->tx_pending))
                list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
 
        list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
        ptxservq->qcnt++;
        phwxmits[ac_index].accnt++;
-       spin_unlock_bh(&xmit_priv->lock);
 
 exit:
 
@@ -2202,10 +2202,11 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
        struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
        struct xmit_frame *pxmitframe = NULL;
        struct sta_priv *pstapriv = &padapter->stapriv;
+       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 
        psta_bmc = rtw_get_bcmc_stainfo(padapter);
 
-       spin_lock_bh(&psta->sleep_q.lock);
+       spin_lock_bh(&pxmitpriv->lock);
 
        xmitframe_phead = get_list_head(&psta->sleep_q);
        list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
@@ -2306,7 +2307,7 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
 
 _exit:
 
-       spin_unlock_bh(&psta->sleep_q.lock);
+       spin_unlock_bh(&pxmitpriv->lock);
 
        if (update_mask)
                update_beacon(padapter, WLAN_EID_TIM, NULL, true);
@@ -2318,8 +2319,9 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst
        struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
        struct xmit_frame *pxmitframe = NULL;
        struct sta_priv *pstapriv = &padapter->stapriv;
+       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 
-       spin_lock_bh(&psta->sleep_q.lock);
+       spin_lock_bh(&pxmitpriv->lock);
 
        xmitframe_phead = get_list_head(&psta->sleep_q);
        list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
@@ -2372,7 +2374,7 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst
                }
        }
 
-       spin_unlock_bh(&psta->sleep_q.lock);
+       spin_unlock_bh(&pxmitpriv->lock);
 }
 
 void enqueue_pending_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
index b5d5e922231ce797a208465b78cf3d11fda09968..15810438a472f0ef726226ede8b4ecdcd67944d3 100644 (file)
@@ -502,7 +502,9 @@ s32 rtl8723bs_hal_xmit(
                        rtw_issue_addbareq_cmd(padapter, pxmitframe);
        }
 
+       spin_lock_bh(&pxmitpriv->lock);
        err = rtw_xmitframe_enqueue(padapter, pxmitframe);
+       spin_unlock_bh(&pxmitpriv->lock);
        if (err != _SUCCESS) {
                rtw_free_xmitframe(pxmitpriv, pxmitframe);
 
index c94fa7d8d5a9e0516fe40bfee470d93171571d66..1b343b434f4d81e71f7b125369741f9acc6cc32c 100644 (file)
@@ -102,13 +102,17 @@ there are several "locks" in mlme_priv,
 since mlme_priv is a shared resource between many threads,
 like ISR/Call-Back functions, the OID handlers, and even timer functions.
 
-
 Each struct __queue has its own locks, already.
-Other items are protected by mlme_priv.lock.
+Other items in mlme_priv are protected by mlme_priv.lock, while items in
+xmit_priv are protected by xmit_priv.lock.
 
 To avoid possible dead lock, any thread trying to modifiying mlme_priv
 SHALL not lock up more than one locks at a time!
 
+The only exception is that queue functions which take the __queue.lock
+may be called with the xmit_priv.lock held. In this case the order
+MUST always be first lock xmit_priv.lock and then call any queue functions
+which take __queue.lock.
 */
 
 
index f2bf6c61197fb888f63b9da5d3146e2b38d2784c..f744ab15bf2c6ec77c507366a26be85de216c1e6 100644 (file)
@@ -869,8 +869,10 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev)
        optee_supp_init(&optee->supp);
        ffa_dev_set_drvdata(ffa_dev, optee);
        ctx = teedev_open(optee->teedev);
-       if (IS_ERR(ctx))
+       if (IS_ERR(ctx)) {
+               rc = PTR_ERR(ctx);
                goto err_rhashtable_free;
+       }
        optee->ctx = ctx;
        rc = optee_notif_init(optee, OPTEE_DEFAULT_MAX_NOTIF_VALUE);
        if (rc)
index 1a55339c7072f77ad36cbfd4e7fdca83fb109a4f..c517d310249f892debe934308b3f0faf97c22b6e 100644 (file)
@@ -1417,8 +1417,10 @@ static int optee_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, optee);
        ctx = teedev_open(optee->teedev);
-       if (IS_ERR(ctx))
+       if (IS_ERR(ctx)) {
+               rc = PTR_ERR(ctx);
                goto err_supp_uninit;
+       }
        optee->ctx = ctx;
        rc = optee_notif_init(optee, max_notif_value);
        if (rc)
index 72acb1f61849709f994e4c73610e4225a1a3a095..4f478812cb5144f7cb7b76f9d88b7194473ca64e 100644 (file)
@@ -404,6 +404,10 @@ static void int3400_notify(acpi_handle handle,
        thermal_prop[3] = kasprintf(GFP_KERNEL, "EVENT=%d", therm_event);
        thermal_prop[4] = NULL;
        kobject_uevent_env(&priv->thermal->device.kobj, KOBJ_CHANGE, thermal_prop);
+       kfree(thermal_prop[0]);
+       kfree(thermal_prop[1]);
+       kfree(thermal_prop[2]);
+       kfree(thermal_prop[3]);
 }
 
 static int int3400_thermal_get_temp(struct thermal_zone_device *thermal,
index a16dd4d5d710e05032355a1e1812b027325c9792..73e68cce292e2c0527e6bcdbb6b8d57cf57cb790 100644 (file)
@@ -419,11 +419,12 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
        for (i = 0; i < tz->trips; i++) {
 
                enum thermal_trip_type type;
-               int temp, hyst;
+               int temp, hyst = 0;
 
                tz->ops->get_trip_type(tz, i, &type);
                tz->ops->get_trip_temp(tz, i, &temp);
-               tz->ops->get_trip_hyst(tz, i, &hyst);
+               if (tz->ops->get_trip_hyst)
+                       tz->ops->get_trip_hyst(tz, i, &hyst);
 
                if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_ID, i) ||
                    nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TRIP_TYPE, type) ||
index 0b1808e3a912bf1f418385eccbcce1a55fbd72ba..fa92f727fdf895fafd556f41ca1460039181ce81 100644 (file)
@@ -439,7 +439,7 @@ static u8 gsm_encode_modem(const struct gsm_dlci *dlci)
                modembits |= MDM_RTR;
        if (dlci->modem_tx & TIOCM_RI)
                modembits |= MDM_IC;
-       if (dlci->modem_tx & TIOCM_CD)
+       if (dlci->modem_tx & TIOCM_CD || dlci->gsm->initiator)
                modembits |= MDM_DV;
        return modembits;
 }
@@ -448,7 +448,7 @@ static u8 gsm_encode_modem(const struct gsm_dlci *dlci)
  *     gsm_print_packet        -       display a frame for debug
  *     @hdr: header to print before decode
  *     @addr: address EA from the frame
- *     @cr: C/R bit from the frame
+ *     @cr: C/R bit seen as initiator
  *     @control: control including PF bit
  *     @data: following data bytes
  *     @dlen: length of data
@@ -548,7 +548,7 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len)
  *     gsm_send        -       send a control frame
  *     @gsm: our GSM mux
  *     @addr: address for control frame
- *     @cr: command/response bit
+ *     @cr: command/response bit seen as initiator
  *     @control:  control byte including PF bit
  *
  *     Format up and transmit a control frame. These do not go via the
@@ -563,11 +563,15 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
        int len;
        u8 cbuf[10];
        u8 ibuf[3];
+       int ocr;
+
+       /* toggle C/R coding if not initiator */
+       ocr = cr ^ (gsm->initiator ? 0 : 1);
 
        switch (gsm->encoding) {
        case 0:
                cbuf[0] = GSM0_SOF;
-               cbuf[1] = (addr << 2) | (cr << 1) | EA;
+               cbuf[1] = (addr << 2) | (ocr << 1) | EA;
                cbuf[2] = control;
                cbuf[3] = EA;   /* Length of data = 0 */
                cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
@@ -577,7 +581,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
        case 1:
        case 2:
                /* Control frame + packing (but not frame stuffing) in mode 1 */
-               ibuf[0] = (addr << 2) | (cr << 1) | EA;
+               ibuf[0] = (addr << 2) | (ocr << 1) | EA;
                ibuf[1] = control;
                ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
                /* Stuffing may double the size worst case */
@@ -611,7 +615,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
 
 static inline void gsm_response(struct gsm_mux *gsm, int addr, int control)
 {
-       gsm_send(gsm, addr, 1, control);
+       gsm_send(gsm, addr, 0, control);
 }
 
 /**
@@ -1017,25 +1021,25 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, const u8 *data,
  *     @tty: virtual tty bound to the DLCI
  *     @dlci: DLCI to affect
  *     @modem: modem bits (full EA)
- *     @clen: command length
+ *     @slen: number of signal octets
  *
  *     Used when a modem control message or line state inline in adaption
  *     layer 2 is processed. Sort out the local modem state and throttles
  */
 
 static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
-                                                       u32 modem, int clen)
+                                                       u32 modem, int slen)
 {
        int  mlines = 0;
        u8 brk = 0;
        int fc;
 
-       /* The modem status command can either contain one octet (v.24 signals)
-          or two octets (v.24 signals + break signals). The length field will
-          either be 2 or 3 respectively. This is specified in section
-          5.4.6.3.7 of the  27.010 mux spec. */
+       /* The modem status command can either contain one octet (V.24 signals)
+        * or two octets (V.24 signals + break signals). This is specified in
+        * section 5.4.6.3.7 of the 07.10 mux spec.
+        */
 
-       if (clen == 2)
+       if (slen == 1)
                modem = modem & 0x7f;
        else {
                brk = modem & 0x7f;
@@ -1092,6 +1096,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
        unsigned int brk = 0;
        struct gsm_dlci *dlci;
        int len = clen;
+       int slen;
        const u8 *dp = data;
        struct tty_struct *tty;
 
@@ -1111,6 +1116,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
                return;
        dlci = gsm->dlci[addr];
 
+       slen = len;
        while (gsm_read_ea(&modem, *dp++) == 0) {
                len--;
                if (len == 0)
@@ -1127,7 +1133,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
                modem |= (brk & 0x7f);
        }
        tty = tty_port_tty_get(&dlci->port);
-       gsm_process_modem(tty, dlci, modem, clen);
+       gsm_process_modem(tty, dlci, modem, slen);
        if (tty) {
                tty_wakeup(tty);
                tty_kref_put(tty);
@@ -1451,6 +1457,9 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
        if (dlci->addr != 0) {
                tty_port_tty_hangup(&dlci->port, false);
                kfifo_reset(&dlci->fifo);
+               /* Ensure that gsmtty_open() can return. */
+               tty_port_set_initialized(&dlci->port, 0);
+               wake_up_interruptible(&dlci->port.open_wait);
        } else
                dlci->gsm->dead = true;
        /* Unregister gsmtty driver,report gsmtty dev remove uevent for user */
@@ -1514,7 +1523,7 @@ static void gsm_dlci_t1(struct timer_list *t)
                        dlci->mode = DLCI_MODE_ADM;
                        gsm_dlci_open(dlci);
                } else {
-                       gsm_dlci_close(dlci);
+                       gsm_dlci_begin_close(dlci); /* prevent half open link */
                }
 
                break;
@@ -1593,6 +1602,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen)
        struct tty_struct *tty;
        unsigned int modem = 0;
        int len = clen;
+       int slen = 0;
 
        if (debug & 16)
                pr_debug("%d bytes for tty\n", len);
@@ -1605,12 +1615,14 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen)
        case 2:         /* Asynchronous serial with line state in each frame */
                while (gsm_read_ea(&modem, *data++) == 0) {
                        len--;
+                       slen++;
                        if (len == 0)
                                return;
                }
+               slen++;
                tty = tty_port_tty_get(port);
                if (tty) {
-                       gsm_process_modem(tty, dlci, modem, clen);
+                       gsm_process_modem(tty, dlci, modem, slen);
                        tty_kref_put(tty);
                }
                fallthrough;
@@ -1748,7 +1760,12 @@ static void gsm_dlci_release(struct gsm_dlci *dlci)
                gsm_destroy_network(dlci);
                mutex_unlock(&dlci->mutex);
 
-               tty_hangup(tty);
+               /* We cannot use tty_hangup() because in tty_kref_put() the tty
+                * driver assumes that the hangup queue is free and reuses it to
+                * queue release_one_tty() -> NULL pointer panic in
+                * process_one_work().
+                */
+               tty_vhangup(tty);
 
                tty_port_tty_set(&dlci->port, NULL);
                tty_kref_put(tty);
@@ -1800,10 +1817,10 @@ static void gsm_queue(struct gsm_mux *gsm)
                goto invalid;
 
        cr = gsm->address & 1;          /* C/R bit */
+       cr ^= gsm->initiator ? 0 : 1;   /* Flip so 1 always means command */
 
        gsm_print_packet("<--", address, cr, gsm->control, gsm->buf, gsm->len);
 
-       cr ^= 1 - gsm->initiator;       /* Flip so 1 always means command */
        dlci = gsm->dlci[address];
 
        switch (gsm->control) {
@@ -3234,9 +3251,9 @@ static void gsmtty_throttle(struct tty_struct *tty)
        if (dlci->state == DLCI_CLOSED)
                return;
        if (C_CRTSCTS(tty))
-               dlci->modem_tx &= ~TIOCM_DTR;
+               dlci->modem_tx &= ~TIOCM_RTS;
        dlci->throttled = true;
-       /* Send an MSC with DTR cleared */
+       /* Send an MSC with RTS cleared */
        gsmtty_modem_update(dlci, 0);
 }
 
@@ -3246,9 +3263,9 @@ static void gsmtty_unthrottle(struct tty_struct *tty)
        if (dlci->state == DLCI_CLOSED)
                return;
        if (C_CRTSCTS(tty))
-               dlci->modem_tx |= TIOCM_DTR;
+               dlci->modem_tx |= TIOCM_RTS;
        dlci->throttled = false;
-       /* Send an MSC with DTR set */
+       /* Send an MSC with RTS set */
        gsmtty_modem_update(dlci, 0);
 }
 
index 64e7e6c8145f8a6ae114ada0c1017b1499db9db4..38d1c0748533cdc951022d6d61d1e07b8814d974 100644 (file)
@@ -734,12 +734,15 @@ static irqreturn_t sc16is7xx_irq(int irq, void *dev_id)
 static void sc16is7xx_tx_proc(struct kthread_work *ws)
 {
        struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port);
+       struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
 
        if ((port->rs485.flags & SER_RS485_ENABLED) &&
            (port->rs485.delay_rts_before_send > 0))
                msleep(port->rs485.delay_rts_before_send);
 
+       mutex_lock(&s->efr_lock);
        sc16is7xx_handle_tx(port);
+       mutex_unlock(&s->efr_lock);
 }
 
 static void sc16is7xx_reconf_rs485(struct uart_port *port)
index 73f419adce610e9d633b7d2dc405322425cf89d4..4bb6d304eb4b21fe3049f44ca000826af2c40ff0 100644 (file)
@@ -1919,6 +1919,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
        struct usbtmc_ctrlrequest request;
        u8 *buffer = NULL;
        int rv;
+       unsigned int is_in, pipe;
        unsigned long res;
 
        res = copy_from_user(&request, arg, sizeof(struct usbtmc_ctrlrequest));
@@ -1928,12 +1929,14 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
        if (request.req.wLength > USBTMC_BUFSIZE)
                return -EMSGSIZE;
 
+       is_in = request.req.bRequestType & USB_DIR_IN;
+
        if (request.req.wLength) {
                buffer = kmalloc(request.req.wLength, GFP_KERNEL);
                if (!buffer)
                        return -ENOMEM;
 
-               if ((request.req.bRequestType & USB_DIR_IN) == 0) {
+               if (!is_in) {
                        /* Send control data to device */
                        res = copy_from_user(buffer, request.data,
                                             request.req.wLength);
@@ -1944,8 +1947,12 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
                }
        }
 
+       if (is_in)
+               pipe = usb_rcvctrlpipe(data->usb_dev, 0);
+       else
+               pipe = usb_sndctrlpipe(data->usb_dev, 0);
        rv = usb_control_msg(data->usb_dev,
-                       usb_rcvctrlpipe(data->usb_dev, 0),
+                       pipe,
                        request.req.bRequest,
                        request.req.bRequestType,
                        request.req.wValue,
@@ -1957,7 +1964,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
                goto exit;
        }
 
-       if (rv && (request.req.bRequestType & USB_DIR_IN)) {
+       if (rv && is_in) {
                /* Read control data from device */
                res = copy_to_user(request.data, buffer, rv);
                if (res)
index 8a63da3ab39d65dcac859f2824e89a79d6a9ce41..88c337bf564ff08b2829ca25cb0e7eae2d9298c3 100644 (file)
@@ -1418,6 +1418,7 @@ void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg);
 void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2);
 int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
 #define dwc2_is_device_connected(hsotg) (hsotg->connected)
+#define dwc2_is_device_enabled(hsotg) (hsotg->enabled)
 int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
 int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup);
 int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg);
@@ -1454,6 +1455,7 @@ static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
                                           int testmode)
 { return 0; }
 #define dwc2_is_device_connected(hsotg) (0)
+#define dwc2_is_device_enabled(hsotg) (0)
 static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 { return 0; }
 static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg,
index 1b39c4776369b476223c9c2a880dc1521867c9a3..d8d6493bc4576ba767d0c13b0255592cbece1595 100644 (file)
@@ -130,8 +130,10 @@ static int dwc2_drd_role_sw_set(struct usb_role_switch *sw, enum usb_role role)
                already = dwc2_ovr_avalid(hsotg, true);
        } else if (role == USB_ROLE_DEVICE) {
                already = dwc2_ovr_bvalid(hsotg, true);
-               /* This clear DCTL.SFTDISCON bit */
-               dwc2_hsotg_core_connect(hsotg);
+               if (dwc2_is_device_enabled(hsotg)) {
+                       /* This clear DCTL.SFTDISCON bit */
+                       dwc2_hsotg_core_connect(hsotg);
+               }
        } else {
                if (dwc2_is_device_mode(hsotg)) {
                        if (!dwc2_ovr_bvalid(hsotg, false))
index 7ff8fc8f79a9b518f44bdff6c7d271b0411bed38..06d0e88ec8af96afd857e31c2c1594c6ac4d45e2 100644 (file)
@@ -43,6 +43,7 @@
 #define PCI_DEVICE_ID_INTEL_ADLP               0x51ee
 #define PCI_DEVICE_ID_INTEL_ADLM               0x54ee
 #define PCI_DEVICE_ID_INTEL_ADLS               0x7ae1
+#define PCI_DEVICE_ID_INTEL_RPLS               0x7a61
 #define PCI_DEVICE_ID_INTEL_TGL                        0x9a15
 #define PCI_DEVICE_ID_AMD_MR                   0x163a
 
@@ -85,8 +86,8 @@ static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
 static struct gpiod_lookup_table platform_bytcr_gpios = {
        .dev_id         = "0000:00:16.0",
        .table          = {
-               GPIO_LOOKUP("INT33FC:00", 54, "reset", GPIO_ACTIVE_HIGH),
-               GPIO_LOOKUP("INT33FC:02", 14, "cs", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("INT33FC:00", 54, "cs", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("INT33FC:02", 14, "reset", GPIO_ACTIVE_HIGH),
                {}
        },
 };
@@ -119,6 +120,13 @@ static const struct property_entry dwc3_pci_intel_properties[] = {
        {}
 };
 
+static const struct property_entry dwc3_pci_intel_byt_properties[] = {
+       PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
+       PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+       PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
+       {}
+};
+
 static const struct property_entry dwc3_pci_mrfld_properties[] = {
        PROPERTY_ENTRY_STRING("dr_mode", "otg"),
        PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
@@ -161,6 +169,10 @@ static const struct software_node dwc3_pci_intel_swnode = {
        .properties = dwc3_pci_intel_properties,
 };
 
+static const struct software_node dwc3_pci_intel_byt_swnode = {
+       .properties = dwc3_pci_intel_byt_properties,
+};
+
 static const struct software_node dwc3_pci_intel_mrfld_swnode = {
        .properties = dwc3_pci_mrfld_properties,
 };
@@ -344,7 +356,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
          (kernel_ulong_t) &dwc3_pci_intel_swnode, },
 
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BYT),
-         (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+         (kernel_ulong_t) &dwc3_pci_intel_byt_swnode, },
 
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD),
          (kernel_ulong_t) &dwc3_pci_intel_mrfld_swnode, },
@@ -409,6 +421,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLS),
          (kernel_ulong_t) &dwc3_pci_intel_swnode, },
 
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS),
+         (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL),
          (kernel_ulong_t) &dwc3_pci_intel_swnode, },
 
index 183b90923f51ba9223108471b77eb4a6dd32131e..a0c883f19a417c3df0b76ff0eedc0f9ef134da8d 100644 (file)
@@ -4160,9 +4160,11 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt)
        unsigned long flags;
        irqreturn_t ret = IRQ_NONE;
 
+       local_bh_disable();
        spin_lock_irqsave(&dwc->lock, flags);
        ret = dwc3_process_event_buf(evt);
        spin_unlock_irqrestore(&dwc->lock, flags);
+       local_bh_enable();
 
        return ret;
 }
index b7ccf18036568a086621cdc0e2a40a1b24b094b3..713efd9aefde8d17e1e32d1200d2345370b6c9bb 100644 (file)
@@ -640,6 +640,7 @@ static int rndis_set_response(struct rndis_params *params,
        BufLength = le32_to_cpu(buf->InformationBufferLength);
        BufOffset = le32_to_cpu(buf->InformationBufferOffset);
        if ((BufLength > RNDIS_MAX_TOTAL_SIZE) ||
+           (BufOffset > RNDIS_MAX_TOTAL_SIZE) ||
            (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE))
                    return -EINVAL;
 
@@ -922,6 +923,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)
        params->resp_avail = resp_avail;
        params->v = v;
        INIT_LIST_HEAD(&params->resp_queue);
+       spin_lock_init(&params->resp_lock);
        pr_debug("%s: configNr = %d\n", __func__, i);
 
        return params;
@@ -1015,12 +1017,14 @@ void rndis_free_response(struct rndis_params *params, u8 *buf)
 {
        rndis_resp_t *r, *n;
 
+       spin_lock(&params->resp_lock);
        list_for_each_entry_safe(r, n, &params->resp_queue, list) {
                if (r->buf == buf) {
                        list_del(&r->list);
                        kfree(r);
                }
        }
+       spin_unlock(&params->resp_lock);
 }
 EXPORT_SYMBOL_GPL(rndis_free_response);
 
@@ -1030,14 +1034,17 @@ u8 *rndis_get_next_response(struct rndis_params *params, u32 *length)
 
        if (!length) return NULL;
 
+       spin_lock(&params->resp_lock);
        list_for_each_entry_safe(r, n, &params->resp_queue, list) {
                if (!r->send) {
                        r->send = 1;
                        *length = r->length;
+                       spin_unlock(&params->resp_lock);
                        return r->buf;
                }
        }
 
+       spin_unlock(&params->resp_lock);
        return NULL;
 }
 EXPORT_SYMBOL_GPL(rndis_get_next_response);
@@ -1054,7 +1061,9 @@ static rndis_resp_t *rndis_add_response(struct rndis_params *params, u32 length)
        r->length = length;
        r->send = 0;
 
+       spin_lock(&params->resp_lock);
        list_add_tail(&r->list, &params->resp_queue);
+       spin_unlock(&params->resp_lock);
        return r;
 }
 
index f6167f7fea82b59da4b0eb40c0fd7effc06bec5c..6206b8b7490f64b0e11dcc71aa2d99691d5d1ac3 100644 (file)
@@ -174,6 +174,7 @@ typedef struct rndis_params {
        void                    (*resp_avail)(void *v);
        void                    *v;
        struct list_head        resp_queue;
+       spinlock_t              resp_lock;
 } rndis_params;
 
 /* RNDIS Message parser and other useless functions */
index 568534a0d17c83f728d3bdfeeb92cc18acd66f31..c109b069f511f7a62fbdf8efc9fc474963f10c0b 100644 (file)
@@ -1436,7 +1436,6 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
        usb_gadget_udc_stop(udc);
 
        udc->driver = NULL;
-       udc->dev.driver = NULL;
        udc->gadget->dev.driver = NULL;
 }
 
@@ -1498,7 +1497,6 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
                        driver->function);
 
        udc->driver = driver;
-       udc->dev.driver = &driver->driver;
        udc->gadget->dev.driver = &driver->driver;
 
        usb_gadget_udc_set_speed(udc, driver->max_speed);
@@ -1521,7 +1519,6 @@ err1:
                dev_err(&udc->dev, "failed to start %s: %d\n",
                        udc->driver->function, ret);
        udc->driver = NULL;
-       udc->dev.driver = NULL;
        udc->gadget->dev.driver = NULL;
        return ret;
 }
index 6ce886fb7bfedd8a7ce52ace84ca4d7aa414873c..2907fad04e2c1413774bed4d06830cea934cf842 100644 (file)
@@ -1615,6 +1615,8 @@ static void xudc_getstatus(struct xusb_udc *udc)
                break;
        case USB_RECIP_ENDPOINT:
                epnum = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK;
+               if (epnum >= XUSB_MAX_ENDPOINTS)
+                       goto stall;
                target_ep = &udc->ep[epnum];
                epcfgreg = udc->read_fn(udc->addr + target_ep->offset);
                halt = epcfgreg & XUSB_EP_CFG_STALL_MASK;
@@ -1682,6 +1684,10 @@ static void xudc_set_clear_feature(struct xusb_udc *udc)
        case USB_RECIP_ENDPOINT:
                if (!udc->setup.wValue) {
                        endpoint = udc->setup.wIndex & USB_ENDPOINT_NUMBER_MASK;
+                       if (endpoint >= XUSB_MAX_ENDPOINTS) {
+                               xudc_ep0_stall(udc);
+                               return;
+                       }
                        target_ep = &udc->ep[endpoint];
                        outinbit = udc->setup.wIndex & USB_ENDPOINT_DIR_MASK;
                        outinbit = outinbit >> 7;
index be09fd9bac5866321eba1dc52d9d7a0c8e760cd6..19b8c7ed74cb10ace60fb8451ced855ef0d4674a 100644 (file)
@@ -716,8 +716,9 @@ static int xenhcd_map_urb_for_request(struct xenhcd_info *info, struct urb *urb,
        return 0;
 }
 
-static void xenhcd_gnttab_done(struct usb_shadow *shadow)
+static void xenhcd_gnttab_done(struct xenhcd_info *info, unsigned int id)
 {
+       struct usb_shadow *shadow = info->shadow + id;
        int nr_segs = 0;
        int i;
 
@@ -726,8 +727,10 @@ static void xenhcd_gnttab_done(struct usb_shadow *shadow)
        if (xenusb_pipeisoc(shadow->req.pipe))
                nr_segs += shadow->req.u.isoc.nr_frame_desc_segs;
 
-       for (i = 0; i < nr_segs; i++)
-               gnttab_end_foreign_access(shadow->req.seg[i].gref, 0, 0UL);
+       for (i = 0; i < nr_segs; i++) {
+               if (!gnttab_try_end_foreign_access(shadow->req.seg[i].gref))
+                       xenhcd_set_error(info, "backend didn't release grant");
+       }
 
        shadow->req.nr_buffer_segs = 0;
        shadow->req.u.isoc.nr_frame_desc_segs = 0;
@@ -841,7 +844,9 @@ static void xenhcd_cancel_all_enqueued_urbs(struct xenhcd_info *info)
        list_for_each_entry_safe(urbp, tmp, &info->in_progress_list, list) {
                req_id = urbp->req_id;
                if (!urbp->unlinked) {
-                       xenhcd_gnttab_done(&info->shadow[req_id]);
+                       xenhcd_gnttab_done(info, req_id);
+                       if (info->error)
+                               return;
                        if (urbp->urb->status == -EINPROGRESS)
                                /* not dequeued */
                                xenhcd_giveback_urb(info, urbp->urb,
@@ -942,8 +947,7 @@ static int xenhcd_urb_request_done(struct xenhcd_info *info)
        rp = info->urb_ring.sring->rsp_prod;
        if (RING_RESPONSE_PROD_OVERFLOW(&info->urb_ring, rp)) {
                xenhcd_set_error(info, "Illegal index on urb-ring");
-               spin_unlock_irqrestore(&info->lock, flags);
-               return 0;
+               goto err;
        }
        rmb(); /* ensure we see queued responses up to "rp" */
 
@@ -952,11 +956,13 @@ static int xenhcd_urb_request_done(struct xenhcd_info *info)
                id = res.id;
                if (id >= XENUSB_URB_RING_SIZE) {
                        xenhcd_set_error(info, "Illegal data on urb-ring");
-                       continue;
+                       goto err;
                }
 
                if (likely(xenusb_pipesubmit(info->shadow[id].req.pipe))) {
-                       xenhcd_gnttab_done(&info->shadow[id]);
+                       xenhcd_gnttab_done(info, id);
+                       if (info->error)
+                               goto err;
                        urb = info->shadow[id].urb;
                        if (likely(urb)) {
                                urb->actual_length = res.actual_length;
@@ -978,6 +984,10 @@ static int xenhcd_urb_request_done(struct xenhcd_info *info)
        spin_unlock_irqrestore(&info->lock, flags);
 
        return more_to_do;
+
+ err:
+       spin_unlock_irqrestore(&info->lock, flags);
+       return 0;
 }
 
 static int xenhcd_conn_notify(struct xenhcd_info *info)
index dc357cabb2654a8293922f40dc29e523d8215fb8..2d378543bc3aa395172c705fbb78adbe7f2c2443 100644 (file)
@@ -1091,6 +1091,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        int                     retval = 0;
        bool                    comp_timer_running = false;
        bool                    pending_portevent = false;
+       bool                    reinit_xhc = false;
 
        if (!hcd->state)
                return 0;
@@ -1107,10 +1108,11 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
 
        spin_lock_irq(&xhci->lock);
-       if ((xhci->quirks & XHCI_RESET_ON_RESUME) || xhci->broken_suspend)
-               hibernated = true;
 
-       if (!hibernated) {
+       if (hibernated || xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
+               reinit_xhc = true;
+
+       if (!reinit_xhc) {
                /*
                 * Some controllers might lose power during suspend, so wait
                 * for controller not ready bit to clear, just as in xHC init.
@@ -1143,12 +1145,17 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                        spin_unlock_irq(&xhci->lock);
                        return -ETIMEDOUT;
                }
-               temp = readl(&xhci->op_regs->status);
        }
 
-       /* If restore operation fails, re-initialize the HC during resume */
-       if ((temp & STS_SRE) || hibernated) {
+       temp = readl(&xhci->op_regs->status);
 
+       /* re-initialize the HC on Restore Error, or Host Controller Error */
+       if (temp & (STS_SRE | STS_HCE)) {
+               reinit_xhc = true;
+               xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
+       }
+
+       if (reinit_xhc) {
                if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
                                !(xhci_all_ports_seen_u0(xhci))) {
                        del_timer_sync(&xhci->comp_mode_recovery_timer);
@@ -1604,9 +1611,12 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
        struct urb_priv *urb_priv;
        int num_tds;
 
-       if (!urb || xhci_check_args(hcd, urb->dev, urb->ep,
-                                       true, true, __func__) <= 0)
+       if (!urb)
                return -EINVAL;
+       ret = xhci_check_args(hcd, urb->dev, urb->ep,
+                                       true, true, __func__);
+       if (ret <= 0)
+               return ret ? ret : -EINVAL;
 
        slot_id = urb->dev->slot_id;
        ep_index = xhci_get_endpoint_index(&urb->ep->desc);
@@ -3323,7 +3333,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
                return -EINVAL;
        ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__);
        if (ret <= 0)
-               return -EINVAL;
+               return ret ? ret : -EINVAL;
        if (usb_ss_max_streams(&ep->ss_ep_comp) == 0) {
                xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion"
                                " descriptor for ep 0x%x does not support streams\n",
index 7d4d0713f4f0d071e7a26f5f2d734f77b933efcb..d2b7e613eb34f0df4cac9a5250016430fb64b62b 100644 (file)
@@ -327,7 +327,6 @@ static int omap2430_probe(struct platform_device *pdev)
        musb->dev.parent                = &pdev->dev;
        musb->dev.dma_mask              = &omap2430_dmamask;
        musb->dev.coherent_dma_mask     = omap2430_dmamask;
-       device_set_of_node_from_dev(&musb->dev, &pdev->dev);
 
        glue->dev                       = &pdev->dev;
        glue->musb                      = musb;
index 58cba8ee0277ae7fe23021b96ed78211f2bb01ca..2798fca712612bee6e572779c6abad7f063cf0bb 100644 (file)
@@ -81,7 +81,6 @@
 #define CH341_QUIRK_SIMULATE_BREAK     BIT(1)
 
 static const struct usb_device_id id_table[] = {
-       { USB_DEVICE(0x1a86, 0x5512) },
        { USB_DEVICE(0x1a86, 0x5523) },
        { USB_DEVICE(0x1a86, 0x7522) },
        { USB_DEVICE(0x1a86, 0x7523) },
index 962e9943fc20ec8a1f6b57905f724587037acd26..e7755d9cfc61a2cc9222ab6d8a8afa54ad087fc0 100644 (file)
@@ -198,6 +198,8 @@ static void option_instat_callback(struct urb *urb);
 
 #define DELL_PRODUCT_5821E                     0x81d7
 #define DELL_PRODUCT_5821E_ESIM                        0x81e0
+#define DELL_PRODUCT_5829E_ESIM                        0x81e4
+#define DELL_PRODUCT_5829E                     0x81e6
 
 #define KYOCERA_VENDOR_ID                      0x0c88
 #define KYOCERA_PRODUCT_KPC650                 0x17da
@@ -1063,6 +1065,10 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = RSVD(0) | RSVD(1) | RSVD(6) },
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5821E_ESIM),
          .driver_info = RSVD(0) | RSVD(1) | RSVD(6) },
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E),
+         .driver_info = RSVD(0) | RSVD(6) },
+       { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM),
+         .driver_info = RSVD(0) | RSVD(6) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },   /* ADU-E100, ADU-310 */
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -1273,10 +1279,16 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = NCTRL(2) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff),    /* Telit LE910-S1 (ECM) */
          .driver_info = NCTRL(2) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701a, 0xff),    /* Telit LE910R1 (RNDIS) */
+         .driver_info = NCTRL(2) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701b, 0xff),    /* Telit LE910R1 (ECM) */
+         .driver_info = NCTRL(2) },
        { USB_DEVICE(TELIT_VENDOR_ID, 0x9010),                          /* Telit SBL FN980 flashing device */
          .driver_info = NCTRL(0) | ZLP },
        { USB_DEVICE(TELIT_VENDOR_ID, 0x9200),                          /* Telit LE910S1 flashing device */
          .driver_info = NCTRL(0) | ZLP },
+       { USB_DEVICE(TELIT_VENDOR_ID, 0x9201),                          /* Telit LE910R1 flashing device */
+         .driver_info = NCTRL(0) | ZLP },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
          .driver_info = RSVD(1) },
index 6d27a5b5e3cac6beb8df1edce9e59f14e5abb8be..7ffcda94d323af085ec1c551749c1cb20da2e3b7 100644 (file)
@@ -761,12 +761,12 @@ static int tps6598x_probe(struct i2c_client *client)
 
        ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
        if (ret < 0)
-               return ret;
+               goto err_clear_mask;
        trace_tps6598x_status(status);
 
        ret = tps6598x_read32(tps, TPS_REG_SYSTEM_CONF, &conf);
        if (ret < 0)
-               return ret;
+               goto err_clear_mask;
 
        /*
         * This fwnode has a "compatible" property, but is never populated as a
@@ -855,7 +855,8 @@ err_role_put:
        usb_role_switch_put(tps->role_sw);
 err_fwnode_put:
        fwnode_handle_put(fwnode);
-
+err_clear_mask:
+       tps6598x_write64(tps, TPS_REG_INT_MASK1, 0);
        return ret;
 }
 
index f648f1c54a0f13cd8d728295e67e3ea0ba1c172d..d0f91078600e9a5fa09b79d408c6f4359436dc31 100644 (file)
@@ -1563,11 +1563,27 @@ static virtio_net_ctrl_ack handle_ctrl_mq(struct mlx5_vdpa_dev *mvdev, u8 cmd)
 
        switch (cmd) {
        case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET:
+               /* This mq feature check aligns with pre-existing userspace
+                * implementation.
+                *
+                * Without it, an untrusted driver could fake a multiqueue config
+                * request down to a non-mq device that may cause kernel to
+                * panic due to uninitialized resources for extra vqs. Even with
+                * a well behaving guest driver, it is not expected to allow
+                * changing the number of vqs on a non-mq device.
+                */
+               if (!MLX5_FEATURE(mvdev, VIRTIO_NET_F_MQ))
+                       break;
+
                read = vringh_iov_pull_iotlb(&cvq->vring, &cvq->riov, (void *)&mq, sizeof(mq));
                if (read != sizeof(mq))
                        break;
 
                newqps = mlx5vdpa16_to_cpu(mvdev, mq.virtqueue_pairs);
+               if (newqps < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN ||
+                   newqps > mlx5_vdpa_max_qps(mvdev->max_vqs))
+                       break;
+
                if (ndev->cur_num_vqs == 2 * newqps) {
                        status = VIRTIO_NET_OK;
                        break;
@@ -1897,11 +1913,25 @@ static u64 mlx5_vdpa_get_device_features(struct vdpa_device *vdev)
        return ndev->mvdev.mlx_features;
 }
 
-static int verify_min_features(struct mlx5_vdpa_dev *mvdev, u64 features)
+static int verify_driver_features(struct mlx5_vdpa_dev *mvdev, u64 features)
 {
+       /* Minimum features to expect */
        if (!(features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM)))
                return -EOPNOTSUPP;
 
+       /* Double check features combination sent down by the driver.
+        * Fail invalid features due to absence of the depended feature.
+        *
+        * Per VIRTIO v1.1 specification, section 5.1.3.1 Feature bit
+        * requirements: "VIRTIO_NET_F_MQ Requires VIRTIO_NET_F_CTRL_VQ".
+        * By failing the invalid features sent down by untrusted drivers,
+        * we're assured the assumption made upon is_index_valid() and
+        * is_ctrl_vq_idx() will not be compromised.
+        */
+       if ((features & (BIT_ULL(VIRTIO_NET_F_MQ) | BIT_ULL(VIRTIO_NET_F_CTRL_VQ))) ==
+            BIT_ULL(VIRTIO_NET_F_MQ))
+               return -EINVAL;
+
        return 0;
 }
 
@@ -1977,7 +2007,7 @@ static int mlx5_vdpa_set_driver_features(struct vdpa_device *vdev, u64 features)
 
        print_features(mvdev, features, true);
 
-       err = verify_min_features(mvdev, features);
+       err = verify_driver_features(mvdev, features);
        if (err)
                return err;
 
index 9846c9de4bfa2007f1d78ef3348bdac0004607e3..1ea525433a5ca17781c2f8180a2d6ae6c77842ce 100644 (file)
@@ -393,7 +393,7 @@ static void vdpa_get_config_unlocked(struct vdpa_device *vdev,
         * If it does happen we assume a legacy guest.
         */
        if (!vdev->features_valid)
-               vdpa_set_features(vdev, 0, true);
+               vdpa_set_features_unlocked(vdev, 0);
        ops->get_config(vdev, offset, buf, len);
 }
 
index 2b1143f11d8f8c67211e2ca871459f9be65d69f7..0a4d93edc4c03bb9ad64018055fa43ed8c82025f 100644 (file)
@@ -294,7 +294,7 @@ vduse_domain_alloc_iova(struct iova_domain *iovad,
 
        iova_pfn = alloc_iova_fast(iovad, iova_len, limit >> shift, true);
 
-       return iova_pfn << shift;
+       return (dma_addr_t)iova_pfn << shift;
 }
 
 static void vduse_domain_free_iova(struct iova_domain *iovad,
index a57e381e830b4183c6d79d992f2561803ecdc32c..cce101e6a940e52432400c45d7c59477f1ae3a05 100644 (file)
@@ -533,8 +533,8 @@ static void vp_vdpa_remove(struct pci_dev *pdev)
 {
        struct vp_vdpa *vp_vdpa = pci_get_drvdata(pdev);
 
-       vdpa_unregister_device(&vp_vdpa->vdpa);
        vp_modern_remove(&vp_vdpa->mdev);
+       vdpa_unregister_device(&vp_vdpa->vdpa);
 }
 
 static struct pci_driver vp_vdpa_driver = {
index 670d56c879e50d0954f5790ec16a864376e13146..40b098320b2a7242a33acb3b0215ed6aab4f41e4 100644 (file)
@@ -57,6 +57,17 @@ int vhost_iotlb_add_range_ctx(struct vhost_iotlb *iotlb,
        if (last < start)
                return -EFAULT;
 
+       /* If the range being mapped is [0, ULONG_MAX], split it into two entries
+        * otherwise its size would overflow u64.
+        */
+       if (start == 0 && last == ULONG_MAX) {
+               u64 mid = last / 2;
+
+               vhost_iotlb_add_range_ctx(iotlb, start, mid, addr, perm, opaque);
+               addr += mid + 1;
+               start = mid + 1;
+       }
+
        if (iotlb->limit &&
            iotlb->nmaps == iotlb->limit &&
            iotlb->flags & VHOST_IOTLB_FLAG_RETIRE) {
index 851539807bc9b53f5d18943fdba81608aa1cba79..ec5249e8c32d9d31efd707163632d8253200aa59 100644 (file)
@@ -286,7 +286,7 @@ static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)
        if (copy_from_user(&features, featurep, sizeof(features)))
                return -EFAULT;
 
-       if (vdpa_set_features(vdpa, features, false))
+       if (vdpa_set_features(vdpa, features))
                return -EINVAL;
 
        return 0;
index 59edb5a1ffe28a934574c33cef5f861467b02970..1768362115c6bb4f81e8faaca2ee713f21c67711 100644 (file)
@@ -1170,6 +1170,13 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
                goto done;
        }
 
+       if ((msg.type == VHOST_IOTLB_UPDATE ||
+            msg.type == VHOST_IOTLB_INVALIDATE) &&
+            msg.size == 0) {
+               ret = -EINVAL;
+               goto done;
+       }
+
        if (dev->msg_handler)
                ret = dev->msg_handler(dev, &msg);
        else
@@ -1981,7 +1988,7 @@ static int vhost_update_used_flags(struct vhost_virtqueue *vq)
        return 0;
 }
 
-static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event)
+static int vhost_update_avail_event(struct vhost_virtqueue *vq)
 {
        if (vhost_put_avail_event(vq))
                return -EFAULT;
@@ -2527,7 +2534,7 @@ bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
                        return false;
                }
        } else {
-               r = vhost_update_avail_event(vq, vq->avail_idx);
+               r = vhost_update_avail_event(vq);
                if (r) {
                        vq_err(vq, "Failed to update avail event index at %p: %d\n",
                               vhost_avail_event(vq), r);
index d6ca1c7ad513ff102fe7b6df8f9caafbd40efdc8..e6c9d41db1de77449240fcaa03941377b18a5087 100644 (file)
@@ -629,16 +629,18 @@ err:
        return ret;
 }
 
-static int vhost_vsock_stop(struct vhost_vsock *vsock)
+static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
 {
        size_t i;
-       int ret;
+       int ret = 0;
 
        mutex_lock(&vsock->dev.mutex);
 
-       ret = vhost_dev_check_owner(&vsock->dev);
-       if (ret)
-               goto err;
+       if (check_owner) {
+               ret = vhost_dev_check_owner(&vsock->dev);
+               if (ret)
+                       goto err;
+       }
 
        for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
                struct vhost_virtqueue *vq = &vsock->vqs[i];
@@ -751,9 +753,15 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file)
 
        /* Iterating over all connections for all CIDs to find orphans is
         * inefficient.  Room for improvement here. */
-       vsock_for_each_connected_socket(vhost_vsock_reset_orphans);
+       vsock_for_each_connected_socket(&vhost_transport.transport,
+                                       vhost_vsock_reset_orphans);
 
-       vhost_vsock_stop(vsock);
+       /* Don't check the owner, because we are in the release path, so we
+        * need to stop the vsock device in any case.
+        * vhost_vsock_stop() can not fail in this case, so we don't need to
+        * check the return code.
+        */
+       vhost_vsock_stop(vsock, false);
        vhost_vsock_flush(vsock);
        vhost_dev_stop(&vsock->dev);
 
@@ -868,7 +876,7 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
                if (start)
                        return vhost_vsock_start(vsock);
                else
-                       return vhost_vsock_stop(vsock);
+                       return vhost_vsock_stop(vsock, true);
        case VHOST_GET_FEATURES:
                features = VHOST_VSOCK_FEATURES;
                if (copy_to_user(argp, &features, sizeof(features)))
index 34f80b7a8a64944e89e4d36c32d601a8acf28211..492fc26f0b65073bb39b54f2c649605c73cca3e1 100644 (file)
@@ -105,7 +105,6 @@ config VIRTIO_BALLOON
 
 config VIRTIO_MEM
        tristate "Virtio mem driver"
-       default m
        depends on X86_64
        depends on VIRTIO
        depends on MEMORY_HOTPLUG
index 00ac9db792a4d3a7798ab3fdf4eb06747064d143..22f15f444f757a4d8294c44da27e1cd8c47dbdd5 100644 (file)
@@ -166,14 +166,13 @@ void virtio_add_status(struct virtio_device *dev, unsigned int status)
 }
 EXPORT_SYMBOL_GPL(virtio_add_status);
 
-int virtio_finalize_features(struct virtio_device *dev)
+/* Do some validation, then set FEATURES_OK */
+static int virtio_features_ok(struct virtio_device *dev)
 {
-       int ret = dev->config->finalize_features(dev);
        unsigned status;
+       int ret;
 
        might_sleep();
-       if (ret)
-               return ret;
 
        ret = arch_has_restricted_virtio_memory_access();
        if (ret) {
@@ -202,8 +201,23 @@ int virtio_finalize_features(struct virtio_device *dev)
        }
        return 0;
 }
-EXPORT_SYMBOL_GPL(virtio_finalize_features);
 
+/**
+ * virtio_reset_device - quiesce device for removal
+ * @dev: the device to reset
+ *
+ * Prevents device from sending interrupts and accessing memory.
+ *
+ * Generally used for cleanup during driver / device removal.
+ *
+ * Once this has been invoked, caller must ensure that
+ * virtqueue_notify / virtqueue_kick are not in progress.
+ *
+ * Note: this guarantees that vq callbacks are not in progress, however caller
+ * is responsible for preventing access from other contexts, such as a system
+ * call/workqueue/bh.  Invoking virtio_break_device then flushing any such
+ * contexts is one way to handle that.
+ * */
 void virtio_reset_device(struct virtio_device *dev)
 {
        dev->config->reset(dev);
@@ -245,17 +259,6 @@ static int virtio_dev_probe(struct device *_d)
                driver_features_legacy = driver_features;
        }
 
-       /*
-        * Some devices detect legacy solely via F_VERSION_1. Write
-        * F_VERSION_1 to force LE config space accesses before FEATURES_OK for
-        * these when needed.
-        */
-       if (drv->validate && !virtio_legacy_is_little_endian()
-                         && device_features & BIT_ULL(VIRTIO_F_VERSION_1)) {
-               dev->features = BIT_ULL(VIRTIO_F_VERSION_1);
-               dev->config->finalize_features(dev);
-       }
-
        if (device_features & (1ULL << VIRTIO_F_VERSION_1))
                dev->features = driver_features & device_features;
        else
@@ -266,13 +269,26 @@ static int virtio_dev_probe(struct device *_d)
                if (device_features & (1ULL << i))
                        __virtio_set_bit(dev, i);
 
+       err = dev->config->finalize_features(dev);
+       if (err)
+               goto err;
+
        if (drv->validate) {
+               u64 features = dev->features;
+
                err = drv->validate(dev);
                if (err)
                        goto err;
+
+               /* Did validation change any features? Then write them again. */
+               if (features != dev->features) {
+                       err = dev->config->finalize_features(dev);
+                       if (err)
+                               goto err;
+               }
        }
 
-       err = virtio_finalize_features(dev);
+       err = virtio_features_ok(dev);
        if (err)
                goto err;
 
@@ -496,7 +512,11 @@ int virtio_device_restore(struct virtio_device *dev)
        /* We have a driver! */
        virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER);
 
-       ret = virtio_finalize_features(dev);
+       ret = dev->config->finalize_features(dev);
+       if (ret)
+               goto err;
+
+       ret = virtio_features_ok(dev);
        if (ret)
                goto err;
 
index 7767a7f0119b25196a3cf37ac52f542b100d2e88..76504559bc25f9c8d3fd73f35a23c99c1fca5983 100644 (file)
@@ -317,7 +317,7 @@ static int virtio_vdpa_finalize_features(struct virtio_device *vdev)
        /* Give virtio_ring a chance to accept features. */
        vring_transport_features(vdev);
 
-       return vdpa_set_features(vdpa, vdev->features, false);
+       return vdpa_set_features(vdpa, vdev->features);
 }
 
 static const char *virtio_vdpa_bus_name(struct virtio_device *vdev)
index 3fa40c723e8e95cb85d8c4ee5449ac716cb43e63..edb0acd0b8323cad2165d23fb4764358af8a45b8 100644 (file)
@@ -169,20 +169,14 @@ undo:
                __del_gref(gref);
        }
 
-       /* It's possible for the target domain to map the just-allocated grant
-        * references by blindly guessing their IDs; if this is done, then
-        * __del_gref will leave them in the queue_gref list. They need to be
-        * added to the global list so that we can free them when they are no
-        * longer referenced.
-        */
-       if (unlikely(!list_empty(&queue_gref)))
-               list_splice_tail(&queue_gref, &gref_list);
        mutex_unlock(&gref_mutex);
        return rc;
 }
 
 static void __del_gref(struct gntalloc_gref *gref)
 {
+       unsigned long addr;
+
        if (gref->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) {
                uint8_t *tmp = kmap(gref->page);
                tmp[gref->notify.pgoff] = 0;
@@ -196,21 +190,16 @@ static void __del_gref(struct gntalloc_gref *gref)
        gref->notify.flags = 0;
 
        if (gref->gref_id) {
-               if (gnttab_query_foreign_access(gref->gref_id))
-                       return;
-
-               if (!gnttab_end_foreign_access_ref(gref->gref_id, 0))
-                       return;
-
-               gnttab_free_grant_reference(gref->gref_id);
+               if (gref->page) {
+                       addr = (unsigned long)page_to_virt(gref->page);
+                       gnttab_end_foreign_access(gref->gref_id, 0, addr);
+               } else
+                       gnttab_free_grant_reference(gref->gref_id);
        }
 
        gref_size--;
        list_del(&gref->next_gref);
 
-       if (gref->page)
-               __free_page(gref->page);
-
        kfree(gref);
 }
 
index 3729bea0c98956ac6124c01260dc4d7423445dca..5c83d41766c8522cb0fbf65f28469b818f7b1ed0 100644 (file)
@@ -134,12 +134,9 @@ struct gnttab_ops {
         */
        unsigned long (*end_foreign_transfer_ref)(grant_ref_t ref);
        /*
-        * Query the status of a grant entry. Ref parameter is reference of
-        * queried grant entry, return value is the status of queried entry.
-        * Detailed status(writing/reading) can be gotten from the return value
-        * by bit operations.
+        * Read the frame number related to a given grant reference.
         */
-       int (*query_foreign_access)(grant_ref_t ref);
+       unsigned long (*read_frame)(grant_ref_t ref);
 };
 
 struct unmap_refs_callback_data {
@@ -284,22 +281,6 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
 }
 EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
 
-static int gnttab_query_foreign_access_v1(grant_ref_t ref)
-{
-       return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing);
-}
-
-static int gnttab_query_foreign_access_v2(grant_ref_t ref)
-{
-       return grstatus[ref] & (GTF_reading|GTF_writing);
-}
-
-int gnttab_query_foreign_access(grant_ref_t ref)
-{
-       return gnttab_interface->query_foreign_access(ref);
-}
-EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
-
 static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly)
 {
        u16 flags, nflags;
@@ -353,6 +334,16 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
 }
 EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
 
+static unsigned long gnttab_read_frame_v1(grant_ref_t ref)
+{
+       return gnttab_shared.v1[ref].frame;
+}
+
+static unsigned long gnttab_read_frame_v2(grant_ref_t ref)
+{
+       return gnttab_shared.v2[ref].full_page.frame;
+}
+
 struct deferred_entry {
        struct list_head list;
        grant_ref_t ref;
@@ -382,12 +373,9 @@ static void gnttab_handle_deferred(struct timer_list *unused)
                spin_unlock_irqrestore(&gnttab_list_lock, flags);
                if (_gnttab_end_foreign_access_ref(entry->ref, entry->ro)) {
                        put_free_entry(entry->ref);
-                       if (entry->page) {
-                               pr_debug("freeing g.e. %#x (pfn %#lx)\n",
-                                        entry->ref, page_to_pfn(entry->page));
-                               put_page(entry->page);
-                       } else
-                               pr_info("freeing g.e. %#x\n", entry->ref);
+                       pr_debug("freeing g.e. %#x (pfn %#lx)\n",
+                                entry->ref, page_to_pfn(entry->page));
+                       put_page(entry->page);
                        kfree(entry);
                        entry = NULL;
                } else {
@@ -412,9 +400,18 @@ static void gnttab_handle_deferred(struct timer_list *unused)
 static void gnttab_add_deferred(grant_ref_t ref, bool readonly,
                                struct page *page)
 {
-       struct deferred_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+       struct deferred_entry *entry;
+       gfp_t gfp = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL;
        const char *what = KERN_WARNING "leaking";
 
+       entry = kmalloc(sizeof(*entry), gfp);
+       if (!page) {
+               unsigned long gfn = gnttab_interface->read_frame(ref);
+
+               page = pfn_to_page(gfn_to_pfn(gfn));
+               get_page(page);
+       }
+
        if (entry) {
                unsigned long flags;
 
@@ -435,11 +432,21 @@ static void gnttab_add_deferred(grant_ref_t ref, bool readonly,
               what, ref, page ? page_to_pfn(page) : -1);
 }
 
+int gnttab_try_end_foreign_access(grant_ref_t ref)
+{
+       int ret = _gnttab_end_foreign_access_ref(ref, 0);
+
+       if (ret)
+               put_free_entry(ref);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(gnttab_try_end_foreign_access);
+
 void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
                               unsigned long page)
 {
-       if (gnttab_end_foreign_access_ref(ref, readonly)) {
-               put_free_entry(ref);
+       if (gnttab_try_end_foreign_access(ref)) {
                if (page != 0)
                        put_page(virt_to_page(page));
        } else
@@ -1417,7 +1424,7 @@ static const struct gnttab_ops gnttab_v1_ops = {
        .update_entry                   = gnttab_update_entry_v1,
        .end_foreign_access_ref         = gnttab_end_foreign_access_ref_v1,
        .end_foreign_transfer_ref       = gnttab_end_foreign_transfer_ref_v1,
-       .query_foreign_access           = gnttab_query_foreign_access_v1,
+       .read_frame                     = gnttab_read_frame_v1,
 };
 
 static const struct gnttab_ops gnttab_v2_ops = {
@@ -1429,7 +1436,7 @@ static const struct gnttab_ops gnttab_v2_ops = {
        .update_entry                   = gnttab_update_entry_v2,
        .end_foreign_access_ref         = gnttab_end_foreign_access_ref_v2,
        .end_foreign_transfer_ref       = gnttab_end_foreign_transfer_ref_v2,
-       .query_foreign_access           = gnttab_query_foreign_access_v2,
+       .read_frame                     = gnttab_read_frame_v2,
 };
 
 static bool gnttab_need_v2(void)
index 3c9ae156b597fa4506af71a8751f336e3ee2d374..0ca351f30a6d25d7c136e32625725f24353254ea 100644 (file)
@@ -337,8 +337,8 @@ static void free_active_ring(struct sock_mapping *map)
        if (!map->active.ring)
                return;
 
-       free_pages((unsigned long)map->active.data.in,
-                       map->active.ring->ring_order);
+       free_pages_exact(map->active.data.in,
+                        PAGE_SIZE << map->active.ring->ring_order);
        free_page((unsigned long)map->active.ring);
 }
 
@@ -352,8 +352,8 @@ static int alloc_active_ring(struct sock_mapping *map)
                goto out;
 
        map->active.ring->ring_order = PVCALLS_RING_ORDER;
-       bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
-                                       PVCALLS_RING_ORDER);
+       bytes = alloc_pages_exact(PAGE_SIZE << PVCALLS_RING_ORDER,
+                                 GFP_KERNEL | __GFP_ZERO);
        if (!bytes)
                goto out;
 
index e8bed1cb76ba26b1533172fa0164645a743f0dac..df689068123157bfee0c0b2dfec1dd29cdb1c21a 100644 (file)
@@ -379,7 +379,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr,
                      unsigned int nr_pages, grant_ref_t *grefs)
 {
        int err;
-       int i, j;
+       unsigned int i;
+       grant_ref_t gref_head;
+
+       err = gnttab_alloc_grant_references(nr_pages, &gref_head);
+       if (err) {
+               xenbus_dev_fatal(dev, err, "granting access to ring page");
+               return err;
+       }
 
        for (i = 0; i < nr_pages; i++) {
                unsigned long gfn;
@@ -389,23 +396,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr,
                else
                        gfn = virt_to_gfn(vaddr);
 
-               err = gnttab_grant_foreign_access(dev->otherend_id, gfn, 0);
-               if (err < 0) {
-                       xenbus_dev_fatal(dev, err,
-                                        "granting access to ring page");
-                       goto fail;
-               }
-               grefs[i] = err;
+               grefs[i] = gnttab_claim_grant_reference(&gref_head);
+               gnttab_grant_foreign_access_ref(grefs[i], dev->otherend_id,
+                                               gfn, 0);
 
                vaddr = vaddr + XEN_PAGE_SIZE;
        }
 
        return 0;
-
-fail:
-       for (j = 0; j < i; j++)
-               gnttab_end_foreign_access_ref(grefs[j], 0);
-       return err;
 }
 EXPORT_SYMBOL_GPL(xenbus_grant_ring);
 
index 4d5ae61580aae336658beefe05bc1d7e15994582..68e5862837649600c3a9fdf46e8b9a339bc15a85 100644 (file)
@@ -36,6 +36,9 @@ config COMPAT_BINFMT_ELF
 config ARCH_BINFMT_ELF_STATE
        bool
 
+config ARCH_BINFMT_ELF_EXTRA_PHDRS
+       bool
+
 config ARCH_HAVE_ELF_PROT
        bool
 
index 5e9157d0da294bbd768c45cc231ba9f0e6160da2..f447c902318da02330b4a08c35bfb6d09481f25c 100644 (file)
@@ -703,7 +703,7 @@ static int afs_writepages_region(struct address_space *mapping,
        struct folio *folio;
        struct page *head_page;
        ssize_t ret;
-       int n;
+       int n, skips = 0;
 
        _enter("%llx,%llx,", start, end);
 
@@ -754,8 +754,15 @@ static int afs_writepages_region(struct address_space *mapping,
 #ifdef CONFIG_AFS_FSCACHE
                                folio_wait_fscache(folio);
 #endif
+                       } else {
+                               start += folio_size(folio);
                        }
                        folio_put(folio);
+                       if (wbc->sync_mode == WB_SYNC_NONE) {
+                               if (skips >= 5 || need_resched())
+                                       break;
+                               skips++;
+                       }
                        continue;
                }
 
index 9e11e6f13e83affc3bedb4850a362e59a303a676..d61543fbd6528d25f16f8eedd8302cb1402920fe 100644 (file)
@@ -1135,14 +1135,25 @@ out_free_interp:
                         * is then page aligned.
                         */
                        load_bias = ELF_PAGESTART(load_bias - vaddr);
-               }
 
-               /*
-                * Calculate the entire size of the ELF mapping (total_size).
-                * (Note that load_addr_set is set to true later once the
-                * initial mapping is performed.)
-                */
-               if (!load_addr_set) {
+                       /*
+                        * Calculate the entire size of the ELF mapping
+                        * (total_size), used for the initial mapping,
+                        * due to load_addr_set which is set to true later
+                        * once the initial mapping is performed.
+                        *
+                        * Note that this is only sensible when the LOAD
+                        * segments are contiguous (or overlapping). If
+                        * used for LOADs that are far apart, this would
+                        * cause the holes between LOADs to be mapped,
+                        * running the risk of having the mapping fail,
+                        * as it would be larger than the ELF file itself.
+                        *
+                        * As a result, only ET_DYN does this, since
+                        * some ET_EXEC (e.g. ia64) may have large virtual
+                        * memory holes between LOADs.
+                        *
+                        */
                        total_size = total_mapping_size(elf_phdata,
                                                        elf_ex->e_phnum);
                        if (!total_size) {
index 8992e0096163e2c4bc6b9c86b180ef0a47232691..ebb2d109e8bb2c3700eb975984cbad634be9d5d7 100644 (file)
@@ -602,6 +602,9 @@ enum {
        /* Indicate that we want the transaction kthread to commit right now. */
        BTRFS_FS_COMMIT_TRANS,
 
+       /* Indicate we have half completed snapshot deletions pending. */
+       BTRFS_FS_UNFINISHED_DROPS,
+
 #if BITS_PER_LONG == 32
        /* Indicate if we have error/warn message printed on 32bit systems */
        BTRFS_FS_32BIT_ERROR,
@@ -1106,8 +1109,15 @@ enum {
        BTRFS_ROOT_QGROUP_FLUSHING,
        /* We started the orphan cleanup for this root. */
        BTRFS_ROOT_ORPHAN_CLEANUP,
+       /* This root has a drop operation that was started previously. */
+       BTRFS_ROOT_UNFINISHED_DROP,
 };
 
+static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
+{
+       clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
+}
+
 /*
  * Record swapped tree blocks of a subvolume tree for delayed subtree trace
  * code. For detail check comment in fs/btrfs/qgroup.c.
@@ -3291,7 +3301,7 @@ void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
 int __init btrfs_auto_defrag_init(void);
 void __cold btrfs_auto_defrag_exit(void);
 int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
-                          struct btrfs_inode *inode);
+                          struct btrfs_inode *inode, u32 extent_thresh);
 int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info);
 void btrfs_cleanup_defrag_inodes(struct btrfs_fs_info *fs_info);
 int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
index 87a5addbedf6d5c87823a453df781357a895a928..48590a3807621a42b283cc5fafec410b02d0262d 100644 (file)
@@ -3813,6 +3813,10 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
 
        set_bit(BTRFS_FS_OPEN, &fs_info->flags);
 
+       /* Kick the cleaner thread so it'll start deleting snapshots. */
+       if (test_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags))
+               wake_up_process(fs_info->cleaner_kthread);
+
 clear_oneshot:
        btrfs_clear_oneshot_options(fs_info);
        return 0;
@@ -4538,6 +4542,12 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
         */
        kthread_park(fs_info->cleaner_kthread);
 
+       /*
+        * If we had UNFINISHED_DROPS we could still be processing them, so
+        * clear that bit and wake up relocation so it can stop.
+        */
+       btrfs_wake_unfinished_drop(fs_info);
+
        /* wait for the qgroup rescan worker to stop */
        btrfs_qgroup_wait_for_completion(fs_info, false);
 
index d89273c4b6b86e4048485b9ede9720a975d69081..96427b1ecac3eacc11c81683cf8e6daa50b4d2d1 100644 (file)
@@ -5622,6 +5622,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
        int ret;
        int level;
        bool root_dropped = false;
+       bool unfinished_drop = false;
 
        btrfs_debug(fs_info, "Drop subvolume %llu", root->root_key.objectid);
 
@@ -5664,6 +5665,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
         * already dropped.
         */
        set_bit(BTRFS_ROOT_DELETING, &root->state);
+       unfinished_drop = test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);
+
        if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
                level = btrfs_header_level(root->node);
                path->nodes[level] = btrfs_lock_root_node(root);
@@ -5838,6 +5841,13 @@ out_free:
        kfree(wc);
        btrfs_free_path(path);
 out:
+       /*
+        * We were an unfinished drop root, check to see if there are any
+        * pending, and if not clear and wake up any waiters.
+        */
+       if (!err && unfinished_drop)
+               btrfs_maybe_wake_unfinished_drop(fs_info);
+
        /*
         * So if we need to stop dropping the snapshot for whatever reason we
         * need to make sure to add it back to the dead root list so that we
index 409bad3928db394f9782f8236f4d628792cf82e5..4c91060d103aee5e36a7987f6663cfcaff4c2d1e 100644 (file)
@@ -6841,14 +6841,24 @@ static void assert_eb_page_uptodate(const struct extent_buffer *eb,
 {
        struct btrfs_fs_info *fs_info = eb->fs_info;
 
+       /*
+        * If we are using the commit root we could potentially clear a page
+        * Uptodate while we're using the extent buffer that we've previously
+        * looked up.  We don't want to complain in this case, as the page was
+        * valid before, we just didn't write it out.  Instead we want to catch
+        * the case where we didn't actually read the block properly, which
+        * would have !PageUptodate && !PageError, as we clear PageError before
+        * reading.
+        */
        if (fs_info->sectorsize < PAGE_SIZE) {
-               bool uptodate;
+               bool uptodate, error;
 
                uptodate = btrfs_subpage_test_uptodate(fs_info, page,
                                                       eb->start, eb->len);
-               WARN_ON(!uptodate);
+               error = btrfs_subpage_test_error(fs_info, page, eb->start, eb->len);
+               WARN_ON(!uptodate && !error);
        } else {
-               WARN_ON(!PageUptodate(page));
+               WARN_ON(!PageUptodate(page) && !PageError(page));
        }
 }
 
index 5a36add213053f007bc9de0909225f7dda488018..c28ceddefae4204c53d2a6d69744274b6daf6ab9 100644 (file)
@@ -261,6 +261,7 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
                        em->mod_len = (em->mod_len + em->mod_start) - merge->mod_start;
                        em->mod_start = merge->mod_start;
                        em->generation = max(em->generation, merge->generation);
+                       set_bit(EXTENT_FLAG_MERGED, &em->flags);
 
                        rb_erase_cached(&merge->rb_node, &tree->map);
                        RB_CLEAR_NODE(&merge->rb_node);
@@ -278,6 +279,7 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
                RB_CLEAR_NODE(&merge->rb_node);
                em->mod_len = (merge->mod_start + merge->mod_len) - em->mod_start;
                em->generation = max(em->generation, merge->generation);
+               set_bit(EXTENT_FLAG_MERGED, &em->flags);
                free_extent_map(merge);
        }
 }
index 8e217337dff9011b0d820943463acb044358dc91..d2fa32ffe3045545bf4b8de0803e7c77222b9122 100644 (file)
@@ -25,6 +25,8 @@ enum {
        EXTENT_FLAG_FILLING,
        /* filesystem extent mapping type */
        EXTENT_FLAG_FS_MAPPING,
+       /* This em is merged from two or more physically adjacent ems */
+       EXTENT_FLAG_MERGED,
 };
 
 struct extent_map {
@@ -40,6 +42,12 @@ struct extent_map {
        u64 ram_bytes;
        u64 block_start;
        u64 block_len;
+
+       /*
+        * Generation of the extent map, for merged em it's the highest
+        * generation of all merged ems.
+        * For non-merged extents, it's from btrfs_file_extent_item::generation.
+        */
        u64 generation;
        unsigned long flags;
        /* Used for chunk mappings, flag EXTENT_FLAG_FS_MAPPING must be set */
index 11204dbbe053040775d57bb6b3becb453a8f3c0d..a0179cc62913ba6c46655e4c5f3d1845c24f24cf 100644 (file)
@@ -50,11 +50,14 @@ struct inode_defrag {
        /* root objectid */
        u64 root;
 
-       /* last offset we were able to defrag */
-       u64 last_offset;
-
-       /* if we've wrapped around back to zero once already */
-       int cycled;
+       /*
+        * The extent size threshold for autodefrag.
+        *
+        * This value is different for compressed/non-compressed extents,
+        * thus needs to be passed from higher layer.
+        * (aka, inode_should_defrag())
+        */
+       u32 extent_thresh;
 };
 
 static int __compare_inode_defrag(struct inode_defrag *defrag1,
@@ -107,8 +110,8 @@ static int __btrfs_add_inode_defrag(struct btrfs_inode *inode,
                         */
                        if (defrag->transid < entry->transid)
                                entry->transid = defrag->transid;
-                       if (defrag->last_offset > entry->last_offset)
-                               entry->last_offset = defrag->last_offset;
+                       entry->extent_thresh = min(defrag->extent_thresh,
+                                                  entry->extent_thresh);
                        return -EEXIST;
                }
        }
@@ -134,7 +137,7 @@ static inline int __need_auto_defrag(struct btrfs_fs_info *fs_info)
  * enabled
  */
 int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
-                          struct btrfs_inode *inode)
+                          struct btrfs_inode *inode, u32 extent_thresh)
 {
        struct btrfs_root *root = inode->root;
        struct btrfs_fs_info *fs_info = root->fs_info;
@@ -160,6 +163,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
        defrag->ino = btrfs_ino(inode);
        defrag->transid = transid;
        defrag->root = root->root_key.objectid;
+       defrag->extent_thresh = extent_thresh;
 
        spin_lock(&fs_info->defrag_inodes_lock);
        if (!test_bit(BTRFS_INODE_IN_DEFRAG, &inode->runtime_flags)) {
@@ -178,34 +182,6 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
        return 0;
 }
 
-/*
- * Requeue the defrag object. If there is a defrag object that points to
- * the same inode in the tree, we will merge them together (by
- * __btrfs_add_inode_defrag()) and free the one that we want to requeue.
- */
-static void btrfs_requeue_inode_defrag(struct btrfs_inode *inode,
-                                      struct inode_defrag *defrag)
-{
-       struct btrfs_fs_info *fs_info = inode->root->fs_info;
-       int ret;
-
-       if (!__need_auto_defrag(fs_info))
-               goto out;
-
-       /*
-        * Here we don't check the IN_DEFRAG flag, because we need merge
-        * them together.
-        */
-       spin_lock(&fs_info->defrag_inodes_lock);
-       ret = __btrfs_add_inode_defrag(inode, defrag);
-       spin_unlock(&fs_info->defrag_inodes_lock);
-       if (ret)
-               goto out;
-       return;
-out:
-       kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
-}
-
 /*
  * pick the defragable inode that we want, if it doesn't exist, we will get
  * the next one.
@@ -278,8 +254,14 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
        struct btrfs_root *inode_root;
        struct inode *inode;
        struct btrfs_ioctl_defrag_range_args range;
-       int num_defrag;
-       int ret;
+       int ret = 0;
+       u64 cur = 0;
+
+again:
+       if (test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state))
+               goto cleanup;
+       if (!__need_auto_defrag(fs_info))
+               goto cleanup;
 
        /* get the inode */
        inode_root = btrfs_get_fs_root(fs_info, defrag->root, true);
@@ -295,39 +277,30 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
                goto cleanup;
        }
 
+       if (cur >= i_size_read(inode)) {
+               iput(inode);
+               goto cleanup;
+       }
+
        /* do a chunk of defrag */
        clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
        memset(&range, 0, sizeof(range));
        range.len = (u64)-1;
-       range.start = defrag->last_offset;
+       range.start = cur;
+       range.extent_thresh = defrag->extent_thresh;
 
        sb_start_write(fs_info->sb);
-       num_defrag = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
+       ret = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
                                       BTRFS_DEFRAG_BATCH);
        sb_end_write(fs_info->sb);
-       /*
-        * if we filled the whole defrag batch, there
-        * must be more work to do.  Queue this defrag
-        * again
-        */
-       if (num_defrag == BTRFS_DEFRAG_BATCH) {
-               defrag->last_offset = range.start;
-               btrfs_requeue_inode_defrag(BTRFS_I(inode), defrag);
-       } else if (defrag->last_offset && !defrag->cycled) {
-               /*
-                * we didn't fill our defrag batch, but
-                * we didn't start at zero.  Make sure we loop
-                * around to the start of the file.
-                */
-               defrag->last_offset = 0;
-               defrag->cycled = 1;
-               btrfs_requeue_inode_defrag(BTRFS_I(inode), defrag);
-       } else {
-               kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
-       }
-
        iput(inode);
-       return 0;
+
+       if (ret < 0)
+               goto cleanup;
+
+       cur = max(cur + fs_info->sectorsize, range.start);
+       goto again;
+
 cleanup:
        kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
        return ret;
index 3b2403b6127ff948615802450e1b2e6b9f4a68cc..5bbea5ec31fc5311487f0318146b93aa99fe96eb 100644 (file)
@@ -560,12 +560,12 @@ static inline int inode_need_compress(struct btrfs_inode *inode, u64 start,
 }
 
 static inline void inode_should_defrag(struct btrfs_inode *inode,
-               u64 start, u64 end, u64 num_bytes, u64 small_write)
+               u64 start, u64 end, u64 num_bytes, u32 small_write)
 {
        /* If this is a small write inside eof, kick off a defrag */
        if (num_bytes < small_write &&
            (start > 0 || end + 1 < inode->disk_i_size))
-               btrfs_add_inode_defrag(NULL, inode);
+               btrfs_add_inode_defrag(NULL, inode, small_write);
 }
 
 /*
@@ -7600,6 +7600,34 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
        }
 
        len = min(len, em->len - (start - em->start));
+
+       /*
+        * If we have a NOWAIT request and the range contains multiple extents
+        * (or a mix of extents and holes), then we return -EAGAIN to make the
+        * caller fallback to a context where it can do a blocking (without
+        * NOWAIT) request. This way we avoid doing partial IO and returning
+        * success to the caller, which is not optimal for writes and for reads
+        * it can result in unexpected behaviour for an application.
+        *
+        * When doing a read, because we use IOMAP_DIO_PARTIAL when calling
+        * iomap_dio_rw(), we can end up returning less data then what the caller
+        * asked for, resulting in an unexpected, and incorrect, short read.
+        * That is, the caller asked to read N bytes and we return less than that,
+        * which is wrong unless we are crossing EOF. This happens if we get a
+        * page fault error when trying to fault in pages for the buffer that is
+        * associated to the struct iov_iter passed to iomap_dio_rw(), and we
+        * have previously submitted bios for other extents in the range, in
+        * which case iomap_dio_rw() may return us EIOCBQUEUED if not all of
+        * those bios have completed by the time we get the page fault error,
+        * which we return back to our caller - we should only return EIOCBQUEUED
+        * after we have submitted bios for all the extents in the range.
+        */
+       if ((flags & IOMAP_NOWAIT) && len < length) {
+               free_extent_map(em);
+               ret = -EAGAIN;
+               goto unlock_err;
+       }
+
        if (write) {
                ret = btrfs_get_blocks_direct_write(&em, inode, dio_data,
                                                    start, len);
index 927771d1853f791862180999fe23b7e97def5364..8d47ec5fc4f4428a563f114dc8e9db0ff9a360e1 100644 (file)
@@ -1012,8 +1012,155 @@ out:
        return ret;
 }
 
+/*
+ * Defrag specific helper to get an extent map.
+ *
+ * Differences between this and btrfs_get_extent() are:
+ *
+ * - No extent_map will be added to inode->extent_tree
+ *   To reduce memory usage in the long run.
+ *
+ * - Extra optimization to skip file extents older than @newer_than
+ *   By using btrfs_search_forward() we can skip entire file ranges that
+ *   have extents created in past transactions, because btrfs_search_forward()
+ *   will not visit leaves and nodes with a generation smaller than given
+ *   minimal generation threshold (@newer_than).
+ *
+ * Return valid em if we find a file extent matching the requirement.
+ * Return NULL if we can not find a file extent matching the requirement.
+ *
+ * Return ERR_PTR() for error.
+ */
+static struct extent_map *defrag_get_extent(struct btrfs_inode *inode,
+                                           u64 start, u64 newer_than)
+{
+       struct btrfs_root *root = inode->root;
+       struct btrfs_file_extent_item *fi;
+       struct btrfs_path path = { 0 };
+       struct extent_map *em;
+       struct btrfs_key key;
+       u64 ino = btrfs_ino(inode);
+       int ret;
+
+       em = alloc_extent_map();
+       if (!em) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       key.objectid = ino;
+       key.type = BTRFS_EXTENT_DATA_KEY;
+       key.offset = start;
+
+       if (newer_than) {
+               ret = btrfs_search_forward(root, &key, &path, newer_than);
+               if (ret < 0)
+                       goto err;
+               /* Can't find anything newer */
+               if (ret > 0)
+                       goto not_found;
+       } else {
+               ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
+               if (ret < 0)
+                       goto err;
+       }
+       if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+               /*
+                * If btrfs_search_slot() makes path to point beyond nritems,
+                * we should not have an empty leaf, as this inode must at
+                * least have its INODE_ITEM.
+                */
+               ASSERT(btrfs_header_nritems(path.nodes[0]));
+               path.slots[0] = btrfs_header_nritems(path.nodes[0]) - 1;
+       }
+       btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
+       /* Perfect match, no need to go one slot back */
+       if (key.objectid == ino && key.type == BTRFS_EXTENT_DATA_KEY &&
+           key.offset == start)
+               goto iterate;
+
+       /* We didn't find a perfect match, needs to go one slot back */
+       if (path.slots[0] > 0) {
+               btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
+               if (key.objectid == ino && key.type == BTRFS_EXTENT_DATA_KEY)
+                       path.slots[0]--;
+       }
+
+iterate:
+       /* Iterate through the path to find a file extent covering @start */
+       while (true) {
+               u64 extent_end;
+
+               if (path.slots[0] >= btrfs_header_nritems(path.nodes[0]))
+                       goto next;
+
+               btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
+
+               /*
+                * We may go one slot back to INODE_REF/XATTR item, then
+                * need to go forward until we reach an EXTENT_DATA.
+                * But we should still has the correct ino as key.objectid.
+                */
+               if (WARN_ON(key.objectid < ino) || key.type < BTRFS_EXTENT_DATA_KEY)
+                       goto next;
+
+               /* It's beyond our target range, definitely not extent found */
+               if (key.objectid > ino || key.type > BTRFS_EXTENT_DATA_KEY)
+                       goto not_found;
+
+               /*
+                *      |       |<- File extent ->|
+                *      \- start
+                *
+                * This means there is a hole between start and key.offset.
+                */
+               if (key.offset > start) {
+                       em->start = start;
+                       em->orig_start = start;
+                       em->block_start = EXTENT_MAP_HOLE;
+                       em->len = key.offset - start;
+                       break;
+               }
+
+               fi = btrfs_item_ptr(path.nodes[0], path.slots[0],
+                                   struct btrfs_file_extent_item);
+               extent_end = btrfs_file_extent_end(&path);
+
+               /*
+                *      |<- file extent ->|     |
+                *                              \- start
+                *
+                * We haven't reached start, search next slot.
+                */
+               if (extent_end <= start)
+                       goto next;
+
+               /* Now this extent covers @start, convert it to em */
+               btrfs_extent_item_to_extent_map(inode, &path, fi, false, em);
+               break;
+next:
+               ret = btrfs_next_item(root, &path);
+               if (ret < 0)
+                       goto err;
+               if (ret > 0)
+                       goto not_found;
+       }
+       btrfs_release_path(&path);
+       return em;
+
+not_found:
+       btrfs_release_path(&path);
+       free_extent_map(em);
+       return NULL;
+
+err:
+       btrfs_release_path(&path);
+       free_extent_map(em);
+       return ERR_PTR(ret);
+}
+
 static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start,
-                                              bool locked)
+                                              u64 newer_than, bool locked)
 {
        struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
@@ -1028,6 +1175,20 @@ static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start,
        em = lookup_extent_mapping(em_tree, start, sectorsize);
        read_unlock(&em_tree->lock);
 
+       /*
+        * We can get a merged extent, in that case, we need to re-search
+        * tree to get the original em for defrag.
+        *
+        * If @newer_than is 0 or em::generation < newer_than, we can trust
+        * this em, as either we don't care about the generation, or the
+        * merged extent map will be rejected anyway.
+        */
+       if (em && test_bit(EXTENT_FLAG_MERGED, &em->flags) &&
+           newer_than && em->generation >= newer_than) {
+               free_extent_map(em);
+               em = NULL;
+       }
+
        if (!em) {
                struct extent_state *cached = NULL;
                u64 end = start + sectorsize - 1;
@@ -1035,7 +1196,7 @@ static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start,
                /* get the big lock and read metadata off disk */
                if (!locked)
                        lock_extent_bits(io_tree, start, end, &cached);
-               em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, start, sectorsize);
+               em = defrag_get_extent(BTRFS_I(inode), start, newer_than);
                if (!locked)
                        unlock_extent_cached(io_tree, start, end, &cached);
 
@@ -1046,23 +1207,42 @@ static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start,
        return em;
 }
 
+static u32 get_extent_max_capacity(const struct extent_map *em)
+{
+       if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
+               return BTRFS_MAX_COMPRESSED;
+       return BTRFS_MAX_EXTENT_SIZE;
+}
+
 static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em,
                                     bool locked)
 {
        struct extent_map *next;
-       bool ret = true;
+       bool ret = false;
 
        /* this is the last extent */
        if (em->start + em->len >= i_size_read(inode))
                return false;
 
-       next = defrag_lookup_extent(inode, em->start + em->len, locked);
+       /*
+        * We want to check if the next extent can be merged with the current
+        * one, which can be an extent created in a past generation, so we pass
+        * a minimum generation of 0 to defrag_lookup_extent().
+        */
+       next = defrag_lookup_extent(inode, em->start + em->len, 0, locked);
+       /* No more em or hole */
        if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)
-               ret = false;
-       else if ((em->block_start + em->block_len == next->block_start) &&
-                (em->block_len > SZ_128K && next->block_len > SZ_128K))
-               ret = false;
-
+               goto out;
+       if (test_bit(EXTENT_FLAG_PREALLOC, &next->flags))
+               goto out;
+       /*
+        * If the next extent is at its max capacity, defragging current extent
+        * makes no sense, as the total number of extents won't change.
+        */
+       if (next->len >= get_extent_max_capacity(em))
+               goto out;
+       ret = true;
+out:
        free_extent_map(next);
        return ret;
 }
@@ -1186,8 +1366,10 @@ struct defrag_target_range {
 static int defrag_collect_targets(struct btrfs_inode *inode,
                                  u64 start, u64 len, u32 extent_thresh,
                                  u64 newer_than, bool do_compress,
-                                 bool locked, struct list_head *target_list)
+                                 bool locked, struct list_head *target_list,
+                                 u64 *last_scanned_ret)
 {
+       bool last_is_target = false;
        u64 cur = start;
        int ret = 0;
 
@@ -1197,7 +1379,9 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
                bool next_mergeable = true;
                u64 range_len;
 
-               em = defrag_lookup_extent(&inode->vfs_inode, cur, locked);
+               last_is_target = false;
+               em = defrag_lookup_extent(&inode->vfs_inode, cur,
+                                         newer_than, locked);
                if (!em)
                        break;
 
@@ -1254,6 +1438,13 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
                if (range_len >= extent_thresh)
                        goto next;
 
+               /*
+                * Skip extents already at its max capacity, this is mostly for
+                * compressed extents, which max cap is only 128K.
+                */
+               if (em->len >= get_extent_max_capacity(em))
+                       goto next;
+
                next_mergeable = defrag_check_next_extent(&inode->vfs_inode, em,
                                                          locked);
                if (!next_mergeable) {
@@ -1272,6 +1463,7 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
                }
 
 add:
+               last_is_target = true;
                range_len = min(extent_map_end(em), start + len) - cur;
                /*
                 * This one is a good target, check if it can be merged into
@@ -1315,6 +1507,17 @@ next:
                        kfree(entry);
                }
        }
+       if (!ret && last_scanned_ret) {
+               /*
+                * If the last extent is not a target, the caller can skip to
+                * the end of that extent.
+                * Otherwise, we can only go the end of the specified range.
+                */
+               if (!last_is_target)
+                       *last_scanned_ret = max(cur, *last_scanned_ret);
+               else
+                       *last_scanned_ret = max(start + len, *last_scanned_ret);
+       }
        return ret;
 }
 
@@ -1373,7 +1576,8 @@ static int defrag_one_locked_target(struct btrfs_inode *inode,
 }
 
 static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len,
-                           u32 extent_thresh, u64 newer_than, bool do_compress)
+                           u32 extent_thresh, u64 newer_than, bool do_compress,
+                           u64 *last_scanned_ret)
 {
        struct extent_state *cached_state = NULL;
        struct defrag_target_range *entry;
@@ -1419,7 +1623,7 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len,
         */
        ret = defrag_collect_targets(inode, start, len, extent_thresh,
                                     newer_than, do_compress, true,
-                                    &target_list);
+                                    &target_list, last_scanned_ret);
        if (ret < 0)
                goto unlock_extent;
 
@@ -1454,7 +1658,8 @@ static int defrag_one_cluster(struct btrfs_inode *inode,
                              u64 start, u32 len, u32 extent_thresh,
                              u64 newer_than, bool do_compress,
                              unsigned long *sectors_defragged,
-                             unsigned long max_sectors)
+                             unsigned long max_sectors,
+                             u64 *last_scanned_ret)
 {
        const u32 sectorsize = inode->root->fs_info->sectorsize;
        struct defrag_target_range *entry;
@@ -1465,7 +1670,7 @@ static int defrag_one_cluster(struct btrfs_inode *inode,
        BUILD_BUG_ON(!IS_ALIGNED(CLUSTER_SIZE, PAGE_SIZE));
        ret = defrag_collect_targets(inode, start, len, extent_thresh,
                                     newer_than, do_compress, false,
-                                    &target_list);
+                                    &target_list, NULL);
        if (ret < 0)
                goto out;
 
@@ -1482,6 +1687,15 @@ static int defrag_one_cluster(struct btrfs_inode *inode,
                        range_len = min_t(u32, range_len,
                                (max_sectors - *sectors_defragged) * sectorsize);
 
+               /*
+                * If defrag_one_range() has updated last_scanned_ret,
+                * our range may already be invalid (e.g. hole punched).
+                * Skip if our range is before last_scanned_ret, as there is
+                * no need to defrag the range anymore.
+                */
+               if (entry->start + range_len <= *last_scanned_ret)
+                       continue;
+
                if (ra)
                        page_cache_sync_readahead(inode->vfs_inode.i_mapping,
                                ra, NULL, entry->start >> PAGE_SHIFT,
@@ -1494,7 +1708,8 @@ static int defrag_one_cluster(struct btrfs_inode *inode,
                 * accounting.
                 */
                ret = defrag_one_range(inode, entry->start, range_len,
-                                      extent_thresh, newer_than, do_compress);
+                                      extent_thresh, newer_than, do_compress,
+                                      last_scanned_ret);
                if (ret < 0)
                        break;
                *sectors_defragged += range_len >>
@@ -1505,6 +1720,8 @@ out:
                list_del_init(&entry->list);
                kfree(entry);
        }
+       if (ret >= 0)
+               *last_scanned_ret = max(*last_scanned_ret, start + len);
        return ret;
 }
 
@@ -1590,6 +1807,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
 
        while (cur < last_byte) {
                const unsigned long prev_sectors_defragged = sectors_defragged;
+               u64 last_scanned = cur;
                u64 cluster_end;
 
                /* The cluster size 256K should always be page aligned */
@@ -1619,8 +1837,8 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
                        BTRFS_I(inode)->defrag_compress = compress_type;
                ret = defrag_one_cluster(BTRFS_I(inode), ra, cur,
                                cluster_end + 1 - cur, extent_thresh,
-                               newer_than, do_compress,
-                               &sectors_defragged, max_to_defrag);
+                               newer_than, do_compress, &sectors_defragged,
+                               max_to_defrag, &last_scanned);
 
                if (sectors_defragged > prev_sectors_defragged)
                        balance_dirty_pages_ratelimited(inode->i_mapping);
@@ -1628,7 +1846,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
                btrfs_inode_unlock(inode, 0);
                if (ret < 0)
                        break;
-               cur = cluster_end + 1;
+               cur = max(cluster_end + 1, last_scanned);
                if (ret > 0) {
                        ret = 0;
                        break;
index 0fb90cbe76697c0efeac27f54a0a5fa005db508f..e6e28a9c798773ac2abf07ff39ba7b597ab4cf4c 100644 (file)
@@ -380,6 +380,17 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
                kunmap(cur_page);
                cur_in += LZO_LEN;
 
+               if (seg_len > lzo1x_worst_compress(PAGE_SIZE)) {
+                       /*
+                        * seg_len shouldn't be larger than we have allocated
+                        * for workspace->cbuf
+                        */
+                       btrfs_err(fs_info, "unexpectedly large lzo segment len %u",
+                                       seg_len);
+                       ret = -EIO;
+                       goto out;
+               }
+
                /* Copy the compressed segment payload into workspace */
                copy_compressed_segment(cb, workspace->cbuf, seg_len, &cur_in);
 
index f12dc687350c71cd103e7e0156dcb2dd903c1162..30d42ea655ce93f25977074fddf6d043a599b7e0 100644 (file)
@@ -1196,6 +1196,14 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
        if (!fs_info->quota_root)
                goto out;
 
+       /*
+        * Unlock the qgroup_ioctl_lock mutex before waiting for the rescan worker to
+        * complete. Otherwise we can deadlock because btrfs_remove_qgroup() needs
+        * to lock that mutex while holding a transaction handle and the rescan
+        * worker needs to commit a transaction.
+        */
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
+
        /*
         * Request qgroup rescan worker to complete and wait for it. This wait
         * must be done before transaction start for quota disable since it may
@@ -1203,7 +1211,6 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
         */
        clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
        btrfs_qgroup_wait_for_completion(fs_info, false);
-       mutex_unlock(&fs_info->qgroup_ioctl_lock);
 
        /*
         * 1 For the root item
index f5465197996dec608ffc9c33576f2538b4b68726..9d8054839782e2c62da3c9f9123b099d7786caf2 100644 (file)
@@ -3960,6 +3960,19 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
        int rw = 0;
        int err = 0;
 
+       /*
+        * This only gets set if we had a half-deleted snapshot on mount.  We
+        * cannot allow relocation to start while we're still trying to clean up
+        * these pending deletions.
+        */
+       ret = wait_on_bit(&fs_info->flags, BTRFS_FS_UNFINISHED_DROPS, TASK_INTERRUPTIBLE);
+       if (ret)
+               return ret;
+
+       /* We may have been woken up by close_ctree, so bail if we're closing. */
+       if (btrfs_fs_closing(fs_info))
+               return -EINTR;
+
        bg = btrfs_lookup_block_group(fs_info, group_start);
        if (!bg)
                return -ENOENT;
index 3d68d2dcd83e3e10f2696892b9c3ea819a53a8a3..ca7426ef61c8a1b4f4edfd16bd8c41c78102912a 100644 (file)
@@ -278,6 +278,21 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 
                WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state));
                if (btrfs_root_refs(&root->root_item) == 0) {
+                       struct btrfs_key drop_key;
+
+                       btrfs_disk_key_to_cpu(&drop_key, &root->root_item.drop_progress);
+                       /*
+                        * If we have a non-zero drop_progress then we know we
+                        * made it partly through deleting this snapshot, and
+                        * thus we need to make sure we block any balance from
+                        * happening until this snapshot is completely dropped.
+                        */
+                       if (drop_key.objectid != 0 || drop_key.type != 0 ||
+                           drop_key.offset != 0) {
+                               set_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
+                               set_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);
+                       }
+
                        set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
                        btrfs_add_dead_root(root);
                }
index 29bd8c7a7706bfbcd7c3823c8210f275ee9e32aa..ef7ae20d2b77bb0e8d7a98584a0df367e1a734db 100644 (file)
@@ -736,7 +736,7 @@ void btrfs_page_unlock_writer(struct btrfs_fs_info *fs_info, struct page *page,
         * Since we own the page lock, no one else could touch subpage::writers
         * and we are safe to do several atomic operations without spinlock.
         */
-       if (atomic_read(&subpage->writers))
+       if (atomic_read(&subpage->writers) == 0)
                /* No writers, locked by plain lock_page() */
                return unlock_page(page);
 
index c3cfdfd8de9b2d2ec040343f9f1dadca6cfe624e..1f1c25db6f6b8a395b912d7c9e7855a6cc98d673 100644 (file)
@@ -854,7 +854,37 @@ btrfs_attach_transaction_barrier(struct btrfs_root *root)
 static noinline void wait_for_commit(struct btrfs_transaction *commit,
                                     const enum btrfs_trans_state min_state)
 {
-       wait_event(commit->commit_wait, commit->state >= min_state);
+       struct btrfs_fs_info *fs_info = commit->fs_info;
+       u64 transid = commit->transid;
+       bool put = false;
+
+       while (1) {
+               wait_event(commit->commit_wait, commit->state >= min_state);
+               if (put)
+                       btrfs_put_transaction(commit);
+
+               if (min_state < TRANS_STATE_COMPLETED)
+                       break;
+
+               /*
+                * A transaction isn't really completed until all of the
+                * previous transactions are completed, but with fsync we can
+                * end up with SUPER_COMMITTED transactions before a COMPLETED
+                * transaction. Wait for those.
+                */
+
+               spin_lock(&fs_info->trans_lock);
+               commit = list_first_entry_or_null(&fs_info->trans_list,
+                                                 struct btrfs_transaction,
+                                                 list);
+               if (!commit || commit->transid > transid) {
+                       spin_unlock(&fs_info->trans_lock);
+                       break;
+               }
+               refcount_inc(&commit->use_count);
+               put = true;
+               spin_unlock(&fs_info->trans_lock);
+       }
 }
 
 int btrfs_wait_for_commit(struct btrfs_fs_info *fs_info, u64 transid)
@@ -1319,6 +1349,32 @@ again:
        return 0;
 }
 
+/*
+ * If we had a pending drop we need to see if there are any others left in our
+ * dead roots list, and if not clear our bit and wake any waiters.
+ */
+void btrfs_maybe_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
+{
+       /*
+        * We put the drop in progress roots at the front of the list, so if the
+        * first entry doesn't have UNFINISHED_DROP set we can wake everybody
+        * up.
+        */
+       spin_lock(&fs_info->trans_lock);
+       if (!list_empty(&fs_info->dead_roots)) {
+               struct btrfs_root *root = list_first_entry(&fs_info->dead_roots,
+                                                          struct btrfs_root,
+                                                          root_list);
+               if (test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state)) {
+                       spin_unlock(&fs_info->trans_lock);
+                       return;
+               }
+       }
+       spin_unlock(&fs_info->trans_lock);
+
+       btrfs_wake_unfinished_drop(fs_info);
+}
+
 /*
  * dead roots are old snapshots that need to be deleted.  This allocates
  * a dirty root struct and adds it into the list of dead roots that need to
@@ -1331,7 +1387,12 @@ void btrfs_add_dead_root(struct btrfs_root *root)
        spin_lock(&fs_info->trans_lock);
        if (list_empty(&root->root_list)) {
                btrfs_grab_root(root);
-               list_add_tail(&root->root_list, &fs_info->dead_roots);
+
+               /* We want to process the partially complete drops first. */
+               if (test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state))
+                       list_add(&root->root_list, &fs_info->dead_roots);
+               else
+                       list_add_tail(&root->root_list, &fs_info->dead_roots);
        }
        spin_unlock(&fs_info->trans_lock);
 }
index 9402d8d944846f2ab398d46125b5448e2b6dc538..ba8a9826eb37567bcd41a3bb1bb36beeb3cff611 100644 (file)
@@ -216,6 +216,7 @@ int btrfs_wait_for_commit(struct btrfs_fs_info *fs_info, u64 transid);
 
 void btrfs_add_dead_root(struct btrfs_root *root);
 int btrfs_defrag_root(struct btrfs_root *root);
+void btrfs_maybe_wake_unfinished_drop(struct btrfs_fs_info *fs_info);
 int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root);
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans);
 void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans);
index 9fd145f1c4bc265da7362a6acb3fb693ec4b817d..aae5697dde329325c412fe5a8ba203ffb5358f54 100644 (file)
@@ -1682,6 +1682,7 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
         */
        for (slot = 0; slot < nritems; slot++) {
                u32 item_end_expected;
+               u64 item_data_end;
                int ret;
 
                btrfs_item_key_to_cpu(leaf, &key, slot);
@@ -1696,6 +1697,8 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
                        return -EUCLEAN;
                }
 
+               item_data_end = (u64)btrfs_item_offset(leaf, slot) +
+                               btrfs_item_size(leaf, slot);
                /*
                 * Make sure the offset and ends are right, remember that the
                 * item data starts at the end of the leaf and grows towards the
@@ -1706,11 +1709,10 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
                else
                        item_end_expected = btrfs_item_offset(leaf,
                                                                 slot - 1);
-               if (unlikely(btrfs_item_data_end(leaf, slot) != item_end_expected)) {
+               if (unlikely(item_data_end != item_end_expected)) {
                        generic_err(leaf, slot,
-                               "unexpected item end, have %u expect %u",
-                               btrfs_item_data_end(leaf, slot),
-                               item_end_expected);
+                               "unexpected item end, have %llu expect %u",
+                               item_data_end, item_end_expected);
                        return -EUCLEAN;
                }
 
@@ -1719,12 +1721,10 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
                 * just in case all the items are consistent to each other, but
                 * all point outside of the leaf.
                 */
-               if (unlikely(btrfs_item_data_end(leaf, slot) >
-                            BTRFS_LEAF_DATA_SIZE(fs_info))) {
+               if (unlikely(item_data_end > BTRFS_LEAF_DATA_SIZE(fs_info))) {
                        generic_err(leaf, slot,
-                       "slot end outside of leaf, have %u expect range [0, %u]",
-                               btrfs_item_data_end(leaf, slot),
-                               BTRFS_LEAF_DATA_SIZE(fs_info));
+                       "slot end outside of leaf, have %llu expect range [0, %u]",
+                               item_data_end, BTRFS_LEAF_DATA_SIZE(fs_info));
                        return -EUCLEAN;
                }
 
index 3ee014c06b82a544df86c9df228bbcc72d5f3b56..6bc8834ac8f7d761d735ad29d571a5a7f845a54a 100644 (file)
@@ -1362,6 +1362,15 @@ again:
                                                 inode, name, namelen);
                        kfree(name);
                        iput(dir);
+                       /*
+                        * Whenever we need to check if a name exists or not, we
+                        * check the subvolume tree. So after an unlink we must
+                        * run delayed items, so that future checks for a name
+                        * during log replay see that the name does not exists
+                        * anymore.
+                        */
+                       if (!ret)
+                               ret = btrfs_run_delayed_items(trans);
                        if (ret)
                                goto out;
                        goto again;
@@ -1614,6 +1623,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
                                 */
                                if (!ret && inode->i_nlink == 0)
                                        inc_nlink(inode);
+                               /*
+                                * Whenever we need to check if a name exists or
+                                * not, we check the subvolume tree. So after an
+                                * unlink we must run delayed items, so that future
+                                * checks for a name during log replay see that the
+                                * name does not exists anymore.
+                                */
+                               if (!ret)
+                                       ret = btrfs_run_delayed_items(trans);
                        }
                        if (ret < 0)
                                goto out;
@@ -4635,7 +4653,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
 
 /*
  * Log all prealloc extents beyond the inode's i_size to make sure we do not
- * lose them after doing a fast fsync and replaying the log. We scan the
+ * lose them after doing a full/fast fsync and replaying the log. We scan the
  * subvolume's root instead of iterating the inode's extent map tree because
  * otherwise we can log incorrect extent items based on extent map conversion.
  * That can happen due to the fact that extent maps are merged when they
@@ -5414,6 +5432,7 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans,
                                   struct btrfs_log_ctx *ctx,
                                   bool *need_log_inode_item)
 {
+       const u64 i_size = i_size_read(&inode->vfs_inode);
        struct btrfs_root *root = inode->root;
        int ins_start_slot = 0;
        int ins_nr = 0;
@@ -5434,13 +5453,21 @@ again:
                if (min_key->type > max_key->type)
                        break;
 
-               if (min_key->type == BTRFS_INODE_ITEM_KEY)
+               if (min_key->type == BTRFS_INODE_ITEM_KEY) {
                        *need_log_inode_item = false;
-
-               if ((min_key->type == BTRFS_INODE_REF_KEY ||
-                    min_key->type == BTRFS_INODE_EXTREF_KEY) &&
-                   inode->generation == trans->transid &&
-                   !recursive_logging) {
+               } else if (min_key->type == BTRFS_EXTENT_DATA_KEY &&
+                          min_key->offset >= i_size) {
+                       /*
+                        * Extents at and beyond eof are logged with
+                        * btrfs_log_prealloc_extents().
+                        * Only regular files have BTRFS_EXTENT_DATA_KEY keys,
+                        * and no keys greater than that, so bail out.
+                        */
+                       break;
+               } else if ((min_key->type == BTRFS_INODE_REF_KEY ||
+                           min_key->type == BTRFS_INODE_EXTREF_KEY) &&
+                          inode->generation == trans->transid &&
+                          !recursive_logging) {
                        u64 other_ino = 0;
                        u64 other_parent = 0;
 
@@ -5471,10 +5498,8 @@ again:
                                btrfs_release_path(path);
                                goto next_key;
                        }
-               }
-
-               /* Skip xattrs, we log them later with btrfs_log_all_xattrs() */
-               if (min_key->type == BTRFS_XATTR_ITEM_KEY) {
+               } else if (min_key->type == BTRFS_XATTR_ITEM_KEY) {
+                       /* Skip xattrs, logged later with btrfs_log_all_xattrs() */
                        if (ins_nr == 0)
                                goto next_slot;
                        ret = copy_items(trans, inode, dst_path, path,
@@ -5527,9 +5552,21 @@ next_key:
                        break;
                }
        }
-       if (ins_nr)
+       if (ins_nr) {
                ret = copy_items(trans, inode, dst_path, path, ins_start_slot,
                                 ins_nr, inode_only, logged_isize);
+               if (ret)
+                       return ret;
+       }
+
+       if (inode_only == LOG_INODE_ALL && S_ISREG(inode->vfs_inode.i_mode)) {
+               /*
+                * Release the path because otherwise we might attempt to double
+                * lock the same leaf with btrfs_log_prealloc_extents() below.
+                */
+               btrfs_release_path(path);
+               ret = btrfs_log_prealloc_extents(trans, inode, dst_path);
+       }
 
        return ret;
 }
index 51c968cd00a6746363f6047ffd94c22d32c5abd9..ae93cee9d25ded5f64c23e9a8f8e0e63864fc494 100644 (file)
@@ -254,7 +254,7 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object,
                ret = cachefiles_inject_write_error();
                if (ret == 0)
                        ret = vfs_fallocate(file, FALLOC_FL_ZERO_RANGE,
-                                           new_size, dio_size);
+                                           new_size, dio_size - new_size);
                if (ret < 0) {
                        trace_cachefiles_io_error(object, file_inode(file), ret,
                                                  cachefiles_trace_fallocate_error);
index 83f41bd0c3a9749d3aa66fb7fadb2337985095d7..35465109d9c4ea70fdab56993c2339af2532b3d6 100644 (file)
@@ -28,6 +28,11 @@ struct cachefiles_xattr {
 static const char cachefiles_xattr_cache[] =
        XATTR_USER_PREFIX "CacheFiles.cache";
 
+struct cachefiles_vol_xattr {
+       __be32  reserved;       /* Reserved, should be 0 */
+       __u8    data[];         /* netfs volume coherency data */
+} __packed;
+
 /*
  * set the state xattr on a cache file
  */
@@ -185,6 +190,7 @@ void cachefiles_prepare_to_write(struct fscache_cookie *cookie)
  */
 bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
 {
+       struct cachefiles_vol_xattr *buf;
        unsigned int len = volume->vcookie->coherency_len;
        const void *p = volume->vcookie->coherency;
        struct dentry *dentry = volume->dentry;
@@ -192,10 +198,17 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
 
        _enter("%x,#%d", volume->vcookie->debug_id, len);
 
+       len += sizeof(*buf);
+       buf = kmalloc(len, GFP_KERNEL);
+       if (!buf)
+               return false;
+       buf->reserved = cpu_to_be32(0);
+       memcpy(buf->data, p, len);
+
        ret = cachefiles_inject_write_error();
        if (ret == 0)
                ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
-                                  p, len, 0);
+                                  buf, len, 0);
        if (ret < 0) {
                trace_cachefiles_vfs_error(NULL, d_inode(dentry), ret,
                                           cachefiles_trace_setxattr_error);
@@ -209,6 +222,7 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
                                               cachefiles_coherency_vol_set_ok);
        }
 
+       kfree(buf);
        _leave(" = %d", ret);
        return ret == 0;
 }
@@ -218,7 +232,7 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
  */
 int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)
 {
-       struct cachefiles_xattr *buf;
+       struct cachefiles_vol_xattr *buf;
        struct dentry *dentry = volume->dentry;
        unsigned int len = volume->vcookie->coherency_len;
        const void *p = volume->vcookie->coherency;
@@ -228,6 +242,7 @@ int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)
 
        _enter("");
 
+       len += sizeof(*buf);
        buf = kmalloc(len, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
@@ -245,7 +260,9 @@ int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)
                                        "Failed to read xattr with error %zd", xlen);
                }
                why = cachefiles_coherency_vol_check_xattr;
-       } else if (memcmp(buf->data, p, len) != 0) {
+       } else if (buf->reserved != cpu_to_be32(0)) {
+               why = cachefiles_coherency_vol_check_resv;
+       } else if (memcmp(buf->data, p, len - sizeof(*buf)) != 0) {
                why = cachefiles_coherency_vol_check_cmp;
        } else {
                why = cachefiles_coherency_vol_check_ok;
index 053cb449eb167ec415ba13dc3e5cfb97fa4e6428..d3020abfe404ae82b9dd162c9d9cb12a2070cd1a 100644 (file)
@@ -3924,7 +3924,8 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
 
        /* only send once per connect */
        spin_lock(&cifs_tcp_ses_lock);
-       if (server->tcpStatus != CifsNeedSessSetup) {
+       if ((server->tcpStatus != CifsNeedSessSetup) &&
+           (ses->status == CifsGood)) {
                spin_unlock(&cifs_tcp_ses_lock);
                return 0;
        }
index d3cd2a94d1e8c3f6f4fa965cf7b6f9d17b35326c..d1f9d2632202787b746697d0acbb904baf2bf5ef 100644 (file)
  */
 DEFINE_SPINLOCK(configfs_dirent_lock);
 
+/*
+ * All of link_obj/unlink_obj/link_group/unlink_group require that
+ * subsys->su_mutex is held.
+ * But parent configfs_subsystem is NULL when config_item is root.
+ * Use this mutex when config_item is root.
+ */
+static DEFINE_MUTEX(configfs_subsystem_mutex);
+
 static void configfs_d_iput(struct dentry * dentry,
                            struct inode * inode)
 {
@@ -1859,7 +1867,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
                group->cg_item.ci_name = group->cg_item.ci_namebuf;
 
        sd = root->d_fsdata;
+       mutex_lock(&configfs_subsystem_mutex);
        link_group(to_config_group(sd->s_element), group);
+       mutex_unlock(&configfs_subsystem_mutex);
 
        inode_lock_nested(d_inode(root), I_MUTEX_PARENT);
 
@@ -1884,7 +1894,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
        inode_unlock(d_inode(root));
 
        if (err) {
+               mutex_lock(&configfs_subsystem_mutex);
                unlink_group(group);
+               mutex_unlock(&configfs_subsystem_mutex);
                configfs_release_fs();
        }
        put_fragment(frag);
@@ -1931,7 +1943,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
 
        dput(dentry);
 
+       mutex_lock(&configfs_subsystem_mutex);
        unlink_group(group);
+       mutex_unlock(&configfs_subsystem_mutex);
        configfs_release_fs();
 }
 
index b8272fb95fd670d36aad8315b30dc122441ed91e..5aa2cf2c2f804b9f9f055999554bf492629c8a3d 100644 (file)
@@ -325,7 +325,7 @@ struct erofs_inode {
                        unsigned char  z_algorithmtype[2];
                        unsigned char  z_logical_clusterbits;
                        unsigned long  z_tailextent_headlcn;
-                       unsigned int   z_idataoff;
+                       erofs_off_t    z_idataoff;
                        unsigned short z_idata_size;
                };
 #endif /* CONFIG_EROFS_FS_ZIP */
index cd54a529460da9b98ef56838b3fd04cb517ae3b0..592730fd6e424fa33027932db66fbaba9f4f8854 100644 (file)
@@ -941,7 +941,17 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
 
        while (count) {
                if (cs->write && cs->pipebufs && page) {
-                       return fuse_ref_page(cs, page, offset, count);
+                       /*
+                        * Can't control lifetime of pipe buffers, so always
+                        * copy user pages.
+                        */
+                       if (cs->req->args->user_pages) {
+                               err = fuse_copy_fill(cs);
+                               if (err)
+                                       return err;
+                       } else {
+                               return fuse_ref_page(cs, page, offset, count);
+                       }
                } else if (!cs->len) {
                        if (cs->move_pages && page &&
                            offset == 0 && count == PAGE_SIZE) {
index 8290944517749161840a047d4416b43750b4c5bb..0fc150c1c50bd9c61742255b1a5eb673df0b7501 100644 (file)
@@ -1413,6 +1413,7 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
                        (PAGE_SIZE - ret) & (PAGE_SIZE - 1);
        }
 
+       ap->args.user_pages = true;
        if (write)
                ap->args.in_pages = true;
        else
index e8e59fbdefebe1e5deaa977ff3100e7bff6358ed..eac4984cc753c2298e135a28f0f8f2e8ec0d9b17 100644 (file)
@@ -256,6 +256,7 @@ struct fuse_args {
        bool nocreds:1;
        bool in_pages:1;
        bool out_pages:1;
+       bool user_pages:1;
        bool out_argvar:1;
        bool page_zeroing:1;
        bool page_replace:1;
index ee846ce371d8fcfc1471e81b9cef08935e14037d..9ee36aa732518dc0d48f23dfad065b492e769b52 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/exportfs.h>
 #include <linux/posix_acl.h>
 #include <linux/pid_namespace.h>
+#include <uapi/linux/magic.h>
 
 MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
 MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -50,8 +51,6 @@ MODULE_PARM_DESC(max_user_congthresh,
  "Global limit for the maximum congestion threshold an "
  "unprivileged user can set");
 
-#define FUSE_SUPER_MAGIC 0x65735546
-
 #define FUSE_DEFAULT_BLKSIZE 512
 
 /** Maximum number of outstanding background requests */
index fbc09dab1f851545a142c30f717acd1cc596b7d1..df58966bc87458e52c91f9509982d86db5efc1f8 100644 (file)
@@ -394,9 +394,12 @@ static int fuse_priv_ioctl(struct inode *inode, struct fuse_file *ff,
        args.out_args[1].value = ptr;
 
        err = fuse_simple_request(fm, &args);
-       if (!err && outarg.flags & FUSE_IOCTL_RETRY)
-               err = -EIO;
-
+       if (!err) {
+               if (outarg.result < 0)
+                       err = outarg.result;
+               else if (outarg.flags & FUSE_IOCTL_RETRY)
+                       err = -EIO;
+       }
        return err;
 }
 
index 77b9c7e4793bf3332a0229ed74603d195b761756..4715980e90150c5c629421dd36ee19f08d149f6b 100644 (file)
@@ -4567,6 +4567,7 @@ static int io_add_buffers(struct io_provide_buf *pbuf, struct io_buffer **head)
                } else {
                        list_add_tail(&buf->list, &(*head)->list);
                }
+               cond_resched();
        }
 
        return i ? i : -ENOMEM;
@@ -7693,7 +7694,7 @@ static int io_run_task_work_sig(void)
 /* when returns >0, the caller should retry */
 static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
                                          struct io_wait_queue *iowq,
-                                         signed long *timeout)
+                                         ktime_t timeout)
 {
        int ret;
 
@@ -7705,8 +7706,9 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
        if (test_bit(0, &ctx->check_cq_overflow))
                return 1;
 
-       *timeout = schedule_timeout(*timeout);
-       return !*timeout ? -ETIME : 1;
+       if (!schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS))
+               return -ETIME;
+       return 1;
 }
 
 /*
@@ -7719,7 +7721,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
 {
        struct io_wait_queue iowq;
        struct io_rings *rings = ctx->rings;
-       signed long timeout = MAX_SCHEDULE_TIMEOUT;
+       ktime_t timeout = KTIME_MAX;
        int ret;
 
        do {
@@ -7735,7 +7737,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
 
                if (get_timespec64(&ts, uts))
                        return -EFAULT;
-               timeout = timespec64_to_jiffies(&ts);
+               timeout = ktime_add_ns(timespec64_to_ktime(ts), ktime_get_ns());
        }
 
        if (sig) {
@@ -7767,7 +7769,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
                }
                prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq,
                                                TASK_INTERRUPTIBLE);
-               ret = io_cqring_wait_schedule(ctx, &iowq, &timeout);
+               ret = io_cqring_wait_schedule(ctx, &iowq, timeout);
                finish_wait(&ctx->cq_wait, &iowq.wq);
                cond_resched();
        } while (ret > 0);
@@ -7924,7 +7926,15 @@ static __cold int io_rsrc_ref_quiesce(struct io_rsrc_data *data,
                ret = wait_for_completion_interruptible(&data->done);
                if (!ret) {
                        mutex_lock(&ctx->uring_lock);
-                       break;
+                       if (atomic_read(&data->refs) > 0) {
+                               /*
+                                * it has been revived by another thread while
+                                * we were unlocked
+                                */
+                               mutex_unlock(&ctx->uring_lock);
+                       } else {
+                               break;
+                       }
                }
 
                atomic_inc(&data->refs);
index 2772dec9dcea4c4871e65c05dd5b68fbf73efcdf..8bde30fa5387da471497af21244ca056ff5a8b24 100644 (file)
@@ -1105,17 +1105,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
                goto read_super_error;
        }
 
-       root = d_make_root(inode);
-       if (!root) {
-               status = -ENOMEM;
-               mlog_errno(status);
-               goto read_super_error;
-       }
-
-       sb->s_root = root;
-
-       ocfs2_complete_mount_recovery(osb);
-
        osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL,
                                                &ocfs2_kset->kobj);
        if (!osb->osb_dev_kset) {
@@ -1133,6 +1122,17 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
                goto read_super_error;
        }
 
+       root = d_make_root(inode);
+       if (!root) {
+               status = -ENOMEM;
+               mlog_errno(status);
+               goto read_super_error;
+       }
+
+       sb->s_root = root;
+
+       ocfs2_complete_mount_recovery(osb);
+
        if (ocfs2_mount_local(osb))
                snprintf(nodestr, sizeof(nodestr), "local");
        else
index cc28623a67b61422472d05b9b040e88e640c99d8..2667db9506e2f2853f46e551332562dec10618af 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -253,7 +253,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
         */
        was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
        for (;;) {
-               unsigned int head = pipe->head;
+               /* Read ->head with a barrier vs post_one_notification() */
+               unsigned int head = smp_load_acquire(&pipe->head);
                unsigned int tail = pipe->tail;
                unsigned int mask = pipe->ring_size - 1;
 
@@ -831,10 +832,8 @@ void free_pipe_info(struct pipe_inode_info *pipe)
        int i;
 
 #ifdef CONFIG_WATCH_QUEUE
-       if (pipe->watch_queue) {
+       if (pipe->watch_queue)
                watch_queue_clear(pipe->watch_queue);
-               put_watch_queue(pipe->watch_queue);
-       }
 #endif
 
        (void) account_pipe_buffers(pipe->user, pipe->nr_accounted, 0);
@@ -844,6 +843,10 @@ void free_pipe_info(struct pipe_inode_info *pipe)
                if (buf->ops)
                        pipe_buf_release(pipe, buf);
        }
+#ifdef CONFIG_WATCH_QUEUE
+       if (pipe->watch_queue)
+               put_watch_queue(pipe->watch_queue);
+#endif
        if (pipe->tmp_page)
                __free_page(pipe->tmp_page);
        kfree(pipe->bufs);
index 6e97ed775074c893d323afd054e1fd62f019aa84..f46060eb91b5cb1c4c64be687aa2c873de43ce20 100644 (file)
@@ -309,7 +309,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
 
        name = arch_vma_name(vma);
        if (!name) {
-               const char *anon_name;
+               struct anon_vma_name *anon_name;
 
                if (!mm) {
                        name = "[vdso]";
@@ -327,10 +327,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
                        goto done;
                }
 
-               anon_name = vma_anon_name(vma);
+               anon_name = anon_vma_name(vma);
                if (anon_name) {
                        seq_pad(m, ' ');
-                       seq_printf(m, "[anon:%s]", anon_name);
+                       seq_printf(m, "[anon:%s]", anon_name->name);
                }
        }
 
@@ -1597,7 +1597,8 @@ static const struct mm_walk_ops pagemap_ops = {
  * Bits 5-54  swap offset if swapped
  * Bit  55    pte is soft-dirty (see Documentation/admin-guide/mm/soft-dirty.rst)
  * Bit  56    page exclusively mapped
- * Bits 57-60 zero
+ * Bit  57    pte is uffd-wp write-protected
+ * Bits 58-60 zero
  * Bit  61    page is file-page or shared-anon
  * Bit  62    page swapped
  * Bit  63    page present
index bafc02bf82203a2699e6b2a879e628060891498f..de7252715b1251dd71004b73e2b7983d5778bb67 100644 (file)
@@ -264,7 +264,6 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
                        if (!gid_valid(gid))
                                return -EINVAL;
                        opts->gid = gid;
-                       set_gid(tracefs_mount->mnt_root, gid);
                        break;
                case Opt_mode:
                        if (match_octal(&args[0], &option))
@@ -291,7 +290,9 @@ static int tracefs_apply_options(struct super_block *sb)
        inode->i_mode |= opts->mode;
 
        inode->i_uid = opts->uid;
-       inode->i_gid = opts->gid;
+
+       /* Set all the group ids to the mount option */
+       set_gid(sb->s_root, opts->gid);
 
        return 0;
 }
index e26b10132d47e2a49edf6da88ad109ea3141b657..8e03b3d3f5fa854be7d4ed6b58898d7b44a256f1 100644 (file)
@@ -878,7 +878,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
                                 new_flags, vma->anon_vma,
                                 vma->vm_file, vma->vm_pgoff,
                                 vma_policy(vma),
-                                NULL_VM_UFFD_CTX, vma_anon_name(vma));
+                                NULL_VM_UFFD_CTX, anon_vma_name(vma));
                if (prev)
                        vma = prev;
                else
@@ -1438,7 +1438,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
                                 vma->anon_vma, vma->vm_file, vma->vm_pgoff,
                                 vma_policy(vma),
                                 ((struct vm_userfaultfd_ctx){ ctx }),
-                                vma_anon_name(vma));
+                                anon_vma_name(vma));
                if (prev) {
                        vma = prev;
                        goto next;
@@ -1615,7 +1615,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
                prev = vma_merge(mm, prev, start, vma_end, new_flags,
                                 vma->anon_vma, vma->vm_file, vma->vm_pgoff,
                                 vma_policy(vma),
-                                NULL_VM_UFFD_CTX, vma_anon_name(vma));
+                                NULL_VM_UFFD_CTX, anon_vma_name(vma));
                if (prev) {
                        vma = prev;
                        goto next;
index 4c0dee78b2f8bbb8a11a827fc3464fad4e3c4e13..d84714e4e46a2a536f3920bc29d63776f0e79f40 100644 (file)
@@ -1753,6 +1753,11 @@ xfs_remount_ro(
        };
        int                     error;
 
+       /* Flush all the dirty data to disk. */
+       error = sync_filesystem(mp->m_super);
+       if (error)
+               return error;
+
        /*
         * Cancel background eofb scanning so it cannot race with the final
         * log force+buftarg wait and deadlock the remount.
@@ -1831,8 +1836,6 @@ xfs_fs_reconfigure(
        if (error)
                return error;
 
-       sync_filesystem(mp->m_super);
-
        /* inode32 -> inode64 */
        if (xfs_has_small_inums(mp) && !xfs_has_small_inums(new_mp)) {
                mp->m_features &= ~XFS_FEAT_SMALL_INUMS;
diff --git a/include/crypto/asym_tpm_subtype.h b/include/crypto/asym_tpm_subtype.h
deleted file mode 100644 (file)
index 48198c3..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#ifndef _LINUX_ASYM_TPM_SUBTYPE_H
-#define _LINUX_ASYM_TPM_SUBTYPE_H
-
-#include <linux/keyctl.h>
-
-struct tpm_key {
-       void *blob;
-       u32 blob_len;
-       uint16_t key_len; /* Size in bits of the key */
-       const void *pub_key; /* pointer inside blob to the public key bytes */
-       uint16_t pub_key_len; /* length of the public key */
-};
-
-struct tpm_key *tpm_key_create(const void *blob, uint32_t blob_len);
-
-extern struct asymmetric_key_subtype asym_tpm_subtype;
-
-#endif /* _LINUX_ASYM_TPM_SUBTYPE_H */
index 604f2bb30ac0d674efaaaa480f52e0cfb890a67c..bf3aac0e5491559c82f3ca741453a85917f35089 100644 (file)
@@ -11,5 +11,7 @@
 #define AIC_TMR_HV_VIRT                1
 #define AIC_TMR_GUEST_PHYS     2
 #define AIC_TMR_GUEST_VIRT     3
+#define AIC_CPU_PMU_E          4
+#define AIC_CPU_PMU_P          5
 
 #endif
index 6acd3cf13a18c70f9a4b8d8bdaf5128dfff6ace4..2419a735420fb8dfb596ff6217d3193f192f21cc 100644 (file)
@@ -38,6 +38,20 @@ extern int restrict_link_by_builtin_and_secondary_trusted(
 #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
 #endif
 
+#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+extern int restrict_link_by_builtin_secondary_and_machine(
+       struct key *dest_keyring,
+       const struct key_type *type,
+       const union key_payload *payload,
+       struct key *restrict_key);
+extern void __init set_machine_trusted_keys(struct key *keyring);
+#else
+#define restrict_link_by_builtin_secondary_and_machine restrict_link_by_builtin_trusted
+static inline void __init set_machine_trusted_keys(struct key *keyring)
+{
+}
+#endif
+
 extern struct pkcs7_message *pkcs7;
 #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
 extern int mark_hash_blacklisted(const char *hash);
index 6c7f478469715ad1317c8028e9dc3cb9787372ac..6562f543c3e04d07ef93613439e1736e263eb598 100644 (file)
@@ -117,30 +117,9 @@ void amba_device_put(struct amba_device *);
 int amba_device_add(struct amba_device *, struct resource *);
 int amba_device_register(struct amba_device *, struct resource *);
 void amba_device_unregister(struct amba_device *);
-struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int);
 int amba_request_regions(struct amba_device *, const char *);
 void amba_release_regions(struct amba_device *);
 
-static inline int amba_pclk_enable(struct amba_device *dev)
-{
-       return clk_enable(dev->pclk);
-}
-
-static inline void amba_pclk_disable(struct amba_device *dev)
-{
-       clk_disable(dev->pclk);
-}
-
-static inline int amba_pclk_prepare(struct amba_device *dev)
-{
-       return clk_prepare(dev->pclk);
-}
-
-static inline void amba_pclk_unprepare(struct amba_device *dev)
-{
-       clk_unprepare(dev->pclk);
-}
-
 /* Some drivers don't use the struct amba_device */
 #define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff)
 #define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f)
index 63ccb525219022e17e39771c669de161ed54666a..220c8c60e021a788f7062a35f44ddc7be4e4a332 100644 (file)
                           ARM_SMCCC_SMC_32,                            \
                           0, 0x7fff)
 
+#define ARM_SMCCC_ARCH_WORKAROUND_3                                    \
+       ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                         \
+                          ARM_SMCCC_SMC_32,                            \
+                          0, 0x3fff)
+
 #define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID                          \
        ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                         \
                           ARM_SMCCC_SMC_32,                            \
index fa517ae604ad2f2d3603b4103d69ace80f3ac584..3121d1fc8e7541921a3e241e51ec2dc8b09725a8 100644 (file)
@@ -209,11 +209,9 @@ static inline bool map_value_has_timer(const struct bpf_map *map)
 static inline void check_and_init_map_value(struct bpf_map *map, void *dst)
 {
        if (unlikely(map_value_has_spin_lock(map)))
-               *(struct bpf_spin_lock *)(dst + map->spin_lock_off) =
-                       (struct bpf_spin_lock){};
+               memset(dst + map->spin_lock_off, 0, sizeof(struct bpf_spin_lock));
        if (unlikely(map_value_has_timer(map)))
-               *(struct bpf_timer *)(dst + map->timer_off) =
-                       (struct bpf_timer){};
+               memset(dst + map->timer_off, 0, sizeof(struct bpf_timer));
 }
 
 /* copy everything but bpf_spin_lock and bpf_timer. There could be one of each. */
@@ -224,7 +222,8 @@ static inline void copy_map_value(struct bpf_map *map, void *dst, void *src)
        if (unlikely(map_value_has_spin_lock(map))) {
                s_off = map->spin_lock_off;
                s_sz = sizeof(struct bpf_spin_lock);
-       } else if (unlikely(map_value_has_timer(map))) {
+       }
+       if (unlikely(map_value_has_timer(map))) {
                t_off = map->timer_off;
                t_sz = sizeof(struct bpf_timer);
        }
@@ -1793,6 +1792,11 @@ struct bpf_core_ctx {
 int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
                   int relo_idx, void *insn);
 
+static inline bool unprivileged_ebpf_enabled(void)
+{
+       return !sysctl_unprivileged_bpf_disabled;
+}
+
 #else /* !CONFIG_BPF_SYSCALL */
 static inline struct bpf_prog *bpf_prog_get(u32 ufd)
 {
@@ -2012,6 +2016,12 @@ bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
 {
        return NULL;
 }
+
+static inline bool unprivileged_ebpf_enabled(void)
+{
+       return false;
+}
+
 #endif /* CONFIG_BPF_SYSCALL */
 
 void __bpf_free_used_btfs(struct bpf_prog_aux *aux,
index 1ab29e61b078ed9a45b7ba76444906161163199e..3522a272b74dded0f3c1109aa276e4c3a5a0faa3 100644 (file)
@@ -382,6 +382,9 @@ struct cpufreq_driver {
        int             (*suspend)(struct cpufreq_policy *policy);
        int             (*resume)(struct cpufreq_policy *policy);
 
+       /* Will be called after the driver is fully initialized */
+       void            (*ready)(struct cpufreq_policy *policy);
+
        struct freq_attr **attr;
 
        /* platform specific boost support code */
index 411a428ace4d4bb0d631639fb9609bf4b1ff68fa..2bc550ac8dc79343a38c428c7b9961d4b3c403c2 100644 (file)
@@ -231,6 +231,7 @@ enum cpuhp_state {
        CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
        CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE,
        CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
+       CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
        CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
        CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
        CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,
index 746e081879a5ab418ff3b2239c33078135555971..f8e206e82476c30f067ac96f0ca4036dc693638c 100644 (file)
@@ -114,7 +114,7 @@ static inline int elf_core_copy_task_fpregs(struct task_struct *t, struct pt_reg
 #endif
 }
 
-#if (defined(CONFIG_UML) && defined(CONFIG_X86_32)) || defined(CONFIG_IA64)
+#ifdef CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS
 /*
  * These functions parameterize elf_core_dump in fs/binfmt_elf.c to write out
  * extra segments containing the gate DSO contents.  Dumping its
@@ -149,6 +149,6 @@ static inline size_t elf_core_extra_data_size(void)
 {
        return 0;
 }
-#endif
+#endif /* CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS */
 
 #endif /* _LINUX_ELFCORE_H */
index b712217f7030408f903afecff8826f93b334b7ec..1ed52441972f9b2fd817b96a468372193bacb04e 100644 (file)
@@ -52,6 +52,7 @@ static inline bool dev_is_mac_header_xmit(const struct net_device *dev)
        case ARPHRD_VOID:
        case ARPHRD_NONE:
        case ARPHRD_RAWIP:
+       case ARPHRD_PIMREG:
                return false;
        default:
                return true;
diff --git a/include/linux/kasan-enabled.h b/include/linux/kasan-enabled.h
new file mode 100644 (file)
index 0000000..6f612d6
--- /dev/null
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_KASAN_ENABLED_H
+#define _LINUX_KASAN_ENABLED_H
+
+#include <linux/static_key.h>
+
+#ifdef CONFIG_KASAN_HW_TAGS
+
+DECLARE_STATIC_KEY_FALSE(kasan_flag_enabled);
+
+static __always_inline bool kasan_enabled(void)
+{
+       return static_branch_likely(&kasan_flag_enabled);
+}
+
+static inline bool kasan_hw_tags_enabled(void)
+{
+       return kasan_enabled();
+}
+
+#else /* CONFIG_KASAN_HW_TAGS */
+
+static inline bool kasan_enabled(void)
+{
+       return IS_ENABLED(CONFIG_KASAN);
+}
+
+static inline bool kasan_hw_tags_enabled(void)
+{
+       return false;
+}
+
+#endif /* CONFIG_KASAN_HW_TAGS */
+
+#endif /* LINUX_KASAN_ENABLED_H */
index 4a45562d889372f4d36878840c312e9da0db73fe..b6a93261c92a016dac48f8c334f0608bbbeabd5d 100644 (file)
@@ -3,6 +3,7 @@
 #define _LINUX_KASAN_H
 
 #include <linux/bug.h>
+#include <linux/kasan-enabled.h>
 #include <linux/kernel.h>
 #include <linux/static_key.h>
 #include <linux/types.h>
@@ -83,33 +84,11 @@ static inline void kasan_disable_current(void) {}
 
 #ifdef CONFIG_KASAN_HW_TAGS
 
-DECLARE_STATIC_KEY_FALSE(kasan_flag_enabled);
-
-static __always_inline bool kasan_enabled(void)
-{
-       return static_branch_likely(&kasan_flag_enabled);
-}
-
-static inline bool kasan_hw_tags_enabled(void)
-{
-       return kasan_enabled();
-}
-
 void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags);
 void kasan_free_pages(struct page *page, unsigned int order);
 
 #else /* CONFIG_KASAN_HW_TAGS */
 
-static inline bool kasan_enabled(void)
-{
-       return IS_ENABLED(CONFIG_KASAN);
-}
-
-static inline bool kasan_hw_tags_enabled(void)
-{
-       return false;
-}
-
 static __always_inline void kasan_alloc_pages(struct page *page,
                                              unsigned int order, gfp_t flags)
 {
index dbf8506decca0f5e4f6527b7a070a1c3c8335f43..acb1ad2356f1b29c6fe4dcb1e8dc1d371d8c2684 100644 (file)
 #ifndef SYM_END
 #define SYM_END(name, sym_type)                                \
        .type name sym_type ASM_NL                      \
-       .size name, .-name
+       .set .L__sym_size_##name, .-name ASM_NL         \
+       .size name, .L__sym_size_##name
+#endif
+
+/* SYM_ALIAS -- use only if you have to */
+#ifndef SYM_ALIAS
+#define SYM_ALIAS(alias, name, sym_type, linkage)                      \
+       linkage(alias) ASM_NL                                           \
+       .set alias, name ASM_NL                                         \
+       .type alias sym_type ASM_NL                                     \
+       .set .L__sym_size_##alias, .L__sym_size_##name ASM_NL           \
+       .size alias, .L__sym_size_##alias
 #endif
 
 /* === code annotations === */
        SYM_ENTRY(name, linkage, SYM_A_NONE)
 #endif
 
-/*
- * SYM_FUNC_START_LOCAL_ALIAS -- use where there are two local names for one
- * function
- */
-#ifndef SYM_FUNC_START_LOCAL_ALIAS
-#define SYM_FUNC_START_LOCAL_ALIAS(name)               \
-       SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
-#endif
-
-/*
- * SYM_FUNC_START_ALIAS -- use where there are two global names for one
- * function
- */
-#ifndef SYM_FUNC_START_ALIAS
-#define SYM_FUNC_START_ALIAS(name)                     \
-       SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
-#endif
-
 /* SYM_FUNC_START -- use for global functions */
 #ifndef SYM_FUNC_START
-/*
- * The same as SYM_FUNC_START_ALIAS, but we will need to distinguish these two
- * later.
- */
 #define SYM_FUNC_START(name)                           \
        SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
 #endif
 
 /* SYM_FUNC_START_LOCAL -- use for local functions */
 #ifndef SYM_FUNC_START_LOCAL
-/* the same as SYM_FUNC_START_LOCAL_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_START_LOCAL(name)                     \
        SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
 #endif
        SYM_START(name, SYM_L_WEAK, SYM_A_NONE)
 #endif
 
-/* SYM_FUNC_END_ALIAS -- the end of LOCAL_ALIASed or ALIASed function */
-#ifndef SYM_FUNC_END_ALIAS
-#define SYM_FUNC_END_ALIAS(name)                       \
-       SYM_END(name, SYM_T_FUNC)
-#endif
-
 /*
  * SYM_FUNC_END -- the end of SYM_FUNC_START_LOCAL, SYM_FUNC_START,
  * SYM_FUNC_START_WEAK, ...
  */
 #ifndef SYM_FUNC_END
-/* the same as SYM_FUNC_END_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_END(name)                             \
        SYM_END(name, SYM_T_FUNC)
 #endif
 
+/*
+ * SYM_FUNC_ALIAS -- define a global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS
+#define SYM_FUNC_ALIAS(alias, name)                                    \
+       SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_GLOBAL)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS_LOCAL -- define a local alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_LOCAL
+#define SYM_FUNC_ALIAS_LOCAL(alias, name)                              \
+       SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_LOCAL)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS_WEAK -- define a weak global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_WEAK
+#define SYM_FUNC_ALIAS_WEAK(alias, name)                               \
+       SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_WEAK)
+#endif
+
 /* SYM_CODE_START -- use for non-C (special) functions */
 #ifndef SYM_CODE_START
 #define SYM_CODE_START(name)                           \
index 598ac3bcc901ff4cffbfbb29b614c02c48e84337..49a48d7709ac18f4846b4b236ae9731098131d28 100644 (file)
@@ -3434,7 +3434,6 @@ enum {
 enum {
        MLX5_TIRC_PACKET_MERGE_MASK_IPV4_LRO  = BIT(0),
        MLX5_TIRC_PACKET_MERGE_MASK_IPV6_LRO  = BIT(1),
-       MLX5_TIRC_PACKET_MERGE_MASK_SHAMPO    = BIT(2),
 };
 
 enum {
@@ -9900,8 +9899,8 @@ struct mlx5_ifc_bufferx_reg_bits {
        u8         reserved_at_0[0x6];
        u8         lossy[0x1];
        u8         epsb[0x1];
-       u8         reserved_at_8[0xc];
-       u8         size[0xc];
+       u8         reserved_at_8[0x8];
+       u8         size[0x10];
 
        u8         xoff_threshold[0x10];
        u8         xon_threshold[0x10];
index 213cc569b19223c8738d980bf57ec0308a41de93..5744a3fc47169a512880561aa2ea91ebad8772fd 100644 (file)
@@ -2626,7 +2626,7 @@ static inline int vma_adjust(struct vm_area_struct *vma, unsigned long start,
 extern struct vm_area_struct *vma_merge(struct mm_struct *,
        struct vm_area_struct *prev, unsigned long addr, unsigned long end,
        unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t,
-       struct mempolicy *, struct vm_userfaultfd_ctx, const char *);
+       struct mempolicy *, struct vm_userfaultfd_ctx, struct anon_vma_name *);
 extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *);
 extern int __split_vma(struct mm_struct *, struct vm_area_struct *,
        unsigned long addr, int new_below);
@@ -3372,11 +3372,12 @@ static inline int seal_check_future_write(int seals, struct vm_area_struct *vma)
 
 #ifdef CONFIG_ANON_VMA_NAME
 int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
-                         unsigned long len_in, const char *name);
+                         unsigned long len_in,
+                         struct anon_vma_name *anon_name);
 #else
 static inline int
 madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
-                     unsigned long len_in, const char *name) {
+                     unsigned long len_in, struct anon_vma_name *anon_name) {
        return 0;
 }
 #endif
index b725839dfe715a4e83ae948fe62d7d1417afdcdd..cf90b1fa2c60c6d9862329926e6762ccbd5af120 100644 (file)
@@ -140,50 +140,91 @@ static __always_inline void del_page_from_lru_list(struct page *page,
 
 #ifdef CONFIG_ANON_VMA_NAME
 /*
- * mmap_lock should be read-locked when calling vma_anon_name() and while using
- * the returned pointer.
+ * mmap_lock should be read-locked when calling anon_vma_name(). Caller should
+ * either keep holding the lock while using the returned pointer or it should
+ * raise anon_vma_name refcount before releasing the lock.
  */
-extern const char *vma_anon_name(struct vm_area_struct *vma);
+extern struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma);
+extern struct anon_vma_name *anon_vma_name_alloc(const char *name);
+extern void anon_vma_name_free(struct kref *kref);
 
-/*
- * mmap_lock should be read-locked for orig_vma->vm_mm.
- * mmap_lock should be write-locked for new_vma->vm_mm or new_vma should be
- * isolated.
- */
-extern void dup_vma_anon_name(struct vm_area_struct *orig_vma,
-                             struct vm_area_struct *new_vma);
+/* mmap_lock should be read-locked */
+static inline void anon_vma_name_get(struct anon_vma_name *anon_name)
+{
+       if (anon_name)
+               kref_get(&anon_name->kref);
+}
 
-/*
- * mmap_lock should be write-locked or vma should have been isolated under
- * write-locked mmap_lock protection.
- */
-extern void free_vma_anon_name(struct vm_area_struct *vma);
+static inline void anon_vma_name_put(struct anon_vma_name *anon_name)
+{
+       if (anon_name)
+               kref_put(&anon_name->kref, anon_vma_name_free);
+}
 
-/* mmap_lock should be read-locked */
-static inline bool is_same_vma_anon_name(struct vm_area_struct *vma,
-                                        const char *name)
+static inline
+struct anon_vma_name *anon_vma_name_reuse(struct anon_vma_name *anon_name)
+{
+       /* Prevent anon_name refcount saturation early on */
+       if (kref_read(&anon_name->kref) < REFCOUNT_MAX) {
+               anon_vma_name_get(anon_name);
+               return anon_name;
+
+       }
+       return anon_vma_name_alloc(anon_name->name);
+}
+
+static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
+                                    struct vm_area_struct *new_vma)
+{
+       struct anon_vma_name *anon_name = anon_vma_name(orig_vma);
+
+       if (anon_name)
+               new_vma->anon_name = anon_vma_name_reuse(anon_name);
+}
+
+static inline void free_anon_vma_name(struct vm_area_struct *vma)
 {
-       const char *vma_name = vma_anon_name(vma);
+       /*
+        * Not using anon_vma_name because it generates a warning if mmap_lock
+        * is not held, which might be the case here.
+        */
+       if (!vma->vm_file)
+               anon_vma_name_put(vma->anon_name);
+}
 
-       /* either both NULL, or pointers to same string */
-       if (vma_name == name)
+static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
+                                   struct anon_vma_name *anon_name2)
+{
+       if (anon_name1 == anon_name2)
                return true;
 
-       return name && vma_name && !strcmp(name, vma_name);
+       return anon_name1 && anon_name2 &&
+               !strcmp(anon_name1->name, anon_name2->name);
 }
+
 #else /* CONFIG_ANON_VMA_NAME */
-static inline const char *vma_anon_name(struct vm_area_struct *vma)
+static inline struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
 {
        return NULL;
 }
-static inline void dup_vma_anon_name(struct vm_area_struct *orig_vma,
-                             struct vm_area_struct *new_vma) {}
-static inline void free_vma_anon_name(struct vm_area_struct *vma) {}
-static inline bool is_same_vma_anon_name(struct vm_area_struct *vma,
-                                        const char *name)
+
+static inline struct anon_vma_name *anon_vma_name_alloc(const char *name)
+{
+       return NULL;
+}
+
+static inline void anon_vma_name_get(struct anon_vma_name *anon_name) {}
+static inline void anon_vma_name_put(struct anon_vma_name *anon_name) {}
+static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
+                                    struct vm_area_struct *new_vma) {}
+static inline void free_anon_vma_name(struct vm_area_struct *vma) {}
+
+static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
+                                   struct anon_vma_name *anon_name2)
 {
        return true;
 }
+
 #endif  /* CONFIG_ANON_VMA_NAME */
 
 static inline void init_tlb_flush_pending(struct mm_struct *mm)
index 5140e5feb486613cdf42df80b4403c68480db8c6..0f549870da6a0d58fdba728fbc7cb0c195b0ec43 100644 (file)
@@ -416,7 +416,10 @@ struct vm_area_struct {
                        struct rb_node rb;
                        unsigned long rb_subtree_last;
                } shared;
-               /* Serialized by mmap_sem. */
+               /*
+                * Serialized by mmap_sem. Never use directly because it is
+                * valid only when vm_file is NULL. Use anon_vma_name instead.
+                */
                struct anon_vma_name *anon_name;
        };
 
index 8b5a314db167d5acf470d63863ef98793af1b85d..f53ea7038441805d5d8fc864be14893f6856bfaa 100644 (file)
@@ -4602,6 +4602,8 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
 
 struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
                                  netdev_features_t features, bool tx_path);
+struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
+                                   netdev_features_t features, __be16 type);
 struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
                                    netdev_features_t features);
 
index b4dd96e4dc8dca30782ae9c1e8458fb9dae412f7..e6487a69113609307cf2ae0fd274bbab4b9d6012 100644 (file)
@@ -101,7 +101,11 @@ static inline struct sk_buff *nf_hook_egress(struct sk_buff *skb, int *rc,
        nf_hook_state_init(&state, NF_NETDEV_EGRESS,
                           NFPROTO_NETDEV, dev, NULL, NULL,
                           dev_net(dev), NULL);
+
+       /* nf assumes rcu_read_lock, not just read_lock_bh */
+       rcu_read_lock();
        ret = nf_hook_slow(skb, &state, e, 0);
+       rcu_read_unlock();
 
        if (ret == 1) {
                return skb;
index 959e0bd9a913ed4a424ee20b3aa59165fc78b386..75470159a194d97fa91e208999217767dd3c9761 100644 (file)
@@ -12,6 +12,7 @@
 #define NVME_TCP_DISC_PORT     8009
 #define NVME_TCP_ADMIN_CCSZ    SZ_8K
 #define NVME_TCP_DIGEST_LENGTH 4
+#define NVME_TCP_MIN_MAXH2CDATA 4096
 
 enum nvme_tcp_pfv {
        NVME_TCP_PFV_1_0 = 0x0,
index 98efb7b5660d9bb7596e41413d5ea3c04fb63436..c9a3ac9efeaa9af0086ac39249c2b55aec36c85a 100644 (file)
@@ -70,7 +70,8 @@ struct nvmem_keepout {
  * @word_size: Minimum read/write access granularity.
  * @stride:    Minimum read/write access stride.
  * @priv:      User context passed to read/write callbacks.
- * @wp-gpio:   Write protect pin
+ * @wp-gpio:   Write protect pin
+ * @ignore_wp:  Write Protect pin is managed by the provider.
  *
  * Note: A default "nvmem<id>" name will be assigned to the device if
  * no name is specified in its configuration. In such case "<id>" is
@@ -92,6 +93,7 @@ struct nvmem_config {
        enum nvmem_type         type;
        bool                    read_only;
        bool                    root_only;
+       bool                    ignore_wp;
        struct device_node      *of_node;
        bool                    no_of_node;
        nvmem_reg_read_t        reg_read;
index 2512e2f9cd4e7964fe08c42052d4313f5cfc6679..0407a38b470ab7ccdb4792957ed179dd8ac15e5d 100644 (file)
@@ -26,6 +26,8 @@
  */
 /* Event uses a 64bit counter */
 #define ARMPMU_EVT_64BIT               1
+/* Event uses a 47bit counter */
+#define ARMPMU_EVT_47BIT               2
 
 #define HW_OP_UNSUPPORTED              0xFFFF
 #define C(_x)                          PERF_COUNT_HW_CACHE_##_x
index 6de8d7a90d78e6cc2d7699ac491c110748b33b63..8fa70ba063a512244561fe0bc75aac48d577bda8 100644 (file)
@@ -87,8 +87,8 @@ extern const int phy_10gbit_features_array[1];
  *
  * @PHY_INTERFACE_MODE_NA: Not Applicable - don't touch
  * @PHY_INTERFACE_MODE_INTERNAL: No interface, MAC and PHY combined
- * @PHY_INTERFACE_MODE_MII: Median-independent interface
- * @PHY_INTERFACE_MODE_GMII: Gigabit median-independent interface
+ * @PHY_INTERFACE_MODE_MII: Media-independent interface
+ * @PHY_INTERFACE_MODE_GMII: Gigabit media-independent interface
  * @PHY_INTERFACE_MODE_SGMII: Serial gigabit media-independent interface
  * @PHY_INTERFACE_MODE_TBI: Ten Bit Interface
  * @PHY_INTERFACE_MODE_REVMII: Reverse Media Independent Interface
index c35f3962dc4fd0cf672181a587671b0b0a32bc02..373003ace639fbccb6b1f1b94cf1ad8393f768cd 100644 (file)
@@ -308,6 +308,11 @@ static inline bool rfkill_blocked(struct rfkill *rfkill)
        return false;
 }
 
+static inline bool rfkill_soft_blocked(struct rfkill *rfkill)
+{
+       return false;
+}
+
 static inline enum rfkill_type rfkill_find_type(const char *name)
 {
        return RFKILL_TYPE_ALL;
index 37bde99b74af0901d059130039539e6e48a245aa..5b6193fd8bd9935bf2ad60b6b08e8d7e1ba8335c 100644 (file)
@@ -660,8 +660,7 @@ static inline __alloc_size(1, 2) void *kcalloc(size_t n, size_t size, gfp_t flag
  * allocator where we care about the real place the memory allocation
  * request comes from.
  */
-extern void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller)
-                                  __alloc_size(1);
+extern void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller);
 #define kmalloc_track_caller(size, flags) \
        __kmalloc_track_caller(size, flags, _RET_IP_)
 
index a6e201758ae9e8c3d4f4fc265dda84768e3e7a99..f19bc3626297ad76c113a5f492032dfb6b7d9856 100644 (file)
@@ -211,6 +211,9 @@ static inline int cpu_to_mem(int cpu)
 #ifndef topology_drawer_id
 #define topology_drawer_id(cpu)                        ((void)(cpu), -1)
 #endif
+#ifndef topology_ppin
+#define topology_ppin(cpu)                     ((void)(cpu), 0ull)
+#endif
 #ifndef topology_sibling_cpumask
 #define topology_sibling_cpumask(cpu)          cpumask_of(cpu)
 #endif
index 70c069aef02ca81e1000079b0464341325f62716..dcea51fb60e2761c9ce468b1a2eddb78ed0919dd 100644 (file)
@@ -699,6 +699,8 @@ event_triggers_post_call(struct trace_event_file *file,
 
 bool trace_event_ignore_this_pid(struct trace_event_file *trace_file);
 
+bool __trace_trigger_soft_disabled(struct trace_event_file *file);
+
 /**
  * trace_trigger_soft_disabled - do triggers and test if soft disabled
  * @file: The file pointer of the event to test
@@ -708,20 +710,20 @@ bool trace_event_ignore_this_pid(struct trace_event_file *trace_file);
  * triggers that require testing the fields, it will return true,
  * otherwise false.
  */
-static inline bool
+static __always_inline bool
 trace_trigger_soft_disabled(struct trace_event_file *file)
 {
        unsigned long eflags = file->flags;
 
-       if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) {
-               if (eflags & EVENT_FILE_FL_TRIGGER_MODE)
-                       event_triggers_call(file, NULL, NULL, NULL);
-               if (eflags & EVENT_FILE_FL_SOFT_DISABLED)
-                       return true;
-               if (eflags & EVENT_FILE_FL_PID_FILTER)
-                       return trace_event_ignore_this_pid(file);
-       }
-       return false;
+       if (likely(!(eflags & (EVENT_FILE_FL_TRIGGER_MODE |
+                              EVENT_FILE_FL_SOFT_DISABLED |
+                              EVENT_FILE_FL_PID_FILTER))))
+               return false;
+
+       if (likely(eflags & EVENT_FILE_FL_TRIGGER_COND))
+               return false;
+
+       return __trace_trigger_soft_disabled(file);
 }
 
 #ifdef CONFIG_BPF_EVENTS
index 2de442ececae47d543f1aa03e636b667900c3b16..721089bb4c8490b685ec356f35cf66e7b60f93e0 100644 (file)
@@ -401,18 +401,24 @@ static inline int vdpa_reset(struct vdpa_device *vdev)
        return ret;
 }
 
-static inline int vdpa_set_features(struct vdpa_device *vdev, u64 features, bool locked)
+static inline int vdpa_set_features_unlocked(struct vdpa_device *vdev, u64 features)
 {
        const struct vdpa_config_ops *ops = vdev->config;
        int ret;
 
-       if (!locked)
-               mutex_lock(&vdev->cf_mutex);
-
        vdev->features_valid = true;
        ret = ops->set_driver_features(vdev, features);
-       if (!locked)
-               mutex_unlock(&vdev->cf_mutex);
+
+       return ret;
+}
+
+static inline int vdpa_set_features(struct vdpa_device *vdev, u64 features)
+{
+       int ret;
+
+       mutex_lock(&vdev->cf_mutex);
+       ret = vdpa_set_features_unlocked(vdev, features);
+       mutex_unlock(&vdev->cf_mutex);
 
        return ret;
 }
index 72292a62cd9050e0f95f997400277cb7833c4ef1..5464f398912a5fea9db9c68b630648a4e5709a46 100644 (file)
@@ -133,7 +133,6 @@ bool is_virtio_device(struct device *dev);
 void virtio_break_device(struct virtio_device *dev);
 
 void virtio_config_changed(struct virtio_device *dev);
-int virtio_finalize_features(struct virtio_device *dev);
 #ifdef CONFIG_PM_SLEEP
 int virtio_device_freeze(struct virtio_device *dev);
 int virtio_device_restore(struct virtio_device *dev);
index 4d107ad31149026e3b0471dd06bccd1be57619e7..dafdc7f48c01b08a84574543af5ff9613b6ab57c 100644 (file)
@@ -64,8 +64,9 @@ struct virtio_shm_region {
  *     Returns the first 64 feature bits (all we currently need).
  * @finalize_features: confirm what device features we'll be using.
  *     vdev: the virtio_device
- *     This gives the final feature bits for the device: it can change
+ *     This sends the driver feature bits to the device: it can change
  *     the dev->feature bits if it wants.
+ * Note: despite the name this can be called any number of times.
  *     Returns 0 on success or error status
  * @bus_name: return the bus name associated with the device (optional)
  *     vdev: the virtio_device
index c994d1b2cdbaa2abb313170749d0ee396a807a90..3b9a40ae8bdba76dec83554989fa67f98cb59aba 100644 (file)
@@ -28,7 +28,8 @@ struct watch_type_filter {
 struct watch_filter {
        union {
                struct rcu_head rcu;
-               unsigned long   type_filter[2]; /* Bitmask of accepted types */
+               /* Bitmask of accepted types */
+               DECLARE_BITMAP(type_filter, WATCH_TYPE__NR);
        };
        u32                     nr_filters;     /* Number of filters */
        struct watch_type_filter filters[];
index ab207677e0a8bd68a8dbd31e57ee8838c396101c..f742e50207fbde4516b5743502d7875573a02fd4 100644 (file)
@@ -205,7 +205,8 @@ struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr);
 struct sock *vsock_find_connected_socket(struct sockaddr_vm *src,
                                         struct sockaddr_vm *dst);
 void vsock_remove_sock(struct vsock_sock *vsk);
-void vsock_for_each_connected_socket(void (*fn)(struct sock *sk));
+void vsock_for_each_connected_socket(struct vsock_transport *transport,
+                                    void (*fn)(struct sock *sk));
 int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk);
 bool vsock_find_cid(unsigned int cid);
 
index 4b3d0b16c185e1a9cd3e3958bbd40843f27e3fea..a647e5fabdbd6d767413c6b0e3382177ccf518df 100644 (file)
@@ -506,8 +506,7 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
 
                tmp = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom);
                if (IS_ERR(tmp)) {
-                       kfree_skb(skb);
-                       return tmp;
+                       return skb;
                }
 
                len -= tmp->len;
index 586f69d084a2a0d1ec4868cf035ff449633671bf..e336e9c1dda4fbafc7d00ea8e86ef2479e9c782d 100644 (file)
@@ -1489,6 +1489,14 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 /* Extended advertising support */
 #define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV))
 
+/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 1789:
+ *
+ * C24: Mandatory if the LE Controller supports Connection State and either
+ * LE Feature (LL Privacy) or LE Feature (Extended Advertising) is supported
+ */
+#define use_enhanced_conn_complete(dev) (ll_privacy_capable(dev) || \
+                                        ext_adv_capable(dev))
+
 /* ----- HCI protocols ----- */
 #define HCI_PROTO_DEFER             0x01
 
index 5218041e5c8f93cd369a2a3a46add3e6a5e41af7..79c67f14c448868f43558a8c7ac4ba1725ef6002 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/checksum.h>
 
 #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
-static inline
+static __always_inline
 __wsum csum_and_copy_from_user (const void __user *src, void *dst,
                                      int len)
 {
@@ -33,7 +33,7 @@ __wsum csum_and_copy_from_user (const void __user *src, void *dst,
 #endif
 
 #ifndef HAVE_CSUM_COPY_USER
-static __inline__ __wsum csum_and_copy_to_user
+static __always_inline __wsum csum_and_copy_to_user
 (const void *src, void __user *dst, int len)
 {
        __wsum sum = csum_partial(src, len, ~0U);
@@ -45,7 +45,7 @@ static __inline__ __wsum csum_and_copy_to_user
 #endif
 
 #ifndef _HAVE_ARCH_CSUM_AND_COPY
-static inline __wsum
+static __always_inline __wsum
 csum_partial_copy_nocheck(const void *src, void *dst, int len)
 {
        memcpy(dst, src, len);
@@ -54,7 +54,7 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len)
 #endif
 
 #ifndef HAVE_ARCH_CSUM_ADD
-static inline __wsum csum_add(__wsum csum, __wsum addend)
+static __always_inline __wsum csum_add(__wsum csum, __wsum addend)
 {
        u32 res = (__force u32)csum;
        res += (__force u32)addend;
@@ -62,12 +62,12 @@ static inline __wsum csum_add(__wsum csum, __wsum addend)
 }
 #endif
 
-static inline __wsum csum_sub(__wsum csum, __wsum addend)
+static __always_inline __wsum csum_sub(__wsum csum, __wsum addend)
 {
        return csum_add(csum, ~addend);
 }
 
-static inline __sum16 csum16_add(__sum16 csum, __be16 addend)
+static __always_inline __sum16 csum16_add(__sum16 csum, __be16 addend)
 {
        u16 res = (__force u16)csum;
 
@@ -75,12 +75,12 @@ static inline __sum16 csum16_add(__sum16 csum, __be16 addend)
        return (__force __sum16)(res + (res < (__force u16)addend));
 }
 
-static inline __sum16 csum16_sub(__sum16 csum, __be16 addend)
+static __always_inline __sum16 csum16_sub(__sum16 csum, __be16 addend)
 {
        return csum16_add(csum, ~addend);
 }
 
-static inline __wsum csum_shift(__wsum sum, int offset)
+static __always_inline __wsum csum_shift(__wsum sum, int offset)
 {
        /* rotate sum to align it with a 16b boundary */
        if (offset & 1)
@@ -88,42 +88,43 @@ static inline __wsum csum_shift(__wsum sum, int offset)
        return sum;
 }
 
-static inline __wsum
+static __always_inline __wsum
 csum_block_add(__wsum csum, __wsum csum2, int offset)
 {
        return csum_add(csum, csum_shift(csum2, offset));
 }
 
-static inline __wsum
+static __always_inline __wsum
 csum_block_add_ext(__wsum csum, __wsum csum2, int offset, int len)
 {
        return csum_block_add(csum, csum2, offset);
 }
 
-static inline __wsum
+static __always_inline __wsum
 csum_block_sub(__wsum csum, __wsum csum2, int offset)
 {
        return csum_block_add(csum, ~csum2, offset);
 }
 
-static inline __wsum csum_unfold(__sum16 n)
+static __always_inline __wsum csum_unfold(__sum16 n)
 {
        return (__force __wsum)n;
 }
 
-static inline __wsum csum_partial_ext(const void *buff, int len, __wsum sum)
+static __always_inline
+__wsum csum_partial_ext(const void *buff, int len, __wsum sum)
 {
        return csum_partial(buff, len, sum);
 }
 
 #define CSUM_MANGLED_0 ((__force __sum16)0xffff)
 
-static inline void csum_replace_by_diff(__sum16 *sum, __wsum diff)
+static __always_inline void csum_replace_by_diff(__sum16 *sum, __wsum diff)
 {
        *sum = csum_fold(csum_add(diff, ~csum_unfold(*sum)));
 }
 
-static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
+static __always_inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
 {
        __wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from);
 
@@ -136,11 +137,16 @@ static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
  *  m : old value of a 16bit field
  *  m' : new value of a 16bit field
  */
-static inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new)
+static __always_inline void csum_replace2(__sum16 *sum, __be16 old, __be16 new)
 {
        *sum = ~csum16_add(csum16_sub(~(*sum), old), new);
 }
 
+static inline void csum_replace(__wsum *csum, __wsum old, __wsum new)
+{
+       *csum = csum_add(csum_sub(*csum, old), new);
+}
+
 struct sk_buff;
 void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
                              __be32 from, __be32 to, bool pseudohdr);
@@ -150,16 +156,16 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
 void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb,
                                     __wsum diff, bool pseudohdr);
 
-static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
-                                           __be16 from, __be16 to,
-                                           bool pseudohdr)
+static __always_inline
+void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
+                             __be16 from, __be16 to, bool pseudohdr)
 {
        inet_proto_csum_replace4(sum, skb, (__force __be32)from,
                                 (__force __be32)to, pseudohdr);
 }
 
-static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
-                                   int start, int offset)
+static __always_inline __wsum remcsum_adjust(void *ptr, __wsum csum,
+                                            int start, int offset)
 {
        __sum16 *psum = (__sum16 *)(ptr + offset);
        __wsum delta;
@@ -175,12 +181,12 @@ static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
        return delta;
 }
 
-static inline void remcsum_unadjust(__sum16 *psum, __wsum delta)
+static __always_inline void remcsum_unadjust(__sum16 *psum, __wsum delta)
 {
        *psum = csum_fold(csum_sub(delta, (__force __wsum)*psum));
 }
 
-static inline __wsum wsum_negate(__wsum val)
+static __always_inline __wsum wsum_negate(__wsum val)
 {
        return (__force __wsum)-((__force u32)val);
 }
index 9c5637d41d95168052686caf7b3ff51b517e6b9b..90cd02ff77ef67f7f65e2c53127c4510c23bd4a9 100644 (file)
@@ -4,6 +4,8 @@
 
 #include <linux/skbuff.h>
 
+#define ESP_SKB_FRAG_MAXSIZE (PAGE_SIZE << SKB_FRAG_PAGE_ORDER)
+
 struct ip_esp_hdr;
 
 static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
index 53cb8de0e589cec4161051a3cfd27de138b282ff..47ffb360ddfac154372d5cf8729a113e5ef736a0 100644 (file)
@@ -475,9 +475,9 @@ int igmp6_late_init(void);
 void igmp6_cleanup(void);
 void igmp6_late_cleanup(void);
 
-int igmp6_event_query(struct sk_buff *skb);
+void igmp6_event_query(struct sk_buff *skb);
 
-int igmp6_event_report(struct sk_buff *skb);
+void igmp6_event_report(struct sk_buff *skb);
 
 
 #ifdef CONFIG_SYSCTL
index 8731d5bcb47ddc53716cbd713601dbef84e63e2b..b08b70989d2cf2f327de443f3abf95daa15ee957 100644 (file)
@@ -97,7 +97,6 @@ struct nf_conn {
        unsigned long status;
 
        u16             cpu;
-       u16             local_origin:1;
        possible_net_t ct_net;
 
 #if IS_ENABLED(CONFIG_NF_NAT)
index a3647fadf1ccb74e9363e05b77271334ba6f10d2..bd59e950f4d67eb47db32ba62579a1ee468a35c1 100644 (file)
@@ -96,6 +96,7 @@ enum flow_offload_xmit_type {
        FLOW_OFFLOAD_XMIT_NEIGH,
        FLOW_OFFLOAD_XMIT_XFRM,
        FLOW_OFFLOAD_XMIT_DIRECT,
+       FLOW_OFFLOAD_XMIT_TC,
 };
 
 #define NF_FLOW_TABLE_ENCAP_MAX                2
@@ -127,7 +128,7 @@ struct flow_offload_tuple {
        struct { }                      __hash;
 
        u8                              dir:2,
-                                       xmit_type:2,
+                                       xmit_type:3,
                                        encap_num:2,
                                        in_vlan_ingress:2;
        u16                             mtu;
@@ -142,6 +143,9 @@ struct flow_offload_tuple {
                        u8              h_source[ETH_ALEN];
                        u8              h_dest[ETH_ALEN];
                } out;
+               struct {
+                       u32             iifidx;
+               } tc;
        };
 };
 
index 9eed51e920e873ca62488c4f233921d62299cbea..980daa6e1e3aa42d42be855630614afb65a5acd9 100644 (file)
@@ -37,7 +37,7 @@ void nf_register_queue_handler(const struct nf_queue_handler *qh);
 void nf_unregister_queue_handler(void);
 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
 
-void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
+bool nf_queue_entry_get_refs(struct nf_queue_entry *entry);
 void nf_queue_entry_free(struct nf_queue_entry *entry);
 
 static inline void init_hashrandom(u32 *jhash_initval)
index eaf55da9a20506950f70dd5ef8888ebd86b5261e..c4c0861deac12ad00edc6a4f50f96c5eba7cf0b3 100644 (file)
@@ -905,9 +905,9 @@ struct nft_expr_ops {
        int                             (*offload)(struct nft_offload_ctx *ctx,
                                                   struct nft_flow_rule *flow,
                                                   const struct nft_expr *expr);
+       bool                            (*offload_action)(const struct nft_expr *expr);
        void                            (*offload_stats)(struct nft_expr *expr,
                                                         const struct flow_stats *stats);
-       u32                             offload_flags;
        const struct nft_expr_type      *type;
        void                            *data;
 };
index f9d95ff82df834a257296285488835cf8271743e..7971478439580c6a7db49892d021e1abfc9e9321 100644 (file)
@@ -67,8 +67,6 @@ struct nft_flow_rule {
        struct flow_rule        *rule;
 };
 
-#define NFT_OFFLOAD_F_ACTION   (1 << 0)
-
 void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow,
                                 enum flow_dissector_key_id addr_type);
 
index ff9b508d9c5ffcb9a30deb730b27046e463bda37..50aecd28b355082bce495a89a8a871b15e3e7e2c 100644 (file)
@@ -507,7 +507,7 @@ struct sock {
 #endif
        u16                     sk_tsflags;
        u8                      sk_shutdown;
-       u32                     sk_tskey;
+       atomic_t                sk_tskey;
        atomic_t                sk_zckey;
 
        u8                      sk_clockid;
@@ -2667,7 +2667,7 @@ static inline void _sock_tx_timestamp(struct sock *sk, __u16 tsflags,
                __sock_tx_timestamp(tsflags, tx_flags);
                if (tsflags & SOF_TIMESTAMPING_OPT_ID && tskey &&
                    tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK)
-                       *tskey = sk->sk_tskey++;
+                       *tskey = atomic_inc_return(&sk->sk_tskey) - 1;
        }
        if (unlikely(sock_flag(sk, SOCK_WIFI_STATUS)))
                *tx_flags |= SKBTX_WIFI_STATUS;
index fdb41e8bb626117b57a926b62bc3da45895da574..76aa6f11a540946c9d429f1cca4fe13b1d2a9385 100644 (file)
@@ -1568,7 +1568,6 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
 void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
 u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
 int xfrm_init_replay(struct xfrm_state *x);
-u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu);
 u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
 int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
 int xfrm_init_state(struct xfrm_state *x);
@@ -1681,14 +1680,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
               const struct xfrm_migrate *m, int num_bundles,
               const struct xfrm_kmaddress *k,
               const struct xfrm_encap_tmpl *encap);
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+                                               u32 if_id);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
                                      struct xfrm_migrate *m,
                                      struct xfrm_encap_tmpl *encap);
 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
                 struct xfrm_migrate *m, int num_bundles,
                 struct xfrm_kmaddress *k, struct net *net,
-                struct xfrm_encap_tmpl *encap);
+                struct xfrm_encap_tmpl *encap, u32 if_id);
 #endif
 
 int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
index 90ae8d191f1a538d0f08ea7cd3583fd9874db339..bae490cac0aa397293c31a7c25e0a85f9b74d152 100644 (file)
@@ -7,7 +7,8 @@
 #ifndef __FSL_DPAA2_FD_H
 #define __FSL_DPAA2_FD_H
 
-#include <linux/kernel.h>
+#include <linux/byteorder/generic.h>
+#include <linux/types.h>
 
 /**
  * DOC: DPAA2 FD - Frame Descriptor APIs for DPAA2
index 7614fee532f1fbefe3f3cd3679fe9952cd798887..edd601f53f5dbde39b85c8fa06bcfa4c65f4e4fb 100644 (file)
@@ -13,7 +13,8 @@
 #define _ASM_POWERPC_IMMAP_QE_H
 #ifdef __KERNEL__
 
-#include <linux/kernel.h>
+#include <linux/types.h>
+
 #include <asm/io.h>
 
 #define QE_IMMAP_SIZE  (1024 * 1024)   /* 1MB from 1MB+IMMR */
index b6febe2250718373eac77a95e169398f0f4d68d3..43ea830cfe1f6094d541afcf267a5bef6d4930ab 100644 (file)
@@ -10,8 +10,8 @@
 #ifndef _QE_TDM_H_
 #define _QE_TDM_H_
 
-#include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/types.h>
 
 #include <soc/fsl/qe/immap_qe.h>
 #include <soc/fsl/qe/qe.h>
@@ -19,6 +19,8 @@
 #include <soc/fsl/qe/ucc.h>
 #include <soc/fsl/qe/ucc_fast.h>
 
+struct device_node;
+
 /* SI RAM entries */
 #define SIR_LAST       0x0001
 #define SIR_BYTE       0x0002
index 9696a5b9b5d1bf78bf7fc54fc6540e1d59553846..ad60b87a3c696902c1de226f320ef6edd180a264 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef __UCC_FAST_H__
 #define __UCC_FAST_H__
 
-#include <linux/kernel.h>
+#include <linux/types.h>
 
 #include <soc/fsl/qe/immap_qe.h>
 #include <soc/fsl/qe/qe.h>
index 11a216e4e919ab600509796a6a6117ef206ed403..7548ce8a202ddef2256c01ee38647ed4a9d7a7d5 100644 (file)
@@ -11,7 +11,7 @@
 #ifndef __UCC_SLOW_H__
 #define __UCC_SLOW_H__
 
-#include <linux/kernel.h>
+#include <linux/types.h>
 
 #include <soc/fsl/qe/immap_qe.h>
 #include <soc/fsl/qe/qe.h>
index c6f5aa74db89b4d1ebb1210b235f56198f096578..2c530637e10aec46f588ac62ad266c655f5370fe 100644 (file)
@@ -56,6 +56,7 @@ enum cachefiles_coherency_trace {
        cachefiles_coherency_set_ok,
        cachefiles_coherency_vol_check_cmp,
        cachefiles_coherency_vol_check_ok,
+       cachefiles_coherency_vol_check_resv,
        cachefiles_coherency_vol_check_xattr,
        cachefiles_coherency_vol_set_fail,
        cachefiles_coherency_vol_set_ok,
@@ -139,6 +140,7 @@ enum cachefiles_error_trace {
        EM(cachefiles_coherency_set_ok,         "SET ok  ")             \
        EM(cachefiles_coherency_vol_check_cmp,  "VOL BAD cmp ")         \
        EM(cachefiles_coherency_vol_check_ok,   "VOL OK      ")         \
+       EM(cachefiles_coherency_vol_check_resv, "VOL BAD resv") \
        EM(cachefiles_coherency_vol_check_xattr,"VOL BAD xatt")         \
        EM(cachefiles_coherency_vol_set_fail,   "VOL SET fail")         \
        E_(cachefiles_coherency_vol_set_ok,     "VOL SET ok  ")
index 61bf4774b8f2a13c6517c8df8f1db7717cfa79f5..fe8e5b74cb39e7571151a02d31b6c4867f22898d 100644 (file)
@@ -40,6 +40,9 @@ typedef __s64 Elf64_Sxword;
 
 #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
 
+/* ARM MTE memory tag segment type */
+#define PT_ARM_MEMTAG_MTE      (PT_LOPROC + 0x1)
+
 /*
  * Extended Numbering
  *
index 225ec87d4f2283c7e2aacba55fbf3d405753b570..7989d9483ea75e2bbaaf78c1fd3d3bca741678ff 100644 (file)
 #define KEY_PAUSECD            201
 #define KEY_PROG3              202
 #define KEY_PROG4              203
-#define KEY_DASHBOARD          204     /* AL Dashboard */
+#define KEY_ALL_APPLICATIONS   204     /* AC Desktop Show All Applications */
+#define KEY_DASHBOARD          KEY_ALL_APPLICATIONS
 #define KEY_SUSPEND            205
 #define KEY_CLOSE              206     /* AC Close */
 #define KEY_PLAY               207
 #define KEY_ASSISTANT          0x247   /* AL Context-aware desktop assistant */
 #define KEY_KBD_LAYOUT_NEXT    0x248   /* AC Next Keyboard Layout Select */
 #define KEY_EMOJI_PICKER       0x249   /* Show/hide emoji picker (HUTRR101) */
+#define KEY_DICTATE            0x24a   /* Start or Stop Voice Dictation Session (HUTRR99) */
 
 #define KEY_BRIGHTNESS_MIN             0x250   /* Set Brightness to Minimum */
 #define KEY_BRIGHTNESS_MAX             0x251   /* Set Brightness to Maximum */
index 5191b57e156220bd7fc6d85940c301e16cc1645a..507ee1f2aa96b12121fabb824f3c62ab3056a65b 100644 (file)
@@ -1134,6 +1134,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_VM_GPA_BITS 207
 #define KVM_CAP_XSAVE2 208
 #define KVM_CAP_SYS_ATTRIBUTES 209
+#define KVM_CAP_PPC_AIL_MODE_3 210
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index 0425cd79af9add4f7790eb5e8925236d9636cdc0..f724129c04255602a1ba25a5c3f870f8b228081c 100644 (file)
@@ -36,6 +36,7 @@
 #define EFIVARFS_MAGIC         0xde5e81e4
 #define HOSTFS_SUPER_MAGIC     0x00c0ffee
 #define OVERLAYFS_SUPER_MAGIC  0x794c7630
+#define FUSE_SUPER_MAGIC       0x65735546
 
 #define MINIX_SUPER_MAGIC      0x137F          /* minix v1 fs, 14 char names */
 #define MINIX_SUPER_MAGIC2     0x138F          /* minix v1 fs, 30 char names */
index 4e29d785189020fb8bf311bd5d09d6c1c5825f97..65e13a099b1a0efa455bc81beabed3f98b5b1541 100644 (file)
@@ -511,6 +511,12 @@ struct xfrm_user_offload {
        int                             ifindex;
        __u8                            flags;
 };
+/* This flag was exposed without any kernel code that supporting it.
+ * Unfortunately, strongswan has the code that uses sets this flag,
+ * which makes impossible to reuse this bit.
+ *
+ * So leave it here to make sure that it won't be reused by mistake.
+ */
 #define XFRM_OFFLOAD_IPV6      1
 #define XFRM_OFFLOAD_INBOUND   2
 
index cb854df031ce0715b9158fa71c7f02ad2c2dc732..c9fea9389ebec74c13a26227f4901f8f577f6c7b 100644 (file)
@@ -104,17 +104,32 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly);
  * access has been ended, free the given page too.  Access will be ended
  * immediately iff the grant entry is not in use, otherwise it will happen
  * some time later.  page may be 0, in which case no freeing will occur.
+ * Note that the granted page might still be accessed (read or write) by the
+ * other side after gnttab_end_foreign_access() returns, so even if page was
+ * specified as 0 it is not allowed to just reuse the page for other
+ * purposes immediately. gnttab_end_foreign_access() will take an additional
+ * reference to the granted page in this case, which is dropped only after
+ * the grant is no longer in use.
+ * This requires that multi page allocations for areas subject to
+ * gnttab_end_foreign_access() are done via alloc_pages_exact() (and freeing
+ * via free_pages_exact()) in order to avoid high order pages.
  */
 void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
                               unsigned long page);
 
+/*
+ * End access through the given grant reference, iff the grant entry is
+ * no longer in use.  In case of success ending foreign access, the
+ * grant reference is deallocated.
+ * Return 1 if the grant entry was freed, 0 if it is still in use.
+ */
+int gnttab_try_end_foreign_access(grant_ref_t ref);
+
 int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn);
 
 unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref);
 unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
 
-int gnttab_query_foreign_access(grant_ref_t ref);
-
 /*
  * operations on reserved batches of grant references
  */
index e16dafeb24504a307c40d1e37c9da6e6ede1a076..3e23b3fa79ff6115caa606098a74d893c7c51fc9 100644 (file)
@@ -5688,7 +5688,8 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
                        }
                        if (check_ptr_off_reg(env, reg, regno))
                                return -EINVAL;
-               } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID || reg2btf_ids[reg->type])) {
+               } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID ||
+                          (reg2btf_ids[base_type(reg->type)] && !type_flag(reg->type)))) {
                        const struct btf_type *reg_ref_t;
                        const struct btf *reg_btf;
                        const char *reg_ref_tname;
@@ -5706,7 +5707,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
                                reg_ref_id = reg->btf_id;
                        } else {
                                reg_btf = btf_vmlinux;
-                               reg_ref_id = *reg2btf_ids[reg->type];
+                               reg_ref_id = *reg2btf_ids[base_type(reg->type)];
                        }
 
                        reg_ref_t = btf_type_skip_modifiers(reg_btf, reg_ref_id,
index 01cfdf40c838c0e538ac895f546695806c47e21b..55c084251fabf5a92419b1a480a1daf55d27a515 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
  */
 #include <linux/bpf.h>
+#include <linux/btf.h>
 #include <linux/bpf-cgroup.h>
 #include <linux/rcupdate.h>
 #include <linux/random.h>
@@ -1075,6 +1076,7 @@ static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer)
        void *key;
        u32 idx;
 
+       BTF_TYPE_EMIT(struct bpf_timer);
        callback_fn = rcu_dereference_check(t->callback_fn, rcu_read_lock_bh_held());
        if (!callback_fn)
                goto out;
index fa4505f9b6119bcb219ab9733847a98da65d1b21..ca70fe6fba387937dfb54f10826f19ac55a8a8e7 100644 (file)
@@ -1355,6 +1355,7 @@ int generic_map_delete_batch(struct bpf_map *map,
                maybe_wait_bpf_programs(map);
                if (err)
                        break;
+               cond_resched();
        }
        if (copy_to_user(&uattr->batch.count, &cp, sizeof(cp)))
                err = -EFAULT;
@@ -1412,6 +1413,7 @@ int generic_map_update_batch(struct bpf_map *map,
 
                if (err)
                        break;
+               cond_resched();
        }
 
        if (copy_to_user(&uattr->batch.count, &cp, sizeof(cp)))
@@ -1509,6 +1511,7 @@ int generic_map_lookup_batch(struct bpf_map *map,
                swap(prev_key, key);
                retry = MAP_LOOKUP_RETRIES;
                cp++;
+               cond_resched();
        }
 
        if (err == -EFAULT)
index 0e877dbcfeea9c337e9af64c9264bc888f5b9968..afc6c0e9c966e1eaf0d46550f3bb8577ad31f2a8 100644 (file)
@@ -546,6 +546,7 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of,
                                          char *buf, size_t nbytes, loff_t off)
 {
        struct cgroup *cgrp;
+       struct cgroup_file_ctx *ctx;
 
        BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX);
 
@@ -553,8 +554,9 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of,
         * Release agent gets called with all capabilities,
         * require capabilities to set release agent.
         */
-       if ((of->file->f_cred->user_ns != &init_user_ns) ||
-           !capable(CAP_SYS_ADMIN))
+       ctx = of->priv;
+       if ((ctx->ns->user_ns != &init_user_ns) ||
+           !file_ns_capable(of->file, &init_user_ns, CAP_SYS_ADMIN))
                return -EPERM;
 
        cgrp = cgroup_kn_lock_live(of->kn, false);
index 9d05c3ca2d5e3cb9cfaebe123a885e4ddd6fd522..a557eea7166fbd5e56be6300cacfb49d2a3a18cf 100644 (file)
@@ -6166,6 +6166,20 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs)
        if (ret)
                goto err;
 
+       /*
+        * Spawning a task directly into a cgroup works by passing a file
+        * descriptor to the target cgroup directory. This can even be an O_PATH
+        * file descriptor. But it can never be a cgroup.procs file descriptor.
+        * This was done on purpose so spawning into a cgroup could be
+        * conceptualized as an atomic
+        *
+        *   fd = openat(dfd_cgroup, "cgroup.procs", ...);
+        *   write(fd, <child-pid>, ...);
+        *
+        * sequence, i.e. it's a shorthand for the caller opening and writing
+        * cgroup.procs of the cgroup indicated by @dfd_cgroup. This allows us
+        * to always use the caller's credentials.
+        */
        ret = cgroup_attach_permissions(cset->dfl_cgrp, dst_cgrp, sb,
                                        !(kargs->flags & CLONE_THREAD),
                                        current->nsproxy->cgroup_ns);
index 4c7254e8f49a546fb1e9d7ccb178005c7b5d3f79..5de18448016cdab512fbc395e403506ba5caa95d 100644 (file)
@@ -2289,6 +2289,7 @@ static void cpuset_attach(struct cgroup_taskset *tset)
        cgroup_taskset_first(tset, &css);
        cs = css_cs(css);
 
+       cpus_read_lock();
        percpu_down_write(&cpuset_rwsem);
 
        guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
@@ -2342,6 +2343,7 @@ static void cpuset_attach(struct cgroup_taskset *tset)
                wake_up(&cpuset_attach_wq);
 
        percpu_up_write(&cpuset_rwsem);
+       cpus_read_unlock();
 }
 
 /* The various types of files and directories in a cpuset file system */
@@ -3522,8 +3524,8 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs)
        return cs;
 }
 
-/**
- * cpuset_node_allowed - Can we allocate on a memory node?
+/*
+ * __cpuset_node_allowed - Can we allocate on a memory node?
  * @node: is this an allowed node?
  * @gfp_mask: memory allocation flags
  *
@@ -3694,8 +3696,8 @@ void cpuset_print_current_mems_allowed(void)
 
 int cpuset_memory_pressure_enabled __read_mostly;
 
-/**
- * cpuset_memory_pressure_bump - keep stats of per-cpuset reclaims.
+/*
+ * __cpuset_memory_pressure_bump - keep stats of per-cpuset reclaims.
  *
  * Keep a running average of the rate of synchronous (direct)
  * page reclaim efforts initiated by tasks in each cpuset.
@@ -3710,7 +3712,7 @@ int cpuset_memory_pressure_enabled __read_mostly;
  * "memory_pressure".  Value displayed is an integer
  * representing the recent rate of entry into the synchronous
  * (direct) page reclaim by any task attached to the cpuset.
- **/
+ */
 
 void __cpuset_memory_pressure_bump(void)
 {
index e9ffb0cc1eecf5951fc2a43abbb6386eaa033411..e8db8d938661774a8917a42951d519f7bf415c77 100644 (file)
@@ -17,6 +17,7 @@ CONFIG_SYMBOLIC_ERRNAME=y
 # Compile-time checks and compiler options
 #
 CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
 CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_FRAME_WARN=2048
 CONFIG_SECTION_MISMATCH_WARN_ONLY=y
index f1e7ea160b43399c89e0e026270f0791796bafaf..6db1c475ec8277331de34e6efac65cda05b4b2b6 100644 (file)
@@ -627,9 +627,14 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
        for (i = 0; i < nr_slots(alloc_size + offset); i++)
                mem->slots[index + i].orig_addr = slot_addr(orig_addr, i);
        tlb_addr = slot_addr(mem->start, index) + offset;
-       if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
-           (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
-               swiotlb_bounce(dev, tlb_addr, mapping_size, DMA_TO_DEVICE);
+       /*
+        * When dir == DMA_FROM_DEVICE we could omit the copy from the orig
+        * to the tlb buffer, if we knew for sure the device will
+        * overwirte the entire current content. But we don't. Thus
+        * unconditional bounce may prevent leaking swiotlb content (i.e.
+        * kernel memory) to user-space.
+        */
+       swiotlb_bounce(dev, tlb_addr, mapping_size, DMA_TO_DEVICE);
        return tlb_addr;
 }
 
@@ -696,10 +701,13 @@ void swiotlb_tbl_unmap_single(struct device *dev, phys_addr_t tlb_addr,
 void swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr,
                size_t size, enum dma_data_direction dir)
 {
-       if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
-               swiotlb_bounce(dev, tlb_addr, size, DMA_TO_DEVICE);
-       else
-               BUG_ON(dir != DMA_FROM_DEVICE);
+       /*
+        * Unconditional bounce is necessary to avoid corruption on
+        * sync_*_for_cpu or dma_ummap_* when the device didn't overwrite
+        * the whole lengt of the bounce buffer.
+        */
+       swiotlb_bounce(dev, tlb_addr, size, DMA_TO_DEVICE);
+       BUG_ON(!valid_dma_direction(dir));
 }
 
 void swiotlb_sync_single_for_cpu(struct device *dev, phys_addr_t tlb_addr,
index a024bf6254df895e7920372d4ef0cb94ac6e6d50..f1e89007f22889c627aadb53934b27cd66b29afe 100644 (file)
@@ -366,14 +366,14 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
                *new = data_race(*orig);
                INIT_LIST_HEAD(&new->anon_vma_chain);
                new->vm_next = new->vm_prev = NULL;
-               dup_vma_anon_name(orig, new);
+               dup_anon_vma_name(orig, new);
        }
        return new;
 }
 
 void vm_area_free(struct vm_area_struct *vma)
 {
-       free_vma_anon_name(vma);
+       free_anon_vma_name(vma);
        kmem_cache_free(vm_area_cachep, vma);
 }
 
index 97dc9e5d6bf92ca7e18c8f474d926e8c51d46679..5b0e172c4d47b2d49a4e58190a9cc23257b06025 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/export.h>
 #include <linux/mm.h>
+#include <linux/mm_inline.h>
 #include <linux/utsname.h>
 #include <linux/mman.h>
 #include <linux/reboot.h>
@@ -2286,15 +2287,16 @@ static int prctl_set_vma(unsigned long opt, unsigned long addr,
 {
        struct mm_struct *mm = current->mm;
        const char __user *uname;
-       char *name, *pch;
+       struct anon_vma_name *anon_name = NULL;
        int error;
 
        switch (opt) {
        case PR_SET_VMA_ANON_NAME:
                uname = (const char __user *)arg;
                if (uname) {
-                       name = strndup_user(uname, ANON_VMA_NAME_MAX_LEN);
+                       char *name, *pch;
 
+                       name = strndup_user(uname, ANON_VMA_NAME_MAX_LEN);
                        if (IS_ERR(name))
                                return PTR_ERR(name);
 
@@ -2304,15 +2306,18 @@ static int prctl_set_vma(unsigned long opt, unsigned long addr,
                                        return -EINVAL;
                                }
                        }
-               } else {
-                       /* Reset the name */
-                       name = NULL;
+                       /* anon_vma has its own copy */
+                       anon_name = anon_vma_name_alloc(name);
+                       kfree(name);
+                       if (!anon_name)
+                               return -ENOMEM;
+
                }
 
                mmap_write_lock(mm);
-               error = madvise_set_anon_name(mm, addr, size, name);
+               error = madvise_set_anon_name(mm, addr, size, anon_name);
                mmap_write_unlock(mm);
-               kfree(name);
+               anon_vma_name_put(anon_name);
                break;
        default:
                error = -EINVAL;
index 5ae443b2882e2f4698a4a71a44be462613967308..730ab56d9e92e65759198f1635dd92564dfd7cbc 100644 (file)
@@ -180,6 +180,10 @@ static int bpf_stats_handler(struct ctl_table *table, int write,
        return ret;
 }
 
+void __weak unpriv_ebpf_notify(int new_state)
+{
+}
+
 static int bpf_unpriv_handler(struct ctl_table *table, int write,
                              void *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -197,6 +201,9 @@ static int bpf_unpriv_handler(struct ctl_table *table, int write,
                        return -EPERM;
                *(int *)table->data = unpriv_enable;
        }
+
+       unpriv_ebpf_notify(unpriv_enable);
+
        return ret;
 }
 #endif /* CONFIG_BPF_SYSCALL && CONFIG_SYSCTL */
index af68a67179b48a54d4eb3f77f4b9fc776c49da9c..21dea90eaa935942c9fce7883993313f9cc4cb87 100644 (file)
@@ -310,10 +310,20 @@ record_it:
        local_irq_restore(flags);
 }
 
-static void blk_trace_free(struct blk_trace *bt)
+static void blk_trace_free(struct request_queue *q, struct blk_trace *bt)
 {
        relay_close(bt->rchan);
-       debugfs_remove(bt->dir);
+
+       /*
+        * If 'bt->dir' is not set, then both 'dropped' and 'msg' are created
+        * under 'q->debugfs_dir', thus lookup and remove them.
+        */
+       if (!bt->dir) {
+               debugfs_remove(debugfs_lookup("dropped", q->debugfs_dir));
+               debugfs_remove(debugfs_lookup("msg", q->debugfs_dir));
+       } else {
+               debugfs_remove(bt->dir);
+       }
        free_percpu(bt->sequence);
        free_percpu(bt->msg_data);
        kfree(bt);
@@ -335,10 +345,10 @@ static void put_probe_ref(void)
        mutex_unlock(&blk_probe_mutex);
 }
 
-static void blk_trace_cleanup(struct blk_trace *bt)
+static void blk_trace_cleanup(struct request_queue *q, struct blk_trace *bt)
 {
        synchronize_rcu();
-       blk_trace_free(bt);
+       blk_trace_free(q, bt);
        put_probe_ref();
 }
 
@@ -352,7 +362,7 @@ static int __blk_trace_remove(struct request_queue *q)
                return -EINVAL;
 
        if (bt->trace_state != Blktrace_running)
-               blk_trace_cleanup(bt);
+               blk_trace_cleanup(q, bt);
 
        return 0;
 }
@@ -572,7 +582,7 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
        ret = 0;
 err:
        if (ret)
-               blk_trace_free(bt);
+               blk_trace_free(q, bt);
        return ret;
 }
 
@@ -1616,7 +1626,7 @@ static int blk_trace_remove_queue(struct request_queue *q)
 
        put_probe_ref();
        synchronize_rcu();
-       blk_trace_free(bt);
+       blk_trace_free(q, bt);
        return 0;
 }
 
@@ -1647,7 +1657,7 @@ static int blk_trace_setup_queue(struct request_queue *q,
        return 0;
 
 free_bt:
-       blk_trace_free(bt);
+       blk_trace_free(q, bt);
        return ret;
 }
 
index f9feb197b2daaf348622665924795a3ae88e4fda..6105b7036482eba6b94ea8e821d450b2c178e660 100644 (file)
@@ -7191,7 +7191,6 @@ static int __init ftrace_nodyn_init(void)
 core_initcall(ftrace_nodyn_init);
 
 static inline int ftrace_init_dyn_tracefs(struct dentry *d_tracer) { return 0; }
-static inline void ftrace_startup_enable(int command) { }
 static inline void ftrace_startup_all(int command) { }
 
 # define ftrace_startup_sysctl()       do { } while (0)
@@ -7791,7 +7790,7 @@ int ftrace_is_dead(void)
 
 /**
  * register_ftrace_function - register a function for profiling
- * @ops - ops structure that holds the function for profiling.
+ * @ops:       ops structure that holds the function for profiling.
  *
  * Register a function to be called by all functions in the
  * kernel.
@@ -7818,7 +7817,7 @@ EXPORT_SYMBOL_GPL(register_ftrace_function);
 
 /**
  * unregister_ftrace_function - unregister a function for profiling.
- * @ops - ops structure that holds the function to unregister
+ * @ops:       ops structure that holds the function to unregister
  *
  * Unregister a function that was added to be called by ftrace profiling.
  */
index 7c2578efde26d4624b117346a208efa903275a5f..eb44418574f9ca5edea3a36b70eb911da13c7bd9 100644 (file)
@@ -235,7 +235,7 @@ static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata;
 static int __init set_trace_boot_options(char *str)
 {
        strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE);
-       return 0;
+       return 1;
 }
 __setup("trace_options=", set_trace_boot_options);
 
@@ -246,7 +246,7 @@ static int __init set_trace_boot_clock(char *str)
 {
        strlcpy(trace_boot_clock_buf, str, MAX_TRACER_SIZE);
        trace_boot_clock = trace_boot_clock_buf;
-       return 0;
+       return 1;
 }
 __setup("trace_clock=", set_trace_boot_clock);
 
@@ -1474,10 +1474,12 @@ static int __init set_buf_size(char *str)
        if (!str)
                return 0;
        buf_size = memparse(str, &str);
-       /* nr_entries can not be zero */
-       if (buf_size == 0)
-               return 0;
-       trace_buf_size = buf_size;
+       /*
+        * nr_entries can not be zero and the startup
+        * tests require some buffer space. Therefore
+        * ensure we have at least 4096 bytes of buffer.
+        */
+       trace_buf_size = max(4096UL, buf_size);
        return 1;
 }
 __setup("trace_buf_size=", set_buf_size);
index d038ddbf1beaa94322067f62d67b8b78343db809..c5b09c31e077253e385dbe958392d4f7908ed999 100644 (file)
@@ -136,7 +136,6 @@ struct kprobe_trace_entry_head {
 
 struct eprobe_trace_entry_head {
        struct trace_entry      ent;
-       unsigned int            type;
 };
 
 struct kretprobe_trace_entry_head {
index 191db32dec4698730cc8580b6265747ccb406dd9..541aa13581b95c697a850973028c43a7db250d4c 100644 (file)
@@ -242,7 +242,6 @@ static int trace_eprobe_tp_arg_update(struct trace_eprobe *ep, int i)
 
 static int eprobe_event_define_fields(struct trace_event_call *event_call)
 {
-       int ret;
        struct eprobe_trace_entry_head field;
        struct trace_probe *tp;
 
@@ -250,8 +249,6 @@ static int eprobe_event_define_fields(struct trace_event_call *event_call)
        if (WARN_ON_ONCE(!tp))
                return -ENOENT;
 
-       DEFINE_FIELD(unsigned int, type, FIELD_STRING_TYPE, 0);
-
        return traceprobe_define_arg_fields(event_call, sizeof(field), tp);
 }
 
@@ -270,7 +267,9 @@ print_eprobe_event(struct trace_iterator *iter, int flags,
        struct trace_event_call *pevent;
        struct trace_event *probed_event;
        struct trace_seq *s = &iter->seq;
+       struct trace_eprobe *ep;
        struct trace_probe *tp;
+       unsigned int type;
 
        field = (struct eprobe_trace_entry_head *)iter->ent;
        tp = trace_probe_primary_from_call(
@@ -278,15 +277,18 @@ print_eprobe_event(struct trace_iterator *iter, int flags,
        if (WARN_ON_ONCE(!tp))
                goto out;
 
+       ep = container_of(tp, struct trace_eprobe, tp);
+       type = ep->event->event.type;
+
        trace_seq_printf(s, "%s: (", trace_probe_name(tp));
 
-       probed_event = ftrace_find_event(field->type);
+       probed_event = ftrace_find_event(type);
        if (probed_event) {
                pevent = container_of(probed_event, struct trace_event_call, event);
                trace_seq_printf(s, "%s.%s", pevent->class->system,
                                 trace_event_name(pevent));
        } else {
-               trace_seq_printf(s, "%u", field->type);
+               trace_seq_printf(s, "%u", type);
        }
 
        trace_seq_putc(s, ')');
@@ -498,10 +500,6 @@ __eprobe_trace_func(struct eprobe_data *edata, void *rec)
                return;
 
        entry = fbuffer.entry = ring_buffer_event_data(fbuffer.event);
-       if (edata->ep->event)
-               entry->type = edata->ep->event->event.type;
-       else
-               entry->type = 0;
        store_trace_args(&entry[1], &edata->ep->tp, rec, sizeof(*entry), dsize);
 
        trace_event_buffer_commit(&fbuffer);
index ada87bfb5bb85da4430ff6cb6d3ed295a8a1a084..dc7f733b4cb3390baa61c5f54389fffde81e5079 100644 (file)
@@ -2289,9 +2289,9 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
                        /*
                         * For backward compatibility, if field_name
                         * was "cpu", then we treat this the same as
-                        * common_cpu.
+                        * common_cpu. This also works for "CPU".
                         */
-                       if (strcmp(field_name, "cpu") == 0) {
+                       if (field && field->filter_type == FILTER_CPU) {
                                *flags |= HIST_FIELD_FL_CPU;
                        } else {
                                hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
@@ -4832,7 +4832,7 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data)
 
                        if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
                                cmp_fn = tracing_map_cmp_none;
-                       else if (!field)
+                       else if (!field || hist_field->flags & HIST_FIELD_FL_CPU)
                                cmp_fn = tracing_map_cmp_num(hist_field->size,
                                                             hist_field->is_signed);
                        else if (is_string_field(field))
index d00fee705f9c57defef5af41dadc63514d405cbc..7eb9d04f1c2ea27c0396901eaea9d434b9f55535 100644 (file)
@@ -84,6 +84,20 @@ event_triggers_call(struct trace_event_file *file,
 }
 EXPORT_SYMBOL_GPL(event_triggers_call);
 
+bool __trace_trigger_soft_disabled(struct trace_event_file *file)
+{
+       unsigned long eflags = file->flags;
+
+       if (eflags & EVENT_FILE_FL_TRIGGER_MODE)
+               event_triggers_call(file, NULL, NULL, NULL);
+       if (eflags & EVENT_FILE_FL_SOFT_DISABLED)
+               return true;
+       if (eflags & EVENT_FILE_FL_PID_FILTER)
+               return trace_event_ignore_this_pid(file);
+       return false;
+}
+EXPORT_SYMBOL_GPL(__trace_trigger_soft_disabled);
+
 /**
  * event_triggers_post_call - Call 'post_triggers' for a trace event
  * @file: The trace_event_file associated with the event
@@ -1295,6 +1309,16 @@ traceon_trigger(struct event_trigger_data *data,
                struct trace_buffer *buffer, void *rec,
                struct ring_buffer_event *event)
 {
+       struct trace_event_file *file = data->private_data;
+
+       if (file) {
+               if (tracer_tracing_is_on(file->tr))
+                       return;
+
+               tracer_tracing_on(file->tr);
+               return;
+       }
+
        if (tracing_is_on())
                return;
 
@@ -1306,8 +1330,15 @@ traceon_count_trigger(struct event_trigger_data *data,
                      struct trace_buffer *buffer, void *rec,
                      struct ring_buffer_event *event)
 {
-       if (tracing_is_on())
-               return;
+       struct trace_event_file *file = data->private_data;
+
+       if (file) {
+               if (tracer_tracing_is_on(file->tr))
+                       return;
+       } else {
+               if (tracing_is_on())
+                       return;
+       }
 
        if (!data->count)
                return;
@@ -1315,7 +1346,10 @@ traceon_count_trigger(struct event_trigger_data *data,
        if (data->count != -1)
                (data->count)--;
 
-       tracing_on();
+       if (file)
+               tracer_tracing_on(file->tr);
+       else
+               tracing_on();
 }
 
 static void
@@ -1323,6 +1357,16 @@ traceoff_trigger(struct event_trigger_data *data,
                 struct trace_buffer *buffer, void *rec,
                 struct ring_buffer_event *event)
 {
+       struct trace_event_file *file = data->private_data;
+
+       if (file) {
+               if (!tracer_tracing_is_on(file->tr))
+                       return;
+
+               tracer_tracing_off(file->tr);
+               return;
+       }
+
        if (!tracing_is_on())
                return;
 
@@ -1334,8 +1378,15 @@ traceoff_count_trigger(struct event_trigger_data *data,
                       struct trace_buffer *buffer, void *rec,
                       struct ring_buffer_event *event)
 {
-       if (!tracing_is_on())
-               return;
+       struct trace_event_file *file = data->private_data;
+
+       if (file) {
+               if (!tracer_tracing_is_on(file->tr))
+                       return;
+       } else {
+               if (!tracing_is_on())
+                       return;
+       }
 
        if (!data->count)
                return;
@@ -1343,7 +1394,10 @@ traceoff_count_trigger(struct event_trigger_data *data,
        if (data->count != -1)
                (data->count)--;
 
-       tracing_off();
+       if (file)
+               tracer_tracing_off(file->tr);
+       else
+               tracing_off();
 }
 
 static int
@@ -1540,7 +1594,12 @@ stacktrace_trigger(struct event_trigger_data *data,
                   struct trace_buffer *buffer,  void *rec,
                   struct ring_buffer_event *event)
 {
-       trace_dump_stack(STACK_SKIP);
+       struct trace_event_file *file = data->private_data;
+
+       if (file)
+               __trace_stack(file->tr, tracing_gen_ctx(), STACK_SKIP);
+       else
+               trace_dump_stack(STACK_SKIP);
 }
 
 static void
index 508f14af4f2c7eb3ddad503adb2701baf05fb8fb..b62fd785b599b25ea3a2308907a843b07ebc2990 100644 (file)
@@ -32,7 +32,7 @@ static int __init set_kprobe_boot_events(char *str)
        strlcpy(kprobe_boot_events_buf, str, COMMAND_LINE_SIZE);
        disable_tracing_selftest("running kprobe events");
 
-       return 0;
+       return 1;
 }
 __setup("kprobe_event=", set_kprobe_boot_events);
 
index 870a08da5b489596f3a69e40bad173d2e8124100..5e3c62a08fc0f48f2bafb6c2d15e7522830a6a28 100644 (file)
@@ -1386,6 +1386,26 @@ static int run_osnoise(void)
                                        osnoise_stop_tracing();
                }
 
+               /*
+                * In some cases, notably when running on a nohz_full CPU with
+                * a stopped tick PREEMPT_RCU has no way to account for QSs.
+                * This will eventually cause unwarranted noise as PREEMPT_RCU
+                * will force preemption as the means of ending the current
+                * grace period. We avoid this problem by calling
+                * rcu_momentary_dyntick_idle(), which performs a zero duration
+                * EQS allowing PREEMPT_RCU to end the current grace period.
+                * This call shouldn't be wrapped inside an RCU critical
+                * section.
+                *
+                * Note that in non PREEMPT_RCU kernels QSs are handled through
+                * cond_resched()
+                */
+               if (IS_ENABLED(CONFIG_PREEMPT_RCU)) {
+                       local_irq_disable();
+                       rcu_momentary_dyntick_idle();
+                       local_irq_enable();
+               }
+
                /*
                 * For the non-preemptive kernel config: let threads runs, if
                 * they so wish.
@@ -1436,6 +1456,37 @@ out:
 static struct cpumask osnoise_cpumask;
 static struct cpumask save_cpumask;
 
+/*
+ * osnoise_sleep - sleep until the next period
+ */
+static void osnoise_sleep(void)
+{
+       u64 interval;
+       ktime_t wake_time;
+
+       mutex_lock(&interface_lock);
+       interval = osnoise_data.sample_period - osnoise_data.sample_runtime;
+       mutex_unlock(&interface_lock);
+
+       /*
+        * differently from hwlat_detector, the osnoise tracer can run
+        * without a pause because preemption is on.
+        */
+       if (!interval) {
+               /* Let synchronize_rcu_tasks() make progress */
+               cond_resched_tasks_rcu_qs();
+               return;
+       }
+
+       wake_time = ktime_add_us(ktime_get(), interval);
+       __set_current_state(TASK_INTERRUPTIBLE);
+
+       while (schedule_hrtimeout_range(&wake_time, 0, HRTIMER_MODE_ABS)) {
+               if (kthread_should_stop())
+                       break;
+       }
+}
+
 /*
  * osnoise_main - The osnoise detection kernel thread
  *
@@ -1444,30 +1495,10 @@ static struct cpumask save_cpumask;
  */
 static int osnoise_main(void *data)
 {
-       u64 interval;
 
        while (!kthread_should_stop()) {
-
                run_osnoise();
-
-               mutex_lock(&interface_lock);
-               interval = osnoise_data.sample_period - osnoise_data.sample_runtime;
-               mutex_unlock(&interface_lock);
-
-               do_div(interval, USEC_PER_MSEC);
-
-               /*
-                * differently from hwlat_detector, the osnoise tracer can run
-                * without a pause because preemption is on.
-                */
-               if (interval < 1) {
-                       /* Let synchronize_rcu_tasks() make progress */
-                       cond_resched_tasks_rcu_qs();
-                       continue;
-               }
-
-               if (msleep_interruptible(interval))
-                       break;
+               osnoise_sleep();
        }
 
        return 0;
@@ -2189,6 +2220,17 @@ static void osnoise_workload_stop(void)
        if (osnoise_has_registered_instances())
                return;
 
+       /*
+        * If callbacks were already disabled in a previous stop
+        * call, there is no need to disable then again.
+        *
+        * For instance, this happens when tracing is stopped via:
+        * echo 0 > tracing_on
+        * echo nop > current_tracer.
+        */
+       if (!trace_osnoise_callback_enabled)
+               return;
+
        trace_osnoise_callback_enabled = false;
        /*
         * Make sure that ftrace_nmi_enter/exit() see
index 73d90179b51bd30833b336180a6edad4ce396458..80863c6508e5e94c48ce39f0746c5858663a87d0 100644 (file)
@@ -871,15 +871,15 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
        switch (ptype) {
        case PROBE_PRINT_NORMAL:
                fmt = "(%lx)";
-               arg = "REC->" FIELD_STRING_IP;
+               arg = "REC->" FIELD_STRING_IP;
                break;
        case PROBE_PRINT_RETURN:
                fmt = "(%lx <- %lx)";
-               arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
+               arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
                break;
        case PROBE_PRINT_EVENT:
-               fmt = "(%u)";
-               arg = "REC->" FIELD_STRING_TYPE;
+               fmt = "";
+               arg = "";
                break;
        default:
                WARN_ON_ONCE(1);
@@ -903,7 +903,7 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
                                        parg->type->fmt);
        }
 
-       pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", arg);
+       pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", arg);
 
        for (i = 0; i < tp->nr_args; i++) {
                parg = tp->args + i;
index 99e7a5df025e2a87d4232da39ca85c69058b667c..92cc149af0fde7c4f763d787f2efc2e9f74f996c 100644 (file)
@@ -38,7 +38,6 @@
 #define FIELD_STRING_IP                "__probe_ip"
 #define FIELD_STRING_RETIP     "__probe_ret_ip"
 #define FIELD_STRING_FUNC      "__probe_func"
-#define FIELD_STRING_TYPE      "__probe_type"
 
 #undef DEFINE_FIELD
 #define DEFINE_FIELD(type, item, name, is_signed)                      \
index afd937a46496ed7c65c784a89ac3fe8ab7181394..abcadbe933bb7662725b7ed4b4930bd73bd3ff01 100644 (file)
@@ -784,9 +784,7 @@ static struct fgraph_ops fgraph_ops __initdata  = {
        .retfunc                = &trace_graph_return,
 };
 
-#if defined(CONFIG_DYNAMIC_FTRACE) && \
-    defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS)
-#define TEST_DIRECT_TRAMP
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
 noinline __noclone static void trace_direct_tramp(void) { }
 #endif
 
@@ -849,7 +847,7 @@ trace_selftest_startup_function_graph(struct tracer *trace,
                goto out;
        }
 
-#ifdef TEST_DIRECT_TRAMP
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
        tracing_reset_online_cpus(&tr->array_buffer);
        set_graph_array(tr);
 
index 6b2e3ca7ee993a7b0ff4fa44a6450770661106dc..5481ba44a8d68463aa01f529a4886a8905190550 100644 (file)
@@ -58,6 +58,18 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
        cred->user_ns = user_ns;
 }
 
+static unsigned long enforced_nproc_rlimit(void)
+{
+       unsigned long limit = RLIM_INFINITY;
+
+       /* Is RLIMIT_NPROC currently enforced? */
+       if (!uid_eq(current_uid(), GLOBAL_ROOT_UID) ||
+           (current_user_ns() != &init_user_ns))
+               limit = rlimit(RLIMIT_NPROC);
+
+       return limit;
+}
+
 /*
  * Create a new user namespace, deriving the creator from the user in the
  * passed credentials, and replacing that user with the new root user for the
@@ -122,7 +134,7 @@ int create_user_ns(struct cred *new)
        for (i = 0; i < MAX_PER_NAMESPACE_UCOUNTS; i++) {
                ns->ucount_max[i] = INT_MAX;
        }
-       set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC));
+       set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_NPROC, enforced_nproc_rlimit());
        set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MSGQUEUE, rlimit(RLIMIT_MSGQUEUE));
        set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_SIGPENDING, rlimit(RLIMIT_SIGPENDING));
        set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MEMLOCK, rlimit(RLIMIT_MEMLOCK));
index 9c9eb20dd2c500d79fa91a926b8e11420ddaaf0f..00703444a21948deaa8b7ac8b57b73528badff0d 100644 (file)
@@ -54,6 +54,7 @@ static void watch_queue_pipe_buf_release(struct pipe_inode_info *pipe,
        bit += page->index;
 
        set_bit(bit, wqueue->notes_bitmap);
+       generic_pipe_buf_release(pipe, buf);
 }
 
 // No try_steal function => no stealing
@@ -112,7 +113,7 @@ static bool post_one_notification(struct watch_queue *wqueue,
        buf->offset = offset;
        buf->len = len;
        buf->flags = PIPE_BUF_FLAG_WHOLE;
-       pipe->head = head + 1;
+       smp_store_release(&pipe->head, head + 1); /* vs pipe_read() */
 
        if (!test_and_clear_bit(note, wqueue->notes_bitmap)) {
                spin_unlock_irq(&pipe->rd_wait.lock);
@@ -219,7 +220,6 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
        struct page **pages;
        unsigned long *bitmap;
        unsigned long user_bufs;
-       unsigned int bmsize;
        int ret, i, nr_pages;
 
        if (!wqueue)
@@ -243,7 +243,8 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
                goto error;
        }
 
-       ret = pipe_resize_ring(pipe, nr_notes);
+       nr_notes = nr_pages * WATCH_QUEUE_NOTES_PER_PAGE;
+       ret = pipe_resize_ring(pipe, roundup_pow_of_two(nr_notes));
        if (ret < 0)
                goto error;
 
@@ -258,17 +259,15 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
                pages[i]->index = i * WATCH_QUEUE_NOTES_PER_PAGE;
        }
 
-       bmsize = (nr_notes + BITS_PER_LONG - 1) / BITS_PER_LONG;
-       bmsize *= sizeof(unsigned long);
-       bitmap = kmalloc(bmsize, GFP_KERNEL);
+       bitmap = bitmap_alloc(nr_notes, GFP_KERNEL);
        if (!bitmap)
                goto error_p;
 
-       memset(bitmap, 0xff, bmsize);
+       bitmap_fill(bitmap, nr_notes);
        wqueue->notes = pages;
        wqueue->notes_bitmap = bitmap;
        wqueue->nr_pages = nr_pages;
-       wqueue->nr_notes = nr_pages * WATCH_QUEUE_NOTES_PER_PAGE;
+       wqueue->nr_notes = nr_notes;
        return 0;
 
 error_p:
@@ -320,7 +319,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe,
                    tf[i].info_mask & WATCH_INFO_LENGTH)
                        goto err_filter;
                /* Ignore any unknown types */
-               if (tf[i].type >= sizeof(wfilter->type_filter) * 8)
+               if (tf[i].type >= WATCH_TYPE__NR)
                        continue;
                nr_filter++;
        }
@@ -336,7 +335,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe,
 
        q = wfilter->filters;
        for (i = 0; i < filter.nr_filters; i++) {
-               if (tf[i].type >= sizeof(wfilter->type_filter) * BITS_PER_LONG)
+               if (tf[i].type >= WATCH_TYPE__NR)
                        continue;
 
                q->type                 = tf[i].type;
@@ -371,6 +370,7 @@ static void __put_watch_queue(struct kref *kref)
 
        for (i = 0; i < wqueue->nr_pages; i++)
                __free_page(wqueue->notes[i]);
+       bitmap_free(wqueue->notes_bitmap);
 
        wfilter = rcu_access_pointer(wqueue->filter);
        if (wfilter)
@@ -566,7 +566,7 @@ void watch_queue_clear(struct watch_queue *wqueue)
        rcu_read_lock();
        spin_lock_bh(&wqueue->lock);
 
-       /* Prevent new additions and prevent notifications from happening */
+       /* Prevent new notifications from being stored. */
        wqueue->defunct = true;
 
        while (!hlist_empty(&wqueue->watches)) {
index c80fde816a7ee6b6eb907a1f2e7b542eba7009dc..9b5a692ce00cbbb7a3746ca4ce9ef7fcb645be1e 100644 (file)
@@ -45,7 +45,6 @@ config BITREVERSE
 config HAVE_ARCH_BITREVERSE
        bool
        default n
-       depends on BITREVERSE
        help
          This option enables the use of hardware bit-reversal instructions on
          architectures which support such operations.
index b0e0acdf96c15e73326c217ae7903fcd364ddc99..6dd5330f7a9957b6d67036390573e5d622df9f92 100644 (file)
@@ -414,6 +414,7 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by
                return 0;
 
        buf->ops = &page_cache_pipe_buf_ops;
+       buf->flags = 0;
        get_page(page);
        buf->page = page;
        buf->offset = offset;
@@ -577,6 +578,7 @@ static size_t push_pipe(struct iov_iter *i, size_t size,
                        break;
 
                buf->ops = &default_pipe_buf_ops;
+               buf->flags = 0;
                buf->page = page;
                buf->offset = 0;
                buf->len = min_t(ssize_t, left, PAGE_SIZE);
index 26a5c9007653aa5deabae35157cdfcf66788ca43..3b413f8c8a7154816fa763c37f7846021504a645 100644 (file)
@@ -869,11 +869,14 @@ static void kmem_cache_invalid_free(struct kunit *test)
        kmem_cache_destroy(cache);
 }
 
+static void empty_cache_ctor(void *object) { }
+
 static void kmem_cache_double_destroy(struct kunit *test)
 {
        struct kmem_cache *cache;
 
-       cache = kmem_cache_create("test_cache", 200, 0, 0, NULL);
+       /* Provide a constructor to prevent cache merging. */
+       cache = kmem_cache_create("test_cache", 200, 0, 0, empty_cache_ctor);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache);
        kmem_cache_destroy(cache);
        KUNIT_EXPECT_KASAN_FAIL(test, kmem_cache_destroy(cache));
index a9d4d724aef7497aba6ae6a787f20ff8dc8fa371..7bc1ba9ce4403be192a6a4655257c5690ebf8726 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1729,11 +1729,11 @@ EXPORT_SYMBOL(fault_in_writeable);
  * @uaddr: start of address range
  * @size: length of address range
  *
- * Faults in an address range using get_user_pages, i.e., without triggering
- * hardware page faults.  This is primarily useful when we already know that
- * some or all of the pages in the address range aren't in memory.
+ * Faults in an address range for writing.  This is primarily useful when we
+ * already know that some or all of the pages in the address range aren't in
+ * memory.
  *
- * Other than fault_in_writeable(), this function is non-destructive.
+ * Unlike fault_in_writeable(), this function is non-destructive.
  *
  * Note that we don't pin or otherwise hold the pages referenced that we fault
  * in.  There's no guarantee that they'll stay in memory for any duration of
@@ -1744,46 +1744,27 @@ EXPORT_SYMBOL(fault_in_writeable);
  */
 size_t fault_in_safe_writeable(const char __user *uaddr, size_t size)
 {
-       unsigned long start = (unsigned long)untagged_addr(uaddr);
-       unsigned long end, nstart, nend;
+       unsigned long start = (unsigned long)uaddr, end;
        struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma = NULL;
-       int locked = 0;
+       bool unlocked = false;
 
-       nstart = start & PAGE_MASK;
+       if (unlikely(size == 0))
+               return 0;
        end = PAGE_ALIGN(start + size);
-       if (end < nstart)
+       if (end < start)
                end = 0;
-       for (; nstart != end; nstart = nend) {
-               unsigned long nr_pages;
-               long ret;
 
-               if (!locked) {
-                       locked = 1;
-                       mmap_read_lock(mm);
-                       vma = find_vma(mm, nstart);
-               } else if (nstart >= vma->vm_end)
-                       vma = vma->vm_next;
-               if (!vma || vma->vm_start >= end)
-                       break;
-               nend = end ? min(end, vma->vm_end) : vma->vm_end;
-               if (vma->vm_flags & (VM_IO | VM_PFNMAP))
-                       continue;
-               if (nstart < vma->vm_start)
-                       nstart = vma->vm_start;
-               nr_pages = (nend - nstart) / PAGE_SIZE;
-               ret = __get_user_pages_locked(mm, nstart, nr_pages,
-                                             NULL, NULL, &locked,
-                                             FOLL_TOUCH | FOLL_WRITE);
-               if (ret <= 0)
+       mmap_read_lock(mm);
+       do {
+               if (fixup_user_fault(mm, start, FAULT_FLAG_WRITE, &unlocked))
                        break;
-               nend = nstart + ret * PAGE_SIZE;
-       }
-       if (locked)
-               mmap_read_unlock(mm);
-       if (nstart == end)
-               return 0;
-       return size - min_t(size_t, nstart - start, size);
+               start = (start + PAGE_SIZE) & PAGE_MASK;
+       } while (start != end);
+       mmap_read_unlock(mm);
+
+       if (size > (unsigned long)uaddr - start)
+               return size - ((unsigned long)uaddr - start);
+       return 0;
 }
 EXPORT_SYMBOL(fault_in_safe_writeable);
 
index 61895cc01d0980a7e657bf32471ac5462b334076..f294db835f4bc46b737cc363ec99e7579ad3fde4 100644 (file)
@@ -4159,10 +4159,10 @@ static int __init hugepages_setup(char *s)
                                pr_warn("HugeTLB: architecture can't support node specific alloc, ignoring!\n");
                                return 0;
                        }
+                       if (tmp >= nr_online_nodes)
+                               goto invalid;
                        node = tmp;
                        p += count + 1;
-                       if (node < 0 || node >= nr_online_nodes)
-                               goto invalid;
                        /* Parse hugepages */
                        if (sscanf(p, "%lu%n", &tmp, &count) != 1)
                                goto invalid;
@@ -4851,14 +4851,13 @@ again:
 }
 
 static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
-                         unsigned long new_addr, pte_t *src_pte)
+                         unsigned long new_addr, pte_t *src_pte, pte_t *dst_pte)
 {
        struct hstate *h = hstate_vma(vma);
        struct mm_struct *mm = vma->vm_mm;
-       pte_t *dst_pte, pte;
        spinlock_t *src_ptl, *dst_ptl;
+       pte_t pte;
 
-       dst_pte = huge_pte_offset(mm, new_addr, huge_page_size(h));
        dst_ptl = huge_pte_lock(h, mm, dst_pte);
        src_ptl = huge_pte_lockptr(h, mm, src_pte);
 
@@ -4917,7 +4916,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
                if (!dst_pte)
                        break;
 
-               move_huge_pte(vma, old_addr, new_addr, src_pte);
+               move_huge_pte(vma, old_addr, new_addr, src_pte, dst_pte);
        }
        flush_tlb_range(vma, old_end - len, old_end);
        mmu_notifier_invalidate_range_end(&range);
index 5604064df4646e786d1c9e2fcf0a35eb71f622ba..38d0f515d5486868e8487a4299abce64764eedb2 100644 (file)
@@ -65,7 +65,7 @@ static int madvise_need_mmap_write(int behavior)
 }
 
 #ifdef CONFIG_ANON_VMA_NAME
-static struct anon_vma_name *anon_vma_name_alloc(const char *name)
+struct anon_vma_name *anon_vma_name_alloc(const char *name)
 {
        struct anon_vma_name *anon_name;
        size_t count;
@@ -81,78 +81,48 @@ static struct anon_vma_name *anon_vma_name_alloc(const char *name)
        return anon_name;
 }
 
-static void vma_anon_name_free(struct kref *kref)
+void anon_vma_name_free(struct kref *kref)
 {
        struct anon_vma_name *anon_name =
                        container_of(kref, struct anon_vma_name, kref);
        kfree(anon_name);
 }
 
-static inline bool has_vma_anon_name(struct vm_area_struct *vma)
+struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
 {
-       return !vma->vm_file && vma->anon_name;
-}
-
-const char *vma_anon_name(struct vm_area_struct *vma)
-{
-       if (!has_vma_anon_name(vma))
-               return NULL;
-
        mmap_assert_locked(vma->vm_mm);
 
-       return vma->anon_name->name;
-}
-
-void dup_vma_anon_name(struct vm_area_struct *orig_vma,
-                      struct vm_area_struct *new_vma)
-{
-       if (!has_vma_anon_name(orig_vma))
-               return;
-
-       kref_get(&orig_vma->anon_name->kref);
-       new_vma->anon_name = orig_vma->anon_name;
-}
-
-void free_vma_anon_name(struct vm_area_struct *vma)
-{
-       struct anon_vma_name *anon_name;
-
-       if (!has_vma_anon_name(vma))
-               return;
+       if (vma->vm_file)
+               return NULL;
 
-       anon_name = vma->anon_name;
-       vma->anon_name = NULL;
-       kref_put(&anon_name->kref, vma_anon_name_free);
+       return vma->anon_name;
 }
 
 /* mmap_lock should be write-locked */
-static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
+static int replace_anon_vma_name(struct vm_area_struct *vma,
+                                struct anon_vma_name *anon_name)
 {
-       const char *anon_name;
+       struct anon_vma_name *orig_name = anon_vma_name(vma);
 
-       if (!name) {
-               free_vma_anon_name(vma);
+       if (!anon_name) {
+               vma->anon_name = NULL;
+               anon_vma_name_put(orig_name);
                return 0;
        }
 
-       anon_name = vma_anon_name(vma);
-       if (anon_name) {
-               /* Same name, nothing to do here */
-               if (!strcmp(name, anon_name))
-                       return 0;
+       if (anon_vma_name_eq(orig_name, anon_name))
+               return 0;
 
-               free_vma_anon_name(vma);
-       }
-       vma->anon_name = anon_vma_name_alloc(name);
-       if (!vma->anon_name)
-               return -ENOMEM;
+       vma->anon_name = anon_vma_name_reuse(anon_name);
+       anon_vma_name_put(orig_name);
 
        return 0;
 }
 #else /* CONFIG_ANON_VMA_NAME */
-static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
+static int replace_anon_vma_name(struct vm_area_struct *vma,
+                                struct anon_vma_name *anon_name)
 {
-       if (name)
+       if (anon_name)
                return -EINVAL;
 
        return 0;
@@ -161,17 +131,19 @@ static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
 /*
  * Update the vm_flags on region of a vma, splitting it or merging it as
  * necessary.  Must be called with mmap_sem held for writing;
+ * Caller should ensure anon_name stability by raising its refcount even when
+ * anon_name belongs to a valid vma because this function might free that vma.
  */
 static int madvise_update_vma(struct vm_area_struct *vma,
                              struct vm_area_struct **prev, unsigned long start,
                              unsigned long end, unsigned long new_flags,
-                             const char *name)
+                             struct anon_vma_name *anon_name)
 {
        struct mm_struct *mm = vma->vm_mm;
        int error;
        pgoff_t pgoff;
 
-       if (new_flags == vma->vm_flags && is_same_vma_anon_name(vma, name)) {
+       if (new_flags == vma->vm_flags && anon_vma_name_eq(anon_vma_name(vma), anon_name)) {
                *prev = vma;
                return 0;
        }
@@ -179,7 +151,7 @@ static int madvise_update_vma(struct vm_area_struct *vma,
        pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
        *prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma,
                          vma->vm_file, pgoff, vma_policy(vma),
-                         vma->vm_userfaultfd_ctx, name);
+                         vma->vm_userfaultfd_ctx, anon_name);
        if (*prev) {
                vma = *prev;
                goto success;
@@ -209,7 +181,7 @@ success:
         */
        vma->vm_flags = new_flags;
        if (!vma->vm_file) {
-               error = replace_vma_anon_name(vma, name);
+               error = replace_anon_vma_name(vma, anon_name);
                if (error)
                        return error;
        }
@@ -975,6 +947,7 @@ static int madvise_vma_behavior(struct vm_area_struct *vma,
                                unsigned long behavior)
 {
        int error;
+       struct anon_vma_name *anon_name;
        unsigned long new_flags = vma->vm_flags;
 
        switch (behavior) {
@@ -1040,8 +1013,11 @@ static int madvise_vma_behavior(struct vm_area_struct *vma,
                break;
        }
 
+       anon_name = anon_vma_name(vma);
+       anon_vma_name_get(anon_name);
        error = madvise_update_vma(vma, prev, start, end, new_flags,
-                                  vma_anon_name(vma));
+                                  anon_name);
+       anon_vma_name_put(anon_name);
 
 out:
        /*
@@ -1225,7 +1201,7 @@ int madvise_walk_vmas(struct mm_struct *mm, unsigned long start,
 static int madvise_vma_anon_name(struct vm_area_struct *vma,
                                 struct vm_area_struct **prev,
                                 unsigned long start, unsigned long end,
-                                unsigned long name)
+                                unsigned long anon_name)
 {
        int error;
 
@@ -1234,7 +1210,7 @@ static int madvise_vma_anon_name(struct vm_area_struct *vma,
                return -EBADF;
 
        error = madvise_update_vma(vma, prev, start, end, vma->vm_flags,
-                                  (const char *)name);
+                                  (struct anon_vma_name *)anon_name);
 
        /*
         * madvise() returns EAGAIN if kernel resources, such as
@@ -1246,7 +1222,7 @@ static int madvise_vma_anon_name(struct vm_area_struct *vma,
 }
 
 int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
-                         unsigned long len_in, const char *name)
+                         unsigned long len_in, struct anon_vma_name *anon_name)
 {
        unsigned long end;
        unsigned long len;
@@ -1266,7 +1242,7 @@ int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
        if (end == start)
                return 0;
 
-       return madvise_walk_vmas(mm, start, end, (unsigned long)name,
+       return madvise_walk_vmas(mm, start, end, (unsigned long)anon_name,
                                 madvise_vma_anon_name);
 }
 #endif /* CONFIG_ANON_VMA_NAME */
index 1018e50566f35a28f07596fdc06da73fd7c28efc..b12a364f2766fdf3cd3b2018aaf9d851b8536073 100644 (file)
@@ -366,14 +366,20 @@ void __init memblock_discard(void)
                addr = __pa(memblock.reserved.regions);
                size = PAGE_ALIGN(sizeof(struct memblock_region) *
                                  memblock.reserved.max);
-               memblock_free_late(addr, size);
+               if (memblock_reserved_in_slab)
+                       kfree(memblock.reserved.regions);
+               else
+                       memblock_free_late(addr, size);
        }
 
        if (memblock.memory.regions != memblock_memory_init_regions) {
                addr = __pa(memblock.memory.regions);
                size = PAGE_ALIGN(sizeof(struct memblock_region) *
                                  memblock.memory.max);
-               memblock_free_late(addr, size);
+               if (memblock_memory_in_slab)
+                       kfree(memblock.memory.regions);
+               else
+                       memblock_free_late(addr, size);
        }
 
        memblock_memory = NULL;
index 9f80f162791a5a51cab843759c5353bb27741da4..08f5f8304746fb675f744ed93eaa7eaf7e53a6d6 100644 (file)
 static void memfd_tag_pins(struct xa_state *xas)
 {
        struct page *page;
-       unsigned int tagged = 0;
+       int latency = 0;
+       int cache_count;
 
        lru_add_drain();
 
        xas_lock_irq(xas);
        xas_for_each(xas, page, ULONG_MAX) {
-               if (xa_is_value(page))
-                       continue;
-               page = find_subpage(page, xas->xa_index);
-               if (page_count(page) - page_mapcount(page) > 1)
+               cache_count = 1;
+               if (!xa_is_value(page) &&
+                   PageTransHuge(page) && !PageHuge(page))
+                       cache_count = HPAGE_PMD_NR;
+
+               if (!xa_is_value(page) &&
+                   page_count(page) - total_mapcount(page) != cache_count)
                        xas_set_mark(xas, MEMFD_TAG_PINNED);
+               if (cache_count != 1)
+                       xas_set(xas, page->index + cache_count);
 
-               if (++tagged % XA_CHECK_SCHED)
+               latency += cache_count;
+               if (latency < XA_CHECK_SCHED)
                        continue;
+               latency = 0;
 
                xas_pause(xas);
                xas_unlock_irq(xas);
@@ -73,7 +81,8 @@ static int memfd_wait_for_pins(struct address_space *mapping)
 
        error = 0;
        for (scan = 0; scan <= LAST_SCAN; scan++) {
-               unsigned int tagged = 0;
+               int latency = 0;
+               int cache_count;
 
                if (!xas_marked(&xas, MEMFD_TAG_PINNED))
                        break;
@@ -87,10 +96,14 @@ static int memfd_wait_for_pins(struct address_space *mapping)
                xas_lock_irq(&xas);
                xas_for_each_marked(&xas, page, ULONG_MAX, MEMFD_TAG_PINNED) {
                        bool clear = true;
-                       if (xa_is_value(page))
-                               continue;
-                       page = find_subpage(page, xas.xa_index);
-                       if (page_count(page) - page_mapcount(page) != 1) {
+
+                       cache_count = 1;
+                       if (!xa_is_value(page) &&
+                           PageTransHuge(page) && !PageHuge(page))
+                               cache_count = HPAGE_PMD_NR;
+
+                       if (!xa_is_value(page) && cache_count !=
+                           page_count(page) - total_mapcount(page)) {
                                /*
                                 * On the last scan, we clean up all those tags
                                 * we inserted; but make a note that we still
@@ -103,8 +116,11 @@ static int memfd_wait_for_pins(struct address_space *mapping)
                        }
                        if (clear)
                                xas_clear_mark(&xas, MEMFD_TAG_PINNED);
-                       if (++tagged % XA_CHECK_SCHED)
+
+                       latency += cache_count;
+                       if (latency < XA_CHECK_SCHED)
                                continue;
+                       latency = 0;
 
                        xas_pause(&xas);
                        xas_unlock_irq(&xas);
index 028e8dd82b4425db7582c9dca713a1f77b86b4fe..69284d3b5e53f868c77da3ecd32aa3a436e8d359 100644 (file)
@@ -814,7 +814,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
                prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
                                 vma->anon_vma, vma->vm_file, pgoff,
                                 new_pol, vma->vm_userfaultfd_ctx,
-                                vma_anon_name(vma));
+                                anon_vma_name(vma));
                if (prev) {
                        vma = prev;
                        next = vma->vm_next;
index 8f584eddd305380d3aae8fb810998e9530468f42..25934e7db3e103e98baa9f9db7083944a1265e2d 100644 (file)
@@ -512,7 +512,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
        pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
        *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
                          vma->vm_file, pgoff, vma_policy(vma),
-                         vma->vm_userfaultfd_ctx, vma_anon_name(vma));
+                         vma->vm_userfaultfd_ctx, anon_vma_name(vma));
        if (*prev) {
                vma = *prev;
                goto success;
index 1e8fdb0b51eddcb8bce46b6f7c0648980827ea04..f61a15474dd6d5ae25039bde9087533cdab17614 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1031,7 +1031,7 @@ again:
 static inline int is_mergeable_vma(struct vm_area_struct *vma,
                                struct file *file, unsigned long vm_flags,
                                struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
-                               const char *anon_name)
+                               struct anon_vma_name *anon_name)
 {
        /*
         * VM_SOFTDIRTY should not prevent from VMA merging, if we
@@ -1049,7 +1049,7 @@ static inline int is_mergeable_vma(struct vm_area_struct *vma,
                return 0;
        if (!is_mergeable_vm_userfaultfd_ctx(vma, vm_userfaultfd_ctx))
                return 0;
-       if (!is_same_vma_anon_name(vma, anon_name))
+       if (!anon_vma_name_eq(anon_vma_name(vma), anon_name))
                return 0;
        return 1;
 }
@@ -1084,7 +1084,7 @@ can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
                     struct anon_vma *anon_vma, struct file *file,
                     pgoff_t vm_pgoff,
                     struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
-                    const char *anon_name)
+                    struct anon_vma_name *anon_name)
 {
        if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
            is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
@@ -1106,7 +1106,7 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
                    struct anon_vma *anon_vma, struct file *file,
                    pgoff_t vm_pgoff,
                    struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
-                   const char *anon_name)
+                   struct anon_vma_name *anon_name)
 {
        if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
            is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
@@ -1167,7 +1167,7 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
                        struct anon_vma *anon_vma, struct file *file,
                        pgoff_t pgoff, struct mempolicy *policy,
                        struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
-                       const char *anon_name)
+                       struct anon_vma_name *anon_name)
 {
        pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
        struct vm_area_struct *area, *next;
@@ -3186,6 +3186,7 @@ void exit_mmap(struct mm_struct *mm)
                vma = remove_vma(vma);
                cond_resched();
        }
+       mm->mmap = NULL;
        mmap_write_unlock(mm);
        vm_unacct_memory(nr_accounted);
 }
@@ -3255,7 +3256,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
                return NULL;    /* should never get here */
        new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
                            vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
-                           vma->vm_userfaultfd_ctx, vma_anon_name(vma));
+                           vma->vm_userfaultfd_ctx, anon_vma_name(vma));
        if (new_vma) {
                /*
                 * Source vma may have been merged into new_vma
index 5ca3fbcb149520f4ea8692f3dfbc7368fe8b4f1a..2887644fd15057db5669997f0ece69dc82427dd1 100644 (file)
@@ -464,7 +464,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
        pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
        *pprev = vma_merge(mm, *pprev, start, end, newflags,
                           vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
-                          vma->vm_userfaultfd_ctx, vma_anon_name(vma));
+                          vma->vm_userfaultfd_ctx, anon_vma_name(vma));
        if (*pprev) {
                vma = *pprev;
                VM_WARN_ON((vma->vm_flags ^ newflags) & ~VM_SOFTDIRTY);
index 8d410424210007f08ac95b41aa26a57fac6b698f..ee67164531c060add65b180b6b0a921ed98de85f 100644 (file)
@@ -478,7 +478,7 @@ struct page *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
                 * __read_swap_cache_async(), which has set SWAP_HAS_CACHE
                 * in swap_map, but not yet added its page to swap cache.
                 */
-               cond_resched();
+               schedule_timeout_uninterruptible(1);
        }
 
        /*
index 7e43369064c861ea2d455e2e71b801cd9a82d2ea..d3102081add001d4986f15b6e7dc539ce769e583 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -587,8 +587,10 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
                return ret;
 
        /* Don't even allow crazy sizes */
-       if (WARN_ON_ONCE(size > INT_MAX))
+       if (unlikely(size > INT_MAX)) {
+               WARN_ON_ONCE(!(flags & __GFP_NOWARN));
                return NULL;
+       }
 
        return __vmalloc_node(size, 1, flags, node,
                        __builtin_return_address(0));
index eb9fb55280ef84c2ca29ecd3d4dd97209d8d0108..01f8067994d687fe8fbeb027b8381fd456f07646 100644 (file)
@@ -281,9 +281,9 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
                                ref = priv->rings[i].intf->ref[j];
                                gnttab_end_foreign_access(ref, 0, 0);
                        }
-                       free_pages((unsigned long)priv->rings[i].data.in,
-                                  priv->rings[i].intf->ring_order -
-                                  (PAGE_SHIFT - XEN_PAGE_SHIFT));
+                       free_pages_exact(priv->rings[i].data.in,
+                                  1UL << (priv->rings[i].intf->ring_order +
+                                          XEN_PAGE_SHIFT));
                }
                gnttab_end_foreign_access(priv->rings[i].ref, 0, 0);
                free_page((unsigned long)priv->rings[i].intf);
@@ -322,8 +322,8 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
        if (ret < 0)
                goto out;
        ring->ref = ret;
-       bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
-                       order - (PAGE_SHIFT - XEN_PAGE_SHIFT));
+       bytes = alloc_pages_exact(1UL << (order + XEN_PAGE_SHIFT),
+                                 GFP_KERNEL | __GFP_ZERO);
        if (!bytes) {
                ret = -ENOMEM;
                goto out;
@@ -354,9 +354,7 @@ out:
        if (bytes) {
                for (i--; i >= 0; i--)
                        gnttab_end_foreign_access(ring->intf->ref[i], 0, 0);
-               free_pages((unsigned long)bytes,
-                          ring->intf->ring_order -
-                          (PAGE_SHIFT - XEN_PAGE_SHIFT));
+               free_pages_exact(bytes, 1UL << (order + XEN_PAGE_SHIFT));
        }
        gnttab_end_foreign_access(ring->ref, 0, 0);
        free_page((unsigned long)ring->intf);
index d53cbb4e25035f43ee57fbb671758d386e7ad9b2..6bd097180772142bacfa09b2dd01a9eb5843db07 100644 (file)
@@ -87,6 +87,13 @@ again:
        ax25_for_each(s, &ax25_list) {
                if (s->ax25_dev == ax25_dev) {
                        sk = s->sk;
+                       if (!sk) {
+                               spin_unlock_bh(&ax25_list_lock);
+                               s->ax25_dev = NULL;
+                               ax25_disconnect(s, ENETUNREACH);
+                               spin_lock_bh(&ax25_list_lock);
+                               goto again;
+                       }
                        sock_hold(sk);
                        spin_unlock_bh(&ax25_list_lock);
                        lock_sock(sk);
index 8a2b78f9c4b2c0a28569d8ab3bda49bce46244be..35fadb924849866f0fcdcd57ad136d158c398a93 100644 (file)
@@ -149,22 +149,25 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
        struct net *net = dev_net(net_dev);
        struct net_device *parent_dev;
        struct net *parent_net;
+       int iflink;
        bool ret;
 
        /* check if this is a batman-adv mesh interface */
        if (batadv_softif_is_valid(net_dev))
                return true;
 
-       /* no more parents..stop recursion */
-       if (dev_get_iflink(net_dev) == 0 ||
-           dev_get_iflink(net_dev) == net_dev->ifindex)
+       iflink = dev_get_iflink(net_dev);
+       if (iflink == 0)
                return false;
 
        parent_net = batadv_getlink_net(net_dev, net);
 
+       /* iflink to itself, most likely physical device */
+       if (net == parent_net && iflink == net_dev->ifindex)
+               return false;
+
        /* recurse over the parent device */
-       parent_dev = __dev_get_by_index((struct net *)parent_net,
-                                       dev_get_iflink(net_dev));
+       parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
        /* if we got a NULL parent_dev there is something broken.. */
        if (!parent_dev) {
                pr_err("Cannot find parent device\n");
@@ -214,14 +217,15 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
        struct net_device *real_netdev = NULL;
        struct net *real_net;
        struct net *net;
-       int ifindex;
+       int iflink;
 
        ASSERT_RTNL();
 
        if (!netdev)
                return NULL;
 
-       if (netdev->ifindex == dev_get_iflink(netdev)) {
+       iflink = dev_get_iflink(netdev);
+       if (iflink == 0) {
                dev_hold(netdev);
                return netdev;
        }
@@ -231,9 +235,16 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
                goto out;
 
        net = dev_net(hard_iface->soft_iface);
-       ifindex = dev_get_iflink(netdev);
        real_net = batadv_getlink_net(netdev, net);
-       real_netdev = dev_get_by_index(real_net, ifindex);
+
+       /* iflink to itself, most likely physical device */
+       if (net == real_net && netdev->ifindex == iflink) {
+               real_netdev = netdev;
+               dev_hold(real_netdev);
+               goto out;
+       }
+
+       real_netdev = dev_get_by_index(real_net, iflink);
 
 out:
        batadv_hardif_put(hard_iface);
index 2b7bd3655b076634773fa08065071101c2273819..2882bc7d79d79d6725e7432b8d3787d11e7b099d 100644 (file)
@@ -2738,6 +2738,7 @@ void hci_release_dev(struct hci_dev *hdev)
        hci_dev_unlock(hdev);
 
        ida_simple_remove(&hci_index_ida, hdev->id);
+       kfree_skb(hdev->sent_cmd);
        kfree(hdev);
 }
 EXPORT_SYMBOL(hci_release_dev);
index 0feb68f125456b1ff770d04cdfb9c3de79067417..ab9aa700b6b33c226c499abea500d01a0c52195b 100644 (file)
@@ -276,40 +276,37 @@ EXPORT_SYMBOL(__hci_cmd_sync_status);
 static void hci_cmd_sync_work(struct work_struct *work)
 {
        struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work);
-       struct hci_cmd_sync_work_entry *entry;
-       hci_cmd_sync_work_func_t func;
-       hci_cmd_sync_work_destroy_t destroy;
-       void *data;
 
        bt_dev_dbg(hdev, "");
 
-       mutex_lock(&hdev->cmd_sync_work_lock);
-       entry = list_first_entry(&hdev->cmd_sync_work_list,
-                                struct hci_cmd_sync_work_entry, list);
-       if (entry) {
-               list_del(&entry->list);
-               func = entry->func;
-               data = entry->data;
-               destroy = entry->destroy;
-               kfree(entry);
-       } else {
-               func = NULL;
-               data = NULL;
-               destroy = NULL;
-       }
-       mutex_unlock(&hdev->cmd_sync_work_lock);
+       /* Dequeue all entries and run them */
+       while (1) {
+               struct hci_cmd_sync_work_entry *entry;
 
-       if (func) {
-               int err;
+               mutex_lock(&hdev->cmd_sync_work_lock);
+               entry = list_first_entry_or_null(&hdev->cmd_sync_work_list,
+                                                struct hci_cmd_sync_work_entry,
+                                                list);
+               if (entry)
+                       list_del(&entry->list);
+               mutex_unlock(&hdev->cmd_sync_work_lock);
 
-               hci_req_sync_lock(hdev);
+               if (!entry)
+                       break;
 
-               err = func(hdev, data);
+               bt_dev_dbg(hdev, "entry %p", entry);
 
-               if (destroy)
-                       destroy(hdev, data, err);
+               if (entry->func) {
+                       int err;
 
-               hci_req_sync_unlock(hdev);
+                       hci_req_sync_lock(hdev);
+                       err = entry->func(hdev, entry->data);
+                       if (entry->destroy)
+                               entry->destroy(hdev, entry->data, err);
+                       hci_req_sync_unlock(hdev);
+               }
+
+               kfree(entry);
        }
 }
 
@@ -1841,6 +1838,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
        struct bdaddr_list *b, *t;
        u8 num_entries = 0;
        bool pend_conn, pend_report;
+       u8 filter_policy;
        int err;
 
        /* Pause advertising if resolving list can be used as controllers are
@@ -1927,6 +1925,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
                err = -EINVAL;
 
 done:
+       filter_policy = err ? 0x00 : 0x01;
+
        /* Enable address resolution when LL Privacy is enabled. */
        err = hci_le_set_addr_resolution_enable_sync(hdev, 0x01);
        if (err)
@@ -1937,7 +1937,7 @@ done:
                hci_resume_advertising_sync(hdev);
 
        /* Select filter policy to use accept list */
-       return err ? 0x00 : 0x01;
+       return filter_policy;
 }
 
 /* Returns true if an le connection is in the scanning state */
@@ -3262,10 +3262,10 @@ static int hci_le_set_event_mask_sync(struct hci_dev *hdev)
        if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
                events[0] |= 0x40;      /* LE Data Length Change */
 
-       /* If the controller supports LL Privacy feature, enable
-        * the corresponding event.
+       /* If the controller supports LL Privacy feature or LE Extended Adv,
+        * enable the corresponding event.
         */
-       if (hdev->le_features[0] & HCI_LE_LL_PRIVACY)
+       if (use_enhanced_conn_complete(hdev))
                events[1] |= 0x02;      /* LE Enhanced Connection Complete */
 
        /* If the controller supports Extended Scanner Filter
@@ -4106,9 +4106,9 @@ int hci_dev_close_sync(struct hci_dev *hdev)
        hci_inquiry_cache_flush(hdev);
        hci_pend_le_actions_clear(hdev);
        hci_conn_hash_flush(hdev);
-       hci_dev_unlock(hdev);
-
+       /* Prevent data races on hdev->smp_data or hdev->smp_bredr_data */
        smp_unregister(hdev);
+       hci_dev_unlock(hdev);
 
        hci_sock_dev_event(hdev, HCI_DEV_DOWN);
 
@@ -5185,7 +5185,7 @@ int hci_le_ext_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
        return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_EXT_CREATE_CONN,
                                        plen, data,
                                        HCI_EV_LE_ENHANCED_CONN_COMPLETE,
-                                       HCI_CMD_TIMEOUT, NULL);
+                                       conn->conn_timeout, NULL);
 }
 
 int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
@@ -5270,9 +5270,18 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
        cp.min_ce_len = cpu_to_le16(0x0000);
        cp.max_ce_len = cpu_to_le16(0x0000);
 
+       /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2261:
+        *
+        * If this event is unmasked and the HCI_LE_Connection_Complete event
+        * is unmasked, only the HCI_LE_Enhanced_Connection_Complete event is
+        * sent when a new connection has been created.
+        */
        err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CONN,
-                                      sizeof(cp), &cp, HCI_EV_LE_CONN_COMPLETE,
-                                      HCI_CMD_TIMEOUT, NULL);
+                                      sizeof(cp), &cp,
+                                      use_enhanced_conn_complete(hdev) ?
+                                      HCI_EV_LE_ENHANCED_CONN_COMPLETE :
+                                      HCI_EV_LE_CONN_COMPLETE,
+                                      conn->conn_timeout, NULL);
 
 done:
        /* Re-enable advertising after the connection attempt is finished. */
index 37087cf7dc5aff20fa0ce69242f28cfee8203d8f..230a7a8196c075bdcb04b1e65a34f80502014d38 100644 (file)
@@ -1218,7 +1218,13 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip)
 static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
 {
        struct mgmt_pending_cmd *cmd = data;
-       struct mgmt_mode *cp = cmd->param;
+       struct mgmt_mode *cp;
+
+       /* Make sure cmd still outstanding. */
+       if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
+               return;
+
+       cp = cmd->param;
 
        bt_dev_dbg(hdev, "err %d", err);
 
@@ -1242,7 +1248,7 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
                                mgmt_status(err));
        }
 
-       mgmt_pending_free(cmd);
+       mgmt_pending_remove(cmd);
 }
 
 static int set_powered_sync(struct hci_dev *hdev, void *data)
@@ -1281,7 +1287,7 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
                goto failed;
        }
 
-       cmd = mgmt_pending_new(sk, MGMT_OP_SET_POWERED, hdev, data, len);
+       cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
                goto failed;
@@ -1290,6 +1296,9 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
        err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd,
                                 mgmt_set_powered_complete);
 
+       if (err < 0)
+               mgmt_pending_remove(cmd);
+
 failed:
        hci_dev_unlock(hdev);
        return err;
@@ -1383,6 +1392,10 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
 
        bt_dev_dbg(hdev, "err %d", err);
 
+       /* Make sure cmd still outstanding. */
+       if (cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
+               return;
+
        hci_dev_lock(hdev);
 
        if (err) {
@@ -1402,7 +1415,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
        new_settings(hdev, cmd->sk);
 
 done:
-       mgmt_pending_free(cmd);
+       mgmt_pending_remove(cmd);
        hci_dev_unlock(hdev);
 }
 
@@ -1511,7 +1524,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
                goto failed;
        }
 
-       cmd = mgmt_pending_new(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
+       cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
                goto failed;
@@ -1538,6 +1551,9 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
        err = hci_cmd_sync_queue(hdev, set_discoverable_sync, cmd,
                                 mgmt_set_discoverable_complete);
 
+       if (err < 0)
+               mgmt_pending_remove(cmd);
+
 failed:
        hci_dev_unlock(hdev);
        return err;
@@ -1550,6 +1566,10 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
 
        bt_dev_dbg(hdev, "err %d", err);
 
+       /* Make sure cmd still outstanding. */
+       if (cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
+               return;
+
        hci_dev_lock(hdev);
 
        if (err) {
@@ -1562,7 +1582,9 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
        new_settings(hdev, cmd->sk);
 
 done:
-       mgmt_pending_free(cmd);
+       if (cmd)
+               mgmt_pending_remove(cmd);
+
        hci_dev_unlock(hdev);
 }
 
@@ -1634,7 +1656,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
                goto failed;
        }
 
-       cmd = mgmt_pending_new(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
+       cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
                goto failed;
@@ -1654,6 +1676,9 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
        err = hci_cmd_sync_queue(hdev, set_connectable_sync, cmd,
                                 mgmt_set_connectable_complete);
 
+       if (err < 0)
+               mgmt_pending_remove(cmd);
+
 failed:
        hci_dev_unlock(hdev);
        return err;
@@ -1774,6 +1799,10 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
        u8 enable = cp->val;
        bool changed;
 
+       /* Make sure cmd still outstanding. */
+       if (cmd != pending_find(MGMT_OP_SET_SSP, hdev))
+               return;
+
        if (err) {
                u8 mgmt_err = mgmt_status(err);
 
@@ -3321,6 +3350,9 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
 
        bt_dev_dbg(hdev, "err %d", err);
 
+       if (cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
+               return;
+
        if (status) {
                mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
                                status);
@@ -3493,6 +3525,9 @@ static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
        struct sk_buff *skb = cmd->skb;
        u8 status = mgmt_status(err);
 
+       if (cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
+               return;
+
        if (!status) {
                if (!skb)
                        status = MGMT_STATUS_FAILED;
@@ -3759,13 +3794,6 @@ static int set_wideband_speech(struct sock *sk, struct hci_dev *hdev,
 
        hci_dev_lock(hdev);
 
-       if (pending_find(MGMT_OP_SET_WIDEBAND_SPEECH, hdev)) {
-               err = mgmt_cmd_status(sk, hdev->id,
-                                     MGMT_OP_SET_WIDEBAND_SPEECH,
-                                     MGMT_STATUS_BUSY);
-               goto unlock;
-       }
-
        if (hdev_is_powered(hdev) &&
            !!cp->val != hci_dev_test_flag(hdev,
                                           HCI_WIDEBAND_SPEECH_ENABLED)) {
@@ -4513,9 +4541,9 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
                }
        }
 
-done:
        hci_dev_unlock(hdev);
 
+done:
        if (status == MGMT_STATUS_SUCCESS)
                device_flags_changed(sk, hdev, &cp->addr.bdaddr, cp->addr.type,
                                     supported_flags, current_flags);
@@ -5036,12 +5064,6 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
                goto unlock;
        }
 
-       if (pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
-               err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
-                                     MGMT_STATUS_BUSY);
-               goto unlock;
-       }
-
        cmd = mgmt_pending_new(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
        if (!cmd)
                err = -ENOMEM;
@@ -5261,11 +5283,16 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
 {
        struct mgmt_pending_cmd *cmd = data;
 
+       if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
+           cmd != pending_find(MGMT_OP_START_LIMITED_DISCOVERY, hdev) &&
+           cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
+               return;
+
        bt_dev_dbg(hdev, "err %d", err);
 
        mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
                          cmd->param, 1);
-       mgmt_pending_free(cmd);
+       mgmt_pending_remove(cmd);
 
        hci_discovery_set_state(hdev, err ? DISCOVERY_STOPPED:
                                DISCOVERY_FINDING);
@@ -5327,7 +5354,7 @@ static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev,
        else
                hdev->discovery.limited = false;
 
-       cmd = mgmt_pending_new(sk, op, hdev, data, len);
+       cmd = mgmt_pending_add(sk, op, hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
                goto failed;
@@ -5336,7 +5363,7 @@ static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev,
        err = hci_cmd_sync_queue(hdev, start_discovery_sync, cmd,
                                 start_discovery_complete);
        if (err < 0) {
-               mgmt_pending_free(cmd);
+               mgmt_pending_remove(cmd);
                goto failed;
        }
 
@@ -5430,7 +5457,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
                goto failed;
        }
 
-       cmd = mgmt_pending_new(sk, MGMT_OP_START_SERVICE_DISCOVERY,
+       cmd = mgmt_pending_add(sk, MGMT_OP_START_SERVICE_DISCOVERY,
                               hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
@@ -5463,7 +5490,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
        err = hci_cmd_sync_queue(hdev, start_discovery_sync, cmd,
                                 start_discovery_complete);
        if (err < 0) {
-               mgmt_pending_free(cmd);
+               mgmt_pending_remove(cmd);
                goto failed;
        }
 
@@ -5495,11 +5522,14 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
 {
        struct mgmt_pending_cmd *cmd = data;
 
+       if (cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
+               return;
+
        bt_dev_dbg(hdev, "err %d", err);
 
        mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
                          cmd->param, 1);
-       mgmt_pending_free(cmd);
+       mgmt_pending_remove(cmd);
 
        if (!err)
                hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
@@ -5535,7 +5565,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
-       cmd = mgmt_pending_new(sk, MGMT_OP_STOP_DISCOVERY, hdev, data, len);
+       cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
                goto unlock;
@@ -5544,7 +5574,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
        err = hci_cmd_sync_queue(hdev, stop_discovery_sync, cmd,
                                 stop_discovery_complete);
        if (err < 0) {
-               mgmt_pending_free(cmd);
+               mgmt_pending_remove(cmd);
                goto unlock;
        }
 
@@ -7474,6 +7504,9 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
        u8 status = mgmt_status(err);
        u16 eir_len;
 
+       if (cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
+               return;
+
        if (!status) {
                if (!skb)
                        status = MGMT_STATUS_FAILED;
@@ -7969,11 +8002,7 @@ static bool requested_adv_flags_are_valid(struct hci_dev *hdev, u32 adv_flags)
 
 static bool adv_busy(struct hci_dev *hdev)
 {
-       return (pending_find(MGMT_OP_ADD_ADVERTISING, hdev) ||
-               pending_find(MGMT_OP_REMOVE_ADVERTISING, hdev) ||
-               pending_find(MGMT_OP_SET_LE, hdev) ||
-               pending_find(MGMT_OP_ADD_EXT_ADV_PARAMS, hdev) ||
-               pending_find(MGMT_OP_ADD_EXT_ADV_DATA, hdev));
+       return pending_find(MGMT_OP_SET_LE, hdev);
 }
 
 static void add_adv_complete(struct hci_dev *hdev, struct sock *sk, u8 instance,
@@ -8563,9 +8592,7 @@ static int remove_advertising(struct sock *sk, struct hci_dev *hdev,
                goto unlock;
        }
 
-       if (pending_find(MGMT_OP_ADD_ADVERTISING, hdev) ||
-           pending_find(MGMT_OP_REMOVE_ADVERTISING, hdev) ||
-           pending_find(MGMT_OP_SET_LE, hdev)) {
+       if (pending_find(MGMT_OP_SET_LE, hdev)) {
                err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADVERTISING,
                                      MGMT_STATUS_BUSY);
                goto unlock;
index edee60bbc7b46dd189e7b83297d627432fcc280d..37eef2ce55aec45e7c097cc81a4a9e80f4925fd6 100644 (file)
@@ -77,11 +77,12 @@ int mgmt_send_event_skb(unsigned short channel, struct sk_buff *skb, int flag,
 {
        struct hci_dev *hdev;
        struct mgmt_hdr *hdr;
-       int len = skb->len;
+       int len;
 
        if (!skb)
                return -EINVAL;
 
+       len = skb->len;
        hdev = bt_cb(skb)->mgmt.hdev;
 
        /* Time stamp */
index a271688780a2c1a3bff6c2578502f972da34a30b..307ee1174a6e2e3d8cb9edd2c7485ddd22014ce6 100644 (file)
@@ -2006,7 +2006,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
                /* set the end-packet for broadcast */
                session->pkt.last = session->pkt.total;
 
-       skcb->tskey = session->sk->sk_tskey++;
+       skcb->tskey = atomic_inc_return(&session->sk->sk_tskey) - 1;
        session->tskey = skcb->tskey;
 
        return session;
index 4603b7cd3cd17e5f39d9d0e047529d07af98bc25..9eb785842258ab8cc1b46b11f1e0551d81010041 100644 (file)
@@ -2710,6 +2710,9 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
        if (unlikely(flags))
                return -EINVAL;
 
+       if (unlikely(len == 0))
+               return 0;
+
        /* First find the starting scatterlist element */
        i = msg->sg.start;
        do {
index a11b286d149593827f1990fb8d06b0295fa72189..b7d2b0dc59a288a34204b23ee313dbd1e7c635c7 100644 (file)
@@ -92,6 +92,31 @@ void dev_remove_offload(struct packet_offload *po)
 }
 EXPORT_SYMBOL(dev_remove_offload);
 
+/**
+ *     skb_eth_gso_segment - segmentation handler for ethernet protocols.
+ *     @skb: buffer to segment
+ *     @features: features for the output path (see dev->features)
+ *     @type: Ethernet Protocol ID
+ */
+struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
+                                   netdev_features_t features, __be16 type)
+{
+       struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
+       struct packet_offload *ptype;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(ptype, &offload_base, list) {
+               if (ptype->type == type && ptype->callbacks.gso_segment) {
+                       segs = ptype->callbacks.gso_segment(skb, features);
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+       return segs;
+}
+EXPORT_SYMBOL(skb_eth_gso_segment);
+
 /**
  *     skb_mac_gso_segment - mac layer segmentation handler.
  *     @skb: buffer to segment
index 53ea262ecafd0c1e537a7e63f313745fb7ba53bb..fbddf966206b61573b94f0f0e433249570a9cba5 100644 (file)
@@ -213,7 +213,7 @@ static ssize_t speed_show(struct device *dev,
        if (!rtnl_trylock())
                return restart_syscall();
 
-       if (netif_running(netdev)) {
+       if (netif_running(netdev) && netif_device_present(netdev)) {
                struct ethtool_link_ksettings cmd;
 
                if (!__ethtool_get_link_ksettings(netdev, &cmd))
index 9d0388bed0c1d2166214c95081f4778afe9f50ed..ea51e23e9247eff1d4ffabd069541c36e3c3f503 100644 (file)
@@ -2276,7 +2276,7 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta)
                /* Free pulled out fragments. */
                while ((list = skb_shinfo(skb)->frag_list) != insp) {
                        skb_shinfo(skb)->frag_list = list->next;
-                       kfree_skb(list);
+                       consume_skb(list);
                }
                /* And insert new clone at head. */
                if (clone) {
@@ -3876,6 +3876,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
                list_skb = list_skb->next;
 
                err = 0;
+               delta_truesize += nskb->truesize;
                if (skb_shared(nskb)) {
                        tmp = skb_clone(nskb, GFP_ATOMIC);
                        if (tmp) {
@@ -3900,7 +3901,6 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
                tail = nskb;
 
                delta_len += nskb->len;
-               delta_truesize += nskb->truesize;
 
                skb_push(nskb, -skb_network_offset(nskb) + offset);
 
@@ -4730,7 +4730,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
        if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
                serr->ee.ee_data = skb_shinfo(skb)->tskey;
                if (sk_is_tcp(sk))
-                       serr->ee.ee_data -= sk->sk_tskey;
+                       serr->ee.ee_data -= atomic_read(&sk->sk_tskey);
        }
 
        err = sock_queue_err_skb(sk, skb);
@@ -6105,7 +6105,7 @@ static int pskb_carve_frag_list(struct sk_buff *skb,
        /* Free pulled out fragments. */
        while ((list = shinfo->frag_list) != insp) {
                shinfo->frag_list = list->next;
-               kfree_skb(list);
+               consume_skb(list);
        }
        /* And insert new clone at head. */
        if (clone) {
index 8eb671c827f90f1f3d2514163fc82998c9906cb6..929a2b096b04e01b85bff0a69209413abe86102d 100644 (file)
@@ -1153,7 +1153,7 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb,
        struct sk_psock *psock;
        struct bpf_prog *prog;
        int ret = __SK_DROP;
-       int len = skb->len;
+       int len = orig_len;
 
        /* clone here so sk_eat_skb() in tcp_read_sock does not drop our data */
        skb = skb_clone(skb, GFP_ATOMIC);
index 4ff806d71921618e2dbf7d5bb041040cbc72b674..6eb174805bf022f2e143c52b68aec3684a8d0956 100644 (file)
@@ -879,9 +879,9 @@ int sock_set_timestamping(struct sock *sk, int optname,
                        if ((1 << sk->sk_state) &
                            (TCPF_CLOSE | TCPF_LISTEN))
                                return -EINVAL;
-                       sk->sk_tskey = tcp_sk(sk)->snd_una;
+                       atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una);
                } else {
-                       sk->sk_tskey = 0;
+                       atomic_set(&sk->sk_tskey, 0);
                }
        }
 
index 7aba355049862d79e1a31d2990b76fe1c1ca318f..73fae16264e10b90c5c6bf0adbb8f0e86a3c357c 100644 (file)
@@ -357,7 +357,8 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq,
        if (IS_ERR(xdp_alloc))
                return PTR_ERR(xdp_alloc);
 
-       trace_mem_connect(xdp_alloc, xdp_rxq);
+       if (trace_mem_connect_enabled() && xdp_alloc)
+               trace_mem_connect(xdp_alloc, xdp_rxq);
        return 0;
 }
 
index b441ab330fd349246083d8fd7c3f95602fc46a4a..dc4fb699b56c3adc3340e336c9924472374d0d0a 100644 (file)
@@ -2073,8 +2073,52 @@ u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev)
 }
 EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask);
 
+static void dcbnl_flush_dev(struct net_device *dev)
+{
+       struct dcb_app_type *itr, *tmp;
+
+       spin_lock_bh(&dcb_lock);
+
+       list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) {
+               if (itr->ifindex == dev->ifindex) {
+                       list_del(&itr->list);
+                       kfree(itr);
+               }
+       }
+
+       spin_unlock_bh(&dcb_lock);
+}
+
+static int dcbnl_netdevice_event(struct notifier_block *nb,
+                                unsigned long event, void *ptr)
+{
+       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+
+       switch (event) {
+       case NETDEV_UNREGISTER:
+               if (!dev->dcbnl_ops)
+                       return NOTIFY_DONE;
+
+               dcbnl_flush_dev(dev);
+
+               return NOTIFY_OK;
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
+static struct notifier_block dcbnl_nb __read_mostly = {
+       .notifier_call  = dcbnl_netdevice_event,
+};
+
 static int __init dcbnl_init(void)
 {
+       int err;
+
+       err = register_netdevice_notifier(&dcbnl_nb);
+       if (err)
+               return err;
+
        rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0);
        rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0);
 
index dcad3100b164637fd581d70ba20e4b31ae6e8a6b..88e2808019b477c140cdfea62e5bf949e5528c7d 100644 (file)
@@ -1058,7 +1058,7 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
 static int dsa_tree_setup_master(struct dsa_switch_tree *dst)
 {
        struct dsa_port *dp;
-       int err;
+       int err = 0;
 
        rtnl_lock();
 
@@ -1066,13 +1066,13 @@ static int dsa_tree_setup_master(struct dsa_switch_tree *dst)
                if (dsa_port_is_cpu(dp)) {
                        err = dsa_master_setup(dp->master, dp);
                        if (err)
-                               return err;
+                               break;
                }
        }
 
        rtnl_unlock();
 
-       return 0;
+       return err;
 }
 
 static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
@@ -1261,7 +1261,7 @@ int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,
        info.tag_ops = tag_ops;
        err = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, &info);
        if (err)
-               return err;
+               goto out_unwind_tagger;
 
        err = dsa_tree_bind_tag_proto(dst, tag_ops);
        if (err)
@@ -1436,6 +1436,7 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
                const char *user_protocol;
 
                master = of_find_net_device_by_node(ethernet);
+               of_node_put(ethernet);
                if (!master)
                        return -EPROBE_DEFER;
 
index 2199104ca7dfa15f943b24bb3dd52c4e181d33eb..880f910b23a99504b12a30d6d1f6ea0f11b51e0b 100644 (file)
@@ -260,11 +260,16 @@ static void dsa_netdev_ops_set(struct net_device *dev,
        dev->dsa_ptr->netdev_ops = ops;
 }
 
+/* Keep the master always promiscuous if the tagging protocol requires that
+ * (garbles MAC DA) or if it doesn't support unicast filtering, case in which
+ * it would revert to promiscuous mode as soon as we call dev_uc_add() on it
+ * anyway.
+ */
 static void dsa_master_set_promiscuity(struct net_device *dev, int inc)
 {
        const struct dsa_device_ops *ops = dev->dsa_ptr->tag_ops;
 
-       if (!ops->promisc_on_master)
+       if ((dev->priv_flags & IFF_UNICAST_FLT) && !ops->promisc_on_master)
                return;
 
        ASSERT_RTNL();
index bd78192e0e47d6b7ff3cccc9038556e8976a714a..1a40c52f5a42dc072960905135f83cf654f120ee 100644 (file)
@@ -395,10 +395,17 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
                .tree_index = dp->ds->dst->index,
                .sw_index = dp->ds->index,
                .port = dp->index,
-               .bridge = *dp->bridge,
        };
        int err;
 
+       /* If the port could not be offloaded to begin with, then
+        * there is nothing to do.
+        */
+       if (!dp->bridge)
+               return;
+
+       info.bridge = *dp->bridge;
+
        /* Here the port is already unbridged. Reflect the current configuration
         * so that drivers can program their chips accordingly.
         */
@@ -781,9 +788,15 @@ int dsa_port_host_fdb_add(struct dsa_port *dp, const unsigned char *addr,
        struct dsa_port *cpu_dp = dp->cpu_dp;
        int err;
 
-       err = dev_uc_add(cpu_dp->master, addr);
-       if (err)
-               return err;
+       /* Avoid a call to __dev_set_promiscuity() on the master, which
+        * requires rtnl_lock(), since we can't guarantee that is held here,
+        * and we can't take it either.
+        */
+       if (cpu_dp->master->priv_flags & IFF_UNICAST_FLT) {
+               err = dev_uc_add(cpu_dp->master, addr);
+               if (err)
+                       return err;
+       }
 
        return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info);
 }
@@ -800,9 +813,11 @@ int dsa_port_host_fdb_del(struct dsa_port *dp, const unsigned char *addr,
        struct dsa_port *cpu_dp = dp->cpu_dp;
        int err;
 
-       err = dev_uc_del(cpu_dp->master, addr);
-       if (err)
-               return err;
+       if (cpu_dp->master->priv_flags & IFF_UNICAST_FLT) {
+               err = dev_uc_del(cpu_dp->master, addr);
+               if (err)
+                       return err;
+       }
 
        return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_DEL, &info);
 }
index 9c465bac1eb0e4e43c5fdc749e27751c34206f73..72fde2888ad2fc2eaa48e87f7db3ca2c9a67f459 100644 (file)
@@ -1376,8 +1376,11 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
        }
 
        ops = rcu_dereference(inet_offloads[proto]);
-       if (likely(ops && ops->callbacks.gso_segment))
+       if (likely(ops && ops->callbacks.gso_segment)) {
                segs = ops->callbacks.gso_segment(skb, features);
+               if (!segs)
+                       skb->network_header = skb_mac_header(skb) + nhoff - skb->head;
+       }
 
        if (IS_ERR_OR_NULL(segs))
                goto out;
index 851f542928a33bfed77f50ba1fc2185f2eefa187..70e6c87fbe3df15c5ca6adc68b685e3a2afa21a4 100644 (file)
@@ -446,6 +446,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
        struct page *page;
        struct sk_buff *trailer;
        int tailen = esp->tailen;
+       unsigned int allocsz;
 
        /* this is non-NULL only with TCP/UDP Encapsulation */
        if (x->encap) {
@@ -455,6 +456,10 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
                        return err;
        }
 
+       allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
+       if (allocsz > ESP_SKB_FRAG_MAXSIZE)
+               goto cow;
+
        if (!skb_cloned(skb)) {
                if (tailen <= skb_tailroom(skb)) {
                        nfrags = 1;
@@ -671,7 +676,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
                struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
                u32 padto;
 
-               padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
+               padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
                if (skb->len < padto)
                        esp.tfclen = padto - skb->len;
        }
index d87f02a6e9346ad0dddcd1177664079140c468d8..935026f4c807e5f02129dd31190617b3e066ff1d 100644 (file)
@@ -110,8 +110,7 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
                                                struct sk_buff *skb,
                                                netdev_features_t features)
 {
-       __skb_push(skb, skb->mac_len);
-       return skb_mac_gso_segment(skb, features);
+       return skb_eth_gso_segment(skb, features, htons(ETH_P_IP));
 }
 
 static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
@@ -160,6 +159,9 @@ static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x,
                        skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
        }
 
+       if (proto == IPPROTO_IPV6)
+               skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP4;
+
        __skb_pull(skb, skb_transport_offset(skb));
        ops = rcu_dereference(inet_offloads[proto]);
        if (likely(ops && ops->callbacks.gso_segment))
index 139cec29ed06cd092ebdfd2bf0d13aaf67c5359d..7911916a480bd9a8ef0e17414a6dcf6def6475dd 100644 (file)
@@ -991,7 +991,7 @@ static int __ip_append_data(struct sock *sk,
 
        if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
            sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
-               tskey = sk->sk_tskey++;
+               tskey = atomic_inc_return(&sk->sk_tskey) - 1;
 
        hh_len = LL_RESERVED_SPACE(rt->dst.dev);
 
index 3a5994b50571f099f3db25039faa98b1bfda8fa4..3ee947557b88358e31afce995b3f157b0c41c0f8 100644 (file)
@@ -187,7 +187,6 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
                         (int)ident, &ipv6_hdr(skb)->daddr, dif);
 #endif
        } else {
-               pr_err("ping: protocol(%x) is not supported\n", ntohs(skb->protocol));
                return NULL;
        }
 
index 02cb275e5487d98b3e124ee102163aac47b2ad6d..28ff2a820f7c935234e5ab7ecd4ed95fb7c5712a 100644 (file)
@@ -1684,11 +1684,13 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
                                if (!copied)
                                        copied = used;
                                break;
-                       } else if (used <= len) {
-                               seq += used;
-                               copied += used;
-                               offset += used;
                        }
+                       if (WARN_ON_ONCE(used > len))
+                               used = len;
+                       seq += used;
+                       copied += used;
+                       offset += used;
+
                        /* If recv_actor drops the lock (e.g. TCP splice
                         * receive) the skb pointer might be invalid when
                         * getting here: tcp_collapse might have deleted it
index b91003538d87a03855df9bd35b751017d37fe031..bc3a043a5d5c7635b7acabe76bb19f7ad59d8db9 100644 (file)
@@ -846,7 +846,7 @@ udp_tunnel_nic_unregister(struct net_device *dev, struct udp_tunnel_nic *utn)
                list_for_each_entry(node, &info->shared->devices, list)
                        if (node->dev == dev)
                                break;
-               if (node->dev != dev)
+               if (list_entry_is_head(node, &info->shared->devices, list))
                        return;
 
                list_del(&node->list);
index 3f23da8c0b10297b955d1953b54ed8027b0434d1..f908e2fd30b24b948061bc7bfabf9c02f35a7233 100644 (file)
@@ -3732,6 +3732,7 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister)
        struct inet6_dev *idev;
        struct inet6_ifaddr *ifa, *tmp;
        bool keep_addr = false;
+       bool was_ready;
        int state, i;
 
        ASSERT_RTNL();
@@ -3797,7 +3798,10 @@ restart:
 
        addrconf_del_rs_timer(idev);
 
-       /* Step 2: clear flags for stateless addrconf */
+       /* Step 2: clear flags for stateless addrconf, repeated down
+        *         detection
+        */
+       was_ready = idev->if_flags & IF_READY;
        if (!unregister)
                idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
 
@@ -3871,7 +3875,7 @@ restart:
        if (unregister) {
                ipv6_ac_destroy_dev(idev);
                ipv6_mc_destroy_dev(idev);
-       } else {
+       } else if (was_ready) {
                ipv6_mc_down(idev);
        }
 
@@ -4998,6 +5002,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
            nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
                goto error;
 
+       spin_lock_bh(&ifa->lock);
        if (!((ifa->flags&IFA_F_PERMANENT) &&
              (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
                preferred = ifa->prefered_lft;
@@ -5019,6 +5024,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
                preferred = INFINITY_LIFE_TIME;
                valid = INFINITY_LIFE_TIME;
        }
+       spin_unlock_bh(&ifa->lock);
 
        if (!ipv6_addr_any(&ifa->peer_addr)) {
                if (nla_put_in6_addr(skb, IFA_LOCAL, &ifa->addr) < 0 ||
index 8bb2c407b46b3f6dec99ddb9ccc3f21a0255323a..55d604c9b3b3ea9898fa660cd46da14cb849d5f8 100644 (file)
@@ -482,6 +482,7 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
        struct page *page;
        struct sk_buff *trailer;
        int tailen = esp->tailen;
+       unsigned int allocsz;
 
        if (x->encap) {
                int err = esp6_output_encap(x, skb, esp);
@@ -490,6 +491,10 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
                        return err;
        }
 
+       allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
+       if (allocsz > ESP_SKB_FRAG_MAXSIZE)
+               goto cow;
+
        if (!skb_cloned(skb)) {
                if (tailen <= skb_tailroom(skb)) {
                        nfrags = 1;
@@ -707,7 +712,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
                struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
                u32 padto;
 
-               padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
+               padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
                if (skb->len < padto)
                        esp.tfclen = padto - skb->len;
        }
@@ -807,8 +812,7 @@ int esp6_input_done2(struct sk_buff *skb, int err)
                struct tcphdr *th;
 
                offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
-
-               if (offset < 0) {
+               if (offset == -1) {
                        err = -EINVAL;
                        goto out;
                }
index ba5e81cd569c8a0128d00c0e6e4eb0dadabb246d..3a293838a91db4846aee08260ca1ec1e290972e7 100644 (file)
@@ -145,8 +145,7 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
                                                struct sk_buff *skb,
                                                netdev_features_t features)
 {
-       __skb_push(skb, skb->mac_len);
-       return skb_mac_gso_segment(skb, features);
+       return skb_eth_gso_segment(skb, features, htons(ETH_P_IPV6));
 }
 
 static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
@@ -199,6 +198,9 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x,
                        ipv6_skip_exthdr(skb, 0, &proto, &frag);
        }
 
+       if (proto == IPPROTO_IPIP)
+               skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP6;
+
        __skb_pull(skb, skb_transport_offset(skb));
        ops = rcu_dereference(inet6_offloads[proto]);
        if (likely(ops && ops->callbacks.gso_segment))
index b29e9ba5e1136a8f34c1dbf636052c5d5b5cc5fb..5f577e21459b7e2302f43b282e0ffdb3e742f3a4 100644 (file)
@@ -114,6 +114,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
        if (likely(ops && ops->callbacks.gso_segment)) {
                skb_reset_transport_header(skb);
                segs = ops->callbacks.gso_segment(skb, features);
+               if (!segs)
+                       skb->network_header = skb_mac_header(skb) + nhoff - skb->head;
        }
 
        if (IS_ERR_OR_NULL(segs))
index 2995f8d89e7e923203be2dfe8674be4ab424d323..194832663d856a771fa52a0d6d09dffb7ff7cff6 100644 (file)
@@ -1408,8 +1408,6 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
                if (np->frag_size)
                        mtu = np->frag_size;
        }
-       if (mtu < IPV6_MIN_MTU)
-               return -EINVAL;
        cork->base.fragsize = mtu;
        cork->base.gso_size = ipc6->gso_size;
        cork->base.tx_flags = 0;
@@ -1465,14 +1463,12 @@ static int __ip6_append_data(struct sock *sk,
 
        if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
            sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
-               tskey = sk->sk_tskey++;
+               tskey = atomic_inc_return(&sk->sk_tskey) - 1;
 
        hh_len = LL_RESERVED_SPACE(rt->dst.dev);
 
        fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
                        (opt ? opt->opt_nflen : 0);
-       maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
-                    sizeof(struct frag_hdr);
 
        headersize = sizeof(struct ipv6hdr) +
                     (opt ? opt->opt_flen + opt->opt_nflen : 0) +
@@ -1480,6 +1476,13 @@ static int __ip6_append_data(struct sock *sk,
                      sizeof(struct frag_hdr) : 0) +
                     rt->rt6i_nfheader_len;
 
+       if (mtu <= fragheaderlen ||
+           ((mtu - fragheaderlen) & ~7) + fragheaderlen <= sizeof(struct frag_hdr))
+               goto emsgsize;
+
+       maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
+                    sizeof(struct frag_hdr);
+
        /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
         * the first fragment
         */
index a8861db52c1877e8bb94a0eee9154af7340d1ba1..909f937befd71fce194517d44cb9a4c5e2876360 100644 (file)
@@ -1371,27 +1371,23 @@ static void mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld,
 }
 
 /* called with rcu_read_lock() */
-int igmp6_event_query(struct sk_buff *skb)
+void igmp6_event_query(struct sk_buff *skb)
 {
        struct inet6_dev *idev = __in6_dev_get(skb->dev);
 
-       if (!idev)
-               return -EINVAL;
-
-       if (idev->dead) {
-               kfree_skb(skb);
-               return -ENODEV;
-       }
+       if (!idev || idev->dead)
+               goto out;
 
        spin_lock_bh(&idev->mc_query_lock);
        if (skb_queue_len(&idev->mc_query_queue) < MLD_MAX_SKBS) {
                __skb_queue_tail(&idev->mc_query_queue, skb);
                if (!mod_delayed_work(mld_wq, &idev->mc_query_work, 0))
                        in6_dev_hold(idev);
+               skb = NULL;
        }
        spin_unlock_bh(&idev->mc_query_lock);
-
-       return 0;
+out:
+       kfree_skb(skb);
 }
 
 static void __mld_query_work(struct sk_buff *skb)
@@ -1542,27 +1538,23 @@ static void mld_query_work(struct work_struct *work)
 }
 
 /* called with rcu_read_lock() */
-int igmp6_event_report(struct sk_buff *skb)
+void igmp6_event_report(struct sk_buff *skb)
 {
        struct inet6_dev *idev = __in6_dev_get(skb->dev);
 
-       if (!idev)
-               return -EINVAL;
-
-       if (idev->dead) {
-               kfree_skb(skb);
-               return -ENODEV;
-       }
+       if (!idev || idev->dead)
+               goto out;
 
        spin_lock_bh(&idev->mc_report_lock);
        if (skb_queue_len(&idev->mc_report_queue) < MLD_MAX_SKBS) {
                __skb_queue_tail(&idev->mc_report_queue, skb);
                if (!mod_delayed_work(mld_wq, &idev->mc_report_work, 0))
                        in6_dev_hold(idev);
+               skb = NULL;
        }
        spin_unlock_bh(&idev->mc_report_lock);
-
-       return 0;
+out:
+       kfree_skb(skb);
 }
 
 static void __mld_report_work(struct sk_buff *skb)
index d0d280077721b89067115d5bbd6cd05b558c8047..ad07904642cad1c0e0a91c5fcfcc46614807d907 100644 (file)
@@ -45,6 +45,19 @@ static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buf
        return xfrm_output(sk, skb);
 }
 
+static int xfrm6_noneed_fragment(struct sk_buff *skb)
+{
+       struct frag_hdr *fh;
+       u8 prevhdr = ipv6_hdr(skb)->nexthdr;
+
+       if (prevhdr != NEXTHDR_FRAGMENT)
+               return 0;
+       fh = (struct frag_hdr *)(skb->data + sizeof(struct ipv6hdr));
+       if (fh->nexthdr == NEXTHDR_ESP || fh->nexthdr == NEXTHDR_AUTH)
+               return 1;
+       return 0;
+}
+
 static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
@@ -73,6 +86,9 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
                xfrm6_local_rxpmtu(skb, mtu);
                kfree_skb(skb);
                return -EMSGSIZE;
+       } else if (toobig && xfrm6_noneed_fragment(skb)) {
+               skb->ignore_df = 1;
+               goto skip_frag;
        } else if (!skb->ignore_df && toobig && skb->sk) {
                xfrm_local_error(skb, mtu);
                kfree_skb(skb);
index de24a7d474dfd643a54e70631a33a2b07f17afd9..fd51db3be91c4064b3f7b5a6f8297e2a9c0843de 100644 (file)
@@ -1699,7 +1699,7 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad
 
        xfrm_probe_algs();
 
-       supp_skb = compose_sadb_supported(hdr, GFP_KERNEL);
+       supp_skb = compose_sadb_supported(hdr, GFP_KERNEL | __GFP_ZERO);
        if (!supp_skb) {
                if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC)
                        pfk->registered &= ~(1<<hdr->sadb_msg_satype);
@@ -2623,7 +2623,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
        }
 
        return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
-                           kma ? &k : NULL, net, NULL);
+                           kma ? &k : NULL, net, NULL, 0);
 
  out:
        return err;
index 74a878f213d3ef352d0d934f288664ed3a1a263f..1deb3d874a4b9f186127685f9e6663c7a41c2dc1 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
  * Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2021 Intel Corporation
+ * Copyright (C) 2018 - 2022 Intel Corporation
  */
 
 #include <linux/ieee80211.h>
@@ -626,6 +626,14 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
                return -EINVAL;
        }
 
+       if (test_sta_flag(sta, WLAN_STA_MFP) &&
+           !test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
+               ht_dbg(sdata,
+                      "MFP STA not authorized - deny BA session request %pM tid %d\n",
+                      sta->sta.addr, tid);
+               return -EINVAL;
+       }
+
        /*
         * 802.11n-2009 11.5.1.1: If the initiating STA is an HT STA, is a
         * member of an IBSS, and has no other existing Block Ack agreement
index 330ea62231faa215408921ea45042c94955c3a49..e87bccaab561f449e0bc9770a6ba307a4aa94ca6 100644 (file)
@@ -376,7 +376,7 @@ struct ieee80211_mgd_auth_data {
 
        u8 key[WLAN_KEY_LEN_WEP104];
        u8 key_len, key_idx;
-       bool done;
+       bool done, waiting;
        bool peer_confirmed;
        bool timeout_started;
 
index e5ccf17618ab2f9f6c6a6c1dc6d10bc58445153c..744842c4513b1f6d488b3eb5ac728e76c774ff80 100644 (file)
@@ -37,6 +37,7 @@
 #define IEEE80211_AUTH_TIMEOUT_SAE     (HZ * 2)
 #define IEEE80211_AUTH_MAX_TRIES       3
 #define IEEE80211_AUTH_WAIT_ASSOC      (HZ * 5)
+#define IEEE80211_AUTH_WAIT_SAE_RETRY  (HZ * 2)
 #define IEEE80211_ASSOC_TIMEOUT                (HZ / 5)
 #define IEEE80211_ASSOC_TIMEOUT_LONG   (HZ / 2)
 #define IEEE80211_ASSOC_TIMEOUT_SHORT  (HZ / 10)
@@ -3011,8 +3012,15 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
                    (status_code == WLAN_STATUS_ANTI_CLOG_REQUIRED ||
                     (auth_transaction == 1 &&
                      (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
-                      status_code == WLAN_STATUS_SAE_PK))))
+                      status_code == WLAN_STATUS_SAE_PK)))) {
+                       /* waiting for userspace now */
+                       ifmgd->auth_data->waiting = true;
+                       ifmgd->auth_data->timeout =
+                               jiffies + IEEE80211_AUTH_WAIT_SAE_RETRY;
+                       ifmgd->auth_data->timeout_started = true;
+                       run_again(sdata, ifmgd->auth_data->timeout);
                        goto notify_driver;
+               }
 
                sdata_info(sdata, "%pM denied authentication (status %d)\n",
                           mgmt->sa, status_code);
@@ -4603,10 +4611,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 
        if (ifmgd->auth_data && ifmgd->auth_data->timeout_started &&
            time_after(jiffies, ifmgd->auth_data->timeout)) {
-               if (ifmgd->auth_data->done) {
+               if (ifmgd->auth_data->done || ifmgd->auth_data->waiting) {
                        /*
-                        * ok ... we waited for assoc but userspace didn't,
-                        * so let's just kill the auth data
+                        * ok ... we waited for assoc or continuation but
+                        * userspace didn't do it, so kill the auth data
                         */
                        ieee80211_destroy_auth_data(sdata, false);
                } else if (ieee80211_auth(sdata)) {
index 93680af62c47da15317c12cb00ccb4e407362029..48d9553dafe37d6d9eb33aed7008a23793d6c9e2 100644 (file)
@@ -2607,7 +2607,8 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
                 * address, so that the authenticator (e.g. hostapd) will see
                 * the frame, but bridge won't forward it anywhere else. Note
                 * that due to earlier filtering, the only other address can
-                * be the PAE group address.
+                * be the PAE group address, unless the hardware allowed them
+                * through in 802.3 offloaded mode.
                 */
                if (unlikely(skb->protocol == sdata->control_port_protocol &&
                             !ether_addr_equal(ehdr->h_dest, sdata->vif.addr)))
@@ -2922,13 +2923,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
            ether_addr_equal(sdata->vif.addr, hdr->addr3))
                return RX_CONTINUE;
 
-       ac = ieee80211_select_queue_80211(sdata, skb, hdr);
+       ac = ieee802_1d_to_ac[skb->priority];
        q = sdata->vif.hw_queue[ac];
        if (ieee80211_queue_stopped(&local->hw, q)) {
                IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
                return RX_DROP_MONITOR;
        }
-       skb_set_queue_mapping(skb, q);
+       skb_set_queue_mapping(skb, ac);
 
        if (!--mesh_hdr->ttl) {
                if (!is_multicast_ether_addr(hdr->addr1))
@@ -4514,12 +4515,7 @@ static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
 
        /* deliver to local stack */
        skb->protocol = eth_type_trans(skb, fast_rx->dev);
-       memset(skb->cb, 0, sizeof(skb->cb));
-       if (rx->list)
-               list_add_tail(&skb->list, rx->list);
-       else
-               netif_receive_skb(skb);
-
+       ieee80211_deliver_skb_to_local_stack(skb, rx);
 }
 
 static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
index 3240b72271a7f3724577907bc99bdfe41a97f9de..7558802a14350a6a4cf59a0e22611ab54ec3eae1 100644 (file)
@@ -35,12 +35,14 @@ static const struct snmp_mib mptcp_snmp_list[] = {
        SNMP_MIB_ITEM("AddAddr", MPTCP_MIB_ADDADDR),
        SNMP_MIB_ITEM("EchoAdd", MPTCP_MIB_ECHOADD),
        SNMP_MIB_ITEM("PortAdd", MPTCP_MIB_PORTADD),
+       SNMP_MIB_ITEM("AddAddrDrop", MPTCP_MIB_ADDADDRDROP),
        SNMP_MIB_ITEM("MPJoinPortSynRx", MPTCP_MIB_JOINPORTSYNRX),
        SNMP_MIB_ITEM("MPJoinPortSynAckRx", MPTCP_MIB_JOINPORTSYNACKRX),
        SNMP_MIB_ITEM("MPJoinPortAckRx", MPTCP_MIB_JOINPORTACKRX),
        SNMP_MIB_ITEM("MismatchPortSynRx", MPTCP_MIB_MISMATCHPORTSYNRX),
        SNMP_MIB_ITEM("MismatchPortAckRx", MPTCP_MIB_MISMATCHPORTACKRX),
        SNMP_MIB_ITEM("RmAddr", MPTCP_MIB_RMADDR),
+       SNMP_MIB_ITEM("RmAddrDrop", MPTCP_MIB_RMADDRDROP),
        SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW),
        SNMP_MIB_ITEM("MPPrioTx", MPTCP_MIB_MPPRIOTX),
        SNMP_MIB_ITEM("MPPrioRx", MPTCP_MIB_MPPRIORX),
index ecd3d8b117e0befe93c898803e240d68d0485014..2966fcb6548bac6ba539183c428ec16e9b77a896 100644 (file)
@@ -28,12 +28,14 @@ enum linux_mptcp_mib_field {
        MPTCP_MIB_ADDADDR,              /* Received ADD_ADDR with echo-flag=0 */
        MPTCP_MIB_ECHOADD,              /* Received ADD_ADDR with echo-flag=1 */
        MPTCP_MIB_PORTADD,              /* Received ADD_ADDR with a port-number */
+       MPTCP_MIB_ADDADDRDROP,          /* Dropped incoming ADD_ADDR */
        MPTCP_MIB_JOINPORTSYNRX,        /* Received a SYN MP_JOIN with a different port-number */
        MPTCP_MIB_JOINPORTSYNACKRX,     /* Received a SYNACK MP_JOIN with a different port-number */
        MPTCP_MIB_JOINPORTACKRX,        /* Received an ACK MP_JOIN with a different port-number */
        MPTCP_MIB_MISMATCHPORTSYNRX,    /* Received a SYN MP_JOIN with a mismatched port-number */
        MPTCP_MIB_MISMATCHPORTACKRX,    /* Received an ACK MP_JOIN with a mismatched port-number */
        MPTCP_MIB_RMADDR,               /* Received RM_ADDR */
+       MPTCP_MIB_RMADDRDROP,           /* Dropped incoming RM_ADDR */
        MPTCP_MIB_RMSUBFLOW,            /* Remove a subflow */
        MPTCP_MIB_MPPRIOTX,             /* Transmit a MP_PRIO */
        MPTCP_MIB_MPPRIORX,             /* Received a MP_PRIO */
index 696b2c4613a7c4e2c065a51ed77532dadec6ceeb..7bea318ac5f285f9ba9b5ece531a0c5eb1387e05 100644 (file)
@@ -213,6 +213,8 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
                mptcp_pm_add_addr_send_ack(msk);
        } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
                pm->remote = *addr;
+       } else {
+               __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP);
        }
 
        spin_unlock_bh(&pm->lock);
@@ -253,8 +255,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
                mptcp_event_addr_removed(msk, rm_list->ids[i]);
 
        spin_lock_bh(&pm->lock);
-       mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED);
-       pm->rm_list_rx = *rm_list;
+       if (mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED))
+               pm->rm_list_rx = *rm_list;
+       else
+               __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_RMADDRDROP);
        spin_unlock_bh(&pm->lock);
 }
 
index 356f596e2032306933cbcd17b3838800fb25ccce..4b5d795383cd6229332ad8f6ef7769f6dcf2b2cc 100644 (file)
@@ -546,6 +546,16 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
        if (msk->pm.add_addr_signaled < add_addr_signal_max) {
                local = select_signal_address(pernet, msk);
 
+               /* due to racing events on both ends we can reach here while
+                * previous add address is still running: if we invoke now
+                * mptcp_pm_announce_addr(), that will fail and the
+                * corresponding id will be marked as used.
+                * Instead let the PM machinery reschedule us when the
+                * current address announce will be completed.
+                */
+               if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
+                       return;
+
                if (local) {
                        if (mptcp_pm_alloc_anno_list(msk, local)) {
                                __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
@@ -650,6 +660,7 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
        unsigned int add_addr_accept_max;
        struct mptcp_addr_info remote;
        unsigned int subflows_max;
+       bool reset_port = false;
        int i, nr;
 
        add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk);
@@ -659,15 +670,19 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
                 msk->pm.add_addr_accepted, add_addr_accept_max,
                 msk->pm.remote.family);
 
-       if (lookup_subflow_by_daddr(&msk->conn_list, &msk->pm.remote))
+       remote = msk->pm.remote;
+       if (lookup_subflow_by_daddr(&msk->conn_list, &remote))
                goto add_addr_echo;
 
+       /* pick id 0 port, if none is provided the remote address */
+       if (!remote.port) {
+               reset_port = true;
+               remote.port = sk->sk_dport;
+       }
+
        /* connect to the specified remote address, using whatever
         * local address the routing configuration will pick.
         */
-       remote = msk->pm.remote;
-       if (!remote.port)
-               remote.port = sk->sk_dport;
        nr = fill_local_addresses_vec(msk, addrs);
 
        msk->pm.add_addr_accepted++;
@@ -680,8 +695,12 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
                __mptcp_subflow_connect(sk, &addrs[i], &remote);
        spin_lock_bh(&msk->pm.lock);
 
+       /* be sure to echo exactly the received address */
+       if (reset_port)
+               remote.port = 0;
+
 add_addr_echo:
-       mptcp_pm_announce_addr(msk, &msk->pm.remote, true);
+       mptcp_pm_announce_addr(msk, &remote, true);
        mptcp_pm_nl_addr_send_ack(msk);
 }
 
index f60f01b14fac4aaa1c772903c7f224a26e9e3955..1c72f25f083ead66007ad0c13af5fe972881b44e 100644 (file)
@@ -466,9 +466,12 @@ static bool mptcp_pending_data_fin(struct sock *sk, u64 *seq)
 static void mptcp_set_datafin_timeout(const struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
+       u32 retransmits;
 
-       mptcp_sk(sk)->timer_ival = min(TCP_RTO_MAX,
-                                      TCP_RTO_MIN << icsk->icsk_retransmits);
+       retransmits = min_t(u32, icsk->icsk_retransmits,
+                           ilog2(TCP_RTO_MAX / TCP_RTO_MIN));
+
+       mptcp_sk(sk)->timer_ival = TCP_RTO_MIN << retransmits;
 }
 
 static void __mptcp_set_timeout(struct sock *sk, long tout)
@@ -3294,6 +3297,17 @@ static int mptcp_ioctl_outq(const struct mptcp_sock *msk, u64 v)
                return 0;
 
        delta = msk->write_seq - v;
+       if (__mptcp_check_fallback(msk) && msk->first) {
+               struct tcp_sock *tp = tcp_sk(msk->first);
+
+               /* the first subflow is disconnected after close - see
+                * __mptcp_close_ssk(). tcp_disconnect() moves the write_seq
+                * so ignore that status, too.
+                */
+               if (!((1 << msk->first->sk_state) &
+                     (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE)))
+                       delta += READ_ONCE(tp->write_seq) - tp->snd_una;
+       }
        if (delta > INT_MAX)
                delta = INT_MAX;
 
index 354cb472f386797d77667b02e0790072b333f40e..8a77a3fd69bcaf7ced4a77e8bfee04905e56ef74 100644 (file)
@@ -428,14 +428,15 @@ static int __nf_register_net_hook(struct net *net, int pf,
        p = nf_entry_dereference(*pp);
        new_hooks = nf_hook_entries_grow(p, reg);
 
-       if (!IS_ERR(new_hooks))
+       if (!IS_ERR(new_hooks)) {
+               hooks_validate(new_hooks);
                rcu_assign_pointer(*pp, new_hooks);
+       }
 
        mutex_unlock(&nf_hook_mutex);
        if (IS_ERR(new_hooks))
                return PTR_ERR(new_hooks);
 
-       hooks_validate(new_hooks);
 #ifdef CONFIG_NETFILTER_INGRESS
        if (nf_ingress_hook(reg, pf))
                net_inc_ingress_queue();
index d6aa5b47031ebcb4a35abbd01f48fc46b746c8ab..bf1e17c678f13aa5c477763e8c6bf47766829fcd 100644 (file)
@@ -1748,9 +1748,6 @@ resolve_normal_ct(struct nf_conn *tmpl,
                        return 0;
                if (IS_ERR(h))
                        return PTR_ERR(h);
-
-               ct = nf_ct_tuplehash_to_ctrack(h);
-               ct->local_origin = state->hook == NF_INET_LOCAL_OUT;
        }
        ct = nf_ct_tuplehash_to_ctrack(h);
 
index b561e0a44a45f36392611d6ed4b94c34f920e29f..fc4265acd9c4e2bead267941b0c5caba39c4c265 100644 (file)
@@ -110,7 +110,11 @@ static int nf_flow_rule_match(struct nf_flow_match *match,
                nf_flow_rule_lwt_match(match, tun_info);
        }
 
-       key->meta.ingress_ifindex = tuple->iifidx;
+       if (tuple->xmit_type == FLOW_OFFLOAD_XMIT_TC)
+               key->meta.ingress_ifindex = tuple->tc.iifidx;
+       else
+               key->meta.ingress_ifindex = tuple->iifidx;
+
        mask->meta.ingress_ifindex = 0xffffffff;
 
        if (tuple->encap_num > 0 && !(tuple->in_vlan_ingress & BIT(0)) &&
index 2d06a66899b26e275613ab2b0471d81af3f3db38..ffcf6529afc3c744fd0c0b6488e0738d9acf0d87 100644 (file)
@@ -494,38 +494,6 @@ another_round:
        goto another_round;
 }
 
-static bool tuple_force_port_remap(const struct nf_conntrack_tuple *tuple)
-{
-       u16 sp, dp;
-
-       switch (tuple->dst.protonum) {
-       case IPPROTO_TCP:
-               sp = ntohs(tuple->src.u.tcp.port);
-               dp = ntohs(tuple->dst.u.tcp.port);
-               break;
-       case IPPROTO_UDP:
-       case IPPROTO_UDPLITE:
-               sp = ntohs(tuple->src.u.udp.port);
-               dp = ntohs(tuple->dst.u.udp.port);
-               break;
-       default:
-               return false;
-       }
-
-       /* IANA: System port range: 1-1023,
-        *         user port range: 1024-49151,
-        *      private port range: 49152-65535.
-        *
-        * Linux default ephemeral port range is 32768-60999.
-        *
-        * Enforce port remapping if sport is significantly lower
-        * than dport to prevent NAT port shadowing, i.e.
-        * accidental match of 'new' inbound connection vs.
-        * existing outbound one.
-        */
-       return sp < 16384 && dp >= 32768;
-}
-
 /* Manipulate the tuple into the range given. For NF_INET_POST_ROUTING,
  * we change the source to map into the range. For NF_INET_PRE_ROUTING
  * and NF_INET_LOCAL_OUT, we change the destination to map into the
@@ -539,17 +507,11 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
                 struct nf_conn *ct,
                 enum nf_nat_manip_type maniptype)
 {
-       bool random_port = range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL;
        const struct nf_conntrack_zone *zone;
        struct net *net = nf_ct_net(ct);
 
        zone = nf_ct_zone(ct);
 
-       if (maniptype == NF_NAT_MANIP_SRC &&
-           !random_port &&
-           !ct->local_origin)
-               random_port = tuple_force_port_remap(orig_tuple);
-
        /* 1) If this srcip/proto/src-proto-part is currently mapped,
         * and that same mapping gives a unique tuple within the given
         * range, use that.
@@ -558,7 +520,8 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
         * So far, we don't do local source mappings, so multiple
         * manips not an issue.
         */
-       if (maniptype == NF_NAT_MANIP_SRC && !random_port) {
+       if (maniptype == NF_NAT_MANIP_SRC &&
+           !(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) {
                /* try the original tuple first */
                if (in_range(orig_tuple, range)) {
                        if (!nf_nat_used_tuple(orig_tuple, ct)) {
@@ -582,7 +545,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
         */
 
        /* Only bother mapping if it's not already in range and unique */
-       if (!random_port) {
+       if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) {
                if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
                        if (!(range->flags & NF_NAT_RANGE_PROTO_OFFSET) &&
                            l4proto_in_range(tuple, maniptype,
index 6d12afabfe8a35069f5355ceb57e8147cf59d187..63d1516816b1fdaa570288c725cc5f721cde694d 100644 (file)
@@ -46,6 +46,15 @@ void nf_unregister_queue_handler(void)
 }
 EXPORT_SYMBOL(nf_unregister_queue_handler);
 
+static void nf_queue_sock_put(struct sock *sk)
+{
+#ifdef CONFIG_INET
+       sock_gen_put(sk);
+#else
+       sock_put(sk);
+#endif
+}
+
 static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
 {
        struct nf_hook_state *state = &entry->state;
@@ -54,7 +63,7 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
        dev_put(state->in);
        dev_put(state->out);
        if (state->sk)
-               sock_put(state->sk);
+               nf_queue_sock_put(state->sk);
 
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
        dev_put(entry->physin);
@@ -87,19 +96,21 @@ static void __nf_queue_entry_init_physdevs(struct nf_queue_entry *entry)
 }
 
 /* Bump dev refs so they don't vanish while packet is out */
-void nf_queue_entry_get_refs(struct nf_queue_entry *entry)
+bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
 {
        struct nf_hook_state *state = &entry->state;
 
+       if (state->sk && !refcount_inc_not_zero(&state->sk->sk_refcnt))
+               return false;
+
        dev_hold(state->in);
        dev_hold(state->out);
-       if (state->sk)
-               sock_hold(state->sk);
 
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
        dev_hold(entry->physin);
        dev_hold(entry->physout);
 #endif
+       return true;
 }
 EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
 
@@ -169,6 +180,18 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
                break;
        }
 
+       if (skb_sk_is_prefetched(skb)) {
+               struct sock *sk = skb->sk;
+
+               if (!sk_is_refcounted(sk)) {
+                       if (!refcount_inc_not_zero(&sk->sk_refcnt))
+                               return -ENOTCONN;
+
+                       /* drop refcount on skb_orphan */
+                       skb->destructor = sock_edemux;
+               }
+       }
+
        entry = kmalloc(sizeof(*entry) + route_key_size, GFP_ATOMIC);
        if (!entry)
                return -ENOMEM;
@@ -187,7 +210,10 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
 
        __nf_queue_entry_init_physdevs(entry);
 
-       nf_queue_entry_get_refs(entry);
+       if (!nf_queue_entry_get_refs(entry)) {
+               kfree(entry);
+               return -ENOTCONN;
+       }
 
        switch (entry->state.pf) {
        case AF_INET:
index 5fa16990da95177791dfaa9e7bb31c92f3cae096..d71a33ae39b354f22590c2d7a751dad2f3450803 100644 (file)
@@ -4502,7 +4502,7 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx,
        list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
                list_del_rcu(&catchall->list);
                nft_set_elem_destroy(set, catchall->elem, true);
-               kfree_rcu(catchall);
+               kfree_rcu(catchall, rcu);
        }
 }
 
@@ -5669,7 +5669,7 @@ static void nft_setelem_catchall_remove(const struct net *net,
        list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
                if (catchall->elem == elem->priv) {
                        list_del_rcu(&catchall->list);
-                       kfree_rcu(catchall);
+                       kfree_rcu(catchall, rcu);
                        break;
                }
        }
@@ -6551,12 +6551,15 @@ static int nf_tables_updobj(const struct nft_ctx *ctx,
 {
        struct nft_object *newobj;
        struct nft_trans *trans;
-       int err;
+       int err = -ENOMEM;
+
+       if (!try_module_get(type->owner))
+               return -ENOENT;
 
        trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ,
                                sizeof(struct nft_trans_obj));
        if (!trans)
-               return -ENOMEM;
+               goto err_trans;
 
        newobj = nft_obj_init(ctx, type, attr);
        if (IS_ERR(newobj)) {
@@ -6573,6 +6576,8 @@ static int nf_tables_updobj(const struct nft_ctx *ctx,
 
 err_free_trans:
        kfree(trans);
+err_trans:
+       module_put(type->owner);
        return err;
 }
 
@@ -8185,7 +8190,7 @@ static void nft_obj_commit_update(struct nft_trans *trans)
        if (obj->ops->update)
                obj->ops->update(obj, newobj);
 
-       kfree(newobj);
+       nft_obj_destroy(&trans->ctx, newobj);
 }
 
 static void nft_commit_release(struct nft_trans *trans)
@@ -8255,6 +8260,12 @@ void nf_tables_trans_destroy_flush_work(void)
 }
 EXPORT_SYMBOL_GPL(nf_tables_trans_destroy_flush_work);
 
+static bool nft_expr_reduce(struct nft_regs_track *track,
+                           const struct nft_expr *expr)
+{
+       return false;
+}
+
 static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *chain)
 {
        const struct nft_expr *expr, *last;
@@ -8302,8 +8313,7 @@ static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *cha
                nft_rule_for_each_expr(expr, last, rule) {
                        track.cur = expr;
 
-                       if (expr->ops->reduce &&
-                           expr->ops->reduce(&track, expr)) {
+                       if (nft_expr_reduce(&track, expr)) {
                                expr = track.cur;
                                continue;
                        }
@@ -8976,7 +8986,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
                        break;
                case NFT_MSG_NEWOBJ:
                        if (nft_trans_obj_update(trans)) {
-                               kfree(nft_trans_obj_newobj(trans));
+                               nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans));
                                nft_trans_destroy(trans);
                        } else {
                                trans->ctx.table->use--;
@@ -9636,10 +9646,13 @@ EXPORT_SYMBOL_GPL(__nft_release_basechain);
 
 static void __nft_release_hook(struct net *net, struct nft_table *table)
 {
+       struct nft_flowtable *flowtable;
        struct nft_chain *chain;
 
        list_for_each_entry(chain, &table->chains, list)
                nf_tables_unregister_hook(net, table, chain);
+       list_for_each_entry(flowtable, &table->flowtables, list)
+               nft_unregister_flowtable_net_hooks(net, &flowtable->hook_list);
 }
 
 static void __nft_release_hooks(struct net *net)
index 9656c1646222201a1ffef46eec24af5478afec3d..2d36952b13920d149110e7d90dff8d7069e78ff8 100644 (file)
@@ -94,7 +94,8 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
 
        expr = nft_expr_first(rule);
        while (nft_expr_more(rule, expr)) {
-               if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
+               if (expr->ops->offload_action &&
+                   expr->ops->offload_action(expr))
                        num_actions++;
 
                expr = nft_expr_next(expr);
index ea2d9c2a44cf08bdb73d678108df20d0e4d9418a..64a6acb6aeae866d1c0205010f69dbdba3709b01 100644 (file)
@@ -710,9 +710,15 @@ static struct nf_queue_entry *
 nf_queue_entry_dup(struct nf_queue_entry *e)
 {
        struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC);
-       if (entry)
-               nf_queue_entry_get_refs(entry);
-       return entry;
+
+       if (!entry)
+               return NULL;
+
+       if (nf_queue_entry_get_refs(entry))
+               return entry;
+
+       kfree(entry);
+       return NULL;
 }
 
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
index bbf3fcba3df4019ad7e1934b6ba6e9c6ae33c057..5b5c607fbf83f020f1b8929c4fa7a36d6a20471a 100644 (file)
@@ -67,6 +67,11 @@ static int nft_dup_netdev_offload(struct nft_offload_ctx *ctx,
        return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_MIRRED, oif);
 }
 
+static bool nft_dup_netdev_offload_action(const struct nft_expr *expr)
+{
+       return true;
+}
+
 static struct nft_expr_type nft_dup_netdev_type;
 static const struct nft_expr_ops nft_dup_netdev_ops = {
        .type           = &nft_dup_netdev_type,
@@ -75,6 +80,7 @@ static const struct nft_expr_ops nft_dup_netdev_ops = {
        .init           = nft_dup_netdev_init,
        .dump           = nft_dup_netdev_dump,
        .offload        = nft_dup_netdev_offload,
+       .offload_action = nft_dup_netdev_offload_action,
 };
 
 static struct nft_expr_type nft_dup_netdev_type __read_mostly = {
index fa9301ca603318abab44e31d13db696ff5747727..619e394a91de9b1e3c39dda95f6946ca403e6a8c 100644 (file)
@@ -79,6 +79,11 @@ static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx,
        return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_REDIRECT, oif);
 }
 
+static bool nft_fwd_netdev_offload_action(const struct nft_expr *expr)
+{
+       return true;
+}
+
 struct nft_fwd_neigh {
        u8                      sreg_dev;
        u8                      sreg_addr;
@@ -222,6 +227,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = {
        .dump           = nft_fwd_netdev_dump,
        .validate       = nft_fwd_validate,
        .offload        = nft_fwd_netdev_offload,
+       .offload_action = nft_fwd_netdev_offload_action,
 };
 
 static const struct nft_expr_ops *
index 90c64d27ae53228a1c0fe3acbd40aa5ba288a7b6..d0f67d325bdfd384cd70a95d527d9ce7bc690b2d 100644 (file)
@@ -213,6 +213,16 @@ static int nft_immediate_offload(struct nft_offload_ctx *ctx,
        return 0;
 }
 
+static bool nft_immediate_offload_action(const struct nft_expr *expr)
+{
+       const struct nft_immediate_expr *priv = nft_expr_priv(expr);
+
+       if (priv->dreg == NFT_REG_VERDICT)
+               return true;
+
+       return false;
+}
+
 static const struct nft_expr_ops nft_imm_ops = {
        .type           = &nft_imm_type,
        .size           = NFT_EXPR_SIZE(sizeof(struct nft_immediate_expr)),
@@ -224,7 +234,7 @@ static const struct nft_expr_ops nft_imm_ops = {
        .dump           = nft_immediate_dump,
        .validate       = nft_immediate_validate,
        .offload        = nft_immediate_offload,
-       .offload_flags  = NFT_OFFLOAD_F_ACTION,
+       .offload_action = nft_immediate_offload_action,
 };
 
 struct nft_expr_type nft_imm_type __read_mostly = {
index c4f308460dd1d469a9c7d5c748226d882d45c266..a726b623963de486a89178f11f657256d0cc06e8 100644 (file)
@@ -340,11 +340,20 @@ static int nft_limit_obj_pkts_dump(struct sk_buff *skb,
        return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS);
 }
 
+static void nft_limit_obj_pkts_destroy(const struct nft_ctx *ctx,
+                                      struct nft_object *obj)
+{
+       struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
+
+       nft_limit_destroy(ctx, &priv->limit);
+}
+
 static struct nft_object_type nft_limit_obj_type;
 static const struct nft_object_ops nft_limit_obj_pkts_ops = {
        .type           = &nft_limit_obj_type,
        .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)),
        .init           = nft_limit_obj_pkts_init,
+       .destroy        = nft_limit_obj_pkts_destroy,
        .eval           = nft_limit_obj_pkts_eval,
        .dump           = nft_limit_obj_pkts_dump,
 };
@@ -378,11 +387,20 @@ static int nft_limit_obj_bytes_dump(struct sk_buff *skb,
        return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES);
 }
 
+static void nft_limit_obj_bytes_destroy(const struct nft_ctx *ctx,
+                                       struct nft_object *obj)
+{
+       struct nft_limit_priv *priv = nft_obj_data(obj);
+
+       nft_limit_destroy(ctx, priv);
+}
+
 static struct nft_object_type nft_limit_obj_type;
 static const struct nft_object_ops nft_limit_obj_bytes_ops = {
        .type           = &nft_limit_obj_type,
        .size           = sizeof(struct nft_limit_priv),
        .init           = nft_limit_obj_bytes_init,
+       .destroy        = nft_limit_obj_bytes_destroy,
        .eval           = nft_limit_obj_bytes_eval,
        .dump           = nft_limit_obj_bytes_dump,
 };
index 662e5eb1cc39e544191b3aab388c3762674d9251..7013f55f05d1ebca3b13d29934d8f6abc1ef36f0 100644 (file)
@@ -220,8 +220,10 @@ static void socket_mt_destroy(const struct xt_mtdtor_param *par)
 {
        if (par->family == NFPROTO_IPV4)
                nf_defrag_ipv4_disable(par->net);
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        else if (par->family == NFPROTO_IPV6)
                nf_defrag_ipv6_disable(par->net);
+#endif
 }
 
 static struct xt_match socket_mt_reg[] __read_mostly = {
index 076774034bb960b16c04609cd120fd5118829538..780d9e2246f394df72016892dcdfdbd55f15a37e 100644 (file)
@@ -423,12 +423,43 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto,
        memcpy(addr, new_addr, sizeof(__be32[4]));
 }
 
-static void set_ipv6_fl(struct ipv6hdr *nh, u32 fl, u32 mask)
+static void set_ipv6_dsfield(struct sk_buff *skb, struct ipv6hdr *nh, u8 ipv6_tclass, u8 mask)
 {
+       u8 old_ipv6_tclass = ipv6_get_dsfield(nh);
+
+       ipv6_tclass = OVS_MASKED(old_ipv6_tclass, ipv6_tclass, mask);
+
+       if (skb->ip_summed == CHECKSUM_COMPLETE)
+               csum_replace(&skb->csum, (__force __wsum)(old_ipv6_tclass << 12),
+                            (__force __wsum)(ipv6_tclass << 12));
+
+       ipv6_change_dsfield(nh, ~mask, ipv6_tclass);
+}
+
+static void set_ipv6_fl(struct sk_buff *skb, struct ipv6hdr *nh, u32 fl, u32 mask)
+{
+       u32 ofl;
+
+       ofl = nh->flow_lbl[0] << 16 |  nh->flow_lbl[1] << 8 |  nh->flow_lbl[2];
+       fl = OVS_MASKED(ofl, fl, mask);
+
        /* Bits 21-24 are always unmasked, so this retains their values. */
-       OVS_SET_MASKED(nh->flow_lbl[0], (u8)(fl >> 16), (u8)(mask >> 16));
-       OVS_SET_MASKED(nh->flow_lbl[1], (u8)(fl >> 8), (u8)(mask >> 8));
-       OVS_SET_MASKED(nh->flow_lbl[2], (u8)fl, (u8)mask);
+       nh->flow_lbl[0] = (u8)(fl >> 16);
+       nh->flow_lbl[1] = (u8)(fl >> 8);
+       nh->flow_lbl[2] = (u8)fl;
+
+       if (skb->ip_summed == CHECKSUM_COMPLETE)
+               csum_replace(&skb->csum, (__force __wsum)htonl(ofl), (__force __wsum)htonl(fl));
+}
+
+static void set_ipv6_ttl(struct sk_buff *skb, struct ipv6hdr *nh, u8 new_ttl, u8 mask)
+{
+       new_ttl = OVS_MASKED(nh->hop_limit, new_ttl, mask);
+
+       if (skb->ip_summed == CHECKSUM_COMPLETE)
+               csum_replace(&skb->csum, (__force __wsum)(nh->hop_limit << 8),
+                            (__force __wsum)(new_ttl << 8));
+       nh->hop_limit = new_ttl;
 }
 
 static void set_ip_ttl(struct sk_buff *skb, struct iphdr *nh, u8 new_ttl,
@@ -546,18 +577,17 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
                }
        }
        if (mask->ipv6_tclass) {
-               ipv6_change_dsfield(nh, ~mask->ipv6_tclass, key->ipv6_tclass);
+               set_ipv6_dsfield(skb, nh, key->ipv6_tclass, mask->ipv6_tclass);
                flow_key->ip.tos = ipv6_get_dsfield(nh);
        }
        if (mask->ipv6_label) {
-               set_ipv6_fl(nh, ntohl(key->ipv6_label),
+               set_ipv6_fl(skb, nh, ntohl(key->ipv6_label),
                            ntohl(mask->ipv6_label));
                flow_key->ipv6.label =
                    *(__be32 *)nh & htonl(IPV6_FLOWINFO_FLOWLABEL);
        }
        if (mask->ipv6_hlimit) {
-               OVS_SET_MASKED(nh->hop_limit, key->ipv6_hlimit,
-                              mask->ipv6_hlimit);
+               set_ipv6_ttl(skb, nh, key->ipv6_hlimit, mask->ipv6_hlimit);
                flow_key->ip.ttl = nh->hop_limit;
        }
        return 0;
index ab87f22cc7ecde517ba4cd0b3804a28c3cccfc85..a7273af2d90097b511988f1ed05abe54de08186f 100644 (file)
@@ -2317,8 +2317,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
                                        copy_skb = skb_get(skb);
                                        skb_head = skb->data;
                                }
-                               if (copy_skb)
+                               if (copy_skb) {
+                                       memset(&PACKET_SKB_CB(copy_skb)->sa.ll, 0,
+                                              sizeof(PACKET_SKB_CB(copy_skb)->sa.ll));
                                        skb_set_owner_r(copy_skb, sk);
+                               }
                        }
                        snaplen = po->rx_ring.frame_size - macoff;
                        if ((int)snaplen < 0) {
@@ -3462,6 +3465,8 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        sock_recv_ts_and_drops(msg, sk, skb);
 
        if (msg->msg_name) {
+               const size_t max_len = min(sizeof(skb->cb),
+                                          sizeof(struct sockaddr_storage));
                int copy_len;
 
                /* If the address length field is there to be filled
@@ -3484,6 +3489,10 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
                                msg->msg_namelen = sizeof(struct sockaddr_ll);
                        }
                }
+               if (WARN_ON_ONCE(copy_len > max_len)) {
+                       copy_len = max_len;
+                       msg->msg_namelen = copy_len;
+               }
                memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len);
        }
 
index 2811348f3acc0b853f54f001b6e80ce3adbe6ad4..ca03e72842541f131f9e54dc112ab92a7519b458 100644 (file)
@@ -274,7 +274,7 @@ static int tcf_action_offload_add_ex(struct tc_action *action,
        err = tc_setup_action(&fl_action->action, actions);
        if (err) {
                NL_SET_ERR_MSG_MOD(extack,
-                                  "Failed to setup tc actions for offload\n");
+                                  "Failed to setup tc actions for offload");
                goto fl_err;
        }
 
index f99247fc64682c2bcfa2e5671c2b8bc4ca637511..ec19f625863a04229a9a3894a423e6dd562844a1 100644 (file)
@@ -361,6 +361,13 @@ static void tcf_ct_flow_table_put(struct tcf_ct_params *params)
        }
 }
 
+static void tcf_ct_flow_tc_ifidx(struct flow_offload *entry,
+                                struct nf_conn_act_ct_ext *act_ct_ext, u8 dir)
+{
+       entry->tuplehash[dir].tuple.xmit_type = FLOW_OFFLOAD_XMIT_TC;
+       entry->tuplehash[dir].tuple.tc.iifidx = act_ct_ext->ifindex[dir];
+}
+
 static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
                                  struct nf_conn *ct,
                                  bool tcp)
@@ -385,10 +392,8 @@ static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
 
        act_ct_ext = nf_conn_act_ct_ext_find(ct);
        if (act_ct_ext) {
-               entry->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx =
-                       act_ct_ext->ifindex[IP_CT_DIR_ORIGINAL];
-               entry->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.iifidx =
-                       act_ct_ext->ifindex[IP_CT_DIR_REPLY];
+               tcf_ct_flow_tc_ifidx(entry, act_ct_ext, FLOW_OFFLOAD_DIR_ORIGINAL);
+               tcf_ct_flow_tc_ifidx(entry, act_ct_ext, FLOW_OFFLOAD_DIR_REPLY);
        }
 
        err = flow_offload_add(&ct_ft->nf_ft, entry);
@@ -533,11 +538,6 @@ static bool tcf_ct_flow_table_lookup(struct tcf_ct_params *p,
        struct nf_conn *ct;
        u8 dir;
 
-       /* Previously seen or loopback */
-       ct = nf_ct_get(skb, &ctinfo);
-       if ((ct && !nf_ct_is_template(ct)) || ctinfo == IP_CT_UNTRACKED)
-               return false;
-
        switch (family) {
        case NFPROTO_IPV4:
                if (!tcf_ct_flow_table_fill_tuple_ipv4(skb, &tuple, &tcph))
index 034e2c74497df7f841d5d5b13b9695d291389089..d9c6d8f30f0935910a5c62a5a78c3813392b8231 100644 (file)
@@ -61,10 +61,6 @@ static void inet_diag_msg_sctpasoc_fill(struct inet_diag_msg *r,
                r->idiag_timer = SCTP_EVENT_TIMEOUT_T3_RTX;
                r->idiag_retrans = asoc->rtx_data_chunks;
                r->idiag_expires = jiffies_to_msecs(t3_rtx->expires - jiffies);
-       } else {
-               r->idiag_timer = 0;
-               r->idiag_retrans = 0;
-               r->idiag_expires = 0;
        }
 }
 
@@ -144,13 +140,14 @@ static int inet_sctp_diag_fill(struct sock *sk, struct sctp_association *asoc,
        r = nlmsg_data(nlh);
        BUG_ON(!sk_fullsock(sk));
 
+       r->idiag_timer = 0;
+       r->idiag_retrans = 0;
+       r->idiag_expires = 0;
        if (asoc) {
                inet_diag_msg_sctpasoc_fill(r, sk, asoc);
        } else {
                inet_diag_msg_common_fill(r, sk);
                r->idiag_state = sk->sk_state;
-               r->idiag_timer = 0;
-               r->idiag_retrans = 0;
        }
 
        if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns, net_admin))
index 306d9e8cd1ddce51d730ba460f4e1b5015404c22..284befa909676b8881a443b37442980700d26d34 100644 (file)
@@ -183,7 +183,7 @@ static int smc_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
        struct smc_sock *smc;
-       int rc = 0;
+       int old_state, rc = 0;
 
        if (!sk)
                goto out;
@@ -191,8 +191,10 @@ static int smc_release(struct socket *sock)
        sock_hold(sk); /* sock_put below */
        smc = smc_sk(sk);
 
+       old_state = sk->sk_state;
+
        /* cleanup for a dangling non-blocking connect */
-       if (smc->connect_nonblock && sk->sk_state == SMC_INIT)
+       if (smc->connect_nonblock && old_state == SMC_INIT)
                tcp_abort(smc->clcsock->sk, ECONNABORTED);
 
        if (cancel_work_sync(&smc->connect_work))
@@ -206,6 +208,10 @@ static int smc_release(struct socket *sock)
        else
                lock_sock(sk);
 
+       if (old_state == SMC_INIT && sk->sk_state == SMC_ACTIVE &&
+           !smc->use_fallback)
+               smc_close_active_abort(smc);
+
        rc = __smc_release(smc);
 
        /* detach socket */
@@ -3081,12 +3087,14 @@ static int __init smc_init(void)
        rc = tcp_register_ulp(&smc_ulp_ops);
        if (rc) {
                pr_err("%s: tcp_ulp_register fails with %d\n", __func__, rc);
-               goto out_sock;
+               goto out_ib;
        }
 
        static_branch_enable(&tcp_have_smc);
        return 0;
 
+out_ib:
+       smc_ib_unregister_client();
 out_sock:
        sock_unregister(PF_SMC);
 out_proto6:
index 29525d03b253f856a205e24f4160f853daa98494..be7d704976ffbd8cb0e9610d554c2c573a9fa3b7 100644 (file)
@@ -1161,8 +1161,8 @@ void smc_conn_free(struct smc_connection *conn)
                        cancel_work_sync(&conn->abort_work);
        }
        if (!list_empty(&lgr->list)) {
-               smc_lgr_unregister_conn(conn);
                smc_buf_unuse(conn, lgr); /* allow buffer reuse */
+               smc_lgr_unregister_conn(conn);
        }
 
        if (!lgr->conns_num)
@@ -1864,7 +1864,8 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
                    (ini->smcd_version == SMC_V2 ||
                     lgr->vlan_id == ini->vlan_id) &&
                    (role == SMC_CLNT || ini->is_smcd ||
-                    lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) {
+                   (lgr->conns_num < SMC_RMBS_PER_LGR_MAX &&
+                     !bitmap_full(lgr->rtokens_used_mask, SMC_RMBS_PER_LGR_MAX)))) {
                        /* link group found */
                        ini->first_contact_local = 0;
                        conn->lgr = lgr;
index 0599246c037690b4b01813956e4af74519277bea..29f0a559d88478db6379fb1eeaaabbd3079d69b0 100644 (file)
@@ -113,7 +113,7 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)
        pnettable = &sn->pnettable;
 
        /* remove table entry */
-       write_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist,
                                 list) {
                if (!pnet_name ||
@@ -131,7 +131,7 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)
                        rc = 0;
                }
        }
-       write_unlock(&pnettable->lock);
+       mutex_unlock(&pnettable->lock);
 
        /* if this is not the initial namespace, stop here */
        if (net != &init_net)
@@ -192,7 +192,7 @@ static int smc_pnet_add_by_ndev(struct net_device *ndev)
        sn = net_generic(net, smc_net_id);
        pnettable = &sn->pnettable;
 
-       write_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) {
                if (pnetelem->type == SMC_PNET_ETH && !pnetelem->ndev &&
                    !strncmp(pnetelem->eth_name, ndev->name, IFNAMSIZ)) {
@@ -206,7 +206,7 @@ static int smc_pnet_add_by_ndev(struct net_device *ndev)
                        break;
                }
        }
-       write_unlock(&pnettable->lock);
+       mutex_unlock(&pnettable->lock);
        return rc;
 }
 
@@ -224,7 +224,7 @@ static int smc_pnet_remove_by_ndev(struct net_device *ndev)
        sn = net_generic(net, smc_net_id);
        pnettable = &sn->pnettable;
 
-       write_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry_safe(pnetelem, tmp_pe, &pnettable->pnetlist, list) {
                if (pnetelem->type == SMC_PNET_ETH && pnetelem->ndev == ndev) {
                        dev_put_track(pnetelem->ndev, &pnetelem->dev_tracker);
@@ -237,7 +237,7 @@ static int smc_pnet_remove_by_ndev(struct net_device *ndev)
                        break;
                }
        }
-       write_unlock(&pnettable->lock);
+       mutex_unlock(&pnettable->lock);
        return rc;
 }
 
@@ -370,7 +370,7 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
        strncpy(new_pe->eth_name, eth_name, IFNAMSIZ);
        rc = -EEXIST;
        new_netdev = true;
-       write_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
                if (tmp_pe->type == SMC_PNET_ETH &&
                    !strncmp(tmp_pe->eth_name, eth_name, IFNAMSIZ)) {
@@ -385,9 +385,9 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net,
                                             GFP_ATOMIC);
                }
                list_add_tail(&new_pe->list, &pnettable->pnetlist);
-               write_unlock(&pnettable->lock);
+               mutex_unlock(&pnettable->lock);
        } else {
-               write_unlock(&pnettable->lock);
+               mutex_unlock(&pnettable->lock);
                kfree(new_pe);
                goto out_put;
        }
@@ -448,7 +448,7 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
        new_pe->ib_port = ib_port;
 
        new_ibdev = true;
-       write_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
                if (tmp_pe->type == SMC_PNET_IB &&
                    !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) {
@@ -458,9 +458,9 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
        }
        if (new_ibdev) {
                list_add_tail(&new_pe->list, &pnettable->pnetlist);
-               write_unlock(&pnettable->lock);
+               mutex_unlock(&pnettable->lock);
        } else {
-               write_unlock(&pnettable->lock);
+               mutex_unlock(&pnettable->lock);
                kfree(new_pe);
        }
        return (new_ibdev) ? 0 : -EEXIST;
@@ -605,7 +605,7 @@ static int _smc_pnet_dump(struct net *net, struct sk_buff *skb, u32 portid,
        pnettable = &sn->pnettable;
 
        /* dump pnettable entries */
-       read_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry(pnetelem, &pnettable->pnetlist, list) {
                if (pnetid && !smc_pnet_match(pnetelem->pnet_name, pnetid))
                        continue;
@@ -620,7 +620,7 @@ static int _smc_pnet_dump(struct net *net, struct sk_buff *skb, u32 portid,
                        break;
                }
        }
-       read_unlock(&pnettable->lock);
+       mutex_unlock(&pnettable->lock);
        return idx;
 }
 
@@ -864,7 +864,7 @@ int smc_pnet_net_init(struct net *net)
        struct smc_pnetids_ndev *pnetids_ndev = &sn->pnetids_ndev;
 
        INIT_LIST_HEAD(&pnettable->pnetlist);
-       rwlock_init(&pnettable->lock);
+       mutex_init(&pnettable->lock);
        INIT_LIST_HEAD(&pnetids_ndev->list);
        rwlock_init(&pnetids_ndev->lock);
 
@@ -944,7 +944,7 @@ static int smc_pnet_find_ndev_pnetid_by_table(struct net_device *ndev,
        sn = net_generic(net, smc_net_id);
        pnettable = &sn->pnettable;
 
-       read_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry(pnetelem, &pnettable->pnetlist, list) {
                if (pnetelem->type == SMC_PNET_ETH && ndev == pnetelem->ndev) {
                        /* get pnetid of netdev device */
@@ -953,7 +953,7 @@ static int smc_pnet_find_ndev_pnetid_by_table(struct net_device *ndev,
                        break;
                }
        }
-       read_unlock(&pnettable->lock);
+       mutex_unlock(&pnettable->lock);
        return rc;
 }
 
@@ -1156,7 +1156,7 @@ int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port)
        sn = net_generic(&init_net, smc_net_id);
        pnettable = &sn->pnettable;
 
-       read_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
                if (tmp_pe->type == SMC_PNET_IB &&
                    !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX) &&
@@ -1166,7 +1166,7 @@ int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port)
                        break;
                }
        }
-       read_unlock(&pnettable->lock);
+       mutex_unlock(&pnettable->lock);
 
        return rc;
 }
@@ -1185,7 +1185,7 @@ int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev)
        sn = net_generic(&init_net, smc_net_id);
        pnettable = &sn->pnettable;
 
-       read_lock(&pnettable->lock);
+       mutex_lock(&pnettable->lock);
        list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) {
                if (tmp_pe->type == SMC_PNET_IB &&
                    !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) {
@@ -1194,7 +1194,7 @@ int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev)
                        break;
                }
        }
-       read_unlock(&pnettable->lock);
+       mutex_unlock(&pnettable->lock);
 
        return rc;
 }
index 14039272f7e4263a3d86f29d0c4f048731af387f..80a88eea494918663f0263b9577c0ca49dcf1542 100644 (file)
@@ -29,7 +29,7 @@ struct smc_link_group;
  * @pnetlist: List of PNETIDs
  */
 struct smc_pnettable {
-       rwlock_t lock;
+       struct mutex lock;
        struct list_head pnetlist;
 };
 
index 473a790f58943537896c16c72b60061b5ffe6840..a2f9c9640716184d8db51e3f76a56a27005ceffb 100644 (file)
@@ -352,16 +352,18 @@ static int tipc_enable_bearer(struct net *net, const char *name,
                goto rejected;
        }
 
-       test_and_set_bit_lock(0, &b->up);
-       rcu_assign_pointer(tn->bearer_list[bearer_id], b);
-       if (skb)
-               tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr);
-
+       /* Create monitoring data before accepting activate messages */
        if (tipc_mon_create(net, bearer_id)) {
                bearer_disable(net, b);
+               kfree_skb(skb);
                return -ENOMEM;
        }
 
+       test_and_set_bit_lock(0, &b->up);
+       rcu_assign_pointer(tn->bearer_list[bearer_id], b);
+       if (skb)
+               tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr);
+
        pr_info("Enabled bearer <%s>, priority %u\n", name, prio);
 
        return res;
index 1e14d7f8f28f1dc19d8b96b2b139cc8b6884048b..e260c0d557f5cfed3e5b54845261ccee066c7d2c 100644 (file)
@@ -2286,6 +2286,11 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
                break;
 
        case STATE_MSG:
+               /* Validate Gap ACK blocks, drop if invalid */
+               glen = tipc_get_gap_ack_blks(&ga, l, hdr, true);
+               if (glen > dlen)
+                       break;
+
                l->rcv_nxt_state = msg_seqno(hdr) + 1;
 
                /* Update own tolerance if peer indicates a non-zero value */
@@ -2311,10 +2316,6 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
                        break;
                }
 
-               /* Receive Gap ACK blocks from peer if any */
-               glen = tipc_get_gap_ack_blks(&ga, l, hdr, true);
-               if(glen > dlen)
-                       break;
                tipc_mon_rcv(l->net, data + glen, dlen - glen, l->addr,
                             &l->mon_state, l->bearer_id);
 
index 01396dd1c899b0cbb61e4a40ad5d69b9c0a2142d..1d8ba233d047483e253ec4cf493a9ac109b41352 100644 (file)
@@ -967,7 +967,7 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
                list_for_each_entry(p, &sr->all_publ, all_publ)
                        if (p->key == *last_key)
                                break;
-               if (p->key != *last_key)
+               if (list_entry_is_head(p, &sr->all_publ, all_publ))
                        return -EPIPE;
        } else {
                p = list_first_entry(&sr->all_publ,
index 3e63c83e641c565f72500ef714694253871d0205..7545321c3440b59ff86936dc42172dacc1b07a31 100644 (file)
@@ -3749,7 +3749,7 @@ static int __tipc_nl_list_sk_publ(struct sk_buff *skb,
                        if (p->key == *last_publ)
                                break;
                }
-               if (p->key != *last_publ) {
+               if (list_entry_is_head(p, &tsk->publications, binding_sock)) {
                        /* We never set seq or call nl_dump_check_consistent()
                         * this means that setting prev_seq here will cause the
                         * consistence check to fail in the netlink callback
index 38baeb189d4e657b1c05fb16f8af620feff9dbe6..f04abf662ec6cb9d3b693f9dd3023a8fb4617c5d 100644 (file)
@@ -334,7 +334,8 @@ void vsock_remove_sock(struct vsock_sock *vsk)
 }
 EXPORT_SYMBOL_GPL(vsock_remove_sock);
 
-void vsock_for_each_connected_socket(void (*fn)(struct sock *sk))
+void vsock_for_each_connected_socket(struct vsock_transport *transport,
+                                    void (*fn)(struct sock *sk))
 {
        int i;
 
@@ -343,8 +344,12 @@ void vsock_for_each_connected_socket(void (*fn)(struct sock *sk))
        for (i = 0; i < ARRAY_SIZE(vsock_connected_table); i++) {
                struct vsock_sock *vsk;
                list_for_each_entry(vsk, &vsock_connected_table[i],
-                                   connected_table)
+                                   connected_table) {
+                       if (vsk->transport != transport)
+                               continue;
+
                        fn(sk_vsock(vsk));
+               }
        }
 
        spin_unlock_bh(&vsock_table_lock);
index fb3302fff62795b1c3723ed0b7982772d7f38d55..5afc194a58bbdf1ac2030614da60434351b6f1ff 100644 (file)
@@ -24,6 +24,7 @@
 static struct workqueue_struct *virtio_vsock_workqueue;
 static struct virtio_vsock __rcu *the_virtio_vsock;
 static DEFINE_MUTEX(the_virtio_vsock_mutex); /* protects the_virtio_vsock */
+static struct virtio_transport virtio_transport; /* forward declaration */
 
 struct virtio_vsock {
        struct virtio_device *vdev;
@@ -384,7 +385,8 @@ static void virtio_vsock_event_handle(struct virtio_vsock *vsock,
        switch (le32_to_cpu(event->id)) {
        case VIRTIO_VSOCK_EVENT_TRANSPORT_RESET:
                virtio_vsock_update_guest_cid(vsock);
-               vsock_for_each_connected_socket(virtio_vsock_reset_sock);
+               vsock_for_each_connected_socket(&virtio_transport.transport,
+                                               virtio_vsock_reset_sock);
                break;
        }
 }
@@ -662,7 +664,8 @@ static void virtio_vsock_remove(struct virtio_device *vdev)
        synchronize_rcu();
 
        /* Reset all connected sockets when the device disappear */
-       vsock_for_each_connected_socket(virtio_vsock_reset_sock);
+       vsock_for_each_connected_socket(&virtio_transport.transport,
+                                       virtio_vsock_reset_sock);
 
        /* Stop all work handlers to make sure no one is accessing the device,
         * so we can safely call virtio_reset_device().
index 7aef34e32bdf8fc9bfb3344002d06e356726c1ca..b17dc9745188e4f1840881209017a23f00c65af9 100644 (file)
@@ -75,6 +75,8 @@ static u32 vmci_transport_qp_resumed_sub_id = VMCI_INVALID_ID;
 
 static int PROTOCOL_OVERRIDE = -1;
 
+static struct vsock_transport vmci_transport; /* forward declaration */
+
 /* Helper function to convert from a VMCI error code to a VSock error code. */
 
 static s32 vmci_transport_error_to_vsock_error(s32 vmci_error)
@@ -882,7 +884,8 @@ static void vmci_transport_qp_resumed_cb(u32 sub_id,
                                         const struct vmci_event_data *e_data,
                                         void *client_data)
 {
-       vsock_for_each_connected_socket(vmci_transport_handle_detach);
+       vsock_for_each_connected_socket(&vmci_transport,
+                                       vmci_transport_handle_detach);
 }
 
 static void vmci_transport_recv_pkt_work(struct work_struct *work)
index 1e9be50469ce10f44df5a0b5f426ce004481b9a1..527ae669f6f736f2df3ad062c2a452f24f4ed3c6 100644 (file)
@@ -33,7 +33,7 @@ $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.hex)
          echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);'; \
         ) > $@
 
-$(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDI) \
+$(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR) \
                      $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR)/*.x509)
        @$(kecho) "  GEN     $@"
        $(Q)(set -e; \
index 578bff9c378bc5f85151f0965a509604701e3cb0..c01fbcc848e863a822cea12badbc3ab8d1ffaaae 100644 (file)
@@ -13411,6 +13411,9 @@ static int handle_nan_filter(struct nlattr *attr_filter,
        i = 0;
        nla_for_each_nested(attr, attr_filter, rem) {
                filter[i].filter = nla_memdup(attr, GFP_KERNEL);
+               if (!filter[i].filter)
+                       goto err;
+
                filter[i].len = nla_len(attr);
                i++;
        }
@@ -13423,6 +13426,15 @@ static int handle_nan_filter(struct nlattr *attr_filter,
        }
 
        return 0;
+
+err:
+       i = 0;
+       nla_for_each_nested(attr, attr_filter, rem) {
+               kfree(filter[i].filter);
+               i++;
+       }
+       kfree(filter);
+       return -ENOMEM;
 }
 
 static int nl80211_nan_add_func(struct sk_buff *skb,
@@ -17816,7 +17828,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
        wdev->chandef = *chandef;
        wdev->preset_chandef = *chandef;
 
-       if (wdev->iftype == NL80211_IFTYPE_STATION &&
+       if ((wdev->iftype == NL80211_IFTYPE_STATION ||
+            wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
            !WARN_ON(!wdev->current_bss))
                cfg80211_update_assoc_bss_entry(wdev, chandef->chan);
 
index 3fa066419d379a2aeb0747d3615cecd3d24b9172..39bce5d764de5d28682368e4cbfa18f7c7f16e63 100644 (file)
@@ -223,6 +223,9 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
        if (x->encap || x->tfcpad)
                return -EINVAL;
 
+       if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND))
+               return -EINVAL;
+
        dev = dev_get_by_index(net, xuo->ifindex);
        if (!dev) {
                if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
@@ -262,7 +265,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
        netdev_tracker_alloc(dev, &xso->dev_tracker, GFP_ATOMIC);
        xso->real_dev = dev;
        xso->num_exthdrs = 1;
-       xso->flags = xuo->flags;
+       /* Don't forward bit that is not implemented */
+       xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6;
 
        err = dev->xfrmdev_ops->xdo_dev_state_add(x);
        if (err) {
index 57448fc519fcd9b6b09f66bcaf996ceb9b34f8d8..1e8b26eecb3f850fefd488682d0f0514358f03d7 100644 (file)
@@ -304,7 +304,10 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
                        if (mtu < IPV6_MIN_MTU)
                                mtu = IPV6_MIN_MTU;
 
-                       icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       if (skb->len > 1280)
+                               icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       else
+                               goto xmit;
                } else {
                        if (!(ip_hdr(skb)->frag_off & htons(IP_DF)))
                                goto xmit;
@@ -673,12 +676,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
        struct net *net = xi->net;
        struct xfrm_if_parms p = {};
 
+       xfrmi_netlink_parms(data, &p);
        if (!p.if_id) {
                NL_SET_ERR_MSG(extack, "if_id must be non zero");
                return -EINVAL;
        }
 
-       xfrmi_netlink_parms(data, &p);
        xi = xfrmi_locate(net, &p);
        if (!xi) {
                xi = netdev_priv(dev);
index 04d1ce9b510fba2bd03fb0e4c41cf75ce8edebd5..882526159d3a9a9db2671cc55226cb89fa1d824d 100644 (file)
@@ -4256,7 +4256,7 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp,
 }
 
 static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
-                                                   u8 dir, u8 type, struct net *net)
+                                                   u8 dir, u8 type, struct net *net, u32 if_id)
 {
        struct xfrm_policy *pol, *ret = NULL;
        struct hlist_head *chain;
@@ -4265,7 +4265,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
        spin_lock_bh(&net->xfrm.xfrm_policy_lock);
        chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir);
        hlist_for_each_entry(pol, chain, bydst) {
-               if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+               if ((if_id == 0 || pol->if_id == if_id) &&
+                   xfrm_migrate_selector_match(sel, &pol->selector) &&
                    pol->type == type) {
                        ret = pol;
                        priority = ret->priority;
@@ -4277,7 +4278,8 @@ static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *
                if ((pol->priority >= priority) && ret)
                        break;
 
-               if (xfrm_migrate_selector_match(sel, &pol->selector) &&
+               if ((if_id == 0 || pol->if_id == if_id) &&
+                   xfrm_migrate_selector_match(sel, &pol->selector) &&
                    pol->type == type) {
                        ret = pol;
                        break;
@@ -4393,7 +4395,7 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
 int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
                 struct xfrm_migrate *m, int num_migrate,
                 struct xfrm_kmaddress *k, struct net *net,
-                struct xfrm_encap_tmpl *encap)
+                struct xfrm_encap_tmpl *encap, u32 if_id)
 {
        int i, err, nx_cur = 0, nx_new = 0;
        struct xfrm_policy *pol = NULL;
@@ -4412,14 +4414,14 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
        }
 
        /* Stage 1 - find policy */
-       if ((pol = xfrm_migrate_policy_find(sel, dir, type, net)) == NULL) {
+       if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
                err = -ENOENT;
                goto out;
        }
 
        /* Stage 2 - find and update state(s) */
        for (i = 0, mp = m; i < num_migrate; i++, mp++) {
-               if ((x = xfrm_migrate_state_find(mp, net))) {
+               if ((x = xfrm_migrate_state_find(mp, net, if_id))) {
                        x_cur[nx_cur] = x;
                        nx_cur++;
                        xc = xfrm_state_migrate(x, mp, encap);
index ca6bee18346d206c826a6dc00b85854bb682ff32..b749935152ba5ae1bc3994ad1b57caefbcab2c4c 100644 (file)
@@ -1579,9 +1579,6 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
        memcpy(&x->mark, &orig->mark, sizeof(x->mark));
        memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
 
-       if (xfrm_init_state(x) < 0)
-               goto error;
-
        x->props.flags = orig->props.flags;
        x->props.extra_flags = orig->props.extra_flags;
 
@@ -1606,7 +1603,8 @@ out:
        return NULL;
 }
 
-struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
+struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
+                                               u32 if_id)
 {
        unsigned int h;
        struct xfrm_state *x = NULL;
@@ -1622,6 +1620,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
                                continue;
                        if (m->reqid && x->props.reqid != m->reqid)
                                continue;
+                       if (if_id != 0 && x->if_id != if_id)
+                               continue;
                        if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
                                             m->old_family) ||
                            !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
@@ -1637,6 +1637,8 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
                        if (x->props.mode != m->mode ||
                            x->id.proto != m->proto)
                                continue;
+                       if (if_id != 0 && x->if_id != if_id)
+                               continue;
                        if (!xfrm_addr_equal(&x->id.daddr, &m->old_daddr,
                                             m->old_family) ||
                            !xfrm_addr_equal(&x->props.saddr, &m->old_saddr,
@@ -1663,6 +1665,11 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
        if (!xc)
                return NULL;
 
+       xc->props.family = m->new_family;
+
+       if (xfrm_init_state(xc) < 0)
+               goto error;
+
        memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr));
        memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr));
 
@@ -2572,7 +2579,7 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x)
 }
 EXPORT_SYMBOL(xfrm_state_delete_tunnel);
 
-u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu)
+u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
 {
        const struct xfrm_type *type = READ_ONCE(x->type);
        struct crypto_aead *aead;
@@ -2603,17 +2610,7 @@ u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu)
        return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
                 net_adj) & ~(blksize - 1)) + net_adj - 2;
 }
-EXPORT_SYMBOL_GPL(__xfrm_state_mtu);
-
-u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
-{
-       mtu = __xfrm_state_mtu(x, mtu);
-
-       if (x->props.family == AF_INET6 && mtu < IPV6_MIN_MTU)
-               return IPV6_MIN_MTU;
-
-       return mtu;
-}
+EXPORT_SYMBOL_GPL(xfrm_state_mtu);
 
 int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
 {
index 8cd6c8129004d238083306958502f9c41ffa5ceb..72b2f173aac8b4367782d64c2cbca3380782efc5 100644 (file)
@@ -630,13 +630,8 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
 
        xfrm_smark_init(attrs, &x->props.smark);
 
-       if (attrs[XFRMA_IF_ID]) {
+       if (attrs[XFRMA_IF_ID])
                x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
-               if (!x->if_id) {
-                       err = -EINVAL;
-                       goto error;
-               }
-       }
 
        err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]);
        if (err)
@@ -1432,13 +1427,8 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        mark = xfrm_mark_get(attrs, &m);
 
-       if (attrs[XFRMA_IF_ID]) {
+       if (attrs[XFRMA_IF_ID])
                if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
-               if (!if_id) {
-                       err = -EINVAL;
-                       goto out_noput;
-               }
-       }
 
        if (p->info.seq) {
                x = xfrm_find_acq_byseq(net, mark, p->info.seq);
@@ -1751,13 +1741,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us
 
        xfrm_mark_get(attrs, &xp->mark);
 
-       if (attrs[XFRMA_IF_ID]) {
+       if (attrs[XFRMA_IF_ID])
                xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
-               if (!xp->if_id) {
-                       err = -EINVAL;
-                       goto error;
-               }
-       }
 
        return xp;
  error:
@@ -2608,6 +2593,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
        int n = 0;
        struct net *net = sock_net(skb->sk);
        struct xfrm_encap_tmpl  *encap = NULL;
+       u32 if_id = 0;
 
        if (attrs[XFRMA_MIGRATE] == NULL)
                return -EINVAL;
@@ -2632,7 +2618,10 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
                        return -ENOMEM;
        }
 
-       err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap);
+       if (attrs[XFRMA_IF_ID])
+               if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
+
+       err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap, if_id);
 
        kfree(encap);
 
index 71f0177e8716ee04f2ddb76ef9b945d421441ded..599429f99f99fdad01e4d5a8182d50ce33b2c2e0 100644 (file)
@@ -62,6 +62,19 @@ config INTEGRITY_PLATFORM_KEYRING
          provided by the platform for verifying the kexec'ed kerned image
          and, possibly, the initramfs signature.
 
+config INTEGRITY_MACHINE_KEYRING
+       bool "Provide a keyring to which Machine Owner Keys may be added"
+       depends on SECONDARY_TRUSTED_KEYRING
+       depends on INTEGRITY_ASYMMETRIC_KEYS
+       depends on SYSTEM_BLACKLIST_KEYRING
+       depends on LOAD_UEFI_KEYS
+       depends on !IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
+       help
+        If set, provide a keyring to which Machine Owner Keys (MOK) may
+        be added. This keyring shall contain just MOK keys.  Unlike keys
+        in the platform keyring, keys contained in the .machine keyring will
+        be trusted within the kernel.
+
 config LOAD_UEFI_KEYS
        depends on INTEGRITY_PLATFORM_KEYRING
        depends on EFI
index 7ee39d66cf166ce1216cba87cd2044a25b9eb9a7..d0ffe37dc1d646f266ebcea57ca7c23cf0839888 100644 (file)
@@ -10,6 +10,7 @@ integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
 integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
 integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
 integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o
+integrity-$(CONFIG_INTEGRITY_MACHINE_KEYRING) += platform_certs/machine_keyring.o
 integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
                                      platform_certs/load_uefi.o \
                                      platform_certs/keyring_handler.o
index 3b06a01bd0fdd5ae59f86ff74735befd5737de77..c8c8a4a4e7a00c800f10ab939839ca00bf378691 100644 (file)
@@ -30,6 +30,7 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
        ".ima",
 #endif
        ".platform",
+       ".machine",
 };
 
 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
@@ -111,6 +112,8 @@ static int __init __integrity_init_keyring(const unsigned int id,
        } else {
                if (id == INTEGRITY_KEYRING_PLATFORM)
                        set_platform_trusted_keys(keyring[id]);
+               if (id == INTEGRITY_KEYRING_MACHINE && trust_moklist())
+                       set_machine_trusted_keys(keyring[id]);
                if (id == INTEGRITY_KEYRING_IMA)
                        load_module_cert(keyring[id]);
        }
@@ -126,7 +129,8 @@ int __init integrity_init_keyring(const unsigned int id)
        perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
                | KEY_USR_READ | KEY_USR_SEARCH;
 
-       if (id == INTEGRITY_KEYRING_PLATFORM) {
+       if (id == INTEGRITY_KEYRING_PLATFORM ||
+           id == INTEGRITY_KEYRING_MACHINE) {
                restriction = NULL;
                goto out;
        }
@@ -139,7 +143,14 @@ int __init integrity_init_keyring(const unsigned int id)
                return -ENOMEM;
 
        restriction->check = restrict_link_to_ima;
-       perm |= KEY_USR_WRITE;
+
+       /*
+        * MOK keys can only be added through a read-only runtime services
+        * UEFI variable during boot. No additional keys shall be allowed to
+        * load into the machine keyring following init from userspace.
+        */
+       if (id != INTEGRITY_KEYRING_MACHINE)
+               perm |= KEY_USR_WRITE;
 
 out:
        return __integrity_init_keyring(id, perm, restriction);
index 547425c20e11720a40a8fd5a3b5f3f5b007fd905..2e214c76115869ac2f0d576f609b3e12a68075c6 100644 (file)
@@ -151,7 +151,8 @@ int integrity_kernel_read(struct file *file, loff_t offset,
 #define INTEGRITY_KEYRING_EVM          0
 #define INTEGRITY_KEYRING_IMA          1
 #define INTEGRITY_KEYRING_PLATFORM     2
-#define INTEGRITY_KEYRING_MAX          3
+#define INTEGRITY_KEYRING_MACHINE      3
+#define INTEGRITY_KEYRING_MAX          4
 
 extern struct dentry *integrity_dir;
 
@@ -283,3 +284,17 @@ static inline void __init add_to_platform_keyring(const char *source,
 {
 }
 #endif
+
+#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+void __init add_to_machine_keyring(const char *source, const void *data, size_t len);
+bool __init trust_moklist(void);
+#else
+static inline void __init add_to_machine_keyring(const char *source,
+                                                 const void *data, size_t len)
+{
+}
+static inline bool __init trust_moklist(void)
+{
+       return false;
+}
+#endif
index 5604bd57c99077d8238cde7b5e6335a13cf16dce..1db4d3b4356dc4d32cd373fceb0bbfc8fb3271c7 100644 (file)
@@ -9,6 +9,7 @@
 #include <keys/asymmetric-type.h>
 #include <keys/system_keyring.h>
 #include "../integrity.h"
+#include "keyring_handler.h"
 
 static efi_guid_t efi_cert_x509_guid __initdata = EFI_CERT_X509_GUID;
 static efi_guid_t efi_cert_x509_sha256_guid __initdata =
@@ -66,7 +67,7 @@ static __init void uefi_revocation_list_x509(const char *source,
 
 /*
  * Return the appropriate handler for particular signature list types found in
- * the UEFI db and MokListRT tables.
+ * the UEFI db tables.
  */
 __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type)
 {
@@ -75,6 +76,21 @@ __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type)
        return 0;
 }
 
+/*
+ * Return the appropriate handler for particular signature list types found in
+ * the MokListRT tables.
+ */
+__init efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type)
+{
+       if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) {
+               if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) && trust_moklist())
+                       return add_to_machine_keyring;
+               else
+                       return add_to_platform_keyring;
+       }
+       return 0;
+}
+
 /*
  * Return the appropriate handler for particular signature list types found in
  * the UEFI dbx and MokListXRT tables.
index 2462bfa08fe3418cf81b9722908987943067d465..284558f30411eb25004500bc96a49f8a51b3bb5a 100644 (file)
@@ -24,6 +24,11 @@ void blacklist_binary(const char *source, const void *data, size_t len);
  */
 efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type);
 
+/*
+ * Return the handler for particular signature list types found in the mok.
+ */
+efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type);
+
 /*
  * Return the handler for particular signature list types found in the dbx.
  */
index 08b6d12f99b4fd7abcff197dada5c448569a0f1c..5f45c3c07dbd481ed087f878a1f286652e6fd235 100644 (file)
@@ -95,7 +95,7 @@ static int __init load_moklist_certs(void)
                rc = parse_efi_signature_list("UEFI:MokListRT (MOKvar table)",
                                              mokvar_entry->data,
                                              mokvar_entry->data_size,
-                                             get_handler_for_db);
+                                             get_handler_for_mok);
                /* All done if that worked. */
                if (!rc)
                        return rc;
@@ -110,7 +110,7 @@ static int __init load_moklist_certs(void)
        mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status);
        if (mok) {
                rc = parse_efi_signature_list("UEFI:MokListRT",
-                                             mok, moksize, get_handler_for_db);
+                                             mok, moksize, get_handler_for_mok);
                kfree(mok);
                if (rc)
                        pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
diff --git a/security/integrity/platform_certs/machine_keyring.c b/security/integrity/platform_certs/machine_keyring.c
new file mode 100644 (file)
index 0000000..7aaed79
--- /dev/null
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Machine keyring routines.
+ *
+ * Copyright (c) 2021, Oracle and/or its affiliates.
+ */
+
+#include <linux/efi.h>
+#include "../integrity.h"
+
+static bool trust_mok;
+
+static __init int machine_keyring_init(void)
+{
+       int rc;
+
+       rc = integrity_init_keyring(INTEGRITY_KEYRING_MACHINE);
+       if (rc)
+               return rc;
+
+       pr_notice("Machine keyring initialized\n");
+       return 0;
+}
+device_initcall(machine_keyring_init);
+
+void __init add_to_machine_keyring(const char *source, const void *data, size_t len)
+{
+       key_perm_t perm;
+       int rc;
+
+       perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
+       rc = integrity_load_cert(INTEGRITY_KEYRING_MACHINE, source, data, len, perm);
+
+       /*
+        * Some MOKList keys may not pass the machine keyring restrictions.
+        * If the restriction check does not pass and the platform keyring
+        * is configured, try to add it into that keyring instead.
+        */
+       if (rc && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING))
+               rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source,
+                                        data, len, perm);
+
+       if (rc)
+               pr_info("Error adding keys to machine keyring %s\n", source);
+}
+
+/*
+ * Try to load the MokListTrustedRT MOK variable to see if we should trust
+ * the MOK keys within the kernel. It is not an error if this variable
+ * does not exist.  If it does not exist, MOK keys should not be trusted
+ * within the machine keyring.
+ */
+static __init bool uefi_check_trust_mok_keys(void)
+{
+       struct efi_mokvar_table_entry *mokvar_entry;
+
+       mokvar_entry = efi_mokvar_entry_find("MokListTrustedRT");
+
+       if (mokvar_entry)
+               return true;
+
+       return false;
+}
+
+bool __init trust_moklist(void)
+{
+       static bool initialized;
+
+       if (!initialized) {
+               initialized = true;
+
+               if (uefi_check_trust_mok_keys())
+                       trust_mok = true;
+       }
+
+       return trust_mok;
+}
index 5de0d599a2748f50f3f4b144b8440f08bc57581b..97bc27bbf079779f193d006ec89e4e2aad881fd1 100644 (file)
@@ -135,15 +135,23 @@ static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_par
 
        switch (op) {
        case KEYCTL_PKEY_ENCRYPT:
+               if (uparams.in_len  > info.max_dec_size ||
+                   uparams.out_len > info.max_enc_size)
+                       return -EINVAL;
+               break;
        case KEYCTL_PKEY_DECRYPT:
                if (uparams.in_len  > info.max_enc_size ||
                    uparams.out_len > info.max_dec_size)
                        return -EINVAL;
                break;
        case KEYCTL_PKEY_SIGN:
+               if (uparams.in_len  > info.max_data_size ||
+                   uparams.out_len > info.max_sig_size)
+                       return -EINVAL;
+               break;
        case KEYCTL_PKEY_VERIFY:
-               if (uparams.in_len  > info.max_sig_size ||
-                   uparams.out_len > info.max_data_size)
+               if (uparams.in_len  > info.max_data_size ||
+                   uparams.in2_len > info.max_sig_size)
                        return -EINVAL;
                break;
        default:
@@ -151,7 +159,7 @@ static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_par
        }
 
        params->in_len  = uparams.in_len;
-       params->out_len = uparams.out_len;
+       params->out_len = uparams.out_len; /* Note: same as in2_len */
        return 0;
 }
 
index d5c891d8d353480f26efe2dce630260ae9e9a6f5..9b9d3ef79cbe3501c1e218cc43ee006ede69c072 100644 (file)
@@ -27,10 +27,10 @@ module_param_named(source, trusted_key_source, charp, 0);
 MODULE_PARM_DESC(source, "Select trusted keys source (tpm or tee)");
 
 static const struct trusted_key_source trusted_key_sources[] = {
-#if defined(CONFIG_TCG_TPM)
+#if IS_REACHABLE(CONFIG_TCG_TPM)
        { "tpm", &trusted_key_tpm_ops },
 #endif
-#if defined(CONFIG_TEE)
+#if IS_REACHABLE(CONFIG_TEE)
        { "tee", &trusted_key_tee_ops },
 #endif
 };
@@ -351,7 +351,7 @@ static int __init init_trusted(void)
 
 static void __exit cleanup_trusted(void)
 {
-       static_call(trusted_key_exit)();
+       static_call_cond(trusted_key_exit)();
 }
 
 late_initcall(init_trusted);
index 727c4e43219d7106c95a062377093b7a8cf50b6a..ff7aea6b3774a86a28a60a05688b551a0de7c2f9 100644 (file)
@@ -77,7 +77,7 @@ void selinux_ima_measure_state_locked(struct selinux_state *state)
        size_t policy_len;
        int rc = 0;
 
-       WARN_ON(!mutex_is_locked(&state->policy_mutex));
+       lockdep_assert_held(&state->policy_mutex);
 
        state_str = selinux_ima_collect_state(state);
        if (!state_str) {
@@ -117,7 +117,7 @@ void selinux_ima_measure_state_locked(struct selinux_state *state)
  */
 void selinux_ima_measure_state(struct selinux_state *state)
 {
-       WARN_ON(mutex_is_locked(&state->policy_mutex));
+       lockdep_assert_not_held(&state->policy_mutex);
 
        mutex_lock(&state->policy_mutex);
        selinux_ima_measure_state_locked(state);
index 4aaee1873a11a9c0141bb1607a09f370eedcfda7..4415fb364d4dc15b60a76b6791a7554044e218ab 100644 (file)
@@ -150,7 +150,6 @@ static const struct snd_kcontrol_new cs4265_snd_controls[] = {
        SOC_SINGLE("E to F Buffer Disable Switch", CS4265_SPDIF_CTL1,
                                6, 1, 0),
        SOC_ENUM("C Data Access", cam_mode_enum),
-       SOC_SINGLE("SPDIF Switch", CS4265_SPDIF_CTL2, 5, 1, 1),
        SOC_SINGLE("Validity Bit Control Switch", CS4265_SPDIF_CTL2,
                                3, 1, 0),
        SOC_ENUM("SPDIF Mono/Stereo", spdif_mono_stereo_enum),
@@ -186,7 +185,7 @@ static const struct snd_soc_dapm_widget cs4265_dapm_widgets[] = {
 
        SND_SOC_DAPM_SWITCH("Loopback", SND_SOC_NOPM, 0, 0,
                        &loopback_ctl),
-       SND_SOC_DAPM_SWITCH("SPDIF", SND_SOC_NOPM, 0, 0,
+       SND_SOC_DAPM_SWITCH("SPDIF", CS4265_SPDIF_CTL2, 5, 1,
                        &spdif_switch),
        SND_SOC_DAPM_SWITCH("DAC", CS4265_PWRCTL, 1, 1,
                        &dac_switch),
index 03ea9591fb164e0979baae743b555ef0ec66208b..a0ca58ba16273b3767107512ede7cc214b1495cc 100644 (file)
@@ -319,7 +319,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
        if (ucontrol->value.integer.value[0] < 0)
                return -EINVAL;
        val = ucontrol->value.integer.value[0];
-       if (mc->platform_max && val > mc->platform_max)
+       if (mc->platform_max && ((int)val + min) > mc->platform_max)
                return -EINVAL;
        if (val > max - min)
                return -EINVAL;
@@ -332,7 +332,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
                if (ucontrol->value.integer.value[1] < 0)
                        return -EINVAL;
                val2 = ucontrol->value.integer.value[1];
-               if (mc->platform_max && val2 > mc->platform_max)
+               if (mc->platform_max && ((int)val2 + min) > mc->platform_max)
                        return -EINVAL;
                if (val2 > max - min)
                        return -EINVAL;
index 1c94eaff1931b993f02ac73e08500767699e9b5f..4a3ff6468aa7597bba50d2f160d375d6b705ac18 100644 (file)
@@ -1261,7 +1261,7 @@ static int had_pcm_mmap(struct snd_pcm_substream *substream,
 {
        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
        return remap_pfn_range(vma, vma->vm_start,
-                       substream->dma_buffer.addr >> PAGE_SHIFT,
+                       substream->runtime->dma_addr >> PAGE_SHIFT,
                        vma->vm_end - vma->vm_start, vma->vm_page_prot);
 }
 
index b3edde68bc3e013c66d3272e8848a090800362d3..323e251ed37bc0f6bc2fc4f8de8143a1872ed8f2 100644 (file)
@@ -281,6 +281,11 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED       3
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED            (1U << 4)
 
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3    KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL          0
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL              1
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED       2
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE              (0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
index 6db4e2932b3d865785f179f5486106803b13629e..65d147974f8d95e63792343135c6589a423afef6 100644 (file)
 /* FREE!                                ( 7*32+10) */
 #define X86_FEATURE_PTI                        ( 7*32+11) /* Kernel Page Table Isolation enabled */
 #define X86_FEATURE_RETPOLINE          ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
-#define X86_FEATURE_RETPOLINE_AMD      ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
+#define X86_FEATURE_RETPOLINE_LFENCE   ( 7*32+13) /* "" Use LFENCE for Spectre variant 2 */
 #define X86_FEATURE_INTEL_PPIN         ( 7*32+14) /* Intel Processor Inventory Number */
 #define X86_FEATURE_CDP_L2             ( 7*32+15) /* Code and Data Prioritization L2 */
 #define X86_FEATURE_MSR_SPEC_CTRL      ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
index dc632b41f1356960495f2cb158ba0c2c072f96ca..65c0d9ce1e295bbe4dc25a6c8c6f8aff09203c7e 100644 (file)
@@ -124,7 +124,7 @@ struct insn {
 #define X86_VEX_B(vex) ((vex) & 0x20)  /* VEX3 Byte1 */
 #define X86_VEX_L(vex) ((vex) & 0x04)  /* VEX3 Byte2, VEX2 Byte1 */
 /* VEX bit fields */
-#define X86_EVEX_M(vex)        ((vex) & 0x03)          /* EVEX Byte1 */
+#define X86_EVEX_M(vex)        ((vex) & 0x07)          /* EVEX Byte1 */
 #define X86_VEX3_M(vex)        ((vex) & 0x1f)          /* VEX3 Byte1 */
 #define X86_VEX2_M     1                       /* VEX2.M always 1 */
 #define X86_VEX_V(vex) (((vex) & 0x78) >> 3)   /* VEX3 Byte2, VEX2 Byte1 */
index 3faf0f97edb1bcd3ebdb2d9d93535b091f8136bf..a4a39c3e0f19674788c8ec8f5baf5a6406599d1d 100644 (file)
 #define MSR_AMD64_ICIBSEXTDCTL         0xc001103c
 #define MSR_AMD64_IBSOPDATA4           0xc001103d
 #define MSR_AMD64_IBS_REG_COUNT_MAX    8 /* includes MSR_AMD64_IBSBRTARGET */
+#define MSR_AMD64_SVM_AVIC_DOORBELL    0xc001011b
 #define MSR_AMD64_VM_PAGE_FLUSH                0xc001011e
 #define MSR_AMD64_SEV_ES_GHCB          0xc0010130
 #define MSR_AMD64_SEV                  0xc0010131
index 59cf2343f3d906fb1bfb3d712edb8f34c39c62ae..d0d7b9bc6cad394c2de1b241956336a7ed9e255e 100644 (file)
@@ -27,8 +27,7 @@
  * Output:
  * rax original destination
  */
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK(memcpy)
+SYM_FUNC_START(__memcpy)
        ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
                      "jmp memcpy_erms", X86_FEATURE_ERMS
 
@@ -40,11 +39,12 @@ SYM_FUNC_START_WEAK(memcpy)
        movl %edx, %ecx
        rep movsb
        RET
-SYM_FUNC_END(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
-EXPORT_SYMBOL(memcpy)
+SYM_FUNC_END(__memcpy)
 EXPORT_SYMBOL(__memcpy)
 
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
 /*
  * memcpy_erms() - enhanced fast string memcpy. This is faster and
  * simpler than memcpy. Use memcpy_erms when possible.
index d624f2bc42f1689c732452cc003df043c80f2cab..fc9ffd3ff3b213a38448d5fbff5493989e21a158 100644 (file)
@@ -17,7 +17,6 @@
  *
  * rax   original destination
  */
-SYM_FUNC_START_WEAK(memset)
 SYM_FUNC_START(__memset)
        /*
         * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
@@ -42,10 +41,11 @@ SYM_FUNC_START(__memset)
        movq %r9,%rax
        RET
 SYM_FUNC_END(__memset)
-SYM_FUNC_END_ALIAS(memset)
-EXPORT_SYMBOL(memset)
 EXPORT_SYMBOL(__memset)
 
+SYM_FUNC_ALIAS_WEAK(memset, __memset)
+EXPORT_SYMBOL(memset)
+
 /*
  * ISO C memset - set a memory block to a byte value. This function uses
  * enhanced rep stosb to override the fast string function.
index ec31f5b60323ded53305f65594c027c1f66c81ca..d12d1358f96d2ec784f4b9281c1ea7f39b3ee0d2 100644 (file)
@@ -690,7 +690,10 @@ AVXcode: 2
 45: vpsrlvd/q Vx,Hx,Wx (66),(v)
 46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
 47: vpsllvd/q Vx,Hx,Wx (66),(v)
-# Skip 0x48-0x4b
+# Skip 0x48
+49: TILERELEASE (v1),(000),(11B) | LDTILECFG Mtc (v1)(000) | STTILECFG Mtc (66),(v1),(000) | TILEZERO Vt (F2),(v1),(11B)
+# Skip 0x4a
+4b: TILELOADD Vt,Wsm (F2),(v1) | TILELOADDT1 Vt,Wsm (66),(v1) | TILESTORED Wsm,Vt (F3),(v)
 4c: vrcp14ps/d Vpd,Wpd (66),(ev)
 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
@@ -705,7 +708,10 @@ AVXcode: 2
 59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
 5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
 5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
-# Skip 0x5c-0x61
+5c: TDPBF16PS Vt,Wt,Ht (F3),(v1)
+# Skip 0x5d
+5e: TDPBSSD Vt,Wt,Ht (F2),(v1) | TDPBSUD Vt,Wt,Ht (F3),(v1) | TDPBUSD Vt,Wt,Ht (66),(v1) | TDPBUUD Vt,Wt,Ht (v1)
+# Skip 0x5f-0x61
 62: vpexpandb/w Vx,Wx (66),(ev)
 63: vpcompressb/w Wx,Vx (66),(ev)
 64: vpblendmd/q Vx,Hx,Wx (66),(ev)
@@ -822,9 +828,9 @@ AVXcode: 3
 05: vpermilpd Vx,Wx,Ib (66),(v)
 06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
 07:
-08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
+08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) | vrndscaleph Vx,Wx,Ib (evo)
 09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
-0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
+0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) | vrndscalesh Vx,Hx,Wx,Ib (evo)
 0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
 0c: vblendps Vx,Hx,Wx,Ib (66)
 0d: vblendpd Vx,Hx,Wx,Ib (66)
@@ -846,8 +852,8 @@ AVXcode: 3
 22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
 23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
 25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
-26: vgetmantps/d Vx,Wx,Ib (66),(ev)
-27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
+26: vgetmantps/d Vx,Wx,Ib (66),(ev) | vgetmantph Vx,Wx,Ib (ev)
+27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) | vgetmantsh Vx,Hx,Wx,Ib (ev)
 30: kshiftrb/w Vk,Uk,Ib (66),(v)
 31: kshiftrd/q Vk,Uk,Ib (66),(v)
 32: kshiftlb/w Vk,Uk,Ib (66),(v)
@@ -871,23 +877,102 @@ AVXcode: 3
 51: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
 54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
 55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
-56: vreduceps/d Vx,Wx,Ib (66),(ev)
-57: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
+56: vreduceps/d Vx,Wx,Ib (66),(ev) | vreduceph Vx,Wx,Ib (ev)
+57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) | vreducesh Vx,Hx,Wx,Ib (ev)
 60: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
 61: vpcmpestri Vdq,Wdq,Ib (66),(v1)
 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
 63: vpcmpistri Vdq,Wdq,Ib (66),(v1)
-66: vfpclassps/d Vk,Wx,Ib (66),(ev)
-67: vfpclassss/d Vk,Wx,Ib (66),(ev)
+66: vfpclassps/d Vk,Wx,Ib (66),(ev) | vfpclassph Vx,Wx,Ib (ev)
+67: vfpclassss/d Vk,Wx,Ib (66),(ev) | vfpclasssh Vx,Wx,Ib (ev)
 70: vpshldw Vx,Hx,Wx,Ib (66),(ev)
 71: vpshldd/q Vx,Hx,Wx,Ib (66),(ev)
 72: vpshrdw Vx,Hx,Wx,Ib (66),(ev)
 73: vpshrdd/q Vx,Hx,Wx,Ib (66),(ev)
+c2: vcmpph Vx,Hx,Wx,Ib (ev) | vcmpsh Vx,Hx,Wx,Ib (F3),(ev)
 cc: sha1rnds4 Vdq,Wdq,Ib
 ce: vgf2p8affineqb Vx,Wx,Ib (66)
 cf: vgf2p8affineinvqb Vx,Wx,Ib (66)
 df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
-f0: RORX Gy,Ey,Ib (F2),(v)
+f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B)
+EndTable
+
+Table: EVEX map 5
+Referrer:
+AVXcode: 5
+10: vmovsh Vx,Hx,Wx (F3),(ev) | vmovsh Vx,Wx (F3),(ev)
+11: vmovsh Wx,Hx,Vx (F3),(ev) | vmovsh Wx,Vx (F3),(ev)
+1d: vcvtps2phx Vx,Wx (66),(ev) | vcvtss2sh Vx,Hx,Wx (ev)
+2a: vcvtsi2sh Vx,Hx,Wx (F3),(ev)
+2c: vcvttsh2si Vx,Wx (F3),(ev)
+2d: vcvtsh2si Vx,Wx (F3),(ev)
+2e: vucomish Vx,Wx (ev)
+2f: vcomish Vx,Wx (ev)
+51: vsqrtph Vx,Wx (ev) | vsqrtsh Vx,Hx,Wx (F3),(ev)
+58: vaddph Vx,Hx,Wx (ev) | vaddsh Vx,Hx,Wx (F3),(ev)
+59: vmulph Vx,Hx,Wx (ev) | vmulsh Vx,Hx,Wx (F3),(ev)
+5a: vcvtpd2ph Vx,Wx (66),(ev) | vcvtph2pd Vx,Wx (ev) | vcvtsd2sh Vx,Hx,Wx (F2),(ev) | vcvtsh2sd Vx,Hx,Wx (F3),(ev)
+5b: vcvtdq2ph Vx,Wx (ev) | vcvtph2dq Vx,Wx (66),(ev) | vcvtqq2ph Vx,Wx (ev) | vcvttph2dq Vx,Wx (F3),(ev)
+5c: vsubph Vx,Hx,Wx (ev) | vsubsh Vx,Hx,Wx (F3),(ev)
+5d: vminph Vx,Hx,Wx (ev) | vminsh Vx,Hx,Wx (F3),(ev)
+5e: vdivph Vx,Hx,Wx (ev) | vdivsh Vx,Hx,Wx (F3),(ev)
+5f: vmaxph Vx,Hx,Wx (ev) | vmaxsh Vx,Hx,Wx (F3),(ev)
+6e: vmovw Vx,Wx (66),(ev)
+78: vcvttph2udq Vx,Wx (ev) | vcvttph2uqq Vx,Wx (66),(ev) | vcvttsh2usi Vx,Wx (F3),(ev)
+79: vcvtph2udq Vx,Wx (ev) | vcvtph2uqq Vx,Wx (66),(ev) | vcvtsh2usi Vx,Wx (F3),(ev)
+7a: vcvttph2qq Vx,Wx (66),(ev) | vcvtudq2ph Vx,Wx (F2),(ev) | vcvtuqq2ph Vx,Wx (F2),(ev)
+7b: vcvtph2qq Vx,Wx (66),(ev) | vcvtusi2sh Vx,Hx,Wx (F3),(ev)
+7c: vcvttph2uw Vx,Wx (ev) | vcvttph2w Vx,Wx (66),(ev)
+7d: vcvtph2uw Vx,Wx (ev) | vcvtph2w Vx,Wx (66),(ev) | vcvtuw2ph Vx,Wx (F2),(ev) | vcvtw2ph Vx,Wx (F3),(ev)
+7e: vmovw Wx,Vx (66),(ev)
+EndTable
+
+Table: EVEX map 6
+Referrer:
+AVXcode: 6
+13: vcvtph2psx Vx,Wx (66),(ev) | vcvtsh2ss Vx,Hx,Wx (ev)
+2c: vscalefph Vx,Hx,Wx (66),(ev)
+2d: vscalefsh Vx,Hx,Wx (66),(ev)
+42: vgetexpph Vx,Wx (66),(ev)
+43: vgetexpsh Vx,Hx,Wx (66),(ev)
+4c: vrcpph Vx,Wx (66),(ev)
+4d: vrcpsh Vx,Hx,Wx (66),(ev)
+4e: vrsqrtph Vx,Wx (66),(ev)
+4f: vrsqrtsh Vx,Hx,Wx (66),(ev)
+56: vfcmaddcph Vx,Hx,Wx (F2),(ev) | vfmaddcph Vx,Hx,Wx (F3),(ev)
+57: vfcmaddcsh Vx,Hx,Wx (F2),(ev) | vfmaddcsh Vx,Hx,Wx (F3),(ev)
+96: vfmaddsub132ph Vx,Hx,Wx (66),(ev)
+97: vfmsubadd132ph Vx,Hx,Wx (66),(ev)
+98: vfmadd132ph Vx,Hx,Wx (66),(ev)
+99: vfmadd132sh Vx,Hx,Wx (66),(ev)
+9a: vfmsub132ph Vx,Hx,Wx (66),(ev)
+9b: vfmsub132sh Vx,Hx,Wx (66),(ev)
+9c: vfnmadd132ph Vx,Hx,Wx (66),(ev)
+9d: vfnmadd132sh Vx,Hx,Wx (66),(ev)
+9e: vfnmsub132ph Vx,Hx,Wx (66),(ev)
+9f: vfnmsub132sh Vx,Hx,Wx (66),(ev)
+a6: vfmaddsub213ph Vx,Hx,Wx (66),(ev)
+a7: vfmsubadd213ph Vx,Hx,Wx (66),(ev)
+a8: vfmadd213ph Vx,Hx,Wx (66),(ev)
+a9: vfmadd213sh Vx,Hx,Wx (66),(ev)
+aa: vfmsub213ph Vx,Hx,Wx (66),(ev)
+ab: vfmsub213sh Vx,Hx,Wx (66),(ev)
+ac: vfnmadd213ph Vx,Hx,Wx (66),(ev)
+ad: vfnmadd213sh Vx,Hx,Wx (66),(ev)
+ae: vfnmsub213ph Vx,Hx,Wx (66),(ev)
+af: vfnmsub213sh Vx,Hx,Wx (66),(ev)
+b6: vfmaddsub231ph Vx,Hx,Wx (66),(ev)
+b7: vfmsubadd231ph Vx,Hx,Wx (66),(ev)
+b8: vfmadd231ph Vx,Hx,Wx (66),(ev)
+b9: vfmadd231sh Vx,Hx,Wx (66),(ev)
+ba: vfmsub231ph Vx,Hx,Wx (66),(ev)
+bb: vfmsub231sh Vx,Hx,Wx (66),(ev)
+bc: vfnmadd231ph Vx,Hx,Wx (66),(ev)
+bd: vfnmadd231sh Vx,Hx,Wx (66),(ev)
+be: vfnmsub231ph Vx,Hx,Wx (66),(ev)
+bf: vfnmsub231sh Vx,Hx,Wx (66),(ev)
+d6: vfcmulcph Vx,Hx,Wx (F2),(ev) | vfmulcph Vx,Hx,Wx (F3),(ev)
+d7: vfcmulcsh Vx,Hx,Wx (F2),(ev) | vfmulcsh Vx,Hx,Wx (F3),(ev)
 EndTable
 
 GrpTable: Grp1
@@ -970,7 +1055,7 @@ GrpTable: Grp7
 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) | ENCLU (111),(11B)
 3: LIDT Ms
 4: SMSW Mw/Rv
-5: rdpkru (110),(11B) | wrpkru (111),(11B) | SAVEPREVSSP (F3),(010),(11B) | RSTORSSP Mq (F3) | SETSSBSY (F3),(000),(11B)
+5: rdpkru (110),(11B) | wrpkru (111),(11B) | SAVEPREVSSP (F3),(010),(11B) | RSTORSSP Mq (F3) | SETSSBSY (F3),(000),(11B) | CLUI (F3),(110),(11B) | SERIALIZE (000),(11B) | STUI (F3),(111),(11B) | TESTUI (F3)(101)(11B) | UIRET (F3),(100),(11B) | XRESLDTRK (F2),(000),(11B) | XSUSLDTRK (F2),(001),(11B)
 6: LMSW Ew
 7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
 EndTable
@@ -987,7 +1072,7 @@ GrpTable: Grp9
 3: xrstors
 4: xsavec
 5: xsaves
-6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
+6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) | SENDUIPI Gq (F3)
 7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
 EndTable
 
index 1600b17dbb8ab67e88e8fee1a2d83ed7dda5b106..1d3a90d93fe2676426a11d754557563c8f4c89b3 100644 (file)
@@ -11,7 +11,7 @@ from drgn.helpers.linux import list_for_each_entry, list_empty
 from drgn.helpers.linux import for_each_page
 from drgn.helpers.linux.cpumask import for_each_online_cpu
 from drgn.helpers.linux.percpu import per_cpu_ptr
-from drgn import container_of, FaultError, Object
+from drgn import container_of, FaultError, Object, cast
 
 
 DESC = """
@@ -69,15 +69,15 @@ def oo_objects(s):
 
 
 def count_partial(n, fn):
-    nr_pages = 0
-    for page in list_for_each_entry('struct page', n.partial.address_of_(),
-                                    'lru'):
-         nr_pages += fn(page)
-    return nr_pages
+    nr_objs = 0
+    for slab in list_for_each_entry('struct slab', n.partial.address_of_(),
+                                    'slab_list'):
+         nr_objs += fn(slab)
+    return nr_objs
 
 
-def count_free(page):
-    return page.objects - page.inuse
+def count_free(slab):
+    return slab.objects - slab.inuse
 
 
 def slub_get_slabinfo(s, cfg):
@@ -145,14 +145,14 @@ def detect_kernel_config():
     return cfg
 
 
-def for_each_slab_page(prog):
+def for_each_slab(prog):
     PGSlab = 1 << prog.constant('PG_slab')
     PGHead = 1 << prog.constant('PG_head')
 
     for page in for_each_page(prog):
         try:
             if page.flags.value_() & PGSlab:
-                yield page
+                yield cast('struct slab *', page)
         except FaultError:
             pass
 
@@ -190,13 +190,13 @@ def main():
                                        'list'):
             obj_cgroups.add(ptr.value_())
 
-        # look over all slab pages, belonging to non-root memcgs
-        # and look for objects belonging to the given memory cgroup
-        for page in for_each_slab_page(prog):
-            objcg_vec_raw = page.memcg_data.value_()
+        # look over all slab folios and look for objects belonging
+        # to the given memory cgroup
+        for slab in for_each_slab(prog):
+            objcg_vec_raw = slab.memcg_data.value_()
             if objcg_vec_raw == 0:
                 continue
-            cache = page.slab_cache
+            cache = slab.slab_cache
             if not cache:
                 continue
             addr = cache.value_()
index 5191b57e156220bd7fc6d85940c301e16cc1645a..507ee1f2aa96b12121fabb824f3c62ab3056a65b 100644 (file)
@@ -1134,6 +1134,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_VM_GPA_BITS 207
 #define KVM_CAP_XSAVE2 208
 #define KVM_CAP_SYS_ATTRIBUTES 209
+#define KVM_CAP_PPC_AIL_MODE_3 210
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index 9708ae8920616aec2e31524b25f59ef7c1d4f44c..ba429cadb18f36f35ced7f2af8ddb21e8367d635 100644 (file)
 "3e f2 ff 25 78 56 34 12 \tnotrack bnd jmp *0x12345678",},
 {{0x3e, 0xf2, 0xff, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "jmp", "indirect",
 "3e f2 ff a4 c8 78 56 34 12 \tnotrack bnd jmp *0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 58 cb    \tvaddph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 58 cb    \tvaddph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 58 cb    \tvaddph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 58 cb    \tvaddsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 58 8c c8 78 56 34 12 \tvaddsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x48, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 48 c2 eb 12 \tvcmple_oqph %zmm3,%zmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x48, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 48 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%eax,%ecx,8),%zmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x08, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 c2 eb 12 \tvcmple_oqph %xmm3,%xmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x08, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%eax,%ecx,8),%xmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x28, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 28 c2 eb 12 \tvcmple_oqph %ymm3,%ymm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x28, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 28 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%eax,%ecx,8),%ymm2,%k5",},
+{{0x62, 0xf3, 0x6e, 0x08, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6e 08 c2 eb 12 \tvcmple_oqsh %xmm3,%xmm2,%k5",},
+{{0x62, 0xf3, 0x6e, 0x08, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6e 08 c2 ac c8 78 56 34 12 12 \tvcmple_oqsh 0x12345678(%eax,%ecx,8),%xmm2,%k5",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2f, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 2f ca    \tvcomish %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 2f 8c c8 78 56 34 12 \tvcomish 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 5b ca    \tvcvtdq2ph %zmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 5b 8c c8 78 56 34 12 \tvcvtdq2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 5b ca    \tvcvtdq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 5b ca    \tvcvtdq2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0xfd, 0x48, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 fd 48 5a ca    \tvcvtpd2ph %zmm2,%xmm1",},
+{{0x62, 0xf5, 0xfd, 0x08, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 fd 08 5a ca    \tvcvtpd2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0xfd, 0x28, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 fd 28 5a ca    \tvcvtpd2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 5b ca    \tvcvtph2dq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 5b ca    \tvcvtph2dq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 5b ca    \tvcvtph2dq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 5a ca    \tvcvtph2pd %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 5a ca    \tvcvtph2pd %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 5a ca    \tvcvtph2pd %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x13, 0xca, }, 6, 0, "", "",
+"62 f2 7d 48 13 ca    \tvcvtph2ps %ymm2,%zmm1",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f2 7d 48 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 79 13 ca       \tvcvtph2ps %xmm2,%xmm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 79 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 7d 13 ca       \tvcvtph2ps %xmm2,%ymm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 7d 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 79 13 ca       \tvcvtph2ps %xmm2,%xmm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 79 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 7d 13 ca       \tvcvtph2ps %xmm2,%ymm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 7d 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x13, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 13 ca    \tvcvtph2psx %ymm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x13, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 13 ca    \tvcvtph2psx %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x13, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 13 ca    \tvcvtph2psx %xmm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7b ca    \tvcvtph2qq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7b ca    \tvcvtph2qq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7b ca    \tvcvtph2qq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 79 ca    \tvcvtph2udq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 79 ca    \tvcvtph2udq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 79 ca    \tvcvtph2udq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 79 ca    \tvcvtph2uqq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 79 ca    \tvcvtph2uqq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 79 ca    \tvcvtph2uqq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 7d ca    \tvcvtph2uw %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 7d ca    \tvcvtph2uw %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 7d ca    \tvcvtph2uw %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7d ca    \tvcvtph2w %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7d ca    \tvcvtph2w %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7d ca    \tvcvtph2w %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7d 48 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%zmm1,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x1d, 0xd1, 0x12, }, 7, 0, "", "",
+"62 f3 7d 48 1d d1 12 \tvcvtps2ph $0x12,%zmm2,%ymm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 7d 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%ymm1,0x12345678(%eax,%ecx,8)",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 79 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%xmm1,0x12345678(%eax,%ecx,8)",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 79 1d d1 12    \tvcvtps2ph $0x12,%xmm2,%xmm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 7d 1d d1 12    \tvcvtps2ph $0x12,%ymm2,%xmm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 7d 1d d1 12    \tvcvtps2ph $0x12,%ymm2,%xmm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 7d 1d 94 c8 78 56 34 12 12 \tvcvtps2ph $0x12,%ymm2,0x12345678(%eax,%ecx,8)",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 79 1d d1 12    \tvcvtps2ph $0x12,%xmm2,%xmm1",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 79 1d 94 c8 78 56 34 12 12 \tvcvtps2ph $0x12,%xmm2,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x1d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 1d ca    \tvcvtps2phx %zmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 1d 8c c8 78 56 34 12 \tvcvtps2phx 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x1d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 1d ca    \tvcvtps2phx %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x1d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 1d ca    \tvcvtps2phx %ymm2,%xmm1",},
+{{0x62, 0xf5, 0xfc, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 fc 48 5b ca    \tvcvtqq2ph %zmm2,%xmm1",},
+{{0x62, 0xf5, 0xfc, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 fc 08 5b ca    \tvcvtqq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0xfc, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 fc 28 5b ca    \tvcvtqq2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0xef, 0x08, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 ef 08 5a 8c c8 78 56 34 12 \tvcvtsd2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5a 8c c8 78 56 34 12 \tvcvtsh2sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x2d, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 2d 84 c8 78 56 34 12 \tvcvtsh2si 0x12345678(%eax,%ecx,8),%eax",},
+{{0x62, 0xf6, 0x6c, 0x08, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6c 08 13 8c c8 78 56 34 12 \tvcvtsh2ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x79, 0xc1, }, 6, 0, "", "",
+"62 f5 7e 08 79 c1    \tvcvtsh2usi %xmm1,%eax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x79, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 79 84 c8 78 56 34 12 \tvcvtsh2usi 0x12345678(%eax,%ecx,8),%eax",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x2a, 0xc8, }, 6, 0, "", "",
+"62 f5 6e 08 2a c8    \tvcvtsi2sh %eax,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x2a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 2a 8c c8 78 56 34 12 \tvcvtsi2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x2a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 2a 8c c8 78 56 34 12 \tvcvtsi2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x1d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 1d cb    \tvcvtss2sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 1d 8c c8 78 56 34 12 \tvcvtss2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7e 48 5b ca    \tvcvttph2dq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 48 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7e 08 5b ca    \tvcvttph2dq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7e 28 5b ca    \tvcvttph2dq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 28 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7a ca    \tvcvttph2qq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7a ca    \tvcvttph2qq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7a ca    \tvcvttph2qq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 78 ca    \tvcvttph2udq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 78 ca    \tvcvttph2udq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 78 ca    \tvcvttph2udq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 78 ca    \tvcvttph2uqq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 78 ca    \tvcvttph2uqq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 78 ca    \tvcvttph2uqq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 7c ca    \tvcvttph2uw %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 7c ca    \tvcvttph2uw %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 7c ca    \tvcvttph2uw %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7c ca    \tvcvttph2w %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7c ca    \tvcvttph2w %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7c ca    \tvcvttph2w %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x2c, 0xc1, }, 6, 0, "", "",
+"62 f5 7e 08 2c c1    \tvcvttsh2si %xmm1,%eax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x2c, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 2c 84 c8 78 56 34 12 \tvcvttsh2si 0x12345678(%eax,%ecx,8),%eax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x78, 0xc1, }, 6, 0, "", "",
+"62 f5 7e 08 78 c1    \tvcvttsh2usi %xmm1,%eax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x78, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 78 84 c8 78 56 34 12 \tvcvttsh2usi 0x12345678(%eax,%ecx,8),%eax",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7f 48 7a ca    \tvcvtudq2ph %zmm2,%ymm1",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 48 7a 8c c8 78 56 34 12 \tvcvtudq2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7f, 0x08, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7f 08 7a ca    \tvcvtudq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x28, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7f 28 7a ca    \tvcvtudq2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0xff, 0x48, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 ff 48 7a ca    \tvcvtuqq2ph %zmm2,%xmm1",},
+{{0x62, 0xf5, 0xff, 0x08, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 ff 08 7a ca    \tvcvtuqq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0xff, 0x28, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 ff 28 7a ca    \tvcvtuqq2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x7b, 0xc8, }, 6, 0, "", "",
+"62 f5 6e 08 7b c8    \tvcvtusi2sh %eax,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 7b 8c c8 78 56 34 12 \tvcvtusi2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 7b 8c c8 78 56 34 12 \tvcvtusi2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7f 48 7d ca    \tvcvtuw2ph %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 48 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7f, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7f 08 7d ca    \tvcvtuw2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 08 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7f 28 7d ca    \tvcvtuw2ph %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7f, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 28 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7e 48 7d ca    \tvcvtw2ph %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 48 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7e 08 7d ca    \tvcvtw2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7e 28 7d ca    \tvcvtw2ph %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 28 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5e cb    \tvdivph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5e cb    \tvdivph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5e cb    \tvdivph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5e cb    \tvdivsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5e 8c c8 78 56 34 12 \tvdivsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 48 56 cb    \tvfcmaddcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 48 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 56 cb    \tvfcmaddcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 28 56 cb    \tvfcmaddcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 28 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x57, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 57 cb    \tvfcmaddcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 57 8c c8 78 56 34 12 \tvfcmaddcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 48 d6 cb    \tvfcmulcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 48 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 d6 cb    \tvfcmulcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 28 d6 cb    \tvfcmulcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 28 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd7, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 d7 cb    \tvfcmulcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 d7 8c c8 78 56 34 12 \tvfcmulcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x98, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 98 cb    \tvfmadd132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x98, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 98 cb    \tvfmadd132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x98, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 98 cb    \tvfmadd132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x99, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 99 cb    \tvfmadd132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x99, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 99 8c c8 78 56 34 12 \tvfmadd132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 a8 cb    \tvfmadd213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a8 cb    \tvfmadd213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 a8 cb    \tvfmadd213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa9, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a9 cb    \tvfmadd213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa9, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a9 8c c8 78 56 34 12 \tvfmadd213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 b8 cb    \tvfmadd231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b8 cb    \tvfmadd231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 b8 cb    \tvfmadd231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb9, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b9 cb    \tvfmadd231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb9, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b9 8c c8 78 56 34 12 \tvfmadd231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 48 56 cb    \tvfmaddcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 48 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 56 cb    \tvfmaddcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 28 56 cb    \tvfmaddcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 28 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x57, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 57 cb    \tvfmaddcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 57 8c c8 78 56 34 12 \tvfmaddcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x96, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 96 cb    \tvfmaddsub132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x96, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 96 cb    \tvfmaddsub132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x96, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 96 cb    \tvfmaddsub132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 a6 cb    \tvfmaddsub213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a6 cb    \tvfmaddsub213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 a6 cb    \tvfmaddsub213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 b6 cb    \tvfmaddsub231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b6 cb    \tvfmaddsub231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 b6 cb    \tvfmaddsub231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9a, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 9a cb    \tvfmsub132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9a, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9a cb    \tvfmsub132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9a, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 9a cb    \tvfmsub132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9b, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9b cb    \tvfmsub132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9b 8c c8 78 56 34 12 \tvfmsub132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xaa, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 aa cb    \tvfmsub213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaa, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 aa cb    \tvfmsub213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xaa, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 aa cb    \tvfmsub213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xab, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ab cb    \tvfmsub213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xab, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ab 8c c8 78 56 34 12 \tvfmsub213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xba, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 ba cb    \tvfmsub231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xba, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ba cb    \tvfmsub231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xba, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 ba cb    \tvfmsub231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbb, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bb cb    \tvfmsub231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbb, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bb 8c c8 78 56 34 12 \tvfmsub231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x97, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 97 cb    \tvfmsubadd132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x97, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 97 cb    \tvfmsubadd132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x97, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 97 cb    \tvfmsubadd132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 a7 cb    \tvfmsubadd213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a7 cb    \tvfmsubadd213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 a7 cb    \tvfmsubadd213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 b7 cb    \tvfmsubadd231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b7 cb    \tvfmsubadd231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 b7 cb    \tvfmsubadd231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 48 d6 cb    \tvfmulcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 48 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 d6 cb    \tvfmulcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 28 d6 cb    \tvfmulcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 28 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd7, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 d7 cb    \tvfmulcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 d7 8c c8 78 56 34 12 \tvfmulcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 9c cb    \tvfnmadd132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9c cb    \tvfnmadd132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 9c cb    \tvfnmadd132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9d, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9d cb    \tvfnmadd132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9d 8c c8 78 56 34 12 \tvfnmadd132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xac, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 ac cb    \tvfnmadd213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xac, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ac cb    \tvfnmadd213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xac, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 ac cb    \tvfnmadd213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xad, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ad cb    \tvfnmadd213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xad, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ad 8c c8 78 56 34 12 \tvfnmadd213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbc, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 bc cb    \tvfnmadd231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbc, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bc cb    \tvfnmadd231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbc, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 bc cb    \tvfnmadd231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbd, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bd cb    \tvfnmadd231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbd, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bd 8c c8 78 56 34 12 \tvfnmadd231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9e, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 9e cb    \tvfnmsub132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9e, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9e cb    \tvfnmsub132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9e, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 9e cb    \tvfnmsub132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9f, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9f cb    \tvfnmsub132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9f 8c c8 78 56 34 12 \tvfnmsub132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xae, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 ae cb    \tvfnmsub213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xae, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ae cb    \tvfnmsub213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xae, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 ae cb    \tvfnmsub213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaf, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 af cb    \tvfnmsub213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaf, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 af 8c c8 78 56 34 12 \tvfnmsub213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbe, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 be cb    \tvfnmsub231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbe, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 be cb    \tvfnmsub231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbe, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 be cb    \tvfnmsub231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbf, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bf cb    \tvfnmsub231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbf, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bf 8c c8 78 56 34 12 \tvfnmsub231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x66, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 66 e9 12 \tvfpclassph $0x12,%zmm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x66, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 66 e9 12 \tvfpclassph $0x12,%xmm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x66, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 66 e9 12 \tvfpclassph $0x12,%ymm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x67, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 67 e9 12 \tvfpclasssh $0x12,%xmm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x67, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 67 ac c8 78 56 34 12 12 \tvfpclasssh $0x12,0x12345678(%eax,%ecx,8),%k5",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x42, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 42 ca    \tvgetexpph %zmm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x42, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 42 ca    \tvgetexpph %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x42, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 42 ca    \tvgetexpph %ymm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x43, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 43 cb    \tvgetexpsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x43, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 43 8c c8 78 56 34 12 \tvgetexpsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x26, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 26 ca 12 \tvgetmantph $0x12,%zmm2,%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 48 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x26, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 26 ca 12 \tvgetmantph $0x12,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x26, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 26 ca 12 \tvgetmantph $0x12,%ymm2,%ymm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 28 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x27, 0xcb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 27 cb 12 \tvgetmantsh $0x12,%xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x27, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 27 8c c8 78 56 34 12 12 \tvgetmantsh $0x12,0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5f cb    \tvmaxph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5f cb    \tvmaxph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5f cb    \tvmaxph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5f cb    \tvmaxsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5f 8c c8 78 56 34 12 \tvmaxsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5d cb    \tvminph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5d cb    \tvminph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5d cb    \tvminph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5d cb    \tvminsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5d 8c c8 78 56 34 12 \tvminsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x11, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 11 8c c8 78 56 34 12 \tvmovsh %xmm1,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x10, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 10 8c c8 78 56 34 12 \tvmovsh 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x10, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 10 cb    \tvmovsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7e, 0xc8, }, 6, 0, "", "",
+"62 f5 7d 08 7e c8    \tvmovw  %xmm1,%eax",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7e 8c c8 78 56 34 12 \tvmovw  %xmm1,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x6e, 0xc8, }, 6, 0, "", "",
+"62 f5 7d 08 6e c8    \tvmovw  %eax,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x6e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 6e 8c c8 78 56 34 12 \tvmovw  0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 59 cb    \tvmulph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 59 cb    \tvmulph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 59 cb    \tvmulph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 59 cb    \tvmulsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 59 8c c8 78 56 34 12 \tvmulsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4c, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 4c ca    \tvrcpph %zmm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4c, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 4c ca    \tvrcpph %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4c, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 4c ca    \tvrcpph %ymm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4d, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 4d cb    \tvrcpsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 4d 8c c8 78 56 34 12 \tvrcpsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x56, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 56 ca 12 \tvreduceph $0x12,%zmm2,%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 48 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x56, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 56 ca 12 \tvreduceph $0x12,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x56, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 56 ca 12 \tvreduceph $0x12,%ymm2,%ymm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 28 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x57, 0xcb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 57 cb 12 \tvreducesh $0x12,%xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 57 8c c8 78 56 34 12 12 \tvreducesh $0x12,0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x08, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 08 ca 12 \tvrndscaleph $0x12,%zmm2,%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 48 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x08, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 08 ca 12 \tvrndscaleph $0x12,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x08, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 08 ca 12 \tvrndscaleph $0x12,%ymm2,%ymm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 28 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x0a, 0xcb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 0a cb 12 \tvrndscalesh $0x12,%xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x0a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 0a 8c c8 78 56 34 12 12 \tvrndscalesh $0x12,0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4e, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 4e ca    \tvrsqrtph %zmm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4e, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 4e ca    \tvrsqrtph %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4e, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 4e ca    \tvrsqrtph %ymm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4f, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 4f cb    \tvrsqrtsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 4f 8c c8 78 56 34 12 \tvrsqrtsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x2c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 2c cb    \tvscalefph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 2c cb    \tvscalefph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x2c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 2c cb    \tvscalefph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2d, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 2d cb    \tvscalefsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 2d 8c c8 78 56 34 12 \tvscalefsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x51, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 51 ca    \tvsqrtph %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x51, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 51 ca    \tvsqrtph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x51, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 51 ca    \tvsqrtph %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x51, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 51 cb    \tvsqrtsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 51 8c c8 78 56 34 12 \tvsqrtsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5c cb    \tvsubph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5c cb    \tvsubph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5c cb    \tvsubph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5c cb    \tvsubsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5c 8c c8 78 56 34 12 \tvsubsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2e, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 2e ca    \tvucomish %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 2e 8c c8 78 56 34 12 \tvucomish 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0xf3, 0x0f, 0x3a, 0xf0, 0xc0, 0x00, }, 6, 0, "", "",
+"f3 0f 3a f0 c0 00    \threset $0x0",},
+{{0x0f, 0x01, 0xe8, }, 3, 0, "", "",
+"0f 01 e8             \tserialize ",},
+{{0xf2, 0x0f, 0x01, 0xe9, }, 4, 0, "", "",
+"f2 0f 01 e9          \txresldtrk ",},
+{{0xf2, 0x0f, 0x01, 0xe8, }, 4, 0, "", "",
+"f2 0f 01 e8          \txsusldtrk ",},
 {{0x0f, 0x01, 0xcf, }, 3, 0, "", "",
 "0f 01 cf             \tencls  ",},
 {{0x0f, 0x01, 0xd7, }, 3, 0, "", "",
index 5da17d41d302b8baff6983911c80fba9b7ccb3fb..3a47e98fec331e5a22bfecd96de653ccf86c5e84 100644 (file)
 "3e f2 ff a4 c8 78 56 34 12 \tnotrack bnd jmpq *0x12345678(%rax,%rcx,8)",},
 {{0x3e, 0xf2, 0x41, 0xff, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "jmp", "indirect",
 "3e f2 41 ff a4 c8 78 56 34 12 \tnotrack bnd jmpq *0x12345678(%r8,%rcx,8)",},
+{{0xc4, 0xe2, 0x78, 0x49, 0x04, 0xc8, }, 6, 0, "", "",
+"c4 e2 78 49 04 c8    \tldtilecfg (%rax,%rcx,8)",},
+{{0xc4, 0xc2, 0x78, 0x49, 0x04, 0xc8, }, 6, 0, "", "",
+"c4 c2 78 49 04 c8    \tldtilecfg (%r8,%rcx,8)",},
+{{0xc4, 0xe2, 0x79, 0x49, 0x04, 0xc8, }, 6, 0, "", "",
+"c4 e2 79 49 04 c8    \tsttilecfg (%rax,%rcx,8)",},
+{{0xc4, 0xc2, 0x79, 0x49, 0x04, 0xc8, }, 6, 0, "", "",
+"c4 c2 79 49 04 c8    \tsttilecfg (%r8,%rcx,8)",},
+{{0xc4, 0xe2, 0x7a, 0x5c, 0xd1, }, 5, 0, "", "",
+"c4 e2 7a 5c d1       \ttdpbf16ps %tmm0,%tmm1,%tmm2",},
+{{0xc4, 0xe2, 0x7b, 0x5e, 0xd1, }, 5, 0, "", "",
+"c4 e2 7b 5e d1       \ttdpbssd %tmm0,%tmm1,%tmm2",},
+{{0xc4, 0xe2, 0x7a, 0x5e, 0xd1, }, 5, 0, "", "",
+"c4 e2 7a 5e d1       \ttdpbsud %tmm0,%tmm1,%tmm2",},
+{{0xc4, 0xe2, 0x79, 0x5e, 0xd1, }, 5, 0, "", "",
+"c4 e2 79 5e d1       \ttdpbusd %tmm0,%tmm1,%tmm2",},
+{{0xc4, 0xe2, 0x78, 0x5e, 0xd1, }, 5, 0, "", "",
+"c4 e2 78 5e d1       \ttdpbuud %tmm0,%tmm1,%tmm2",},
+{{0xc4, 0xe2, 0x7b, 0x4b, 0x0c, 0xc8, }, 6, 0, "", "",
+"c4 e2 7b 4b 0c c8    \ttileloadd (%rax,%rcx,8),%tmm1",},
+{{0xc4, 0xc2, 0x7b, 0x4b, 0x14, 0xc8, }, 6, 0, "", "",
+"c4 c2 7b 4b 14 c8    \ttileloadd (%r8,%rcx,8),%tmm2",},
+{{0xc4, 0xe2, 0x79, 0x4b, 0x0c, 0xc8, }, 6, 0, "", "",
+"c4 e2 79 4b 0c c8    \ttileloaddt1 (%rax,%rcx,8),%tmm1",},
+{{0xc4, 0xc2, 0x79, 0x4b, 0x14, 0xc8, }, 6, 0, "", "",
+"c4 c2 79 4b 14 c8    \ttileloaddt1 (%r8,%rcx,8),%tmm2",},
+{{0xc4, 0xe2, 0x78, 0x49, 0xc0, }, 5, 0, "", "",
+"c4 e2 78 49 c0       \ttilerelease ",},
+{{0xc4, 0xe2, 0x7a, 0x4b, 0x0c, 0xc8, }, 6, 0, "", "",
+"c4 e2 7a 4b 0c c8    \ttilestored %tmm1,(%rax,%rcx,8)",},
+{{0xc4, 0xc2, 0x7a, 0x4b, 0x14, 0xc8, }, 6, 0, "", "",
+"c4 c2 7a 4b 14 c8    \ttilestored %tmm2,(%r8,%rcx,8)",},
+{{0xc4, 0xe2, 0x7b, 0x49, 0xc0, }, 5, 0, "", "",
+"c4 e2 7b 49 c0       \ttilezero %tmm0",},
+{{0xc4, 0xe2, 0x7b, 0x49, 0xf8, }, 5, 0, "", "",
+"c4 e2 7b 49 f8       \ttilezero %tmm7",},
+{{0xf3, 0x0f, 0x01, 0xee, }, 4, 0, "", "",
+"f3 0f 01 ee          \tclui   ",},
+{{0xf3, 0x0f, 0xc7, 0xf0, }, 4, 0, "", "",
+"f3 0f c7 f0          \tsenduipi %rax",},
+{{0xf3, 0x41, 0x0f, 0xc7, 0xf0, }, 5, 0, "", "",
+"f3 41 0f c7 f0       \tsenduipi %r8",},
+{{0xf3, 0x0f, 0x01, 0xef, }, 4, 0, "", "",
+"f3 0f 01 ef          \tstui   ",},
+{{0xf3, 0x0f, 0x01, 0xed, }, 4, 0, "", "",
+"f3 0f 01 ed          \ttestui ",},
+{{0xf3, 0x0f, 0x01, 0xec, }, 4, 0, "", "",
+"f3 0f 01 ec          \tuiret  ",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 58 cb    \tvaddph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x48, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 48 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 58 cb    \tvaddph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x08, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 08 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 58 cb    \tvaddph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x28, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 28 58 8c c8 78 56 34 12 \tvaddph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x58, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 58 cb    \tvaddsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 58 8c c8 78 56 34 12 \tvaddsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x58, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 58 8c c8 78 56 34 12 \tvaddsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x48, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 48 c2 eb 12 \tvcmple_oqph %zmm3,%zmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x48, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 48 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%rax,%rcx,8),%zmm2,%k5",},
+{{0x67, 0x62, 0xf3, 0x6c, 0x48, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 6c 48 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%eax,%ecx,8),%zmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x08, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 c2 eb 12 \tvcmple_oqph %xmm3,%xmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x08, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%rax,%rcx,8),%xmm2,%k5",},
+{{0x67, 0x62, 0xf3, 0x6c, 0x08, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 6c 08 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%eax,%ecx,8),%xmm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x28, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 28 c2 eb 12 \tvcmple_oqph %ymm3,%ymm2,%k5",},
+{{0x62, 0xf3, 0x6c, 0x28, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 28 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%rax,%rcx,8),%ymm2,%k5",},
+{{0x67, 0x62, 0xf3, 0x6c, 0x28, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 6c 28 c2 ac c8 78 56 34 12 12 \tvcmple_oqph 0x12345678(%eax,%ecx,8),%ymm2,%k5",},
+{{0x62, 0xf3, 0x6e, 0x08, 0xc2, 0xeb, 0x12, }, 7, 0, "", "",
+"62 f3 6e 08 c2 eb 12 \tvcmple_oqsh %xmm3,%xmm2,%k5",},
+{{0x62, 0xf3, 0x6e, 0x08, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6e 08 c2 ac c8 78 56 34 12 12 \tvcmple_oqsh 0x12345678(%rax,%rcx,8),%xmm2,%k5",},
+{{0x67, 0x62, 0xf3, 0x6e, 0x08, 0xc2, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 6e 08 c2 ac c8 78 56 34 12 12 \tvcmple_oqsh 0x12345678(%eax,%ecx,8),%xmm2,%k5",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2f, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 2f ca    \tvcomish %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 2f 8c c8 78 56 34 12 \tvcomish 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x2f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 2f 8c c8 78 56 34 12 \tvcomish 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 5b ca    \tvcvtdq2ph %zmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 5b 8c c8 78 56 34 12 \tvcvtdq2ph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 48 5b 8c c8 78 56 34 12 \tvcvtdq2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 5b ca    \tvcvtdq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 5b ca    \tvcvtdq2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0xfd, 0x48, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 fd 48 5a ca    \tvcvtpd2ph %zmm2,%xmm1",},
+{{0x62, 0xf5, 0xfd, 0x08, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 fd 08 5a ca    \tvcvtpd2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0xfd, 0x28, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 fd 28 5a ca    \tvcvtpd2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 5b ca    \tvcvtph2dq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 5b ca    \tvcvtph2dq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 5b ca    \tvcvtph2dq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x28, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 28 5b 8c c8 78 56 34 12 \tvcvtph2dq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 5a ca    \tvcvtph2pd %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x48, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 48 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 5a ca    \tvcvtph2pd %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x5a, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 5a ca    \tvcvtph2pd %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x28, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 28 5a 8c c8 78 56 34 12 \tvcvtph2pd 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x13, 0xca, }, 6, 0, "", "",
+"62 f2 7d 48 13 ca    \tvcvtph2ps %ymm2,%zmm1",},
+{{0x62, 0xf2, 0x7d, 0x48, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f2 7d 48 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf2, 0x7d, 0x48, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f2 7d 48 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 79 13 ca       \tvcvtph2ps %xmm2,%xmm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 79 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0xc4, 0xe2, 0x79, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"67 c4 e2 79 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 7d 13 ca       \tvcvtph2ps %xmm2,%ymm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 7d 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0xc4, 0xe2, 0x7d, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"67 c4 e2 7d 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 79 13 ca       \tvcvtph2ps %xmm2,%xmm1",},
+{{0xc4, 0xe2, 0x79, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 79 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0xc4, 0xe2, 0x79, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"67 c4 e2 79 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0xca, }, 5, 0, "", "",
+"c4 e2 7d 13 ca       \tvcvtph2ps %xmm2,%ymm1",},
+{{0xc4, 0xe2, 0x7d, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
+"c4 e2 7d 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0xc4, 0xe2, 0x7d, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"67 c4 e2 7d 13 8c c8 78 56 34 12 \tvcvtph2ps 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x13, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 13 ca    \tvcvtph2psx %ymm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x48, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 48 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x13, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 13 ca    \tvcvtph2psx %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x08, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 08 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x13, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 13 ca    \tvcvtph2psx %xmm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x28, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 28 13 8c c8 78 56 34 12 \tvcvtph2psx 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7b ca    \tvcvtph2qq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7b ca    \tvcvtph2qq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7b, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7b ca    \tvcvtph2qq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x28, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 28 7b 8c c8 78 56 34 12 \tvcvtph2qq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 79 ca    \tvcvtph2udq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x48, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 48 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 79 ca    \tvcvtph2udq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 79 ca    \tvcvtph2udq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x28, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 28 79 8c c8 78 56 34 12 \tvcvtph2udq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 79 ca    \tvcvtph2uqq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 79 ca    \tvcvtph2uqq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x79, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 79 ca    \tvcvtph2uqq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x28, 0x79, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 28 79 8c c8 78 56 34 12 \tvcvtph2uqq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 7d ca    \tvcvtph2uw %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 48 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 7d ca    \tvcvtph2uw %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 7d ca    \tvcvtph2uw %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 28 7d 8c c8 78 56 34 12 \tvcvtph2uw 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7d ca    \tvcvtph2w %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7d ca    \tvcvtph2w %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7d ca    \tvcvtph2w %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 28 7d 8c c8 78 56 34 12 \tvcvtph2w 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7d 48 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%zmm1,0x12345678(%rax,%rcx,8)",},
+{{0x67, 0x62, 0xf3, 0x7d, 0x48, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7d 48 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%zmm1,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf3, 0x7d, 0x48, 0x1d, 0xd1, 0x12, }, 7, 0, "", "",
+"62 f3 7d 48 1d d1 12 \tvcvtps2ph $0x12,%zmm2,%ymm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 7d 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%ymm1,0x12345678(%rax,%rcx,8)",},
+{{0x67, 0xc4, 0xe3, 0x7d, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"67 c4 e3 7d 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%ymm1,0x12345678(%eax,%ecx,8)",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 79 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%xmm1,0x12345678(%rax,%rcx,8)",},
+{{0x67, 0xc4, 0xe3, 0x79, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"67 c4 e3 79 1d 8c c8 78 56 34 12 12 \tvcvtps2ph $0x12,%xmm1,0x12345678(%eax,%ecx,8)",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 79 1d d1 12    \tvcvtps2ph $0x12,%xmm2,%xmm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 7d 1d d1 12    \tvcvtps2ph $0x12,%ymm2,%xmm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 7d 1d d1 12    \tvcvtps2ph $0x12,%ymm2,%xmm1",},
+{{0xc4, 0xe3, 0x7d, 0x1d, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 7d 1d 94 c8 78 56 34 12 12 \tvcvtps2ph $0x12,%ymm2,0x12345678(%rax,%rcx,8)",},
+{{0x67, 0xc4, 0xe3, 0x7d, 0x1d, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"67 c4 e3 7d 1d 94 c8 78 56 34 12 12 \tvcvtps2ph $0x12,%ymm2,0x12345678(%eax,%ecx,8)",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0xd1, 0x12, }, 6, 0, "", "",
+"c4 e3 79 1d d1 12    \tvcvtps2ph $0x12,%xmm2,%xmm1",},
+{{0xc4, 0xe3, 0x79, 0x1d, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 11, 0, "", "",
+"c4 e3 79 1d 94 c8 78 56 34 12 12 \tvcvtps2ph $0x12,%xmm2,0x12345678(%rax,%rcx,8)",},
+{{0x67, 0xc4, 0xe3, 0x79, 0x1d, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"67 c4 e3 79 1d 94 c8 78 56 34 12 12 \tvcvtps2ph $0x12,%xmm2,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x1d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 1d ca    \tvcvtps2phx %zmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 1d 8c c8 78 56 34 12 \tvcvtps2phx 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 1d 8c c8 78 56 34 12 \tvcvtps2phx 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x1d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 1d ca    \tvcvtps2phx %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x1d, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 1d ca    \tvcvtps2phx %ymm2,%xmm1",},
+{{0x62, 0xf5, 0xfc, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 fc 48 5b ca    \tvcvtqq2ph %zmm2,%xmm1",},
+{{0x62, 0xf5, 0xfc, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 fc 08 5b ca    \tvcvtqq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0xfc, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 fc 28 5b ca    \tvcvtqq2ph %ymm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0xef, 0x08, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 ef 08 5a 8c c8 78 56 34 12 \tvcvtsd2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x5a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 5a 8c c8 78 56 34 12 \tvcvtsh2sd 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x2d, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 2d 84 c8 78 56 34 12 \tvcvtsh2si 0x12345678(%eax,%ecx,8),%eax",},
+{{0x67, 0x62, 0xf5, 0xfe, 0x08, 0x2d, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 fe 08 2d 84 c8 78 56 34 12 \tvcvtsh2si 0x12345678(%eax,%ecx,8),%rax",},
+{{0x67, 0x62, 0xf6, 0x6c, 0x08, 0x13, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6c 08 13 8c c8 78 56 34 12 \tvcvtsh2ss 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x79, 0xc1, }, 6, 0, "", "",
+"62 f5 7e 08 79 c1    \tvcvtsh2usi %xmm1,%eax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x79, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 79 84 c8 78 56 34 12 \tvcvtsh2usi 0x12345678(%rax,%rcx,8),%eax",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x79, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 79 84 c8 78 56 34 12 \tvcvtsh2usi 0x12345678(%eax,%ecx,8),%eax",},
+{{0x62, 0xf5, 0xfe, 0x08, 0x79, 0xc1, }, 6, 0, "", "",
+"62 f5 fe 08 79 c1    \tvcvtsh2usi %xmm1,%rax",},
+{{0x62, 0xf5, 0xfe, 0x08, 0x79, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 fe 08 79 84 c8 78 56 34 12 \tvcvtsh2usi 0x12345678(%rax,%rcx,8),%rax",},
+{{0x67, 0x62, 0xf5, 0xfe, 0x08, 0x79, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 fe 08 79 84 c8 78 56 34 12 \tvcvtsh2usi 0x12345678(%eax,%ecx,8),%rax",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x2a, 0xc8, }, 6, 0, "", "",
+"62 f5 6e 08 2a c8    \tvcvtsi2sh %eax,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x2a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 2a 8c c8 78 56 34 12 \tvcvtsi2shl 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x2a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 2a 8c c8 78 56 34 12 \tvcvtsi2shl 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0xee, 0x08, 0x2a, 0xc8, }, 6, 0, "", "",
+"62 f5 ee 08 2a c8    \tvcvtsi2sh %rax,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x2a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 2a 8c c8 78 56 34 12 \tvcvtsi2shl 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x2a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 2a 8c c8 78 56 34 12 \tvcvtsi2shl 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x1d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 1d cb    \tvcvtss2sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 1d 8c c8 78 56 34 12 \tvcvtss2sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x08, 0x1d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 08 1d 8c c8 78 56 34 12 \tvcvtss2sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7e 48 5b ca    \tvcvttph2dq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 48 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x48, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 48 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7e 08 5b ca    \tvcvttph2dq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x5b, 0xca, }, 6, 0, "", "",
+"62 f5 7e 28 5b ca    \tvcvttph2dq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 28 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x28, 0x5b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 28 5b 8c c8 78 56 34 12 \tvcvttph2dq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7a ca    \tvcvttph2qq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7a ca    \tvcvttph2qq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7a ca    \tvcvttph2qq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x28, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 28 7a 8c c8 78 56 34 12 \tvcvttph2qq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 78 ca    \tvcvttph2udq %ymm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x48, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 48 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 78 ca    \tvcvttph2udq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 78 ca    \tvcvttph2udq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x28, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 28 78 8c c8 78 56 34 12 \tvcvttph2udq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 78 ca    \tvcvttph2uqq %xmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 78 ca    \tvcvttph2uqq %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x78, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 78 ca    \tvcvttph2uqq %xmm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x28, 0x78, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 28 78 8c c8 78 56 34 12 \tvcvttph2uqq 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 7c ca    \tvcvttph2uw %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x48, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 48 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 7c ca    \tvcvttph2uw %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 7c ca    \tvcvttph2uw %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x28, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 28 7c 8c c8 78 56 34 12 \tvcvttph2uw 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7d 48 7c ca    \tvcvttph2w %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x48, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 48 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x48, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 48 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7d 08 7c ca    \tvcvttph2w %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7c, 0xca, }, 6, 0, "", "",
+"62 f5 7d 28 7c ca    \tvcvttph2w %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7d, 0x28, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 28 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x28, 0x7c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 28 7c 8c c8 78 56 34 12 \tvcvttph2w 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x2c, 0xc1, }, 6, 0, "", "",
+"62 f5 7e 08 2c c1    \tvcvttsh2si %xmm1,%eax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x2c, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 2c 84 c8 78 56 34 12 \tvcvttsh2si 0x12345678(%rax,%rcx,8),%eax",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x2c, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 2c 84 c8 78 56 34 12 \tvcvttsh2si 0x12345678(%eax,%ecx,8),%eax",},
+{{0x62, 0xf5, 0xfe, 0x08, 0x2c, 0xc1, }, 6, 0, "", "",
+"62 f5 fe 08 2c c1    \tvcvttsh2si %xmm1,%rax",},
+{{0x62, 0xf5, 0xfe, 0x08, 0x2c, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 fe 08 2c 84 c8 78 56 34 12 \tvcvttsh2si 0x12345678(%rax,%rcx,8),%rax",},
+{{0x67, 0x62, 0xf5, 0xfe, 0x08, 0x2c, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 fe 08 2c 84 c8 78 56 34 12 \tvcvttsh2si 0x12345678(%eax,%ecx,8),%rax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x78, 0xc1, }, 6, 0, "", "",
+"62 f5 7e 08 78 c1    \tvcvttsh2usi %xmm1,%eax",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x78, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 78 84 c8 78 56 34 12 \tvcvttsh2usi 0x12345678(%rax,%rcx,8),%eax",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x78, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 78 84 c8 78 56 34 12 \tvcvttsh2usi 0x12345678(%eax,%ecx,8),%eax",},
+{{0x62, 0xf5, 0xfe, 0x08, 0x78, 0xc1, }, 6, 0, "", "",
+"62 f5 fe 08 78 c1    \tvcvttsh2usi %xmm1,%rax",},
+{{0x62, 0xf5, 0xfe, 0x08, 0x78, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 fe 08 78 84 c8 78 56 34 12 \tvcvttsh2usi 0x12345678(%rax,%rcx,8),%rax",},
+{{0x67, 0x62, 0xf5, 0xfe, 0x08, 0x78, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 fe 08 78 84 c8 78 56 34 12 \tvcvttsh2usi 0x12345678(%eax,%ecx,8),%rax",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7f 48 7a ca    \tvcvtudq2ph %zmm2,%ymm1",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 48 7a 8c c8 78 56 34 12 \tvcvtudq2ph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7f, 0x48, 0x7a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7f 48 7a 8c c8 78 56 34 12 \tvcvtudq2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7f, 0x08, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7f 08 7a ca    \tvcvtudq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x28, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 7f 28 7a ca    \tvcvtudq2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0xff, 0x48, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 ff 48 7a ca    \tvcvtuqq2ph %zmm2,%xmm1",},
+{{0x62, 0xf5, 0xff, 0x08, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 ff 08 7a ca    \tvcvtuqq2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0xff, 0x28, 0x7a, 0xca, }, 6, 0, "", "",
+"62 f5 ff 28 7a ca    \tvcvtuqq2ph %ymm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x7b, 0xc8, }, 6, 0, "", "",
+"62 f5 6e 08 7b c8    \tvcvtusi2sh %eax,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 7b 8c c8 78 56 34 12 \tvcvtusi2shl 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 7b 8c c8 78 56 34 12 \tvcvtusi2shl 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0xee, 0x08, 0x7b, 0xc8, }, 6, 0, "", "",
+"62 f5 ee 08 7b c8    \tvcvtusi2sh %rax,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 7b 8c c8 78 56 34 12 \tvcvtusi2shl 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x7b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 7b 8c c8 78 56 34 12 \tvcvtusi2shl 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7f 48 7d ca    \tvcvtuw2ph %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7f, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 48 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7f, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7f 48 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7f, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7f 08 7d ca    \tvcvtuw2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 08 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7f, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7f 08 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7f, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7f 28 7d ca    \tvcvtuw2ph %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7f, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7f 28 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7f, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7f 28 7d 8c c8 78 56 34 12 \tvcvtuw2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7e 48 7d ca    \tvcvtw2ph %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 48 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x48, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 48 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7e 08 7d ca    \tvcvtw2ph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x7d, 0xca, }, 6, 0, "", "",
+"62 f5 7e 28 7d ca    \tvcvtw2ph %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7e, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 28 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x28, 0x7d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 28 7d 8c c8 78 56 34 12 \tvcvtw2ph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5e cb    \tvdivph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x48, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 48 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5e cb    \tvdivph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x08, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 08 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5e cb    \tvdivph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x28, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 28 5e 8c c8 78 56 34 12 \tvdivph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5e, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5e cb    \tvdivsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5e 8c c8 78 56 34 12 \tvdivsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x5e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 5e 8c c8 78 56 34 12 \tvdivsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 48 56 cb    \tvfcmaddcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 48 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 48 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 56 cb    \tvfcmaddcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 08 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 28 56 cb    \tvfcmaddcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 28 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 28 56 8c c8 78 56 34 12 \tvfcmaddcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x57, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 57 cb    \tvfcmaddcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 57 8c c8 78 56 34 12 \tvfcmaddcsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 08 57 8c c8 78 56 34 12 \tvfcmaddcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 48 d6 cb    \tvfcmulcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x48, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 48 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x48, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 48 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 d6 cb    \tvfcmulcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x08, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 08 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 28 d6 cb    \tvfcmulcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x28, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 28 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x28, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 28 d6 8c c8 78 56 34 12 \tvfcmulcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd7, 0xcb, }, 6, 0, "", "",
+"62 f6 6f 08 d7 cb    \tvfcmulcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6f, 0x08, 0xd7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6f 08 d7 8c c8 78 56 34 12 \tvfcmulcsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6f, 0x08, 0xd7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6f 08 d7 8c c8 78 56 34 12 \tvfcmulcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x98, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 98 cb    \tvfmadd132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x98, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 98 cb    \tvfmadd132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x98, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 98 cb    \tvfmadd132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0x98, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 98 8c c8 78 56 34 12 \tvfmadd132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x99, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 99 cb    \tvfmadd132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x99, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 99 8c c8 78 56 34 12 \tvfmadd132sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x99, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 99 8c c8 78 56 34 12 \tvfmadd132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 a8 cb    \tvfmadd213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a8 cb    \tvfmadd213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 a8 cb    \tvfmadd213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xa8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 a8 8c c8 78 56 34 12 \tvfmadd213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa9, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a9 cb    \tvfmadd213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa9, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a9 8c c8 78 56 34 12 \tvfmadd213sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xa9, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 a9 8c c8 78 56 34 12 \tvfmadd213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 b8 cb    \tvfmadd231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b8 cb    \tvfmadd231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb8, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 b8 cb    \tvfmadd231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xb8, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 b8 8c c8 78 56 34 12 \tvfmadd231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb9, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b9 cb    \tvfmadd231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb9, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b9 8c c8 78 56 34 12 \tvfmadd231sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xb9, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 b9 8c c8 78 56 34 12 \tvfmadd231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 48 56 cb    \tvfmaddcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 48 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 48 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 56 cb    \tvfmaddcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 08 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0x56, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 28 56 cb    \tvfmaddcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 28 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 28 56 8c c8 78 56 34 12 \tvfmaddcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x57, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 57 cb    \tvfmaddcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 57 8c c8 78 56 34 12 \tvfmaddcsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 08 57 8c c8 78 56 34 12 \tvfmaddcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x96, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 96 cb    \tvfmaddsub132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x96, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 96 cb    \tvfmaddsub132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x96, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 96 cb    \tvfmaddsub132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0x96, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 96 8c c8 78 56 34 12 \tvfmaddsub132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 a6 cb    \tvfmaddsub213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a6 cb    \tvfmaddsub213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 a6 cb    \tvfmaddsub213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xa6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 a6 8c c8 78 56 34 12 \tvfmaddsub213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 b6 cb    \tvfmaddsub231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b6 cb    \tvfmaddsub231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb6, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 b6 cb    \tvfmaddsub231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xb6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 b6 8c c8 78 56 34 12 \tvfmaddsub231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9a, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 9a cb    \tvfmsub132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9a, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9a cb    \tvfmsub132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9a, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 9a cb    \tvfmsub132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0x9a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 9a 8c c8 78 56 34 12 \tvfmsub132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9b, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9b cb    \tvfmsub132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9b 8c c8 78 56 34 12 \tvfmsub132sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x9b, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 9b 8c c8 78 56 34 12 \tvfmsub132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xaa, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 aa cb    \tvfmsub213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaa, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 aa cb    \tvfmsub213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xaa, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 aa cb    \tvfmsub213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xaa, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 aa 8c c8 78 56 34 12 \tvfmsub213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xab, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ab cb    \tvfmsub213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xab, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ab 8c c8 78 56 34 12 \tvfmsub213sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xab, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 ab 8c c8 78 56 34 12 \tvfmsub213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xba, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 ba cb    \tvfmsub231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xba, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ba cb    \tvfmsub231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xba, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 ba cb    \tvfmsub231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xba, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 ba 8c c8 78 56 34 12 \tvfmsub231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbb, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bb cb    \tvfmsub231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbb, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bb 8c c8 78 56 34 12 \tvfmsub231sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xbb, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 bb 8c c8 78 56 34 12 \tvfmsub231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x97, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 97 cb    \tvfmsubadd132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x97, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 97 cb    \tvfmsubadd132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x97, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 97 cb    \tvfmsubadd132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0x97, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 97 8c c8 78 56 34 12 \tvfmsubadd132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 a7 cb    \tvfmsubadd213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 a7 cb    \tvfmsubadd213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 a7 cb    \tvfmsubadd213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xa7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 a7 8c c8 78 56 34 12 \tvfmsubadd213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 b7 cb    \tvfmsubadd231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 b7 cb    \tvfmsubadd231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb7, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 b7 cb    \tvfmsubadd231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xb7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 b7 8c c8 78 56 34 12 \tvfmsubadd231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 48 d6 cb    \tvfmulcph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x48, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 48 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x48, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 48 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 d6 cb    \tvfmulcph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x08, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 08 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0xd6, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 28 d6 cb    \tvfmulcph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x28, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 28 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x28, 0xd6, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 28 d6 8c c8 78 56 34 12 \tvfmulcph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd7, 0xcb, }, 6, 0, "", "",
+"62 f6 6e 08 d7 cb    \tvfmulcsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6e, 0x08, 0xd7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6e 08 d7 8c c8 78 56 34 12 \tvfmulcsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6e, 0x08, 0xd7, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6e 08 d7 8c c8 78 56 34 12 \tvfmulcsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 9c cb    \tvfnmadd132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9c cb    \tvfnmadd132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 9c cb    \tvfnmadd132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0x9c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 9c 8c c8 78 56 34 12 \tvfnmadd132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9d, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9d cb    \tvfnmadd132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9d 8c c8 78 56 34 12 \tvfnmadd132sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x9d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 9d 8c c8 78 56 34 12 \tvfnmadd132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xac, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 ac cb    \tvfnmadd213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xac, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ac cb    \tvfnmadd213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xac, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 ac cb    \tvfnmadd213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xac, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 ac 8c c8 78 56 34 12 \tvfnmadd213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xad, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ad cb    \tvfnmadd213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xad, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ad 8c c8 78 56 34 12 \tvfnmadd213sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xad, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 ad 8c c8 78 56 34 12 \tvfnmadd213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbc, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 bc cb    \tvfnmadd231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbc, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bc cb    \tvfnmadd231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbc, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 bc cb    \tvfnmadd231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xbc, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 bc 8c c8 78 56 34 12 \tvfnmadd231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbd, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bd cb    \tvfnmadd231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbd, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bd 8c c8 78 56 34 12 \tvfnmadd231sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xbd, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 bd 8c c8 78 56 34 12 \tvfnmadd231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9e, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 9e cb    \tvfnmsub132ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9e, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9e cb    \tvfnmsub132ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9e, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 9e cb    \tvfnmsub132ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0x9e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 9e 8c c8 78 56 34 12 \tvfnmsub132ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9f, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 9f cb    \tvfnmsub132sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x9f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 9f 8c c8 78 56 34 12 \tvfnmsub132sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x9f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 9f 8c c8 78 56 34 12 \tvfnmsub132sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xae, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 ae cb    \tvfnmsub213ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xae, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 ae cb    \tvfnmsub213ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xae, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 ae cb    \tvfnmsub213ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xae, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 ae 8c c8 78 56 34 12 \tvfnmsub213ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaf, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 af cb    \tvfnmsub213sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xaf, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 af 8c c8 78 56 34 12 \tvfnmsub213sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xaf, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 af 8c c8 78 56 34 12 \tvfnmsub213sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbe, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 be cb    \tvfnmsub231ph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbe, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 be cb    \tvfnmsub231ph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbe, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 be cb    \tvfnmsub231ph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0xbe, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 be 8c c8 78 56 34 12 \tvfnmsub231ph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbf, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 bf cb    \tvfnmsub231sh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0xbf, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 bf 8c c8 78 56 34 12 \tvfnmsub231sh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0xbf, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 bf 8c c8 78 56 34 12 \tvfnmsub231sh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x66, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 66 e9 12 \tvfpclassph $0x12,%zmm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x66, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 66 e9 12 \tvfpclassph $0x12,%xmm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x66, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 66 e9 12 \tvfpclassph $0x12,%ymm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x67, 0xe9, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 67 e9 12 \tvfpclasssh $0x12,%xmm1,%k5",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x67, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 67 ac c8 78 56 34 12 12 \tvfpclasssh $0x12,0x12345678(%rax,%rcx,8),%k5",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x08, 0x67, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 08 67 ac c8 78 56 34 12 12 \tvfpclasssh $0x12,0x12345678(%eax,%ecx,8),%k5",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x42, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 42 ca    \tvgetexpph %zmm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x48, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 48 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x42, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 42 ca    \tvgetexpph %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x08, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 08 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x42, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 42 ca    \tvgetexpph %ymm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x28, 0x42, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 28 42 8c c8 78 56 34 12 \tvgetexpph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x43, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 43 cb    \tvgetexpsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x43, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 43 8c c8 78 56 34 12 \tvgetexpsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x43, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 43 8c c8 78 56 34 12 \tvgetexpsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x26, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 26 ca 12 \tvgetmantph $0x12,%zmm2,%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 48 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x48, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 48 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x26, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 26 ca 12 \tvgetmantph $0x12,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x08, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 08 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x26, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 26 ca 12 \tvgetmantph $0x12,%ymm2,%ymm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 28 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x28, 0x26, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 28 26 8c c8 78 56 34 12 12 \tvgetmantph $0x12,0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x27, 0xcb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 27 cb 12 \tvgetmantsh $0x12,%xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x27, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 27 8c c8 78 56 34 12 12 \tvgetmantsh $0x12,0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf3, 0x6c, 0x08, 0x27, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 6c 08 27 8c c8 78 56 34 12 12 \tvgetmantsh $0x12,0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5f cb    \tvmaxph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x48, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 48 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5f cb    \tvmaxph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x08, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 08 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5f cb    \tvmaxph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x28, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 28 5f 8c c8 78 56 34 12 \tvmaxph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5f, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5f cb    \tvmaxsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5f 8c c8 78 56 34 12 \tvmaxsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x5f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 5f 8c c8 78 56 34 12 \tvmaxsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5d cb    \tvminph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x48, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 48 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5d cb    \tvminph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x08, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 08 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5d cb    \tvminph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x28, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 28 5d 8c c8 78 56 34 12 \tvminph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5d, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5d cb    \tvminsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5d 8c c8 78 56 34 12 \tvminsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x5d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 5d 8c c8 78 56 34 12 \tvminsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x11, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 11 8c c8 78 56 34 12 \tvmovsh %xmm1,0x12345678(%rax,%rcx,8)",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x11, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 11 8c c8 78 56 34 12 \tvmovsh %xmm1,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf5, 0x7e, 0x08, 0x10, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7e 08 10 8c c8 78 56 34 12 \tvmovsh 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7e, 0x08, 0x10, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7e 08 10 8c c8 78 56 34 12 \tvmovsh 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x10, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 10 cb    \tvmovsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7e, 0xc8, }, 6, 0, "", "",
+"62 f5 7d 08 7e c8    \tvmovw  %xmm1,%eax",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x7e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 7e 8c c8 78 56 34 12 \tvmovw  %xmm1,0x12345678(%rax,%rcx,8)",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x7e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 7e 8c c8 78 56 34 12 \tvmovw  %xmm1,0x12345678(%eax,%ecx,8)",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x6e, 0xc8, }, 6, 0, "", "",
+"62 f5 7d 08 6e c8    \tvmovw  %eax,%xmm1",},
+{{0x62, 0xf5, 0x7d, 0x08, 0x6e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7d 08 6e 8c c8 78 56 34 12 \tvmovw  0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7d, 0x08, 0x6e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7d 08 6e 8c c8 78 56 34 12 \tvmovw  0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 59 cb    \tvmulph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x48, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 48 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 59 cb    \tvmulph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x08, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 08 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 59 cb    \tvmulph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x28, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 28 59 8c c8 78 56 34 12 \tvmulph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x59, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 59 cb    \tvmulsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 59 8c c8 78 56 34 12 \tvmulsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x59, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 59 8c c8 78 56 34 12 \tvmulsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4c, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 4c ca    \tvrcpph %zmm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x48, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 48 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4c, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 4c ca    \tvrcpph %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x08, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 08 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4c, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 4c ca    \tvrcpph %ymm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x28, 0x4c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 28 4c 8c c8 78 56 34 12 \tvrcpph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4d, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 4d cb    \tvrcpsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 4d 8c c8 78 56 34 12 \tvrcpsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x4d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 4d 8c c8 78 56 34 12 \tvrcpsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x56, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 56 ca 12 \tvreduceph $0x12,%zmm2,%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 48 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x48, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 48 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x56, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 56 ca 12 \tvreduceph $0x12,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x08, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 08 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x56, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 56 ca 12 \tvreduceph $0x12,%ymm2,%ymm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 28 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x28, 0x56, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 28 56 8c c8 78 56 34 12 12 \tvreduceph $0x12,0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x57, 0xcb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 57 cb 12 \tvreducesh $0x12,%xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 57 8c c8 78 56 34 12 12 \tvreducesh $0x12,0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf3, 0x6c, 0x08, 0x57, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 6c 08 57 8c c8 78 56 34 12 12 \tvreducesh $0x12,0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x08, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 48 08 ca 12 \tvrndscaleph $0x12,%zmm2,%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x48, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 48 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x48, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 48 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x08, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 08 08 ca 12 \tvrndscaleph $0x12,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x08, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 08 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x08, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 08 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x08, 0xca, 0x12, }, 7, 0, "", "",
+"62 f3 7c 28 08 ca 12 \tvrndscaleph $0x12,%ymm2,%ymm1",},
+{{0x62, 0xf3, 0x7c, 0x28, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 7c 28 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf3, 0x7c, 0x28, 0x08, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 7c 28 08 8c c8 78 56 34 12 12 \tvrndscaleph $0x12,0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x0a, 0xcb, 0x12, }, 7, 0, "", "",
+"62 f3 6c 08 0a cb 12 \tvrndscalesh $0x12,%xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf3, 0x6c, 0x08, 0x0a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 12, 0, "", "",
+"62 f3 6c 08 0a 8c c8 78 56 34 12 12 \tvrndscalesh $0x12,0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf3, 0x6c, 0x08, 0x0a, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x12, }, 13, 0, "", "",
+"67 62 f3 6c 08 0a 8c c8 78 56 34 12 12 \tvrndscalesh $0x12,0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4e, 0xca, }, 6, 0, "", "",
+"62 f6 7d 48 4e ca    \tvrsqrtph %zmm2,%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x48, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 48 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x48, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 48 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4e, 0xca, }, 6, 0, "", "",
+"62 f6 7d 08 4e ca    \tvrsqrtph %xmm2,%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x08, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 08 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x08, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 08 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4e, 0xca, }, 6, 0, "", "",
+"62 f6 7d 28 4e ca    \tvrsqrtph %ymm2,%ymm1",},
+{{0x62, 0xf6, 0x7d, 0x28, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 7d 28 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf6, 0x7d, 0x28, 0x4e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 7d 28 4e 8c c8 78 56 34 12 \tvrsqrtph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4f, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 4f cb    \tvrsqrtsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x4f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 4f 8c c8 78 56 34 12 \tvrsqrtsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x4f, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 4f 8c c8 78 56 34 12 \tvrsqrtsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x2c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 48 2c cb    \tvscalefph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x48, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 48 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x48, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 48 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 2c cb    \tvscalefph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x2c, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 28 2c cb    \tvscalefph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x28, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 28 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x28, 0x2c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 28 2c 8c c8 78 56 34 12 \tvscalefph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2d, 0xcb, }, 6, 0, "", "",
+"62 f6 6d 08 2d cb    \tvscalefsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf6, 0x6d, 0x08, 0x2d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f6 6d 08 2d 8c c8 78 56 34 12 \tvscalefsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf6, 0x6d, 0x08, 0x2d, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f6 6d 08 2d 8c c8 78 56 34 12 \tvscalefsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x51, 0xca, }, 6, 0, "", "",
+"62 f5 7c 48 51 ca    \tvsqrtph %zmm2,%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x48, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 48 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%rax,%rcx,8),%zmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x48, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 48 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%eax,%ecx,8),%zmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x51, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 51 ca    \tvsqrtph %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x51, 0xca, }, 6, 0, "", "",
+"62 f5 7c 28 51 ca    \tvsqrtph %ymm2,%ymm1",},
+{{0x62, 0xf5, 0x7c, 0x28, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 28 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%rax,%rcx,8),%ymm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x28, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 28 51 8c c8 78 56 34 12 \tvsqrtph 0x12345678(%eax,%ecx,8),%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x51, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 51 cb    \tvsqrtsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 51 8c c8 78 56 34 12 \tvsqrtsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x51, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 51 8c c8 78 56 34 12 \tvsqrtsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 48 5c cb    \tvsubph %zmm3,%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x48, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 48 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%rax,%rcx,8),%zmm2,%zmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x48, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 48 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%eax,%ecx,8),%zmm2,%zmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 08 5c cb    \tvsubph %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x08, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 08 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x08, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 08 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6c 28 5c cb    \tvsubph %ymm3,%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6c, 0x28, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6c 28 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%rax,%rcx,8),%ymm2,%ymm1",},
+{{0x67, 0x62, 0xf5, 0x6c, 0x28, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6c 28 5c 8c c8 78 56 34 12 \tvsubph 0x12345678(%eax,%ecx,8),%ymm2,%ymm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5c, 0xcb, }, 6, 0, "", "",
+"62 f5 6e 08 5c cb    \tvsubsh %xmm3,%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x6e, 0x08, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 6e 08 5c 8c c8 78 56 34 12 \tvsubsh 0x12345678(%rax,%rcx,8),%xmm2,%xmm1",},
+{{0x67, 0x62, 0xf5, 0x6e, 0x08, 0x5c, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 6e 08 5c 8c c8 78 56 34 12 \tvsubsh 0x12345678(%eax,%ecx,8),%xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2e, 0xca, }, 6, 0, "", "",
+"62 f5 7c 08 2e ca    \tvucomish %xmm2,%xmm1",},
+{{0x62, 0xf5, 0x7c, 0x08, 0x2e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "",
+"62 f5 7c 08 2e 8c c8 78 56 34 12 \tvucomish 0x12345678(%rax,%rcx,8),%xmm1",},
+{{0x67, 0x62, 0xf5, 0x7c, 0x08, 0x2e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 12, 0, "", "",
+"67 62 f5 7c 08 2e 8c c8 78 56 34 12 \tvucomish 0x12345678(%eax,%ecx,8),%xmm1",},
+{{0xf3, 0x0f, 0x3a, 0xf0, 0xc0, 0x00, }, 6, 0, "", "",
+"f3 0f 3a f0 c0 00    \threset $0x0",},
+{{0x0f, 0x01, 0xe8, }, 3, 0, "", "",
+"0f 01 e8             \tserialize ",},
+{{0xf2, 0x0f, 0x01, 0xe9, }, 4, 0, "", "",
+"f2 0f 01 e9          \txresldtrk ",},
+{{0xf2, 0x0f, 0x01, 0xe8, }, 4, 0, "", "",
+"f2 0f 01 e8          \txsusldtrk ",},
 {{0x0f, 0x01, 0xcf, }, 3, 0, "", "",
 "0f 01 cf             \tencls  ",},
 {{0x0f, 0x01, 0xd7, }, 3, 0, "", "",
index c3808e94c46e09af93f2fc3e1004550d7ee7fbec..a391464c8dee7277792632c1e07f18deb3e9a746 100644 (file)
@@ -1910,6 +1910,724 @@ int main(void)
        asm volatile("notrack bnd jmpq *0x12345678(%rax,%rcx,8)");      /* Expecting: jmp indirect 0 */
        asm volatile("notrack bnd jmpq *0x12345678(%r8,%rcx,8)");       /* Expecting: jmp indirect 0 */
 
+       /* AMX */
+
+       asm volatile("ldtilecfg (%rax,%rcx,8)");
+       asm volatile("ldtilecfg (%r8,%rcx,8)");
+       asm volatile("sttilecfg (%rax,%rcx,8)");
+       asm volatile("sttilecfg (%r8,%rcx,8)");
+       asm volatile("tdpbf16ps %tmm0, %tmm1, %tmm2");
+       asm volatile("tdpbssd %tmm0, %tmm1, %tmm2");
+       asm volatile("tdpbsud %tmm0, %tmm1, %tmm2");
+       asm volatile("tdpbusd %tmm0, %tmm1, %tmm2");
+       asm volatile("tdpbuud %tmm0, %tmm1, %tmm2");
+       asm volatile("tileloadd (%rax,%rcx,8), %tmm1");
+       asm volatile("tileloadd (%r8,%rcx,8), %tmm2");
+       asm volatile("tileloaddt1 (%rax,%rcx,8), %tmm1");
+       asm volatile("tileloaddt1 (%r8,%rcx,8), %tmm2");
+       asm volatile("tilerelease");
+       asm volatile("tilestored %tmm1, (%rax,%rcx,8)");
+       asm volatile("tilestored %tmm2, (%r8,%rcx,8)");
+       asm volatile("tilezero %tmm0");
+       asm volatile("tilezero %tmm7");
+
+       /* User Interrupt */
+
+       asm volatile("clui");
+       asm volatile("senduipi %rax");
+       asm volatile("senduipi %r8");
+       asm volatile("stui");
+       asm volatile("testui");
+       asm volatile("uiret");
+
+       /* AVX512-FP16 */
+
+       asm volatile("vaddph %zmm3, %zmm2, %zmm1");
+       asm volatile("vaddph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vaddph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vaddph %xmm3, %xmm2, %xmm1");
+       asm volatile("vaddph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vaddph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vaddph %ymm3, %ymm2, %ymm1");
+       asm volatile("vaddph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vaddph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vaddsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vaddsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vaddsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcmpph $0x12, %zmm3, %zmm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%rax,%rcx,8), %zmm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%eax,%ecx,8), %zmm2, %k5");
+       asm volatile("vcmpph $0x12, %xmm3, %xmm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%rax,%rcx,8), %xmm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %k5");
+       asm volatile("vcmpph $0x12, %ymm3, %ymm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%rax,%rcx,8), %ymm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%eax,%ecx,8), %ymm2, %k5");
+       asm volatile("vcmpsh $0x12, %xmm3, %xmm2, %k5");
+       asm volatile("vcmpsh $0x12, 0x12345678(%rax,%rcx,8), %xmm2, %k5");
+       asm volatile("vcmpsh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %k5");
+       asm volatile("vcomish %xmm2, %xmm1");
+       asm volatile("vcomish 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcomish 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtdq2ph %zmm2, %ymm1");
+       asm volatile("vcvtdq2ph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtdq2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtdq2ph %xmm2, %xmm1");
+       asm volatile("vcvtdq2ph %ymm2, %xmm1");
+       asm volatile("vcvtpd2ph %zmm2, %xmm1");
+       asm volatile("vcvtpd2ph %xmm2, %xmm1");
+       asm volatile("vcvtpd2ph %ymm2, %xmm1");
+       asm volatile("vcvtph2dq %ymm2, %zmm1");
+       asm volatile("vcvtph2dq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2dq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2dq %xmm2, %xmm1");
+       asm volatile("vcvtph2dq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2dq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2dq %xmm2, %ymm1");
+       asm volatile("vcvtph2dq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2dq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2pd %xmm2, %zmm1");
+       asm volatile("vcvtph2pd 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2pd 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2pd %xmm2, %xmm1");
+       asm volatile("vcvtph2pd 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2pd 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2pd %xmm2, %ymm1");
+       asm volatile("vcvtph2pd 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2pd 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2ps %ymm2, %zmm1");
+       asm volatile("vcvtph2ps 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2ps %xmm2, %xmm1");
+       asm volatile("vcvtph2ps 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2ps %xmm2, %ymm1");
+       asm volatile("vcvtph2ps 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2ps %xmm2, %xmm1");
+       asm volatile("vcvtph2ps 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2ps %xmm2, %ymm1");
+       asm volatile("vcvtph2ps 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2psx %ymm2, %zmm1");
+       asm volatile("vcvtph2psx 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2psx 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2psx %xmm2, %xmm1");
+       asm volatile("vcvtph2psx 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2psx 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2psx %xmm2, %ymm1");
+       asm volatile("vcvtph2psx 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2psx 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2qq %xmm2, %zmm1");
+       asm volatile("vcvtph2qq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2qq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2qq %xmm2, %xmm1");
+       asm volatile("vcvtph2qq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2qq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2qq %xmm2, %ymm1");
+       asm volatile("vcvtph2qq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2qq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2udq %ymm2, %zmm1");
+       asm volatile("vcvtph2udq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2udq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2udq %xmm2, %xmm1");
+       asm volatile("vcvtph2udq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2udq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2udq %xmm2, %ymm1");
+       asm volatile("vcvtph2udq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2udq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2uqq %xmm2, %zmm1");
+       asm volatile("vcvtph2uqq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2uqq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2uqq %xmm2, %xmm1");
+       asm volatile("vcvtph2uqq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2uqq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2uqq %xmm2, %ymm1");
+       asm volatile("vcvtph2uqq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2uqq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2uw %zmm2, %zmm1");
+       asm volatile("vcvtph2uw 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2uw 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2uw %xmm2, %xmm1");
+       asm volatile("vcvtph2uw 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2uw 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2uw %ymm2, %ymm1");
+       asm volatile("vcvtph2uw 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2uw 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2w %zmm2, %zmm1");
+       asm volatile("vcvtph2w 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtph2w 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2w %xmm2, %xmm1");
+       asm volatile("vcvtph2w 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtph2w 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2w %ymm2, %ymm1");
+       asm volatile("vcvtph2w 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtph2w 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtps2ph $0x12, %zmm1, 0x12345678(%rax,%rcx,8)");
+       asm volatile("vcvtps2ph $0x12, %zmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %zmm2, %ymm1");
+       asm volatile("vcvtps2ph $0x12, %ymm1, 0x12345678(%rax,%rcx,8)");
+       asm volatile("vcvtps2ph $0x12, %ymm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm1, 0x12345678(%rax,%rcx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %ymm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %ymm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %ymm2, 0x12345678(%rax,%rcx,8)");
+       asm volatile("vcvtps2ph $0x12, %ymm2, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %xmm2, 0x12345678(%rax,%rcx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm2, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2phx %zmm2, %ymm1");
+       asm volatile("vcvtps2phx 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtps2phx 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtps2phx %xmm2, %xmm1");
+       asm volatile("vcvtps2phx %ymm2, %xmm1");
+       asm volatile("vcvtqq2ph %zmm2, %xmm1");
+       asm volatile("vcvtqq2ph %xmm2, %xmm1");
+       asm volatile("vcvtqq2ph %ymm2, %xmm1");
+       asm volatile("vcvtsd2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsh2sd 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsh2si 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvtsh2si 0x12345678(%eax,%ecx,8), %rax");
+       asm volatile("vcvtsh2ss 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsh2usi %xmm1, %eax");
+       asm volatile("vcvtsh2usi 0x12345678(%rax,%rcx,8), %eax");
+       asm volatile("vcvtsh2usi 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvtsh2usi %xmm1, %rax");
+       asm volatile("vcvtsh2usi 0x12345678(%rax,%rcx,8), %rax");
+       asm volatile("vcvtsh2usi 0x12345678(%eax,%ecx,8), %rax");
+       asm volatile("vcvtsi2sh %eax, %xmm2, %xmm1");
+       asm volatile("vcvtsi2sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsi2sh %rax, %xmm2, %xmm1");
+       asm volatile("vcvtsi2sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtss2sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vcvtss2sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vcvtss2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvttph2dq %ymm2, %zmm1");
+       asm volatile("vcvttph2dq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvttph2dq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2dq %xmm2, %xmm1");
+       asm volatile("vcvttph2dq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvttph2dq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2dq %xmm2, %ymm1");
+       asm volatile("vcvttph2dq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvttph2dq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2qq %xmm2, %zmm1");
+       asm volatile("vcvttph2qq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvttph2qq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2qq %xmm2, %xmm1");
+       asm volatile("vcvttph2qq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvttph2qq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2qq %xmm2, %ymm1");
+       asm volatile("vcvttph2qq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvttph2qq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2udq %ymm2, %zmm1");
+       asm volatile("vcvttph2udq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvttph2udq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2udq %xmm2, %xmm1");
+       asm volatile("vcvttph2udq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvttph2udq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2udq %xmm2, %ymm1");
+       asm volatile("vcvttph2udq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvttph2udq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2uqq %xmm2, %zmm1");
+       asm volatile("vcvttph2uqq 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvttph2uqq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2uqq %xmm2, %xmm1");
+       asm volatile("vcvttph2uqq 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvttph2uqq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2uqq %xmm2, %ymm1");
+       asm volatile("vcvttph2uqq 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvttph2uqq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2uw %zmm2, %zmm1");
+       asm volatile("vcvttph2uw 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvttph2uw 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2uw %xmm2, %xmm1");
+       asm volatile("vcvttph2uw 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvttph2uw 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2uw %ymm2, %ymm1");
+       asm volatile("vcvttph2uw 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvttph2uw 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2w %zmm2, %zmm1");
+       asm volatile("vcvttph2w 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvttph2w 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2w %xmm2, %xmm1");
+       asm volatile("vcvttph2w 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvttph2w 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2w %ymm2, %ymm1");
+       asm volatile("vcvttph2w 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvttph2w 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttsh2si %xmm1, %eax");
+       asm volatile("vcvttsh2si 0x12345678(%rax,%rcx,8), %eax");
+       asm volatile("vcvttsh2si 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvttsh2si %xmm1, %rax");
+       asm volatile("vcvttsh2si 0x12345678(%rax,%rcx,8), %rax");
+       asm volatile("vcvttsh2si 0x12345678(%eax,%ecx,8), %rax");
+       asm volatile("vcvttsh2usi %xmm1, %eax");
+       asm volatile("vcvttsh2usi 0x12345678(%rax,%rcx,8), %eax");
+       asm volatile("vcvttsh2usi 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvttsh2usi %xmm1, %rax");
+       asm volatile("vcvttsh2usi 0x12345678(%rax,%rcx,8), %rax");
+       asm volatile("vcvttsh2usi 0x12345678(%eax,%ecx,8), %rax");
+       asm volatile("vcvtudq2ph %zmm2, %ymm1");
+       asm volatile("vcvtudq2ph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtudq2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtudq2ph %xmm2, %xmm1");
+       asm volatile("vcvtudq2ph %ymm2, %xmm1");
+       asm volatile("vcvtuqq2ph %zmm2, %xmm1");
+       asm volatile("vcvtuqq2ph %xmm2, %xmm1");
+       asm volatile("vcvtuqq2ph %ymm2, %xmm1");
+       asm volatile("vcvtusi2sh %eax, %xmm2, %xmm1");
+       asm volatile("vcvtusi2sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vcvtusi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtusi2sh %rax, %xmm2, %xmm1");
+       asm volatile("vcvtusi2sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vcvtusi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtuw2ph %zmm2, %zmm1");
+       asm volatile("vcvtuw2ph 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtuw2ph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtuw2ph %xmm2, %xmm1");
+       asm volatile("vcvtuw2ph 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtuw2ph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtuw2ph %ymm2, %ymm1");
+       asm volatile("vcvtuw2ph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtuw2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtw2ph %zmm2, %zmm1");
+       asm volatile("vcvtw2ph 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vcvtw2ph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtw2ph %xmm2, %xmm1");
+       asm volatile("vcvtw2ph 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vcvtw2ph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtw2ph %ymm2, %ymm1");
+       asm volatile("vcvtw2ph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vcvtw2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vdivph %zmm3, %zmm2, %zmm1");
+       asm volatile("vdivph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vdivph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vdivph %xmm3, %xmm2, %xmm1");
+       asm volatile("vdivph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vdivph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vdivph %ymm3, %ymm2, %ymm1");
+       asm volatile("vdivph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vdivph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vdivsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vdivsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vdivsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmaddcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfcmaddcph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfcmaddcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfcmaddcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmaddcph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfcmaddcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmaddcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfcmaddcph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfcmaddcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfcmaddcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmaddcsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfcmaddcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmulcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfcmulcph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfcmulcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfcmulcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmulcph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfcmulcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmulcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfcmulcph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfcmulcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfcmulcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmulcsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfcmulcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmadd132ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd132ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmadd132ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd132sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmadd213ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd213ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmadd213ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd213sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmadd231ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd231ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmadd231ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd231sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddcph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddcph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddcph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddcsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddsub213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddsub231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsub132ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub132ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsub132ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub132sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsub213ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub213ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsub213ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub213sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsub231ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub231ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsub231ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub231sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsubadd213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsubadd231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmulcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmulcph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfmulcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmulcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmulcph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmulcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmulcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmulcph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfmulcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmulcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmulcsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfmulcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmadd132ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd132ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmadd132ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd132sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmadd213ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd213ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmadd213ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd213sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmadd231ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd231ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmadd231ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd231sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmsub132ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub132ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmsub132ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub132sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmsub213ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub213ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmsub213ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub213sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmsub231ph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub231ph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmsub231ph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub231sh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfpclassph $0x12, %zmm1, %k5");
+       asm volatile("vfpclassph $0x12, %xmm1, %k5");
+       asm volatile("vfpclassph $0x12, %ymm1, %k5");
+       asm volatile("vfpclasssh $0x12, %xmm1, %k5");
+       asm volatile("vfpclasssh $0x12, 0x12345678(%rax,%rcx,8), %k5");
+       asm volatile("vfpclasssh $0x12, 0x12345678(%eax,%ecx,8), %k5");
+       asm volatile("vgetexpph %zmm2, %zmm1");
+       asm volatile("vgetexpph 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vgetexpph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vgetexpph %xmm2, %xmm1");
+       asm volatile("vgetexpph 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vgetexpph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vgetexpph %ymm2, %ymm1");
+       asm volatile("vgetexpph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vgetexpph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vgetexpsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vgetexpsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vgetexpsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vgetmantph $0x12, %zmm2, %zmm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vgetmantph $0x12, %xmm2, %xmm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vgetmantph $0x12, %ymm2, %ymm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vgetmantsh $0x12, %xmm3, %xmm2, %xmm1");
+       asm volatile("vgetmantsh $0x12, 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vgetmantsh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmaxph %zmm3, %zmm2, %zmm1");
+       asm volatile("vmaxph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vmaxph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vmaxph %xmm3, %xmm2, %xmm1");
+       asm volatile("vmaxph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vmaxph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmaxph %ymm3, %ymm2, %ymm1");
+       asm volatile("vmaxph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vmaxph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vmaxsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vmaxsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vmaxsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vminph %zmm3, %zmm2, %zmm1");
+       asm volatile("vminph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vminph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vminph %xmm3, %xmm2, %xmm1");
+       asm volatile("vminph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vminph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vminph %ymm3, %ymm2, %ymm1");
+       asm volatile("vminph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vminph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vminsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vminsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vminsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmovsh %xmm1, 0x12345678(%rax,%rcx,8)");
+       asm volatile("vmovsh %xmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vmovsh 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vmovsh 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vmovsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vmovw %xmm1, %eax");
+       asm volatile("vmovw %xmm1, 0x12345678(%rax,%rcx,8)");
+       asm volatile("vmovw %xmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vmovw %eax, %xmm1");
+       asm volatile("vmovw 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vmovw 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vmulph %zmm3, %zmm2, %zmm1");
+       asm volatile("vmulph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vmulph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vmulph %xmm3, %xmm2, %xmm1");
+       asm volatile("vmulph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vmulph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmulph %ymm3, %ymm2, %ymm1");
+       asm volatile("vmulph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vmulph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vmulsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vmulsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vmulsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vrcpph %zmm2, %zmm1");
+       asm volatile("vrcpph 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vrcpph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vrcpph %xmm2, %xmm1");
+       asm volatile("vrcpph 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vrcpph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vrcpph %ymm2, %ymm1");
+       asm volatile("vrcpph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vrcpph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vrcpsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vrcpsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vrcpsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vreduceph $0x12, %zmm2, %zmm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vreduceph $0x12, %xmm2, %xmm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vreduceph $0x12, %ymm2, %ymm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vreducesh $0x12, %xmm3, %xmm2, %xmm1");
+       asm volatile("vreducesh $0x12, 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vreducesh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vrndscaleph $0x12, %zmm2, %zmm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vrndscaleph $0x12, %xmm2, %xmm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vrndscaleph $0x12, %ymm2, %ymm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vrndscalesh $0x12, %xmm3, %xmm2, %xmm1");
+       asm volatile("vrndscalesh $0x12, 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vrndscalesh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vrsqrtph %zmm2, %zmm1");
+       asm volatile("vrsqrtph 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vrsqrtph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vrsqrtph %xmm2, %xmm1");
+       asm volatile("vrsqrtph 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vrsqrtph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vrsqrtph %ymm2, %ymm1");
+       asm volatile("vrsqrtph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vrsqrtph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vrsqrtsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vrsqrtsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vrsqrtsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vscalefph %zmm3, %zmm2, %zmm1");
+       asm volatile("vscalefph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vscalefph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vscalefph %xmm3, %xmm2, %xmm1");
+       asm volatile("vscalefph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vscalefph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vscalefph %ymm3, %ymm2, %ymm1");
+       asm volatile("vscalefph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vscalefph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vscalefsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vscalefsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vscalefsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vsqrtph %zmm2, %zmm1");
+       asm volatile("vsqrtph 0x12345678(%rax,%rcx,8), %zmm1");
+       asm volatile("vsqrtph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vsqrtph %xmm2, %xmm1");
+       asm volatile("vsqrtph 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vsqrtph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vsqrtph %ymm2, %ymm1");
+       asm volatile("vsqrtph 0x12345678(%rax,%rcx,8), %ymm1");
+       asm volatile("vsqrtph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vsqrtsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vsqrtsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vsqrtsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vsubph %zmm3, %zmm2, %zmm1");
+       asm volatile("vsubph 0x12345678(%rax,%rcx,8), %zmm2, %zmm1");
+       asm volatile("vsubph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vsubph %xmm3, %xmm2, %xmm1");
+       asm volatile("vsubph 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vsubph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vsubph %ymm3, %ymm2, %ymm1");
+       asm volatile("vsubph 0x12345678(%rax,%rcx,8), %ymm2, %ymm1");
+       asm volatile("vsubph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vsubsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vsubsh 0x12345678(%rax,%rcx,8), %xmm2, %xmm1");
+       asm volatile("vsubsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vucomish %xmm2, %xmm1");
+       asm volatile("vucomish 0x12345678(%rax,%rcx,8), %xmm1");
+       asm volatile("vucomish 0x12345678(%eax,%ecx,8), %xmm1");
+
 #else  /* #ifdef __x86_64__ */
 
        /* bound r32, mem (same op code as EVEX prefix) */
@@ -3670,8 +4388,479 @@ int main(void)
        asm volatile("notrack bnd jmp *(0x12345678)");          /* Expecting: jmp indirect 0 */
        asm volatile("notrack bnd jmp *0x12345678(%eax,%ecx,8)"); /* Expecting: jmp indirect 0 */
 
+       /* AVX512-FP16 */
+
+       asm volatile("vaddph %zmm3, %zmm2, %zmm1");
+       asm volatile("vaddph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vaddph %xmm3, %xmm2, %xmm1");
+       asm volatile("vaddph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vaddph %ymm3, %ymm2, %ymm1");
+       asm volatile("vaddph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vaddsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vaddsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcmpph $0x12, %zmm3, %zmm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%eax,%ecx,8), %zmm2, %k5");
+       asm volatile("vcmpph $0x12, %xmm3, %xmm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %k5");
+       asm volatile("vcmpph $0x12, %ymm3, %ymm2, %k5");
+       asm volatile("vcmpph $0x12, 0x12345678(%eax,%ecx,8), %ymm2, %k5");
+       asm volatile("vcmpsh $0x12, %xmm3, %xmm2, %k5");
+       asm volatile("vcmpsh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %k5");
+       asm volatile("vcomish %xmm2, %xmm1");
+       asm volatile("vcomish 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtdq2ph %zmm2, %ymm1");
+       asm volatile("vcvtdq2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtdq2ph %xmm2, %xmm1");
+       asm volatile("vcvtdq2ph %ymm2, %xmm1");
+       asm volatile("vcvtpd2ph %zmm2, %xmm1");
+       asm volatile("vcvtpd2ph %xmm2, %xmm1");
+       asm volatile("vcvtpd2ph %ymm2, %xmm1");
+       asm volatile("vcvtph2dq %ymm2, %zmm1");
+       asm volatile("vcvtph2dq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2dq %xmm2, %xmm1");
+       asm volatile("vcvtph2dq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2dq %xmm2, %ymm1");
+       asm volatile("vcvtph2dq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2pd %xmm2, %zmm1");
+       asm volatile("vcvtph2pd 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2pd %xmm2, %xmm1");
+       asm volatile("vcvtph2pd 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2pd %xmm2, %ymm1");
+       asm volatile("vcvtph2pd 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2ps %ymm2, %zmm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2ps %xmm2, %xmm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2ps %xmm2, %ymm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2ps %xmm2, %xmm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2ps %xmm2, %ymm1");
+       asm volatile("vcvtph2ps 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2psx %ymm2, %zmm1");
+       asm volatile("vcvtph2psx 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2psx %xmm2, %xmm1");
+       asm volatile("vcvtph2psx 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2psx %xmm2, %ymm1");
+       asm volatile("vcvtph2psx 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2qq %xmm2, %zmm1");
+       asm volatile("vcvtph2qq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2qq %xmm2, %xmm1");
+       asm volatile("vcvtph2qq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2qq %xmm2, %ymm1");
+       asm volatile("vcvtph2qq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2udq %ymm2, %zmm1");
+       asm volatile("vcvtph2udq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2udq %xmm2, %xmm1");
+       asm volatile("vcvtph2udq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2udq %xmm2, %ymm1");
+       asm volatile("vcvtph2udq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2uqq %xmm2, %zmm1");
+       asm volatile("vcvtph2uqq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2uqq %xmm2, %xmm1");
+       asm volatile("vcvtph2uqq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2uqq %xmm2, %ymm1");
+       asm volatile("vcvtph2uqq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2uw %zmm2, %zmm1");
+       asm volatile("vcvtph2uw 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2uw %xmm2, %xmm1");
+       asm volatile("vcvtph2uw 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2uw %ymm2, %ymm1");
+       asm volatile("vcvtph2uw 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtph2w %zmm2, %zmm1");
+       asm volatile("vcvtph2w 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtph2w %xmm2, %xmm1");
+       asm volatile("vcvtph2w 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtph2w %ymm2, %ymm1");
+       asm volatile("vcvtph2w 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtps2ph $0x12, %zmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %zmm2, %ymm1");
+       asm volatile("vcvtps2ph $0x12, %ymm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %ymm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %ymm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %ymm2, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2ph $0x12, %xmm2, %xmm1");
+       asm volatile("vcvtps2ph $0x12, %xmm2, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vcvtps2phx %zmm2, %ymm1");
+       asm volatile("vcvtps2phx 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtps2phx %xmm2, %xmm1");
+       asm volatile("vcvtps2phx %ymm2, %xmm1");
+       asm volatile("vcvtqq2ph %zmm2, %xmm1");
+       asm volatile("vcvtqq2ph %xmm2, %xmm1");
+       asm volatile("vcvtqq2ph %ymm2, %xmm1");
+       asm volatile("vcvtsd2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsh2sd 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsh2si 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvtsh2ss 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsh2usi %xmm1, %eax");
+       asm volatile("vcvtsh2usi 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvtsi2sh %eax, %xmm2, %xmm1");
+       asm volatile("vcvtsi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtsi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtss2sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vcvtss2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvttph2dq %ymm2, %zmm1");
+       asm volatile("vcvttph2dq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2dq %xmm2, %xmm1");
+       asm volatile("vcvttph2dq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2dq %xmm2, %ymm1");
+       asm volatile("vcvttph2dq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2qq %xmm2, %zmm1");
+       asm volatile("vcvttph2qq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2qq %xmm2, %xmm1");
+       asm volatile("vcvttph2qq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2qq %xmm2, %ymm1");
+       asm volatile("vcvttph2qq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2udq %ymm2, %zmm1");
+       asm volatile("vcvttph2udq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2udq %xmm2, %xmm1");
+       asm volatile("vcvttph2udq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2udq %xmm2, %ymm1");
+       asm volatile("vcvttph2udq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2uqq %xmm2, %zmm1");
+       asm volatile("vcvttph2uqq 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2uqq %xmm2, %xmm1");
+       asm volatile("vcvttph2uqq 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2uqq %xmm2, %ymm1");
+       asm volatile("vcvttph2uqq 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2uw %zmm2, %zmm1");
+       asm volatile("vcvttph2uw 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2uw %xmm2, %xmm1");
+       asm volatile("vcvttph2uw 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2uw %ymm2, %ymm1");
+       asm volatile("vcvttph2uw 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttph2w %zmm2, %zmm1");
+       asm volatile("vcvttph2w 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvttph2w %xmm2, %xmm1");
+       asm volatile("vcvttph2w 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvttph2w %ymm2, %ymm1");
+       asm volatile("vcvttph2w 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvttsh2si %xmm1, %eax");
+       asm volatile("vcvttsh2si 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvttsh2usi %xmm1, %eax");
+       asm volatile("vcvttsh2usi 0x12345678(%eax,%ecx,8), %eax");
+       asm volatile("vcvtudq2ph %zmm2, %ymm1");
+       asm volatile("vcvtudq2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtudq2ph %xmm2, %xmm1");
+       asm volatile("vcvtudq2ph %ymm2, %xmm1");
+       asm volatile("vcvtuqq2ph %zmm2, %xmm1");
+       asm volatile("vcvtuqq2ph %xmm2, %xmm1");
+       asm volatile("vcvtuqq2ph %ymm2, %xmm1");
+       asm volatile("vcvtusi2sh %eax, %xmm2, %xmm1");
+       asm volatile("vcvtusi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtusi2sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vcvtuw2ph %zmm2, %zmm1");
+       asm volatile("vcvtuw2ph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtuw2ph %xmm2, %xmm1");
+       asm volatile("vcvtuw2ph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtuw2ph %ymm2, %ymm1");
+       asm volatile("vcvtuw2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vcvtw2ph %zmm2, %zmm1");
+       asm volatile("vcvtw2ph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vcvtw2ph %xmm2, %xmm1");
+       asm volatile("vcvtw2ph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vcvtw2ph %ymm2, %ymm1");
+       asm volatile("vcvtw2ph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vdivph %zmm3, %zmm2, %zmm1");
+       asm volatile("vdivph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vdivph %xmm3, %xmm2, %xmm1");
+       asm volatile("vdivph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vdivph %ymm3, %ymm2, %ymm1");
+       asm volatile("vdivph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vdivsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vdivsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmaddcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfcmaddcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfcmaddcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmaddcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmaddcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfcmaddcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfcmaddcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmaddcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmulcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfcmulcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfcmulcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmulcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfcmulcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfcmulcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfcmulcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfcmulcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmadd132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmadd132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmadd213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmadd213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmadd231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmadd231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmadd231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmadd231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmadd231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmadd231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddsub132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddsub213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddsub213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmaddsub231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmaddsub231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmaddsub231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmaddsub231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsub132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsub132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsub213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsub213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsub231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsub231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsub231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsub231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsub231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsub231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsubadd132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsubadd213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsubadd213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmsubadd231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmsubadd231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmsubadd231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmsubadd231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmulcph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfmulcph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfmulcph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmulcph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfmulcph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfmulcph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfmulcsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfmulcsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmadd132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmadd132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmadd213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmadd213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmadd231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmadd231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmadd231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmadd231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmadd231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmadd231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub132ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmsub132ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub132ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub132ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub132ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmsub132ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub132sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub132sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub213ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmsub213ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub213ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub213ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub213ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmsub213ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub213sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub213sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub231ph %zmm3, %zmm2, %zmm1");
+       asm volatile("vfnmsub231ph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vfnmsub231ph %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub231ph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfnmsub231ph %ymm3, %ymm2, %ymm1");
+       asm volatile("vfnmsub231ph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vfnmsub231sh %xmm3, %xmm2, %xmm1");
+       asm volatile("vfnmsub231sh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vfpclassph $0x12, %zmm1, %k5");
+       asm volatile("vfpclassph $0x12, %xmm1, %k5");
+       asm volatile("vfpclassph $0x12, %ymm1, %k5");
+       asm volatile("vfpclasssh $0x12, %xmm1, %k5");
+       asm volatile("vfpclasssh $0x12, 0x12345678(%eax,%ecx,8), %k5");
+       asm volatile("vgetexpph %zmm2, %zmm1");
+       asm volatile("vgetexpph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vgetexpph %xmm2, %xmm1");
+       asm volatile("vgetexpph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vgetexpph %ymm2, %ymm1");
+       asm volatile("vgetexpph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vgetexpsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vgetexpsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vgetmantph $0x12, %zmm2, %zmm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vgetmantph $0x12, %xmm2, %xmm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vgetmantph $0x12, %ymm2, %ymm1");
+       asm volatile("vgetmantph $0x12, 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vgetmantsh $0x12, %xmm3, %xmm2, %xmm1");
+       asm volatile("vgetmantsh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmaxph %zmm3, %zmm2, %zmm1");
+       asm volatile("vmaxph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vmaxph %xmm3, %xmm2, %xmm1");
+       asm volatile("vmaxph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmaxph %ymm3, %ymm2, %ymm1");
+       asm volatile("vmaxph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vmaxsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vmaxsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vminph %zmm3, %zmm2, %zmm1");
+       asm volatile("vminph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vminph %xmm3, %xmm2, %xmm1");
+       asm volatile("vminph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vminph %ymm3, %ymm2, %ymm1");
+       asm volatile("vminph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vminsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vminsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmovsh %xmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vmovsh 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vmovsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vmovw %xmm1, %eax");
+       asm volatile("vmovw %xmm1, 0x12345678(%eax,%ecx,8)");
+       asm volatile("vmovw %eax, %xmm1");
+       asm volatile("vmovw 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vmulph %zmm3, %zmm2, %zmm1");
+       asm volatile("vmulph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vmulph %xmm3, %xmm2, %xmm1");
+       asm volatile("vmulph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vmulph %ymm3, %ymm2, %ymm1");
+       asm volatile("vmulph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vmulsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vmulsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vrcpph %zmm2, %zmm1");
+       asm volatile("vrcpph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vrcpph %xmm2, %xmm1");
+       asm volatile("vrcpph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vrcpph %ymm2, %ymm1");
+       asm volatile("vrcpph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vrcpsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vrcpsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vreduceph $0x12, %zmm2, %zmm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vreduceph $0x12, %xmm2, %xmm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vreduceph $0x12, %ymm2, %ymm1");
+       asm volatile("vreduceph $0x12, 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vreducesh $0x12, %xmm3, %xmm2, %xmm1");
+       asm volatile("vreducesh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vrndscaleph $0x12, %zmm2, %zmm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vrndscaleph $0x12, %xmm2, %xmm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vrndscaleph $0x12, %ymm2, %ymm1");
+       asm volatile("vrndscaleph $0x12, 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vrndscalesh $0x12, %xmm3, %xmm2, %xmm1");
+       asm volatile("vrndscalesh $0x12, 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vrsqrtph %zmm2, %zmm1");
+       asm volatile("vrsqrtph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vrsqrtph %xmm2, %xmm1");
+       asm volatile("vrsqrtph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vrsqrtph %ymm2, %ymm1");
+       asm volatile("vrsqrtph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vrsqrtsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vrsqrtsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vscalefph %zmm3, %zmm2, %zmm1");
+       asm volatile("vscalefph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vscalefph %xmm3, %xmm2, %xmm1");
+       asm volatile("vscalefph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vscalefph %ymm3, %ymm2, %ymm1");
+       asm volatile("vscalefph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vscalefsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vscalefsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vsqrtph %zmm2, %zmm1");
+       asm volatile("vsqrtph 0x12345678(%eax,%ecx,8), %zmm1");
+       asm volatile("vsqrtph %xmm2, %xmm1");
+       asm volatile("vsqrtph 0x12345678(%eax,%ecx,8), %xmm1");
+       asm volatile("vsqrtph %ymm2, %ymm1");
+       asm volatile("vsqrtph 0x12345678(%eax,%ecx,8), %ymm1");
+       asm volatile("vsqrtsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vsqrtsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vsubph %zmm3, %zmm2, %zmm1");
+       asm volatile("vsubph 0x12345678(%eax,%ecx,8), %zmm2, %zmm1");
+       asm volatile("vsubph %xmm3, %xmm2, %xmm1");
+       asm volatile("vsubph 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vsubph %ymm3, %ymm2, %ymm1");
+       asm volatile("vsubph 0x12345678(%eax,%ecx,8), %ymm2, %ymm1");
+       asm volatile("vsubsh %xmm3, %xmm2, %xmm1");
+       asm volatile("vsubsh 0x12345678(%eax,%ecx,8), %xmm2, %xmm1");
+       asm volatile("vucomish %xmm2, %xmm1");
+       asm volatile("vucomish 0x12345678(%eax,%ecx,8), %xmm1");
+
 #endif /* #ifndef __x86_64__ */
 
+       /* Prediction history reset */
+
+       asm volatile("hreset $0");
+
+       /* Serialize instruction execution */
+
+       asm volatile("serialize");
+
+       /* TSX suspend load address tracking */
+
+       asm volatile("xresldtrk");
+       asm volatile("xsusldtrk");
+
        /* SGX */
 
        asm volatile("encls");
index f924246eff781a2d9888b5b77025fc079527586f..8d9b55959256a1c0009501460f095ef217b8b1a2 100644 (file)
@@ -29,7 +29,7 @@ struct evsel *arch_evlist__leader(struct list_head *list)
 
        __evlist__for_each_entry(list, evsel) {
                if (evsel->pmu_name && !strcmp(evsel->pmu_name, "cpu") &&
-                       evsel->name && strstr(evsel->name, "slots"))
+                       evsel->name && strcasestr(evsel->name, "slots"))
                        return evsel;
        }
        return first;
index 740ae764537e8c886ce91897056bde7d2602bada..134612bde0cb3c0c9f706e58dd24b5ce64ab6b74 100644 (file)
@@ -106,7 +106,7 @@ static void nest_epollfd(void)
        printinfo("Nesting level(s): %d\n", nested);
 
        epollfdp = calloc(nested, sizeof(int));
-       if (!epollfd)
+       if (!epollfdp)
                err(EXIT_FAILURE, "calloc");
 
        for (i = 0; i < nested; i++) {
index abae8184e171ed44d36eb198e61fbe8378ecfe92..fa478ddcd18ae03dae3f27998a680fab9a2b2ca3 100644 (file)
@@ -463,7 +463,7 @@ static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
                return -EINVAL;
 
        if (PRINT_FIELD(WEIGHT) &&
-           evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT))
+           evsel__do_check_stype(evsel, PERF_SAMPLE_WEIGHT_TYPE, "WEIGHT", PERF_OUTPUT_WEIGHT, allow_user_set))
                return -EINVAL;
 
        if (PRINT_FIELD(SYM) &&
index 1f147fe6595f8ca67f11819768f41a424be820bd..e32ece90e164a2ab38c5bd484351f1e6f0965e3f 100644 (file)
 #include "tests.h"
 #include "../perf-sys.h"
 
-/*
- * PowerPC and S390 do not support creation of instruction breakpoints using the
- * perf_event interface.
- *
- * Just disable the test for these architectures until these issues are
- * resolved.
- */
-#if defined(__powerpc__) || defined(__s390x__)
-#define BP_ACCOUNT_IS_SUPPORTED 0
-#else
-#define BP_ACCOUNT_IS_SUPPORTED 1
-#endif
-
 #define NUM_THREADS 5
 
 static struct {
@@ -135,7 +122,7 @@ static int test__sigtrap(struct test_suite *test __maybe_unused, int subtest __m
        char sbuf[STRERR_BUFSIZE];
        int i, fd, ret = TEST_FAIL;
 
-       if (!BP_ACCOUNT_IS_SUPPORTED) {
+       if (!BP_SIGNAL_IS_SUPPORTED) {
                pr_debug("Test not supported on this architecture");
                return TEST_SKIP;
        }
index f5d260b1df4d1c7eb3492d7fd8d7f729186b15ed..15a4547d608eca8292c615f12a8df970239bf956 100644 (file)
@@ -44,10 +44,6 @@ int perf_data__create_dir(struct perf_data *data, int nr)
        if (!files)
                return -ENOMEM;
 
-       data->dir.version = PERF_DIR_VERSION;
-       data->dir.files   = files;
-       data->dir.nr      = nr;
-
        for (i = 0; i < nr; i++) {
                struct perf_data_file *file = &files[i];
 
@@ -62,6 +58,9 @@ int perf_data__create_dir(struct perf_data *data, int nr)
                file->fd = ret;
        }
 
+       data->dir.version = PERF_DIR_VERSION;
+       data->dir.files   = files;
+       data->dir.nr      = nr;
        return 0;
 
 out_err:
index 7f234215147d4bebbc3d6eeb7898f12edb288422..57f02beef023c6f27b142ee0bbf12e93cd9e9041 100644 (file)
@@ -154,8 +154,8 @@ int evlist__fix_hybrid_cpus(struct evlist *evlist, const char *cpu_list)
                perf_cpu_map__put(matched_cpus);
                perf_cpu_map__put(unmatched_cpus);
        }
-
-       ret = (unmatched_count == events_nr) ? -1 : 0;
+       if (events_nr)
+               ret = (unmatched_count == events_nr) ? -1 : 0;
 out:
        perf_cpu_map__put(cpus);
        return ret;
index eaad04e1672a47523b13114e828f4961eecec745..41a66a48cbdffaa600a520e479f88841157539ae 100644 (file)
@@ -346,7 +346,7 @@ struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affin
 {
        struct evlist_cpu_iterator itr = {
                .container = evlist,
-               .evsel = evlist__first(evlist),
+               .evsel = NULL,
                .cpu_map_idx = 0,
                .evlist_cpu_map_idx = 0,
                .evlist_cpu_map_nr = perf_cpu_map__nr(evlist->core.all_cpus),
@@ -354,16 +354,22 @@ struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affin
                .affinity = affinity,
        };
 
-       if (itr.affinity) {
-               itr.cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0);
-               affinity__set(itr.affinity, itr.cpu.cpu);
-               itr.cpu_map_idx = perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu);
-               /*
-                * If this CPU isn't in the evsel's cpu map then advance through
-                * the list.
-                */
-               if (itr.cpu_map_idx == -1)
-                       evlist_cpu_iterator__next(&itr);
+       if (evlist__empty(evlist)) {
+               /* Ensure the empty list doesn't iterate. */
+               itr.evlist_cpu_map_idx = itr.evlist_cpu_map_nr;
+       } else {
+               itr.evsel = evlist__first(evlist);
+               if (itr.affinity) {
+                       itr.cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0);
+                       affinity__set(itr.affinity, itr.cpu.cpu);
+                       itr.cpu_map_idx = perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu);
+                       /*
+                        * If this CPU isn't in the evsel's cpu map then advance
+                        * through the list.
+                        */
+                       if (itr.cpu_map_idx == -1)
+                               evlist_cpu_iterator__next(&itr);
+               }
        }
        return itr;
 }
index 5acf053fca7d418399bc35567d19c22e88652cb5..aa0c5179836d1bbb805c8766f64e09a0c204f190 100644 (file)
 #ifndef SYM_END
 #define SYM_END(name, sym_type)                                \
        .type name sym_type ASM_NL                      \
+       .set .L__sym_size_##name, .-name ASM_NL         \
        .size name, .-name
 #endif
 
-/*
- * SYM_FUNC_START_ALIAS -- use where there are two global names for one
- * function
- */
-#ifndef SYM_FUNC_START_ALIAS
-#define SYM_FUNC_START_ALIAS(name)                     \
-       SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
+/* SYM_ALIAS -- use only if you have to */
+#ifndef SYM_ALIAS
+#define SYM_ALIAS(alias, name, sym_type, linkage)                      \
+       linkage(alias) ASM_NL                                           \
+       .set alias, name ASM_NL                                         \
+       .type alias sym_type ASM_NL                                     \
+       .set .L__sym_size_##alias, .L__sym_size_##name ASM_NL           \
+       .size alias, .L__sym_size_##alias
 #endif
 
 /* SYM_FUNC_START -- use for global functions */
 #ifndef SYM_FUNC_START
-/*
- * The same as SYM_FUNC_START_ALIAS, but we will need to distinguish these two
- * later.
- */
 #define SYM_FUNC_START(name)                           \
        SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
 #endif
 
 /* SYM_FUNC_START_LOCAL -- use for local functions */
 #ifndef SYM_FUNC_START_LOCAL
-/* the same as SYM_FUNC_START_LOCAL_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_START_LOCAL(name)                     \
        SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
 #endif
 
-/* SYM_FUNC_END_ALIAS -- the end of LOCAL_ALIASed or ALIASed function */
-#ifndef SYM_FUNC_END_ALIAS
-#define SYM_FUNC_END_ALIAS(name)                       \
-       SYM_END(name, SYM_T_FUNC)
-#endif
-
 /* SYM_FUNC_START_WEAK -- use for weak functions */
 #ifndef SYM_FUNC_START_WEAK
 #define SYM_FUNC_START_WEAK(name)                      \
  * SYM_FUNC_START_WEAK, ...
  */
 #ifndef SYM_FUNC_END
-/* the same as SYM_FUNC_END_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_END(name)                             \
        SYM_END(name, SYM_T_FUNC)
 #endif
 
+/*
+ * SYM_FUNC_ALIAS -- define a global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS
+#define SYM_FUNC_ALIAS(alias, name)                                    \
+       SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_GLOBAL)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS_LOCAL -- define a local alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_LOCAL
+#define SYM_FUNC_ALIAS_LOCAL(alias, name)                              \
+       SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_LOCAL)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS_WEAK -- define a weak global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_WEAK
+#define SYM_FUNC_ALIAS_WEAK(alias, name)                               \
+       SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_WEAK)
+#endif
+
 #endif /* PERF_LINUX_LINKAGE_H_ */
index 9739b05b999eb0de8fa4a28cac452881bd3f5974..24997925ae00d66a95c58b2afdac3d54894661f3 100644 (file)
@@ -1648,6 +1648,7 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
 {
        struct parse_events_term *term;
        struct list_head *list = NULL;
+       struct list_head *orig_head = NULL;
        struct perf_pmu *pmu = NULL;
        int ok = 0;
        char *config;
@@ -1674,7 +1675,6 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
        }
        list_add_tail(&term->list, head);
 
-
        /* Add it for all PMUs that support the alias */
        list = malloc(sizeof(struct list_head));
        if (!list)
@@ -1687,13 +1687,15 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
 
                list_for_each_entry(alias, &pmu->aliases, list) {
                        if (!strcasecmp(alias->name, str)) {
+                               parse_events_copy_term_list(head, &orig_head);
                                if (!parse_events_add_pmu(parse_state, list,
-                                                         pmu->name, head,
+                                                         pmu->name, orig_head,
                                                          true, true)) {
                                        pr_debug("%s -> %s/%s/\n", str,
                                                 pmu->name, alias->str);
                                        ok++;
                                }
+                               parse_events_terms__delete(orig_head);
                        }
                }
        }
@@ -2193,7 +2195,7 @@ int perf_pmu__test_parse_init(void)
        for (i = 0; i < ARRAY_SIZE(symbols); i++, tmp++) {
                tmp->type = symbols[i].type;
                tmp->symbol = strdup(symbols[i].symbol);
-               if (!list->symbol)
+               if (!tmp->symbol)
                        goto err_free;
        }
 
index b2ed3140a1faaa1acda190707e236a6a873b156c..dfde9eada224afd31d81842054b108ea576873f2 100644 (file)
@@ -231,7 +231,7 @@ void symbols__fixup_end(struct rb_root_cached *symbols)
                prev = curr;
                curr = rb_entry(nd, struct symbol, rb_node);
 
-               if (prev->end == prev->start && prev->end != curr->start)
+               if (prev->end == prev->start || prev->end != curr->start)
                        arch__symbols__fixup_end(prev, curr);
        }
 
index d8eeeafb50dcb62a93548e4752dee0f0136191dd..1e13b7523918efbb2da9eb509d7aa3cf14083a20 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
 extern void do_syscall(int sve_vl);
index a3c1e67441f9ec795688b85d518f876bf30d7a4d..4c418b2021e02ebb8e1c5792c65d607d95f51d6f 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
 /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
 #ifndef NT_ARM_SVE
 #define NT_ARM_SVE 0x405
@@ -489,6 +487,8 @@ static int do_parent(pid_t child)
        unsigned int vq, vl;
        bool vl_supported;
 
+       ksft_print_msg("Parent is %d, child is %d\n", getpid(), child);
+
        /* Attach to the child */
        while (1) {
                int sig;
index a876db1f096abe29979cc6b859a4aaa3efce9ca2..325bca0de0f6e147e130da07604fc1c08b2d3e11 100644 (file)
 #include "kselftest.h"
 #include "mte_common_util.h"
 
-#define PR_SET_TAGGED_ADDR_CTRL 55
-#define PR_GET_TAGGED_ADDR_CTRL 56
-# define PR_TAGGED_ADDR_ENABLE  (1UL << 0)
-# define PR_MTE_TCF_SHIFT      1
-# define PR_MTE_TCF_NONE       (0UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TCF_SYNC       (1UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TCF_ASYNC      (2UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TCF_MASK       (3UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TAG_SHIFT      3
-# define PR_MTE_TAG_MASK       (0xffffUL << PR_MTE_TAG_SHIFT)
-
 #include "mte_def.h"
 
 #define NUM_ITERATIONS         1024
index 1de7a0abd0ae391d3d3c117eca425b437be9b01c..f4ae5f87a3b77e6c0cb92af764d7875d4a459f3b 100644 (file)
@@ -3,6 +3,7 @@
 
 #define _GNU_SOURCE
 
+#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -11,6 +12,7 @@
 #include <string.h>
 #include <ucontext.h>
 #include <unistd.h>
+#include <sys/uio.h>
 #include <sys/mman.h>
 
 #include "kselftest.h"
 
 static size_t page_sz;
 
-static int check_usermem_access_fault(int mem_type, int mode, int mapping)
+#define TEST_NAME_MAX 100
+
+enum test_type {
+       READ_TEST,
+       WRITE_TEST,
+       READV_TEST,
+       WRITEV_TEST,
+       LAST_TEST,
+};
+
+static int check_usermem_access_fault(int mem_type, int mode, int mapping,
+                                      int tag_offset, int tag_len,
+                                      enum test_type test_type)
 {
        int fd, i, err;
        char val = 'A';
-       size_t len, read_len;
+       ssize_t len, syscall_len;
        void *ptr, *ptr_next;
+       int fileoff, ptroff, size;
+       int sizes[] = {1, 2, 3, 8, 16, 32, 4096, page_sz};
 
-       err = KSFT_FAIL;
+       err = KSFT_PASS;
        len = 2 * page_sz;
        mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
        fd = create_temp_file();
@@ -43,9 +59,9 @@ static int check_usermem_access_fault(int mem_type, int mode, int mapping)
        }
        mte_initialize_current_context(mode, (uintptr_t)ptr, len);
        /* Copy from file into buffer with valid tag */
-       read_len = read(fd, ptr, len);
+       syscall_len = read(fd, ptr, len);
        mte_wait_after_trig();
-       if (cur_mte_cxt.fault_valid || read_len < len)
+       if (cur_mte_cxt.fault_valid || syscall_len < len)
                goto usermem_acc_err;
        /* Verify same pattern is read */
        for (i = 0; i < len; i++)
@@ -54,36 +70,136 @@ static int check_usermem_access_fault(int mem_type, int mode, int mapping)
        if (i < len)
                goto usermem_acc_err;
 
-       /* Tag the next half of memory with different value */
-       ptr_next = (void *)((unsigned long)ptr + page_sz);
+       if (!tag_len)
+               tag_len = len - tag_offset;
+       /* Tag a part of memory with different value */
+       ptr_next = (void *)((unsigned long)ptr + tag_offset);
        ptr_next = mte_insert_new_tag(ptr_next);
-       mte_set_tag_address_range(ptr_next, page_sz);
+       mte_set_tag_address_range(ptr_next, tag_len);
 
-       lseek(fd, 0, 0);
-       /* Copy from file into buffer with invalid tag */
-       read_len = read(fd, ptr, len);
-       mte_wait_after_trig();
-       /*
-        * Accessing user memory in kernel with invalid tag should fail in sync
-        * mode without fault but may not fail in async mode as per the
-        * implemented MTE userspace support in Arm64 kernel.
-        */
-       if (mode == MTE_SYNC_ERR &&
-           !cur_mte_cxt.fault_valid && read_len < len) {
-               err = KSFT_PASS;
-       } else if (mode == MTE_ASYNC_ERR &&
-                  !cur_mte_cxt.fault_valid && read_len == len) {
-               err = KSFT_PASS;
+       for (fileoff = 0; fileoff < 16; fileoff++) {
+               for (ptroff = 0; ptroff < 16; ptroff++) {
+                       for (i = 0; i < ARRAY_SIZE(sizes); i++) {
+                               size = sizes[i];
+                               lseek(fd, 0, 0);
+
+                               /* perform file operation on buffer with invalid tag */
+                               switch (test_type) {
+                               case READ_TEST:
+                                       syscall_len = read(fd, ptr + ptroff, size);
+                                       break;
+                               case WRITE_TEST:
+                                       syscall_len = write(fd, ptr + ptroff, size);
+                                       break;
+                               case READV_TEST: {
+                                       struct iovec iov[1];
+                                       iov[0].iov_base = ptr + ptroff;
+                                       iov[0].iov_len = size;
+                                       syscall_len = readv(fd, iov, 1);
+                                       break;
+                               }
+                               case WRITEV_TEST: {
+                                       struct iovec iov[1];
+                                       iov[0].iov_base = ptr + ptroff;
+                                       iov[0].iov_len = size;
+                                       syscall_len = writev(fd, iov, 1);
+                                       break;
+                               }
+                               case LAST_TEST:
+                                       goto usermem_acc_err;
+                               }
+
+                               mte_wait_after_trig();
+                               /*
+                                * Accessing user memory in kernel with invalid tag should fail in sync
+                                * mode without fault but may not fail in async mode as per the
+                                * implemented MTE userspace support in Arm64 kernel.
+                                */
+                               if (cur_mte_cxt.fault_valid) {
+                                       goto usermem_acc_err;
+                               }
+                               if (mode == MTE_SYNC_ERR && syscall_len < len) {
+                                       /* test passed */
+                               } else if (mode == MTE_ASYNC_ERR && syscall_len == size) {
+                                       /* test passed */
+                               } else {
+                                       goto usermem_acc_err;
+                               }
+                       }
+               }
        }
+
+       goto exit;
+
 usermem_acc_err:
+       err = KSFT_FAIL;
+exit:
        mte_free_memory((void *)ptr, len, mem_type, true);
        close(fd);
        return err;
 }
 
+void format_test_name(char* name, int name_len, int type, int sync, int map, int len, int offset) {
+       const char* test_type;
+       const char* mte_type;
+       const char* map_type;
+
+       switch (type) {
+       case READ_TEST:
+               test_type = "read";
+               break;
+       case WRITE_TEST:
+               test_type = "write";
+               break;
+       case READV_TEST:
+               test_type = "readv";
+               break;
+       case WRITEV_TEST:
+               test_type = "writev";
+               break;
+       default:
+               assert(0);
+               break;
+       }
+
+       switch (sync) {
+       case MTE_SYNC_ERR:
+               mte_type = "MTE_SYNC_ERR";
+               break;
+       case MTE_ASYNC_ERR:
+               mte_type = "MTE_ASYNC_ERR";
+               break;
+       default:
+               assert(0);
+               break;
+       }
+
+       switch (map) {
+       case MAP_SHARED:
+               map_type = "MAP_SHARED";
+               break;
+       case MAP_PRIVATE:
+               map_type = "MAP_PRIVATE";
+               break;
+       default:
+               assert(0);
+               break;
+       }
+
+       snprintf(name, name_len,
+                "test type: %s, %s, %s, tag len: %d, tag offset: %d\n",
+                test_type, mte_type, map_type, len, offset);
+}
+
 int main(int argc, char *argv[])
 {
        int err;
+       int t, s, m, l, o;
+       int mte_sync[] = {MTE_SYNC_ERR, MTE_ASYNC_ERR};
+       int maps[] = {MAP_SHARED, MAP_PRIVATE};
+       int tag_lens[] = {0, MT_GRANULE_SIZE};
+       int tag_offsets[] = {page_sz, MT_GRANULE_SIZE};
+       char test_name[TEST_NAME_MAX];
 
        page_sz = getpagesize();
        if (!page_sz) {
@@ -98,17 +214,28 @@ int main(int argc, char *argv[])
        mte_register_signal(SIGSEGV, mte_default_handler);
 
        /* Set test plan */
-       ksft_set_plan(4);
+       ksft_set_plan(64);
 
-       evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),
-               "Check memory access from kernel in sync mode, private mapping and mmap memory\n");
-       evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED),
-               "Check memory access from kernel in sync mode, shared mapping and mmap memory\n");
-
-       evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE),
-               "Check memory access from kernel in async mode, private mapping and mmap memory\n");
-       evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED),
-               "Check memory access from kernel in async mode, shared mapping and mmap memory\n");
+       for (t = 0; t < LAST_TEST; t++) {
+               for (s = 0; s < ARRAY_SIZE(mte_sync); s++) {
+                       for (m = 0; m < ARRAY_SIZE(maps); m++) {
+                               for (l = 0; l < ARRAY_SIZE(tag_lens); l++) {
+                                       for (o = 0; o < ARRAY_SIZE(tag_offsets); o++) {
+                                               int sync = mte_sync[s];
+                                               int map = maps[m];
+                                               int offset = tag_offsets[o];
+                                               int tag_len = tag_lens[l];
+                                               int res = check_usermem_access_fault(USE_MMAP, sync,
+                                                                                    map, offset,
+                                                                                    tag_len, t);
+                                               format_test_name(test_name, TEST_NAME_MAX,
+                                                                t, sync, map, tag_len, offset);
+                                               evaluate_test(res, test_name);
+                                       }
+                               }
+                       }
+               }
+       }
 
        mte_restore_setup();
        ksft_print_cnts();
index ebe8694dbef0f9ae39f744cea90da36672ee017e..f909b70d9e980be483ddb7a0a7bcc7d36d28c6ce 100644 (file)
@@ -53,6 +53,7 @@ struct tdescr {
        char                    *name;
        char                    *descr;
        unsigned long           feats_required;
+       unsigned long           feats_incompatible;
        /* bitmask of effectively supported feats: populated at run-time */
        unsigned long           feats_supported;
        bool                    initialized;
index 2f8c23af3b5e006c9cc422a4a2eb70720a5db807..5743897984b0e70333b994525f8e2e01903121ea 100644 (file)
@@ -36,6 +36,8 @@ static inline char *feats_to_string(unsigned long feats)
 {
        size_t flen = MAX_FEATS_SZ - 1;
 
+       feats_string[0] = '\0';
+
        for (int i = 0; i < FMAX_END; i++) {
                if (feats & (1UL << i)) {
                        size_t tlen = strlen(feats_names[i]);
@@ -256,7 +258,7 @@ int test_init(struct tdescr *td)
                td->minsigstksz = MINSIGSTKSZ;
        fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
 
-       if (td->feats_required) {
+       if (td->feats_required || td->feats_incompatible) {
                td->feats_supported = 0;
                /*
                 * Checking for CPU required features using both the
@@ -267,15 +269,29 @@ int test_init(struct tdescr *td)
                if (getauxval(AT_HWCAP) & HWCAP_SVE)
                        td->feats_supported |= FEAT_SVE;
                if (feats_ok(td)) {
-                       fprintf(stderr,
-                               "Required Features: [%s] supported\n",
-                               feats_to_string(td->feats_required &
-                                               td->feats_supported));
+                       if (td->feats_required & td->feats_supported)
+                               fprintf(stderr,
+                                       "Required Features: [%s] supported\n",
+                                       feats_to_string(td->feats_required &
+                                                       td->feats_supported));
+                       if (!(td->feats_incompatible & td->feats_supported))
+                               fprintf(stderr,
+                                       "Incompatible Features: [%s] absent\n",
+                                       feats_to_string(td->feats_incompatible));
                } else {
-                       fprintf(stderr,
-                               "Required Features: [%s] NOT supported\n",
-                               feats_to_string(td->feats_required &
-                                               ~td->feats_supported));
+                       if ((td->feats_required & td->feats_supported) !=
+                           td->feats_supported)
+                               fprintf(stderr,
+                                       "Required Features: [%s] NOT supported\n",
+                                       feats_to_string(td->feats_required &
+                                                       ~td->feats_supported));
+                       if (td->feats_incompatible & td->feats_supported)
+                               fprintf(stderr,
+                                       "Incompatible Features: [%s] supported\n",
+                                       feats_to_string(td->feats_incompatible &
+                                                       ~td->feats_supported));
+
+
                        td->result = KSFT_SKIP;
                        return 0;
                }
index 6772b5c8d274db7bcac54cc0be4a74666399b0e9..f3aa99ba67bb7e919929fbbc5c6c87a51d1fcb20 100644 (file)
@@ -18,6 +18,8 @@ void test_result(struct tdescr *td);
 
 static inline bool feats_ok(struct tdescr *td)
 {
+       if (td->feats_incompatible & td->feats_supported)
+               return false;
        return (td->feats_required & td->feats_supported) == td->feats_required;
 }
 
diff --git a/tools/testing/selftests/bpf/prog_tests/timer_crash.c b/tools/testing/selftests/bpf/prog_tests/timer_crash.c
new file mode 100644 (file)
index 0000000..f74b823
--- /dev/null
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include "timer_crash.skel.h"
+
+enum {
+       MODE_ARRAY,
+       MODE_HASH,
+};
+
+static void test_timer_crash_mode(int mode)
+{
+       struct timer_crash *skel;
+
+       skel = timer_crash__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "timer_crash__open_and_load"))
+               return;
+       skel->bss->pid = getpid();
+       skel->bss->crash_map = mode;
+       if (!ASSERT_OK(timer_crash__attach(skel), "timer_crash__attach"))
+               goto end;
+       usleep(1);
+end:
+       timer_crash__destroy(skel);
+}
+
+void test_timer_crash(void)
+{
+       if (test__start_subtest("array"))
+               test_timer_crash_mode(MODE_ARRAY);
+       if (test__start_subtest("hash"))
+               test_timer_crash_mode(MODE_HASH);
+}
index 2966564b8497aa4cd03049a209e2044e580a652c..6c85b00f27b2e5e795bc3fa9dbb21c50d9999ece 100644 (file)
@@ -235,7 +235,7 @@ SEC("sk_msg1")
 int bpf_prog4(struct sk_msg_md *msg)
 {
        int *bytes, zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
-       int *start, *end, *start_push, *end_push, *start_pop, *pop;
+       int *start, *end, *start_push, *end_push, *start_pop, *pop, err = 0;
 
        bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
        if (bytes)
@@ -249,8 +249,11 @@ int bpf_prog4(struct sk_msg_md *msg)
                bpf_msg_pull_data(msg, *start, *end, 0);
        start_push = bpf_map_lookup_elem(&sock_bytes, &two);
        end_push = bpf_map_lookup_elem(&sock_bytes, &three);
-       if (start_push && end_push)
-               bpf_msg_push_data(msg, *start_push, *end_push, 0);
+       if (start_push && end_push) {
+               err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
+               if (err)
+                       return SK_DROP;
+       }
        start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
        pop = bpf_map_lookup_elem(&sock_bytes, &five);
        if (start_pop && pop)
@@ -263,6 +266,7 @@ int bpf_prog6(struct sk_msg_md *msg)
 {
        int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, key = 0;
        int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop, *f;
+       int err = 0;
        __u64 flags = 0;
 
        bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
@@ -279,8 +283,11 @@ int bpf_prog6(struct sk_msg_md *msg)
 
        start_push = bpf_map_lookup_elem(&sock_bytes, &two);
        end_push = bpf_map_lookup_elem(&sock_bytes, &three);
-       if (start_push && end_push)
-               bpf_msg_push_data(msg, *start_push, *end_push, 0);
+       if (start_push && end_push) {
+               err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
+               if (err)
+                       return SK_DROP;
+       }
 
        start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
        pop = bpf_map_lookup_elem(&sock_bytes, &five);
@@ -338,7 +345,7 @@ SEC("sk_msg5")
 int bpf_prog10(struct sk_msg_md *msg)
 {
        int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop;
-       int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
+       int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, err = 0;
 
        bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
        if (bytes)
@@ -352,8 +359,11 @@ int bpf_prog10(struct sk_msg_md *msg)
                bpf_msg_pull_data(msg, *start, *end, 0);
        start_push = bpf_map_lookup_elem(&sock_bytes, &two);
        end_push = bpf_map_lookup_elem(&sock_bytes, &three);
-       if (start_push && end_push)
-               bpf_msg_push_data(msg, *start_push, *end_push, 0);
+       if (start_push && end_push) {
+               err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
+               if (err)
+                       return SK_PASS;
+       }
        start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
        pop = bpf_map_lookup_elem(&sock_bytes, &five);
        if (start_pop && pop)
diff --git a/tools/testing/selftests/bpf/progs/timer_crash.c b/tools/testing/selftests/bpf/progs/timer_crash.c
new file mode 100644 (file)
index 0000000..f8f7944
--- /dev/null
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <vmlinux.h>
+#include <bpf/bpf_tracing.h>
+#include <bpf/bpf_helpers.h>
+
+struct map_elem {
+       struct bpf_timer timer;
+       struct bpf_spin_lock lock;
+};
+
+struct {
+       __uint(type, BPF_MAP_TYPE_ARRAY);
+       __uint(max_entries, 1);
+       __type(key, int);
+       __type(value, struct map_elem);
+} amap SEC(".maps");
+
+struct {
+       __uint(type, BPF_MAP_TYPE_HASH);
+       __uint(max_entries, 1);
+       __type(key, int);
+       __type(value, struct map_elem);
+} hmap SEC(".maps");
+
+int pid = 0;
+int crash_map = 0; /* 0 for amap, 1 for hmap */
+
+SEC("fentry/do_nanosleep")
+int sys_enter(void *ctx)
+{
+       struct map_elem *e, value = {};
+       void *map = crash_map ? (void *)&hmap : (void *)&amap;
+
+       if (bpf_get_current_task_btf()->tgid != pid)
+               return 0;
+
+       *(void **)&value = (void *)0xdeadcaf3;
+
+       bpf_map_update_elem(map, &(int){0}, &value, 0);
+       /* For array map, doing bpf_map_update_elem will do a
+        * check_and_free_timer_in_array, which will trigger the crash if timer
+        * pointer was overwritten, for hmap we need to use bpf_timer_cancel.
+        */
+       if (crash_map == 1) {
+               e = bpf_map_lookup_elem(map, &(int){0});
+               if (!e)
+                       return 0;
+               bpf_timer_cancel(&e->timer);
+       }
+       return 0;
+}
+
+char _license[] SEC("license") = "GPL";
index bcb110e830ceca31f424bbe3f3faa07dfb4c98fc..dea33dc937906adb9adf4f7707386e7efe6f5925 100755 (executable)
@@ -50,8 +50,8 @@ for current_test in ${TESTS:-$ALL_TESTS}; do
                        else
                                log_test "'$current_test' [$profile] overflow $target"
                        fi
+                       RET_FIN=$(( RET_FIN || RET ))
                done
-               RET_FIN=$(( RET_FIN || RET ))
        done
 done
 current_test=""
index 3e3e06ea5703cd93e73f619f4c39ffe16115eb80..86e787895f78b19300677529884f01e6eeb65cab 100644 (file)
@@ -60,7 +60,8 @@ __tc_police_test()
 
        tc_police_rules_create $count $should_fail
 
-       offload_count=$(tc filter show dev $swp1 ingress | grep in_hw | wc -l)
+       offload_count=$(tc -j filter show dev $swp1 ingress |
+                       jq "[.[] | select(.options.in_hw == true)] | length")
        ((offload_count == count))
        check_err_fail $should_fail $? "tc police offload count"
 }
index 9ad38bd360a42ebd540c70a6b7663c72408ec311..b08d30bf71c513f443d665d5e30f368842d8d275 100644 (file)
@@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
 {
        struct kvm_vm *vm;
        unsigned int i;
+       int ret;
        int nr_vcpus = test_args.nr_vcpus;
 
        vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
@@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
 
        ucall_init(vm, NULL);
        test_init_timer_irq(vm);
-       vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+       ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+       if (ret < 0) {
+               print_skip("Failed to create vgic-v3");
+               exit(KSFT_SKIP);
+       }
 
        /* Make all the test's cmdline args visible to the guest */
        sync_global_to_guest(vm, test_args);
index e6c7d7f8fbd1bcafdbe19f59e7cdf8a39b37c2cd..7eca977999170edc95a9b1bacbdeb1454e39fc79 100644 (file)
@@ -761,6 +761,10 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
 
        gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
                        GICD_BASE_GPA, GICR_BASE_GPA);
+       if (gic_fd < 0) {
+               print_skip("Failed to create vgic-v3, skipping");
+               exit(KSFT_SKIP);
+       }
 
        vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
                guest_irq_handlers[args.eoi_split][args.level_sensitive]);
index b3a0fca0d7806473c2431c2555d4d682003affd0..f5cd0c536d85cd9048ffc08cf38181fde1747073 100644 (file)
@@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
                        nr_vcpus, nr_vcpus_created);
 
        /* Distributor setup */
-       gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
+       if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3,
+                              false, &gic_fd) != 0)
+               return -1;
 
        kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
                        0, &nr_irqs, true);
index 192a2899bae8fcd65d5fb3b60a3916df9b07fbf9..94df2692e6e4a70062f07a45ec7278fcb3d51302 100644 (file)
@@ -455,6 +455,7 @@ static void mfd_fail_write(int fd)
                        printf("mmap()+mprotect() didn't fail as expected\n");
                        abort();
                }
+               munmap(p, mfd_def_size);
        }
 
        /* verify PUNCH_HOLE fails */
index 2674ba20d52490b6309bd47607d67827675b9826..ff821025d30963237cedb8d2d3ace47e4ef511c9 100755 (executable)
@@ -71,6 +71,36 @@ chk_msk_remote_key_nr()
                __chk_nr "grep -c remote_key" $*
 }
 
+# $1: ns, $2: port
+wait_local_port_listen()
+{
+       local listener_ns="${1}"
+       local port="${2}"
+
+       local port_hex i
+
+       port_hex="$(printf "%04X" "${port}")"
+       for i in $(seq 10); do
+               ip netns exec "${listener_ns}" cat /proc/net/tcp | \
+                       awk "BEGIN {rc=1} {if (\$2 ~ /:${port_hex}\$/ && \$4 ~ /0A/) {rc=0; exit}} END {exit rc}" &&
+                       break
+               sleep 0.1
+       done
+}
+
+wait_connected()
+{
+       local listener_ns="${1}"
+       local port="${2}"
+
+       local port_hex i
+
+       port_hex="$(printf "%04X" "${port}")"
+       for i in $(seq 10); do
+               ip netns exec ${listener_ns} grep -q " 0100007F:${port_hex} " /proc/net/tcp && break
+               sleep 0.1
+       done
+}
 
 trap cleanup EXIT
 ip netns add $ns
@@ -81,15 +111,15 @@ echo "a" | \
                ip netns exec $ns \
                        ./mptcp_connect -p 10000 -l -t ${timeout_poll} \
                                0.0.0.0 >/dev/null &
-sleep 0.1
+wait_local_port_listen $ns 10000
 chk_msk_nr 0 "no msk on netns creation"
 
 echo "b" | \
        timeout ${timeout_test} \
                ip netns exec $ns \
-                       ./mptcp_connect -p 10000 -j -t ${timeout_poll} \
+                       ./mptcp_connect -p 10000 -r 0 -t ${timeout_poll} \
                                127.0.0.1 >/dev/null &
-sleep 0.1
+wait_connected $ns 10000
 chk_msk_nr 2 "after MPC handshake "
 chk_msk_remote_key_nr 2 "....chk remote_key"
 chk_msk_fallback_nr 0 "....chk no fallback"
@@ -101,13 +131,13 @@ echo "a" | \
                ip netns exec $ns \
                        ./mptcp_connect -p 10001 -l -s TCP -t ${timeout_poll} \
                                0.0.0.0 >/dev/null &
-sleep 0.1
+wait_local_port_listen $ns 10001
 echo "b" | \
        timeout ${timeout_test} \
                ip netns exec $ns \
-                       ./mptcp_connect -p 10001 -j -t ${timeout_poll} \
+                       ./mptcp_connect -p 10001 -r 0 -t ${timeout_poll} \
                                127.0.0.1 >/dev/null &
-sleep 0.1
+wait_connected $ns 10001
 chk_msk_fallback_nr 1 "check fallback"
 flush_pids
 
@@ -119,7 +149,7 @@ for I in `seq 1 $NR_CLIENTS`; do
                                ./mptcp_connect -p $((I+10001)) -l -w 10 \
                                        -t ${timeout_poll} 0.0.0.0 >/dev/null &
 done
-sleep 0.1
+wait_local_port_listen $ns $((NR_CLIENTS + 10001))
 
 for I in `seq 1 $NR_CLIENTS`; do
        echo "b" | \
index cb5809b89081003ff0b6baa34bf236a601af1eea..f0f4ab96b8f3e10d40d3b04758fea87cb36cc2b8 100755 (executable)
@@ -763,8 +763,8 @@ run_tests_disconnect()
        run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-I 3 -i $old_cin"
 
        # restore previous status
-       cout=$old_cout
-       cout_disconnect="$cout".disconnect
+       sin=$old_sin
+       sin_disconnect="$cout".disconnect
        cin=$old_cin
        cin_disconnect="$cin".disconnect
        connect_per_transfer=1
index c0801df15f547265e2f63d0625ca7f958e765572..0c8a2a20b96cf04eee3bcca6b2a3ac8465753d1c 100755 (executable)
@@ -660,6 +660,7 @@ chk_join_nr()
        local ack_nr=$4
        local count
        local dump_stats
+       local with_cookie
 
        printf "%02u %-36s %s" "$TEST_COUNT" "$msg" "syn"
        count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPJoinSynRx | awk '{print $2}'`
@@ -673,12 +674,20 @@ chk_join_nr()
        fi
 
        echo -n " - synack"
+       with_cookie=`ip netns exec $ns2 sysctl -n net.ipv4.tcp_syncookies`
        count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPJoinSynAckRx | awk '{print $2}'`
        [ -z "$count" ] && count=0
        if [ "$count" != "$syn_ack_nr" ]; then
-               echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr"
-               ret=1
-               dump_stats=1
+               # simult connections exceeding the limit with cookie enabled could go up to
+               # synack validation as the conn limit can be enforced reliably only after
+               # the subflow creation
+               if [ "$with_cookie" = 2 ] && [ "$count" -gt "$syn_ack_nr" ] && [ "$count" -le "$syn_nr" ]; then
+                       echo -n "[ ok ]"
+               else
+                       echo "[fail] got $count JOIN[s] synack expected $syn_ack_nr"
+                       ret=1
+                       dump_stats=1
+               fi
        else
                echo -n "[ ok ]"
        fi
@@ -752,11 +761,17 @@ chk_add_nr()
        local mis_ack_nr=${8:-0}
        local count
        local dump_stats
+       local timeout
+
+       timeout=`ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout`
 
        printf "%-39s %s" " " "add"
-       count=`ip netns exec $ns2 nstat -as | grep MPTcpExtAddAddr | awk '{print $2}'`
+       count=`ip netns exec $ns2 nstat -as MPTcpExtAddAddr | grep MPTcpExtAddAddr | awk '{print $2}'`
        [ -z "$count" ] && count=0
-       if [ "$count" != "$add_nr" ]; then
+
+       # if the test configured a short timeout tolerate greater then expected
+       # add addrs options, due to retransmissions
+       if [ "$count" != "$add_nr" ] && [ "$timeout" -gt 1 -o "$count" -lt "$add_nr" ]; then
                echo "[fail] got $count ADD_ADDR[s] expected $add_nr"
                ret=1
                dump_stats=1
@@ -961,7 +976,7 @@ wait_for_tw()
        local ns=$1
 
        while [ $time -lt $timeout_ms ]; do
-               local cnt=$(ip netns exec $ns ss -t state time-wait |wc -l)
+               local cnt=$(ip netns exec $ns nstat -as TcpAttemptFails | grep TcpAttemptFails | awk '{print $2}')
 
                [ "$cnt" = 1 ] && return 1
                time=$((time + 100))
@@ -1158,7 +1173,10 @@ signal_address_tests()
        ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags signal
        ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags signal
        ip netns exec $ns2 ./pm_nl_ctl add 10.0.4.2 flags signal
-       run_tests $ns1 $ns2 10.0.1.1
+
+       # the peer could possibly miss some addr notification, allow retransmission
+       ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
+       run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
        chk_join_nr "signal addresses race test" 3 3 3
 
        # the server will not signal the address terminating
index 543ad7513a8e9feeb705e3a22bdd0e2784119e39..694732e4b3448666ffe24f9e58050b2c2bda5a3a 100755 (executable)
@@ -374,6 +374,16 @@ run_cmd() {
        return $rc
 }
 
+run_cmd_bg() {
+       cmd="$*"
+
+       if [ "$VERBOSE" = "1" ]; then
+               printf "    COMMAND: %s &\n" "${cmd}"
+       fi
+
+       $cmd 2>&1 &
+}
+
 # Find the auto-generated name for this namespace
 nsname() {
        eval echo \$NS_$1
@@ -670,10 +680,10 @@ setup_nettest_xfrm() {
        [ ${1} -eq 6 ] && proto="-6" || proto=""
        port=${2}
 
-       run_cmd ${ns_a} nettest ${proto} -q -D -s -x -p ${port} -t 5 &
+       run_cmd_bg "${ns_a}" nettest "${proto}" -q -D -s -x -p "${port}" -t 5
        nettest_pids="${nettest_pids} $!"
 
-       run_cmd ${ns_b} nettest ${proto} -q -D -s -x -p ${port} -t 5 &
+       run_cmd_bg "${ns_b}" nettest "${proto}" -q -D -s -x -p "${port}" -t 5
        nettest_pids="${nettest_pids} $!"
 }
 
@@ -865,7 +875,6 @@ setup_ovs_bridge() {
 setup() {
        [ "$(id -u)" -ne 0 ] && echo "  need to run as root" && return $ksft_skip
 
-       cleanup
        for arg do
                eval setup_${arg} || { echo "  ${arg} not supported"; return 1; }
        done
@@ -876,7 +885,7 @@ trace() {
 
        for arg do
                [ "${ns_cmd}" = "" ] && ns_cmd="${arg}" && continue
-               ${ns_cmd} tcpdump -s 0 -i "${arg}" -w "${name}_${arg}.pcap" 2> /dev/null &
+               ${ns_cmd} tcpdump --immediate-mode -s 0 -i "${arg}" -w "${name}_${arg}.pcap" 2> /dev/null &
                tcpdump_pids="${tcpdump_pids} $!"
                ns_cmd=
        done
@@ -1836,6 +1845,10 @@ run_test() {
 
        unset IFS
 
+       # Since cleanup() relies on variables modified by this subshell, it
+       # has to run in this context.
+       trap cleanup EXIT
+
        if [ "$VERBOSE" = "1" ]; then
                printf "\n##########################################################################\n\n"
        fi
index 8448f74adfecbcd4c0c4d451e1f50ac54e79e66e..4cb887b574138ddc3a00c8d673a8281be2cfcc68 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 nf-queue
+connect_close
index e4f845dd942b3f32a07c74414f9a2f20c598ea8e..7e81c9a7fff904b487ec851eec53b1a533bfc6f7 100644 (file)
@@ -9,6 +9,6 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \
        conntrack_vrf.sh nft_synproxy.sh
 
 LDLIBS = -lmnl
-TEST_GEN_FILES =  nf-queue
+TEST_GEN_FILES =  nf-queue connect_close
 
 include ../lib.mk
diff --git a/tools/testing/selftests/netfilter/connect_close.c b/tools/testing/selftests/netfilter/connect_close.c
new file mode 100644 (file)
index 0000000..1c3b0ad
--- /dev/null
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#define PORT 12345
+#define RUNTIME 10
+
+static struct {
+       unsigned int timeout;
+       unsigned int port;
+} opts = {
+       .timeout = RUNTIME,
+       .port = PORT,
+};
+
+static void handler(int sig)
+{
+       _exit(sig == SIGALRM ? 0 : 1);
+}
+
+static void set_timeout(void)
+{
+       struct sigaction action = {
+               .sa_handler = handler,
+       };
+
+       sigaction(SIGALRM, &action, NULL);
+
+       alarm(opts.timeout);
+}
+
+static void do_connect(const struct sockaddr_in *dst)
+{
+       int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+       if (s >= 0)
+               fcntl(s, F_SETFL, O_NONBLOCK);
+
+       connect(s, (struct sockaddr *)dst, sizeof(*dst));
+       close(s);
+}
+
+static void do_accept(const struct sockaddr_in *src)
+{
+       int c, one = 1, s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+       if (s < 0)
+               return;
+
+       setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+       setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
+
+       bind(s, (struct sockaddr *)src, sizeof(*src));
+
+       listen(s, 16);
+
+       c = accept(s, NULL, NULL);
+       if (c >= 0)
+               close(c);
+
+       close(s);
+}
+
+static int accept_loop(void)
+{
+       struct sockaddr_in src = {
+               .sin_family = AF_INET,
+               .sin_port = htons(opts.port),
+       };
+
+       inet_pton(AF_INET, "127.0.0.1", &src.sin_addr);
+
+       set_timeout();
+
+       for (;;)
+               do_accept(&src);
+
+       return 1;
+}
+
+static int connect_loop(void)
+{
+       struct sockaddr_in dst = {
+               .sin_family = AF_INET,
+               .sin_port = htons(opts.port),
+       };
+
+       inet_pton(AF_INET, "127.0.0.1", &dst.sin_addr);
+
+       set_timeout();
+
+       for (;;)
+               do_connect(&dst);
+
+       return 1;
+}
+
+static void parse_opts(int argc, char **argv)
+{
+       int c;
+
+       while ((c = getopt(argc, argv, "t:p:")) != -1) {
+               switch (c) {
+               case 't':
+                       opts.timeout = atoi(optarg);
+                       break;
+               case 'p':
+                       opts.port = atoi(optarg);
+                       break;
+               }
+       }
+}
+
+int main(int argc, char *argv[])
+{
+       pid_t p;
+
+       parse_opts(argc, argv);
+
+       p = fork();
+       if (p < 0)
+               return 111;
+
+       if (p > 0)
+               return accept_loop();
+
+       return connect_loop();
+}
index 79fe627b9e817a087178e1efbbce443b884c0c4d..eb8543b9a5c4025e09ea33f0bd90040fb7f6f02f 100755 (executable)
@@ -880,9 +880,8 @@ EOF
                return $ksft_skip
        fi
 
-       # test default behaviour. Packet from ns1 to ns0 is not redirected
-       # due to automatic port translation.
-       test_port_shadow "default" "ROUTER"
+       # test default behaviour. Packet from ns1 to ns0 is redirected to ns2.
+       test_port_shadow "default" "CLIENT"
 
        # test packet filter based mitigation: prevent forwarding of
        # packets claiming to come from the service port.
index 7d27f1f3bc0108933ddbf22960e99f2a79db546c..e12729753351a7093b5965535a7f2025ef1c6e8f 100755 (executable)
@@ -113,6 +113,7 @@ table inet $name {
        chain output {
                type filter hook output priority $prio; policy accept;
                tcp dport 12345 queue num 3
+               tcp sport 23456 queue num 3
                jump nfq
        }
        chain post {
@@ -296,6 +297,23 @@ test_tcp_localhost()
        wait 2>/dev/null
 }
 
+test_tcp_localhost_connectclose()
+{
+       tmpfile=$(mktemp) || exit 1
+
+       ip netns exec ${nsrouter} ./connect_close -p 23456 -t $timeout &
+
+       ip netns exec ${nsrouter} ./nf-queue -q 3 -t $timeout &
+       local nfqpid=$!
+
+       sleep 1
+       rm -f "$tmpfile"
+
+       wait $rpid
+       [ $? -eq 0 ] && echo "PASS: tcp via loopback with connect/close"
+       wait 2>/dev/null
+}
+
 test_tcp_localhost_requeue()
 {
 ip netns exec ${nsrouter} nft -f /dev/stdin <<EOF
@@ -424,6 +442,7 @@ test_queue 20
 
 test_tcp_forward
 test_tcp_localhost
+test_tcp_localhost_connectclose
 test_tcp_localhost_requeue
 test_icmp_vrf
 
index 2956584e1e37ff0b244b8db4997d0a2445177676..75af864e07b6547ebcf43ce26a2adbc1132b1935 100644 (file)
@@ -4,7 +4,7 @@ include ../lib.mk
 
 .PHONY: all clean
 
-CAN_BUILD_X86_64 := $(shell ../x86/check_cc.sh $(CC) \
+CAN_BUILD_X86_64 := $(shell ../x86/check_cc.sh "$(CC)" \
                            ../x86/trivial_64bit_program.c)
 
 ifndef OBJCOPY
index 9d4322c946e2bed95891933c1c924e532ff4a24b..006b464c8fc949f6de00499130aeb148107e8908 100644 (file)
@@ -21,7 +21,7 @@
 
 void encl_delete(struct encl *encl)
 {
-       struct encl_segment *heap_seg = &encl->segment_tbl[encl->nr_segments - 1];
+       struct encl_segment *heap_seg;
 
        if (encl->encl_base)
                munmap((void *)encl->encl_base, encl->encl_size);
@@ -32,10 +32,11 @@ void encl_delete(struct encl *encl)
        if (encl->fd)
                close(encl->fd);
 
-       munmap(heap_seg->src, heap_seg->size);
-
-       if (encl->segment_tbl)
+       if (encl->segment_tbl) {
+               heap_seg = &encl->segment_tbl[encl->nr_segments - 1];
+               munmap(heap_seg->src, heap_seg->size);
                free(encl->segment_tbl);
+       }
 
        memset(encl, 0, sizeof(*encl));
 }
index 370c4995f7c4abccb8c2741b872a3871a0c874a6..dd74fa42302e035bb39154bb54bcf700f9ba13a4 100644 (file)
@@ -146,7 +146,8 @@ static bool setup_test_encl(unsigned long heap_size, struct encl *encl,
 
        if (!encl_load("test_encl.elf", encl, heap_size)) {
                encl_delete(encl);
-               TH_LOG("Failed to load the test enclave.\n");
+               TH_LOG("Failed to load the test enclave.");
+               return false;
        }
 
        if (!encl_measure(encl))
@@ -185,8 +186,6 @@ static bool setup_test_encl(unsigned long heap_size, struct encl *encl,
        return true;
 
 err:
-       encl_delete(encl);
-
        for (i = 0; i < encl->nr_segments; i++) {
                seg = &encl->segment_tbl[i];
 
@@ -205,7 +204,9 @@ err:
                fclose(maps_file);
        }
 
-       TH_LOG("Failed to initialize the test enclave.\n");
+       TH_LOG("Failed to initialize the test enclave.");
+
+       encl_delete(encl);
 
        return false;
 }
index f34486cd7342d51a9cfddab193ca01243fb0b2e4..057a4f49c79d963e0657088a10d09ec1baf31bd5 100644 (file)
@@ -56,6 +56,7 @@ TSS2_RESMGR_TPM_RC_LAYER = (11 << TSS2_RC_LAYER_SHIFT)
 
 TPM2_CAP_HANDLES = 0x00000001
 TPM2_CAP_COMMANDS = 0x00000002
+TPM2_CAP_PCRS = 0x00000005
 TPM2_CAP_TPM_PROPERTIES = 0x00000006
 
 TPM2_PT_FIXED = 0x100
@@ -712,3 +713,33 @@ class Client:
             pt += 1
 
         return handles
+
+    def get_cap_pcrs(self):
+        pcr_banks = {}
+
+        fmt = '>HII III'
+
+        cmd = struct.pack(fmt,
+                          TPM2_ST_NO_SESSIONS,
+                          struct.calcsize(fmt),
+                          TPM2_CC_GET_CAPABILITY,
+                          TPM2_CAP_PCRS, 0, 1)
+        rsp = self.send_cmd(cmd)[10:]
+        _, _, cnt = struct.unpack('>BII', rsp[:9])
+        rsp = rsp[9:]
+
+        # items are TPMS_PCR_SELECTION's
+        for i in range(0, cnt):
+              hash, sizeOfSelect = struct.unpack('>HB', rsp[:3])
+              rsp = rsp[3:]
+
+              pcrSelect = 0
+              if sizeOfSelect > 0:
+                  pcrSelect, = struct.unpack('%ds' % sizeOfSelect,
+                                             rsp[:sizeOfSelect])
+                  rsp = rsp[sizeOfSelect:]
+                  pcrSelect = int.from_bytes(pcrSelect, byteorder='big')
+
+              pcr_banks[hash] = pcrSelect
+
+        return pcr_banks
index 9d764306887b7008b5a75b2eab6584c2abb06e76..ffe98b5c8d22f33a0ad7fa0529344fc52e1693bf 100644 (file)
@@ -27,7 +27,17 @@ class SmokeTest(unittest.TestCase):
         result = self.client.unseal(self.root_key, blob, auth, None)
         self.assertEqual(data, result)
 
+    def determine_bank_alg(self, mask):
+        pcr_banks = self.client.get_cap_pcrs()
+        for bank_alg, pcrSelection in pcr_banks.items():
+            if pcrSelection & mask == mask:
+                return bank_alg
+        return None
+
     def test_seal_with_policy(self):
+        bank_alg = self.determine_bank_alg(1 << 16)
+        self.assertIsNotNone(bank_alg)
+
         handle = self.client.start_auth_session(tpm2.TPM2_SE_TRIAL)
 
         data = ('X' * 64).encode()
@@ -35,7 +45,7 @@ class SmokeTest(unittest.TestCase):
         pcrs = [16]
 
         try:
-            self.client.policy_pcr(handle, pcrs)
+            self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg)
             self.client.policy_password(handle)
 
             policy_dig = self.client.get_policy_digest(handle)
@@ -47,7 +57,7 @@ class SmokeTest(unittest.TestCase):
         handle = self.client.start_auth_session(tpm2.TPM2_SE_POLICY)
 
         try:
-            self.client.policy_pcr(handle, pcrs)
+            self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg)
             self.client.policy_password(handle)
 
             result = self.client.unseal(self.root_key, blob, auth, handle)
@@ -72,6 +82,9 @@ class SmokeTest(unittest.TestCase):
         self.assertEqual(rc, tpm2.TPM2_RC_AUTH_FAIL)
 
     def test_unseal_with_wrong_policy(self):
+        bank_alg = self.determine_bank_alg(1 << 16 | 1 << 1)
+        self.assertIsNotNone(bank_alg)
+
         handle = self.client.start_auth_session(tpm2.TPM2_SE_TRIAL)
 
         data = ('X' * 64).encode()
@@ -79,7 +92,7 @@ class SmokeTest(unittest.TestCase):
         pcrs = [16]
 
         try:
-            self.client.policy_pcr(handle, pcrs)
+            self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg)
             self.client.policy_password(handle)
 
             policy_dig = self.client.get_policy_digest(handle)
@@ -91,13 +104,13 @@ class SmokeTest(unittest.TestCase):
         # Extend first a PCR that is not part of the policy and try to unseal.
         # This should succeed.
 
-        ds = tpm2.get_digest_size(tpm2.TPM2_ALG_SHA1)
-        self.client.extend_pcr(1, ('X' * ds).encode())
+        ds = tpm2.get_digest_size(bank_alg)
+        self.client.extend_pcr(1, ('X' * ds).encode(), bank_alg=bank_alg)
 
         handle = self.client.start_auth_session(tpm2.TPM2_SE_POLICY)
 
         try:
-            self.client.policy_pcr(handle, pcrs)
+            self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg)
             self.client.policy_password(handle)
 
             result = self.client.unseal(self.root_key, blob, auth, handle)
@@ -109,14 +122,14 @@ class SmokeTest(unittest.TestCase):
 
         # Then, extend a PCR that is part of the policy and try to unseal.
         # This should fail.
-        self.client.extend_pcr(16, ('X' * ds).encode())
+        self.client.extend_pcr(16, ('X' * ds).encode(), bank_alg=bank_alg)
 
         handle = self.client.start_auth_session(tpm2.TPM2_SE_POLICY)
 
         rc = 0
 
         try:
-            self.client.policy_pcr(handle, pcrs)
+            self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg)
             self.client.policy_password(handle)
 
             result = self.client.unseal(self.root_key, blob, auth, handle)
@@ -302,3 +315,19 @@ class AsyncTest(unittest.TestCase):
         log.debug("Calling get_cap in a NON_BLOCKING mode")
         async_client.get_cap(tpm2.TPM2_CAP_HANDLES, tpm2.HR_LOADED_SESSION)
         async_client.close()
+
+    def test_flush_invalid_context(self):
+        log = logging.getLogger(__name__)
+        log.debug(sys._getframe().f_code.co_name)
+
+        async_client = tpm2.Client(tpm2.Client.FLAG_SPACE | tpm2.Client.FLAG_NONBLOCK)
+        log.debug("Calling flush_context passing in an invalid handle ")
+        handle = 0x80123456
+        rc = 0
+        try:
+            async_client.flush_context(handle)
+        except OSError as e:
+            rc = e.errno
+
+        self.assertEqual(rc, 22)
+        async_client.close()
index 1607322a112c91732f7c020325513b2c8c9c06ab..a14b5b80089706946b869c4a1d88dc3dd57ee1a7 100644 (file)
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for vm selftests
 
+LOCAL_HDRS += $(selfdir)/vm/local_config.h $(top_srcdir)/mm/gup_test.h
+
 include local_config.mk
 
 uname_M := $(shell uname -m 2>/dev/null || echo not)
@@ -140,10 +142,6 @@ endif
 
 $(OUTPUT)/mlock-random-test $(OUTPUT)/memfd_secret: LDLIBS += -lcap
 
-$(OUTPUT)/gup_test: ../../../../mm/gup_test.h
-
-$(OUTPUT)/hmm-tests: local_config.h
-
 # HMM_EXTRA_LIBS may get set in local_config.mk, or it may be left empty.
 $(OUTPUT)/hmm-tests: LDLIBS += $(HMM_EXTRA_LIBS)
 
index 2a7c33631a298874e2e8991a72ac3998d9317c83..1d689084a54ba3e1f86c189bdcd7b10fafba1295 100644 (file)
@@ -3,9 +3,10 @@
  * hugepage-mremap:
  *
  * Example of remapping huge page memory in a user application using the
- * mremap system call.  Code assumes a hugetlbfs filesystem is mounted
- * at './huge'.  The amount of memory used by this test is decided by a command
- * line argument in MBs. If missing, the default amount is 10MB.
+ * mremap system call.  The path to a file in a hugetlbfs filesystem must
+ * be passed as the last argument to this test.  The amount of memory used
+ * by this test in MBs can optionally be passed as an argument.  If no memory
+ * amount is passed, the default amount is 10MB.
  *
  * To make sure the test triggers pmd sharing and goes through the 'unshare'
  * path in the mremap code use 1GB (1024) or more.
@@ -25,7 +26,6 @@
 #define DEFAULT_LENGTH_MB 10UL
 #define MB_TO_BYTES(x) (x * 1024 * 1024)
 
-#define FILE_NAME "huge/hugepagefile"
 #define PROTECTION (PROT_READ | PROT_WRITE | PROT_EXEC)
 #define FLAGS (MAP_SHARED | MAP_ANONYMOUS)
 
@@ -107,17 +107,26 @@ static void register_region_with_uffd(char *addr, size_t len)
 
 int main(int argc, char *argv[])
 {
+       size_t length;
+
+       if (argc != 2 && argc != 3) {
+               printf("Usage: %s [length_in_MB] <hugetlb_file>\n", argv[0]);
+               exit(1);
+       }
+
        /* Read memory length as the first arg if valid, otherwise fallback to
-        * the default length. Any additional args are ignored.
+        * the default length.
         */
-       size_t length = argc > 1 ? (size_t)atoi(argv[1]) : 0UL;
+       if (argc == 3)
+               length = argc > 2 ? (size_t)atoi(argv[1]) : 0UL;
 
        length = length > 0 ? length : DEFAULT_LENGTH_MB;
        length = MB_TO_BYTES(length);
 
        int ret = 0;
 
-       int fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
+       /* last arg is the hugetlb file name */
+       int fd = open(argv[argc-1], O_CREAT | O_RDWR, 0755);
 
        if (fd < 0) {
                perror("Open failed");
@@ -169,5 +178,8 @@ int main(int argc, char *argv[])
 
        munmap(addr, length);
 
+       close(fd);
+       unlink(argv[argc-1]);
+
        return ret;
 }
index d91bde511268667ab183b98bdd1fa99258173df9..eed44322d1a635e6405bd6bc79eacf434a76697d 100644 (file)
@@ -17,9 +17,6 @@
 #define MAP_FIXED_NOREPLACE 0x100000
 #endif
 
-#define BASE_ADDRESS   (256ul * 1024 * 1024)
-
-
 static void dump_maps(void)
 {
        char cmd[32];
@@ -28,18 +25,46 @@ static void dump_maps(void)
        system(cmd);
 }
 
+static unsigned long find_base_addr(unsigned long size)
+{
+       void *addr;
+       unsigned long flags;
+
+       flags = MAP_PRIVATE | MAP_ANONYMOUS;
+       addr = mmap(NULL, size, PROT_NONE, flags, -1, 0);
+       if (addr == MAP_FAILED) {
+               printf("Error: couldn't map the space we need for the test\n");
+               return 0;
+       }
+
+       if (munmap(addr, size) != 0) {
+               printf("Error: couldn't map the space we need for the test\n");
+               return 0;
+       }
+       return (unsigned long)addr;
+}
+
 int main(void)
 {
+       unsigned long base_addr;
        unsigned long flags, addr, size, page_size;
        char *p;
 
        page_size = sysconf(_SC_PAGE_SIZE);
 
+       //let's find a base addr that is free before we start the tests
+       size = 5 * page_size;
+       base_addr = find_base_addr(size);
+       if (!base_addr) {
+               printf("Error: couldn't map the space we need for the test\n");
+               return 1;
+       }
+
        flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;
 
        // Check we can map all the areas we need below
        errno = 0;
-       addr = BASE_ADDRESS;
+       addr = base_addr;
        size = 5 * page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
 
@@ -60,7 +85,7 @@ int main(void)
        printf("unmap() successful\n");
 
        errno = 0;
-       addr = BASE_ADDRESS + page_size;
+       addr = base_addr + page_size;
        size = 3 * page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
        printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
@@ -80,7 +105,7 @@ int main(void)
         *     +4 |  free  | new
         */
        errno = 0;
-       addr = BASE_ADDRESS;
+       addr = base_addr;
        size = 5 * page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
        printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
@@ -101,7 +126,7 @@ int main(void)
         *     +4 |  free  |
         */
        errno = 0;
-       addr = BASE_ADDRESS + (2 * page_size);
+       addr = base_addr + (2 * page_size);
        size = page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
        printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
@@ -121,7 +146,7 @@ int main(void)
         *     +4 |  free  | new
         */
        errno = 0;
-       addr = BASE_ADDRESS + (3 * page_size);
+       addr = base_addr + (3 * page_size);
        size = 2 * page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
        printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
@@ -141,7 +166,7 @@ int main(void)
         *     +4 |  free  |
         */
        errno = 0;
-       addr = BASE_ADDRESS;
+       addr = base_addr;
        size = 2 * page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
        printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
@@ -161,7 +186,7 @@ int main(void)
         *     +4 |  free  |
         */
        errno = 0;
-       addr = BASE_ADDRESS;
+       addr = base_addr;
        size = page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
        printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
@@ -181,7 +206,7 @@ int main(void)
         *     +4 |  free  |  new
         */
        errno = 0;
-       addr = BASE_ADDRESS + (4 * page_size);
+       addr = base_addr + (4 * page_size);
        size = page_size;
        p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
        printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
@@ -192,7 +217,7 @@ int main(void)
                return 1;
        }
 
-       addr = BASE_ADDRESS;
+       addr = base_addr;
        size = 5 * page_size;
        if (munmap((void *)addr, size) != 0) {
                dump_maps();
index 75d4017413944660dcc213afe7a69d71da4d7e5d..71d2dc198fc178653ad105aa7884877618110f3d 100755 (executable)
@@ -111,13 +111,14 @@ fi
 echo "-----------------------"
 echo "running hugepage-mremap"
 echo "-----------------------"
-./hugepage-mremap 256
+./hugepage-mremap $mnt/huge_mremap
 if [ $? -ne 0 ]; then
        echo "[FAIL]"
        exitcode=1
 else
        echo "[PASS]"
 fi
+rm -f $mnt/huge_mremap
 
 echo "NOTE: The above hugetlb tests provide minimal coverage.  Use"
 echo "      https://github.com/libhugetlbfs/libhugetlbfs.git for"
index 2f49c9af1b582449b5e06d250ae2a9b69c0a461e..3fc1d2ee294859fcc3b6c587b4a22182725686f4 100644 (file)
@@ -46,6 +46,7 @@
 #include <signal.h>
 #include <poll.h>
 #include <string.h>
+#include <linux/mman.h>
 #include <sys/mman.h>
 #include <sys/syscall.h>
 #include <sys/ioctl.h>
index 3e2089c8cf54967fdd375ec151a15827e104fc53..8c669c0d662ee275f27132d2fcab174660ab4c81 100755 (executable)
@@ -7,7 +7,7 @@ CC="$1"
 TESTPROG="$2"
 shift 2
 
-if "$CC" -o /dev/null "$TESTPROG" -O0 "$@" 2>/dev/null; then
+if [ -n "$CC" ] && $CC -o /dev/null "$TESTPROG" -O0 "$@" 2>/dev/null; then
     echo 1
 else
     echo 0
index 5648f9252e580870a4b6fcc72ff09debb34405f8..e60f1862bad09901f509a619fda2cd847ada2535 100644 (file)
@@ -810,7 +810,7 @@ struct osnoise_tool *osnoise_init_trace_tool(char *tracer)
 
        retval = enable_tracer_by_name(trace->trace.inst, tracer);
        if (retval) {
-               err_msg("Could not enable osnoiser tracer for tracing\n");
+               err_msg("Could not enable %s tracer for tracing\n", tracer);
                goto out_err;
        }
 
index 1f0b7fce55cf68d3a2e1652ebf2c9bb9ba6b9070..52c053cc1789d915ac2d8bbcb822e27f179e8025 100644 (file)
@@ -426,7 +426,7 @@ static void osnoise_hist_usage(char *usage)
        static const char * const msg[] = {
                "",
                "  usage: rtla osnoise hist [-h] [-D] [-d s] [-p us] [-r us] [-s us] [-S us] [-t[=file]] \\",
-               "         [-c cpu-list] [-P priority] [-b N] [-e N] [--no-header] [--no-summary] \\",
+               "         [-c cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\",
                "         [--no-index] [--with-zeros]",
                "",
                "         -h/--help: print this menu",
@@ -439,7 +439,7 @@ static void osnoise_hist_usage(char *usage)
                "         -D/--debug: print debug info",
                "         -t/--trace[=file]: save the stopped trace to [file|osnoise_trace.txt]",
                "         -b/--bucket-size N: set the histogram bucket size (default 1)",
-               "         -e/--entries N: set the number of entries of the histogram (default 256)",
+               "         -E/--entries N: set the number of entries of the histogram (default 256)",
                "            --no-header: do not print header",
                "            --no-summary: do not print summary",
                "            --no-index: do not print index",
@@ -486,7 +486,7 @@ static struct osnoise_hist_params
        while (1) {
                static struct option long_options[] = {
                        {"bucket-size",         required_argument,      0, 'b'},
-                       {"entries",             required_argument,      0, 'e'},
+                       {"entries",             required_argument,      0, 'E'},
                        {"cpus",                required_argument,      0, 'c'},
                        {"debug",               no_argument,            0, 'D'},
                        {"duration",            required_argument,      0, 'd'},
@@ -507,7 +507,7 @@ static struct osnoise_hist_params
                /* getopt_long stores the option index here. */
                int option_index = 0;
 
-               c = getopt_long(argc, argv, "c:b:d:e:Dhp:P:r:s:S:t::0123",
+               c = getopt_long(argc, argv, "c:b:d:E:Dhp:P:r:s:S:t::0123",
                                 long_options, &option_index);
 
                /* detect the end of the options. */
@@ -534,7 +534,7 @@ static struct osnoise_hist_params
                        if (!params->duration)
                                osnoise_hist_usage("Invalid -D duration\n");
                        break;
-               case 'e':
+               case 'E':
                        params->entries = get_llong_from_str(optarg);
                        if ((params->entries < 10) || (params->entries > 9999999))
                                osnoise_hist_usage("Entries must be > 10 and < 9999999\n");
index c67dc28ef716af5e68769e51829a3908cfae7030..7af769b9c0dee1a532b9eb1b1fdefd77fd5d8c96 100644 (file)
@@ -573,6 +573,7 @@ out_top:
        osnoise_free_top(tool->data);
        osnoise_destroy_tool(record);
        osnoise_destroy_tool(tool);
+       free(params);
 out_exit:
        exit(return_value);
 }
index 436a799f9adf9fad3a436578e4fe3eb09d29aa9e..237e1735afa7c0ee8caedcdb924a878a8767a126 100644 (file)
@@ -429,7 +429,7 @@ static void timerlat_hist_usage(char *usage)
        char *msg[] = {
                "",
                "  usage: [rtla] timerlat hist [-h] [-q] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] [-t[=file]] \\",
-               "         [-c cpu-list] [-P priority] [-e N] [-b N]  [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
+               "         [-c cpu-list] [-P priority] [-E N] [-b N]  [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
                "         [--no-index] [--with-zeros]",
                "",
                "         -h/--help: print this menu",
@@ -443,7 +443,7 @@ static void timerlat_hist_usage(char *usage)
                "         -T/--trace[=file]: save the stopped trace to [file|timerlat_trace.txt]",
                "         -n/--nano: display data in nanoseconds",
                "         -b/--bucket-size N: set the histogram bucket size (default 1)",
-               "         -e/--entries N: set the number of entries of the histogram (default 256)",
+               "         -E/--entries N: set the number of entries of the histogram (default 256)",
                "            --no-irq: ignore IRQ latencies",
                "            --no-thread: ignore thread latencies",
                "            --no-header: do not print header",
@@ -494,7 +494,7 @@ static struct timerlat_hist_params
                        {"cpus",                required_argument,      0, 'c'},
                        {"bucket-size",         required_argument,      0, 'b'},
                        {"debug",               no_argument,            0, 'D'},
-                       {"entries",             required_argument,      0, 'e'},
+                       {"entries",             required_argument,      0, 'E'},
                        {"duration",            required_argument,      0, 'd'},
                        {"help",                no_argument,            0, 'h'},
                        {"irq",                 required_argument,      0, 'i'},
@@ -516,7 +516,7 @@ static struct timerlat_hist_params
                /* getopt_long stores the option index here. */
                int option_index = 0;
 
-               c = getopt_long(argc, argv, "c:b:d:e:Dhi:np:P:s:t::T:012345",
+               c = getopt_long(argc, argv, "c:b:d:E:Dhi:np:P:s:t::T:012345",
                                 long_options, &option_index);
 
                /* detect the end of the options. */
@@ -543,7 +543,7 @@ static struct timerlat_hist_params
                        if (!params->duration)
                                timerlat_hist_usage("Invalid -D duration\n");
                        break;
-               case 'e':
+               case 'E':
                        params->entries = get_llong_from_str(optarg);
                        if ((params->entries < 10) || (params->entries > 9999999))
                                        timerlat_hist_usage("Entries must be > 10 and < 9999999\n");
diff --git a/tools/virtio/linux/mm_types.h b/tools/virtio/linux/mm_types.h
new file mode 100644 (file)
index 0000000..356ba4d
--- /dev/null
@@ -0,0 +1,3 @@
+struct folio {
+       struct page page;
+};
index cb3f29c09aff3522b6225f1710d71e27097de9a2..23f142af544ad796146361cc81ce3315d303f42e 100644 (file)
@@ -130,6 +130,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features)
        memset(dev, 0, sizeof *dev);
        dev->vdev.features = features;
        INIT_LIST_HEAD(&dev->vdev.vqs);
+       spin_lock_init(&dev->vdev.vqs_list_lock);
        dev->buf_size = 1024;
        dev->buf = malloc(dev->buf_size);
        assert(dev->buf);
index 58d31da8a2f7c2eac20f64da3952f43614592341..0afc016cc54d4cc61d0364cf4d7c3c64afe50814 100644 (file)
@@ -5528,9 +5528,7 @@ static int kvm_suspend(void)
 static void kvm_resume(void)
 {
        if (kvm_usage_count) {
-#ifdef CONFIG_LOCKDEP
-               WARN_ON(lockdep_is_held(&kvm_count_lock));
-#endif
+               lockdep_assert_not_held(&kvm_count_lock);
                hardware_enable_nolock(NULL);
        }
 }