Merge tag 'x86_urgent_for_v5.11_rc7' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 7 Feb 2021 17:40:47 +0000 (09:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 7 Feb 2021 17:40:47 +0000 (09:40 -0800)
Pull x86 fixes from Borislav Petkov:
 "I hope this is the last batch of x86/urgent updates for this round:

   - Remove superfluous EFI PGD range checks which lead to those
     assertions failing with certain kernel configs and LLVM.

   - Disable setting breakpoints on facilities involved in #DB exception
     handling to avoid infinite loops.

   - Add extra serialization to non-serializing MSRs (IA32_TSC_DEADLINE
     and x2 APIC MSRs) to adhere to SDM's recommendation and avoid any
     theoretical issues.

   - Re-add the EPB MSR reading on turbostat so that it works on older
     kernels which don't have the corresponding EPB sysfs file.

   - Add Alder Lake to the list of CPUs which support split lock.

   - Fix %dr6 register handling in order to be able to set watchpoints
     with gdb again.

   - Disable CET instrumentation in the kernel so that gcc doesn't add
     ENDBR64 to kernel code and thus confuse tracing"

* tag 'x86_urgent_for_v5.11_rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/efi: Remove EFI PGD build time checks
  x86/debug: Prevent data breakpoints on cpu_dr7
  x86/debug: Prevent data breakpoints on __per_cpu_offset
  x86/apic: Add extra serialization for non-serializing MSRs
  tools/power/turbostat: Fallback to an MSR read for EPB
  x86/split_lock: Enable the split lock feature on another Alder Lake CPU
  x86/debug: Fix DR6 handling
  x86/build: Disable CET instrumentation in the kernel

592 files changed:
.clang-format
.mailmap
Documentation/Makefile
Documentation/admin-guide/media/rkisp1.rst
Documentation/asm-annotations.rst
Documentation/devicetree/bindings/arm/cpus.yaml
Documentation/devicetree/bindings/display/bridge/sii902x.txt
Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
Documentation/devicetree/bindings/extcon/wlf,arizona.yaml
Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml
Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml
Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml
Documentation/devicetree/bindings/i2c/i2c-gpio.yaml
Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml
Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml
Documentation/devicetree/bindings/iio/adc/maxim,max9611.yaml
Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml
Documentation/devicetree/bindings/iio/adc/ti,palmas-gpadc.yaml
Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml
Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml
Documentation/devicetree/bindings/input/adc-keys.txt
Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
Documentation/devicetree/bindings/leds/richtek,rt8515.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt
Documentation/devicetree/bindings/media/mediatek-mdp.txt
Documentation/devicetree/bindings/mmc/mmc-controller.yaml
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml
Documentation/devicetree/bindings/net/ethernet-controller.yaml
Documentation/devicetree/bindings/net/snps,dwmac.yaml
Documentation/devicetree/bindings/power/supply/battery.yaml
Documentation/devicetree/bindings/power/supply/bq2515x.yaml
Documentation/devicetree/bindings/regulator/dlg,da9121.yaml
Documentation/devicetree/bindings/regulator/fixed-regulator.yaml
Documentation/devicetree/bindings/rtc/rtc.yaml
Documentation/devicetree/bindings/serial/pl011.yaml
Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml
Documentation/devicetree/bindings/sound/sgtl5000.yaml
Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
Documentation/devicetree/bindings/watchdog/watchdog.yaml
Documentation/filesystems/overlayfs.rst
Documentation/kbuild/gcc-plugins.rst
Documentation/kbuild/llvm.rst
Documentation/kbuild/makefiles.rst
Documentation/networking/ip-sysctl.rst
Documentation/virt/kvm/api.rst
Documentation/virt/kvm/nested-vmx.rst
Documentation/virt/kvm/running-nested-guests.rst
MAINTAINERS
Makefile
arch/arm/boot/compressed/atags_to_fdt.c
arch/arm/boot/dts/imx6q-tbs2910.dts
arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
arch/arm/boot/dts/imx6qdl-sr-som.dtsi
arch/arm/boot/dts/imx7d-flex-concentrator.dts
arch/arm/boot/dts/lpc32xx.dtsi
arch/arm/boot/dts/omap3-gta04.dtsi
arch/arm/boot/dts/omap4-droid4-xt894.dts
arch/arm/boot/dts/ste-db8500.dtsi
arch/arm/boot/dts/ste-db8520.dtsi
arch/arm/boot/dts/ste-db9500.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi
arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi
arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
arch/arm/boot/dts/sun7i-a20-bananapro.dts
arch/arm/include/asm/kexec-internal.h [new file with mode: 0644]
arch/arm/include/debug/tegra.S
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/relocate_kernel.S
arch/arm/kernel/signal.c
arch/arm/mach-footbridge/dc21285.c
arch/arm/mach-imx/suspend-imx6.S
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/cpuidle44xx.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm64/boot/dts/amlogic/meson-axg.dtsi
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
arch/arm64/boot/dts/amlogic/meson-gx.dtsi
arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts
arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
arch/arm64/boot/dts/freescale/imx8mn.dtsi
arch/arm64/boot/dts/freescale/imx8mp.dtsi
arch/arm64/boot/dts/qcom/sdm845-db845c.dts
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
arch/arm64/boot/dts/rockchip/px30.dtsi
arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/configs/defconfig
arch/arm64/include/asm/memory.h
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/nvhe/hyp-init.S
arch/arm64/kvm/hyp/nvhe/psci-relay.c
arch/arm64/kvm/pmu-emul.c
arch/arm64/kvm/sys_regs.c
arch/arm64/mm/physaddr.c
arch/ia64/Makefile
arch/ia64/include/uapi/asm/cmpxchg.h
arch/ia64/kernel/time.c
arch/ia64/scripts/unwcheck.py
arch/parisc/Kconfig
arch/parisc/include/asm/irq.h
arch/parisc/kernel/entry.S
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/vdso32/Makefile
arch/powerpc/kernel/vdso32/vdso32_wrapper.S [deleted file]
arch/powerpc/kernel/vdso32_wrapper.S [new file with mode: 0644]
arch/powerpc/kernel/vdso64/Makefile
arch/powerpc/kernel/vdso64/sigtramp.S
arch/powerpc/kernel/vdso64/vdso64.lds.S
arch/powerpc/kernel/vdso64/vdso64_wrapper.S [deleted file]
arch/powerpc/kernel/vdso64_wrapper.S [new file with mode: 0644]
arch/powerpc/lib/sstep.c
arch/riscv/Kconfig
arch/riscv/include/asm/page.h
arch/riscv/include/asm/set_memory.h
arch/riscv/kernel/setup.c
arch/riscv/mm/init.c
arch/s390/boot/uv.c
arch/s390/include/asm/uv.h
arch/s390/kernel/uv.c
arch/um/Kconfig
arch/um/drivers/ubd_kern.c
arch/um/drivers/virtio_uml.c
arch/um/include/asm/io.h
arch/um/include/asm/pgtable.h
arch/um/include/asm/set_memory.h [deleted file]
arch/um/include/shared/kern_util.h
arch/um/kernel/kmsg_dump.c
arch/um/kernel/process.c
arch/um/kernel/time.c
arch/um/kernel/tlb.c
arch/um/kernel/um_arch.c
arch/um/os-Linux/helper.c
arch/um/os-Linux/time.c
arch/x86/entry/thunk_64.S
arch/x86/include/asm/idtentry.h
arch/x86/kernel/setup.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/emulate.c
arch/x86/kvm/kvm_cache_regs.h
arch/x86/kvm/mmu.h
arch/x86/kvm/mmu/tdp_mmu.c
arch/x86/kvm/svm/nested.c
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/pmu_intel.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/mm/mem_encrypt.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/xen-asm.S
block/bfq-iosched.c
block/blk-cgroup.c
block/blk-mq.h
block/genhd.c
block/partitions/core.c
drivers/acpi/arm64/iort.c
drivers/acpi/device_sysfs.c
drivers/acpi/scan.c
drivers/acpi/thermal.c
drivers/block/nbd.c
drivers/block/null_blk/zoned.c
drivers/block/xen-blkfront.c
drivers/bus/arm-integrator-lm.c
drivers/bus/simple-pm-bus.c
drivers/clk/imx/Kconfig
drivers/clk/mmp/clk-audio.c
drivers/clk/qcom/gcc-sc7180.c
drivers/clk/qcom/gcc-sm8250.c
drivers/crypto/marvell/cesa/cesa.h
drivers/firmware/efi/apple-properties.c
drivers/firmware/imx/Kconfig
drivers/gpio/gpiolib-cdev.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_stream.h
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
drivers/gpu/drm/amd/display/dc/dcn30/Makefile
drivers/gpu/drm/amd/display/dc/dcn301/Makefile
drivers/gpu/drm/amd/display/dc/dcn302/Makefile
drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/inc/smu_v11_0.h
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
drivers/gpu/drm/bridge/lontium-lt9611uxc.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dp.h
drivers/gpu/drm/i915/display/intel_dp_link_training.c
drivers/gpu/drm/i915/display/intel_dp_link_training.h
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_overlay.c
drivers/gpu/drm/i915/display/intel_sprite.c
drivers/gpu/drm/i915/gem/i915_gem_domain.c
drivers/gpu/drm/i915/gem/i915_gem_object.h
drivers/gpu/drm/i915/gt/gen7_renderclear.c
drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
drivers/gpu/drm/i915/gt/intel_ggtt.c
drivers/gpu/drm/i915/i915_active.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
drivers/gpu/drm/nouveau/dispnv50/base507c.c
drivers/gpu/drm/nouveau/dispnv50/base827c.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/dispnv50/head917d.c
drivers/gpu/drm/nouveau/dispnv50/wndw.c
drivers/gpu/drm/nouveau/include/nvhw/class/cl917d.h
drivers/gpu/drm/nouveau/include/nvif/push.h
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_svm.c
drivers/gpu/drm/ttm/ttm_pool.c
drivers/gpu/drm/vc4/vc4_hvs.c
drivers/gpu/drm/vc4/vc4_plane.c
drivers/hid/hid-multitouch.c
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.h
drivers/i2c/busses/i2c-mt65xx.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_qp.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/usnic/usnic_ib_sysfs.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
drivers/infiniband/sw/rxe/rxe_net.c
drivers/infiniband/sw/rxe/rxe_resp.c
drivers/input/joystick/xpad.c
drivers/input/misc/ariel-pwrbutton.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/touchscreen/goodix.c
drivers/input/touchscreen/ili210x.c
drivers/input/touchscreen/st1232.c
drivers/iommu/amd/amd_iommu.h
drivers/iommu/amd/amd_iommu_types.h
drivers/iommu/amd/init.c
drivers/iommu/intel/dmar.c
drivers/iommu/intel/iommu.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/flash/Kconfig [new file with mode: 0644]
drivers/leds/flash/Makefile [new file with mode: 0644]
drivers/leds/flash/leds-rt8515.c [new file with mode: 0644]
drivers/leds/led-triggers.c
drivers/leds/leds-ariel.c
drivers/leds/leds-lm3533.c
drivers/md/bcache/features.h
drivers/media/cec/platform/Makefile
drivers/media/common/videobuf2/videobuf2-v4l2.c
drivers/media/i2c/ccs-pll.c
drivers/media/i2c/ccs/ccs-data.c
drivers/media/pci/intel/ipu3/ipu3-cio2.c
drivers/media/platform/qcom/venus/core.c
drivers/media/platform/rcar-vin/rcar-core.c
drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c
drivers/media/rc/ir-mce_kbd-decoder.c
drivers/media/rc/ite-cir.c
drivers/media/rc/rc-main.c
drivers/media/rc/serial_ir.c
drivers/media/v4l2-core/v4l2-common.c
drivers/mmc/core/sdio_cis.c
drivers/mmc/host/sdhci-pltfm.h
drivers/net/arcnet/arc-rimi.c
drivers/net/arcnet/arcdevice.h
drivers/net/arcnet/arcnet.c
drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com20020-pci.c
drivers/net/arcnet/com20020_cs.c
drivers/net/arcnet/com90io.c
drivers/net/arcnet/com90xx.c
drivers/net/can/dev.c
drivers/net/dsa/bcm_sf2.c
drivers/net/dsa/microchip/ksz8795.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_ethtool.c
drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_txrx.c
drivers/net/ethernet/intel/igc/igc_ethtool.c
drivers/net/ethernet/intel/igc/igc_i225.c
drivers/net/ethernet/intel/igc/igc_mac.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/mellanox/mlx5/core/en/health.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.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.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
drivers/net/ipa/gsi.c
drivers/net/ipa/ipa_endpoint.c
drivers/net/ipa/ipa_mem.c
drivers/net/team/team.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/qmi_wwan.c
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
drivers/net/wireless/intel/iwlwifi/fw/acpi.h
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
drivers/net/wireless/intel/iwlwifi/iwl-io.c
drivers/net/wireless/intel/iwlwifi/iwl-io.h
drivers/net/wireless/intel/iwlwifi/iwl-prph.h
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
drivers/net/wireless/intel/iwlwifi/queue/tx.c
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
drivers/net/wireless/mediatek/mt7601u/dma.c
drivers/nvme/host/core.c
drivers/nvme/host/multipath.c
drivers/nvme/host/pci.c
drivers/nvme/target/tcp.c
drivers/of/device.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aspm.c
drivers/platform/x86/dell-wmi-sysman/sysman.c
drivers/platform/x86/hp-wmi.c
drivers/regulator/core.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-mc146818-lib.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_int.h
drivers/s390/crypto/vfio_ap_drv.c
drivers/s390/crypto/vfio_ap_ops.c
drivers/s390/crypto/vfio_ap_private.h
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/qla2xxx/qla_os.c
drivers/soc/atmel/soc.c
drivers/soc/imx/Kconfig
drivers/soc/litex/Kconfig
drivers/soc/sunxi/sunxi_mbus.c
drivers/soc/ti/omap_prm.c
drivers/spi/spi-altera.c
drivers/spi/spidev.c
drivers/staging/media/hantro/hantro_v4l2.c
drivers/staging/media/sunxi/cedrus/cedrus_h264.c
drivers/staging/rtl8723bs/include/rtw_wifi_regd.h
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
drivers/staging/rtl8723bs/os_dep/sdio_intf.c
drivers/staging/rtl8723bs/os_dep/wifi_regd.c
drivers/target/iscsi/iscsi_target_login.c
drivers/tee/optee/call.c
drivers/thunderbolt/acpi.c
drivers/tty/n_tty.c
drivers/tty/tty_io.c
drivers/usb/class/usblp.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc3/core.c
drivers/usb/gadget/legacy/ether.c
drivers/usb/gadget/udc/aspeed-vhub/hub.c
drivers/usb/host/xhci-mtk-sch.c
drivers/usb/host/xhci-mtk.c
drivers/usb/host/xhci-mtk.h
drivers/usb/host/xhci-mvebu.c
drivers/usb/host/xhci-mvebu.h
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci-plat.h
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/option.c
drivers/vdpa/mlx5/core/mlx5_vdpa.h
drivers/vdpa/mlx5/core/mr.c
drivers/vdpa/mlx5/net/mlx5_vnet.c
drivers/xen/xenbus/xenbus_probe.c
fs/afs/main.c
fs/block_dev.c
fs/btrfs/block-group.c
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/free-space-tree.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifsfs.c
fs/cifs/cifsproto.h
fs/cifs/connect.c
fs/cifs/dfs_cache.c
fs/cifs/dir.c
fs/cifs/fs_context.c
fs/cifs/smb2pdu.h
fs/cifs/transport.c
fs/ecryptfs/inode.c
fs/hugetlbfs/inode.c
fs/io_uring.c
fs/nfs/pnfs.c
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/file.c
fs/overlayfs/inode.c
fs/overlayfs/overlayfs.h
fs/overlayfs/ovl_entry.h
fs/overlayfs/readdir.c
fs/overlayfs/super.c
fs/overlayfs/util.c
fs/pipe.c
include/drm/drm_dp_mst_helper.h
include/dt-bindings/sound/apq8016-lpass.h
include/dt-bindings/sound/qcom,lpass.h [new file with mode: 0644]
include/dt-bindings/sound/sc7180-lpass.h
include/linux/hugetlb.h
include/linux/iommu.h
include/linux/kasan.h
include/linux/kprobes.h
include/linux/linkage.h
include/linux/mlx5/driver.h
include/linux/regulator/consumer.h
include/linux/sunrpc/xdr.h
include/linux/tracepoint.h
include/linux/tty.h
include/linux/vmalloc.h
include/media/v4l2-common.h
include/net/lapb.h
include/net/netfilter/nf_tables.h
include/net/sch_generic.h
include/net/tcp.h
include/net/udp.h
include/sound/pcm.h
include/uapi/linux/mrp_bridge.h
include/uapi/linux/rkisp1-config.h
include/uapi/linux/rpl.h
include/uapi/linux/v4l2-subdev.h
include/uapi/rdma/vmw_pvrdma-abi.h
init/Kconfig
init/init_task.c
init/main.c
kernel/bpf/bpf_inode_storage.c
kernel/bpf/bpf_lsm.c
kernel/bpf/cgroup.c
kernel/bpf/preload/Makefile
kernel/dma/map_benchmark.c
kernel/entry/common.c
kernel/futex.c
kernel/gcov/Kconfig
kernel/kexec_core.c
kernel/kprobes.c
kernel/locking/rtmutex.c
kernel/locking/rtmutex_common.h
kernel/power/swap.c
kernel/printk/printk.c
kernel/trace/fgraph.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_kprobe.c
lib/ubsan.c
lib/ubsan.h
mm/compaction.c
mm/filemap.c
mm/huge_memory.c
mm/hugetlb.c
mm/kasan/kasan.h
mm/memblock.c
mm/migrate.c
mm/page_alloc.c
mm/slub.c
net/bridge/br_private_mrp.h
net/core/neighbour.c
net/decnet/dn_route.c
net/hsr/hsr_main.h
net/ipv4/ip_tunnel.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/tcp_recovery.c
net/ipv4/tcp_timer.c
net/ipv4/udp_offload.c
net/ipv6/udp_offload.c
net/key/af_key.c
net/lapb/lapb_iface.c
net/lapb/lapb_out.c
net/lapb/lapb_timer.c
net/mac80211/driver-ops.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/rate.c
net/mac80211/spectmgmt.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_dynset.c
net/nfc/netlink.c
net/nfc/rawsock.c
net/rds/rdma.c
net/rxrpc/af_rxrpc.c
net/rxrpc/call_accept.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/auth_gss_internal.h [new file with mode: 0644]
net/sunrpc/auth_gss/gss_krb5_mech.c
net/sunrpc/svcsock.c
net/switchdev/switchdev.c
net/vmw_vsock/af_vsock.c
net/wireless/wext-core.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_policy.c
scripts/Makefile
scripts/bloat-o-meter
scripts/checkpatch.pl
scripts/clang-tools/gen_compile_commands.py
scripts/clang-tools/run-clang-tools.py
scripts/diffconfig
scripts/dummy-tools/gcc
scripts/jobserver-exec
scripts/kallsyms.c
scripts/kconfig/mconf-cfg.sh
security/commoncap.c
sound/core/pcm_native.c
sound/hda/intel-dsp-config.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_via.c
sound/soc/amd/renoir/rn-pci-acp3x.c
sound/soc/codecs/ak4458.c
sound/soc/codecs/wm_adsp.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/skylake/skl-topology.c
sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
sound/soc/qcom/lpass-cpu.c
sound/soc/qcom/lpass-ipq806x.c
sound/soc/qcom/lpass-lpaif-reg.h
sound/soc/qcom/lpass-platform.c
sound/soc/qcom/lpass-sc7180.c
sound/soc/qcom/lpass.h
sound/soc/soc-topology.c
sound/soc/sof/intel/Kconfig
sound/soc/sof/sof-acpi-dev.c
sound/soc/sof/sof-pci-dev.c
sound/usb/format.c
tools/testing/selftests/net/forwarding/router_mpath_nh.sh
tools/testing/selftests/net/forwarding/router_multipath.sh
tools/testing/selftests/net/xfrm_policy.sh
virt/kvm/kvm_main.c

index 10dc5a9a61b3e33ba3c82e2059db2275e34efa63..01a341ceec6c04935529bb3bc4254a59ec651e93 100644 (file)
@@ -122,6 +122,7 @@ ForEachMacros:
   - 'drm_for_each_bridge_in_chain'
   - 'drm_for_each_connector_iter'
   - 'drm_for_each_crtc'
+  - 'drm_for_each_crtc_reverse'
   - 'drm_for_each_encoder'
   - 'drm_for_each_encoder_mask'
   - 'drm_for_each_fb'
@@ -203,14 +204,13 @@ ForEachMacros:
   - 'for_each_matching_node'
   - 'for_each_matching_node_and_match'
   - 'for_each_member'
-  - 'for_each_mem_region'
-  - 'for_each_memblock_type'
   - 'for_each_memcg_cache_index'
   - 'for_each_mem_pfn_range'
   - '__for_each_mem_range'
   - 'for_each_mem_range'
   - '__for_each_mem_range_rev'
   - 'for_each_mem_range_rev'
+  - 'for_each_mem_region'
   - 'for_each_migratetype_order'
   - 'for_each_msi_entry'
   - 'for_each_msi_entry_safe'
@@ -276,10 +276,8 @@ ForEachMacros:
   - 'for_each_reserved_mem_range'
   - 'for_each_reserved_mem_region'
   - 'for_each_rtd_codec_dais'
-  - 'for_each_rtd_codec_dais_rollback'
   - 'for_each_rtd_components'
   - 'for_each_rtd_cpu_dais'
-  - 'for_each_rtd_cpu_dais_rollback'
   - 'for_each_rtd_dais'
   - 'for_each_set_bit'
   - 'for_each_set_bit_from'
@@ -298,6 +296,7 @@ ForEachMacros:
   - '__for_each_thread'
   - 'for_each_thread'
   - 'for_each_unicast_dest_pgid'
+  - 'for_each_vsi'
   - 'for_each_wakeup_source'
   - 'for_each_zone'
   - 'for_each_zone_zonelist'
@@ -330,6 +329,7 @@ ForEachMacros:
   - 'hlist_for_each_entry_rcu_bh'
   - 'hlist_for_each_entry_rcu_notrace'
   - 'hlist_for_each_entry_safe'
+  - 'hlist_for_each_entry_srcu'
   - '__hlist_for_each_rcu'
   - 'hlist_for_each_safe'
   - 'hlist_nulls_for_each_entry'
@@ -378,6 +378,7 @@ ForEachMacros:
   - 'list_for_each_entry_safe_continue'
   - 'list_for_each_entry_safe_from'
   - 'list_for_each_entry_safe_reverse'
+  - 'list_for_each_entry_srcu'
   - 'list_for_each_prev'
   - 'list_for_each_prev_safe'
   - 'list_for_each_safe'
@@ -411,6 +412,8 @@ ForEachMacros:
   - 'of_property_for_each_string'
   - 'of_property_for_each_u32'
   - 'pci_bus_for_each_resource'
+  - 'pcl_for_each_chunk'
+  - 'pcl_for_each_segment'
   - 'pcm_for_each_format'
   - 'ping_portaddr_for_each_entry'
   - 'plist_for_each'
index b1ab0129c7d6b034b1e41355892afdebf60ebdb8..d674968df008b6b242d84bed04a7ddbdac0ba278 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -9,9 +9,6 @@
 #
 # Please keep this list dictionary sorted.
 #
-# This comment is parsed by git-shortlog:
-# repo-abbrev: /pub/scm/linux/kernel/git/
-#
 Aaron Durbin <adurbin@google.com>
 Adam Oldham <oldhamca@gmail.com>
 Adam Radford <aradford@gmail.com>
@@ -182,6 +179,8 @@ Kees Cook <keescook@chromium.org> <kees.cook@canonical.com>
 Kees Cook <keescook@chromium.org> <keescook@google.com>
 Kees Cook <keescook@chromium.org> <kees@outflux.net>
 Kees Cook <keescook@chromium.org> <kees@ubuntu.com>
+Keith Busch <kbusch@kernel.org> <keith.busch@intel.com>
+Keith Busch <kbusch@kernel.org> <keith.busch@linux.intel.com>
 Kenneth W Chen <kenneth.w.chen@intel.com>
 Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru>
 Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com>
@@ -202,6 +201,8 @@ Li Yang <leoyang.li@nxp.com> <leoli@freescale.com>
 Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
 Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
 Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
+Manivannan Sadhasivam <mani@kernel.org> <manivannanece23@gmail.com>
+Manivannan Sadhasivam <mani@kernel.org> <manivannan.sadhasivam@linaro.org>
 Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
 Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com>
 Mark Brown <broonie@sirena.org.uk>
@@ -247,6 +248,7 @@ Morten Welinder <welinder@anemone.rentec.com>
 Morten Welinder <welinder@darter.rentec.com>
 Morten Welinder <welinder@troll.com>
 Mythri P K <mythripk@ti.com>
+Nathan Chancellor <nathan@kernel.org> <natechancellor@gmail.com>
 Nguyen Anh Quynh <aquynh@gmail.com>
 Nicolas Ferre <nicolas.ferre@microchip.com> <nicolas.ferre@atmel.com>
 Nicolas Pitre <nico@fluxnic.net> <nicolas.pitre@linaro.org>
@@ -337,6 +339,8 @@ Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org>
 Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
 Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
 Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
+Viresh Kumar <viresh.kumar@linaro.org> <viresh.kumar@linaro.org>
+Viresh Kumar <viresh.kumar@linaro.org> <viresh.kumar@linaro.com>
 Vivien Didelot <vivien.didelot@gmail.com> <vivien.didelot@savoirfairelinux.com>
 Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com>
 Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
index 61a7310b49e0ce355e8f73e4afa33d6026545387..9c42dde97671f21d42fc7f484b0eeb217e5c1014 100644 (file)
@@ -75,7 +75,7 @@ quiet_cmd_sphinx = SPHINX  $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
       cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media $2 && \
        PYTHONDONTWRITEBYTECODE=1 \
        BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
-       $(PYTHON) $(srctree)/scripts/jobserver-exec \
+       $(PYTHON3) $(srctree)/scripts/jobserver-exec \
        $(SHELL) $(srctree)/Documentation/sphinx/parallel-wrapper.sh \
        $(SPHINXBUILD) \
        -b $2 \
index 2267e4fb475e58921b8fd60a6495a492e0570388..ccf418713623b676935cb422956c7418a15bd23c 100644 (file)
@@ -13,6 +13,22 @@ This file documents the driver for the Rockchip ISP1 that is part of RK3288
 and RK3399 SoCs. The driver is located under drivers/staging/media/rkisp1
 and uses the Media-Controller API.
 
+Revisions
+=========
+
+There exist multiple smaller revisions to this ISP that got introduced in
+later SoCs. Revisions can be found in the enum :c:type:`rkisp1_cif_isp_version`
+in the UAPI and the revision of the ISP inside the running SoC can be read
+in the field hw_revision of struct media_device_info as returned by
+ioctl MEDIA_IOC_DEVICE_INFO.
+
+Versions in use are:
+
+- RKISP1_V10: used at least in rk3288 and rk3399
+- RKISP1_V11: declared in the original vendor code, but not used
+- RKISP1_V12: used at least in rk3326 and px30
+- RKISP1_V13: used at least in rk1808
+
 Topology
 ========
 .. _rkisp1_topology_graph:
index 32ea57483378ddeea5edc84278fe3d412920fcc5..76424e0431f4b5903b303774520c83d0cffc8004 100644 (file)
@@ -100,6 +100,11 @@ Instruction Macros
 ~~~~~~~~~~~~~~~~~~
 This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above.
 
+``objtool`` requires that all code must be contained in an ELF symbol. Symbol
+names that have a ``.L`` prefix do not emit symbol table entries. ``.L``
+prefixed symbols can be used within a code region, but should be avoided for
+denoting a range of code via ``SYM_*_START/END`` annotations.
+
 * ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the
   most frequent markings**. They are used for functions with standard calling
   conventions -- global and local. Like in C, they both align the functions to
index 14cd727d3c4b75c12afed857664d4dc5822a7f51..f02fd10de604b90907e5b9336183457a8fcc33f3 100644 (file)
@@ -232,7 +232,6 @@ properties:
       by this cpu (see ./idle-states.yaml).
 
   capacity-dmips-mhz:
-    $ref: '/schemas/types.yaml#/definitions/uint32'
     description:
       u32 value representing CPU capacity (see ./cpu-capacity.txt) in
       DMIPS/MHz, relative to highest capacity-dmips-mhz
index 02c21b58474189fe956e83189f622c5359c1faa7..3bc760cc31cbbeee3487230db7a4cd40fe0ff12b 100644 (file)
@@ -40,7 +40,7 @@ Optional properties:
        documents on how to describe the way the sii902x device is
        connected to the rest of the audio system:
        Documentation/devicetree/bindings/sound/simple-card.yaml
-       Documentation/devicetree/bindings/sound/audio-graph-card.txt
+       Documentation/devicetree/bindings/sound/audio-graph-card.yaml
        Note: In case of the audio-graph-card binding the used port
        index should be 3.
 
index 33977e15bebdf2f0005b00d51e21fb10f65b8cbc..ed76332ec01e830dd0607a000afb6c4c34e5dedd 100644 (file)
@@ -23,7 +23,7 @@ connected to.
 
 For a description of the display interface sink function blocks, see
 Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt.
+Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
 
 Required properties (all function blocks):
 - compatible: "mediatek,<chip>-disp-<function>", one of
@@ -61,7 +61,7 @@ Required properties (DMA function blocks):
        "mediatek,<chip>-disp-wdma"
   the supported chips are mt2701, mt8167 and mt8173.
 - larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
 - iommus: Should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
   for details.
index 5fe784f487c5ee17651d68ff5fc7e9e1bc5b5bf4..efdf59abb2e18b454f194c4e2bb4401ee725d187 100644 (file)
@@ -85,7 +85,6 @@ properties:
   wlf,micd-timeout-ms:
     description:
       Timeout for microphone detection, specified in milliseconds.
-    $ref: "/schemas/types.yaml#/definitions/uint32"
 
   wlf,micd-force-micbias:
     description:
index eef614962b1039e91bccdbdf23abfbf44be9894a..bf04151b63d2b4e474b2bc8c6fcca6e192eb09fe 100644 (file)
@@ -49,7 +49,6 @@ properties:
     description:
       This property controls the Accumulation Dead band which allows to set the
       level of current below which no accumulation takes place.
-    $ref: /schemas/types.yaml#/definitions/uint32
     maximum: 255
     default: 0
 
index 00a6511354e6c911eeef8006ae662d537eb9486d..5d3ce641fcdeb431bb9678c7e8ecf7945da00bea 100644 (file)
@@ -73,11 +73,9 @@ properties:
     description: |
       Temperature sensor trimming factor. It can be used to manually adjust the
       temperature measurements within 7.130 degrees Celsius.
-    maxItems: 1
-    items:
-      default: 0
-      minimum: 0
-      maximum: 7130
+    default: 0
+    minimum: 0
+    maximum: 7130
 
 additionalProperties: false
 
index 8020d739a078e53d23692ce76acdf668fb805713..1502b22c77ccb6711912de5ab967345b4c267bd5 100644 (file)
@@ -52,7 +52,6 @@ properties:
   ti,bus-range-microvolt:
     description: |
       This is the operating range of the bus voltage in microvolt
-    $ref: /schemas/types.yaml#/definitions/uint32
     enum: [16000000, 32000000]
     default: 32000000
 
index cc3aa2a5e70bf707c0dd521f7aac7228acecaf44..ff99344788ab84374e797b6375fa05d41f45b152 100644 (file)
@@ -39,11 +39,9 @@ properties:
 
   i2c-gpio,delay-us:
     description: delay between GPIO operations (may depend on each platform)
-    $ref: /schemas/types.yaml#/definitions/uint32
 
   i2c-gpio,timeout-ms:
     description: timeout to get data
-    $ref: /schemas/types.yaml#/definitions/uint32
 
   # Deprecated properties, do not use in new device tree sources:
   gpios:
index c22b66b6219eaa37fa630ed4b6f5118690ff70c7..d9293c57f573c0534adb777f88efad95e5da6c85 100644 (file)
@@ -66,21 +66,18 @@ properties:
     default: 400000
 
   i2c-sda-hold-time-ns:
-    maxItems: 1
     description: |
       The property should contain the SDA hold time in nanoseconds. This option
       is only supported in hardware blocks version 1.11a or newer or on
       Microsemi SoCs.
 
   i2c-scl-falling-time-ns:
-    maxItems: 1
     description: |
       The property should contain the SCL falling time in nanoseconds.
       This value is used to compute the tLOW period.
     default: 300
 
   i2c-sda-falling-time-ns:
-    maxItems: 1
     description: |
       The property should contain the SDA falling time in nanoseconds.
       This value is used to compute the tHIGH period.
index e0cc3b2e895749b1d74d915d27aa8a321645562a..22b7ed3723f6735360f7515b722607979e13e3aa 100644 (file)
@@ -80,7 +80,7 @@ properties:
     type: boolean
 
   bipolar:
-    description: see Documentation/devicetree/bindings/iio/adc/adc.txt
+    description: see Documentation/devicetree/bindings/iio/adc/adc.yaml
     type: boolean
 
 required:
index 9475a9e6e92075a748f2cc270f4c70488cc76aec..95774a55629df1d59717e5ff656c535691f686a9 100644 (file)
@@ -23,7 +23,6 @@ properties:
     maxItems: 1
 
   shunt-resistor-micro-ohms:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description: |
       Value in micro Ohms of the shunt resistor connected between the RS+ and
       RS- inputs, across which the current is measured.  Value needed to compute
index 28417b31b5589b2bcb27e648643387a9a1500069..517e32976c30426a49e6e49a9f927c6547daecce 100644 (file)
@@ -246,7 +246,6 @@ patternProperties:
           Resolution (bits) to use for conversions:
             - can be 6, 8, 10 or 12 on stm32f4
             - can be 8, 10, 12, 14 or 16 on stm32h7 and stm32mp1
-        $ref: /schemas/types.yaml#/definitions/uint32
 
       st,adc-channels:
         description: |
index 692dacd0fee5fa9a87f4ebff610cb168dc7bf7be..7b895784e00853a13abc6630b453549be6b9d744 100644 (file)
@@ -42,7 +42,6 @@ properties:
     const: 1
 
   ti,channel0-current-microamp:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description: Channel 0 current in uA.
     enum:
       - 0
@@ -51,7 +50,6 @@ properties:
       - 20
 
   ti,channel3-current-microamp:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description: Channel 3 current in uA.
     enum:
       - 0
index 626ccb6fe21e136a0b493ef56f9ec3f3d75bad77..fd4edca34a2851bc5d4f5df944e5c403dc04fad3 100644 (file)
@@ -46,31 +46,42 @@ properties:
       two properties must be present:
 
   adi,range-microvolt:
-    $ref: /schemas/types.yaml#/definitions/int32-array
     description: |
       Voltage output range specified as <minimum, maximum>
-    enum:
-      - [[0, 5000000]]
-      - [[0, 10000000]]
-      - [[-5000000, 5000000]]
-      - [[-10000000, 10000000]]
+    oneOf:
+      - items:
+          - const: 0
+          - enum: [5000000, 10000000]
+      - items:
+          - const: -5000000
+          - const: 5000000
+      - items:
+          - const: -10000000
+          - const: 10000000
 
   adi,range-microamp:
-    $ref: /schemas/types.yaml#/definitions/int32-array
     description: |
       Current output range specified as <minimum, maximum>
-    enum:
-      - [[0, 20000]]
-      - [[0, 24000]]
-      - [[4, 24000]]
-      - [[-20000, 20000]]
-      - [[-24000, 24000]]
-      - [[-1000, 22000]]
+    oneOf:
+      - items:
+          - const: 0
+          - enum: [20000, 24000]
+      - items:
+          - const: 4
+          - const: 24000
+      - items:
+          - const: -20000
+          - const: 20000
+      - items:
+          - const: -24000
+          - const: 24000
+      - items:
+          - const: -1000
+          - const: 22000
 
   reset-gpios: true
 
   adi,dc-dc-ilim-microamp:
-    $ref: /schemas/types.yaml#/definitions/uint32
     enum: [150000, 200000, 250000, 300000, 350000, 400000]
     description: |
       The dc-to-dc converter current limit.
index 64b8626370393662d2dfaaf27d0291452d96bd76..967778fb0ce89f6129f857226d6581b0459722ea 100644 (file)
@@ -21,7 +21,6 @@ properties:
     description: Connected to ADC_RDY pin.
 
   maxim,led-current-microamp:
-    $ref: /schemas/types.yaml#/definitions/uint32-array
     minItems: 2
     maxItems: 2
     description: |
index e551814629b48e3a0ece53bf226864a701d1ed61..6c8be6a9ace286c359c1ed50fca83879b01e18ed 100644 (file)
@@ -5,7 +5,8 @@ Required properties:
  - compatible: "adc-keys"
  - io-channels: Phandle to an ADC channel
  - io-channel-names = "buttons";
- - keyup-threshold-microvolt: Voltage at which all the keys are considered up.
+ - keyup-threshold-microvolt: Voltage above or equal to which all the keys are
+                             considered up.
 
 Optional properties:
        - poll-interval: Poll interval time in milliseconds
@@ -17,7 +18,12 @@ Each button (key) is represented as a sub-node of "adc-keys":
 Required subnode-properties:
        - label: Descriptive name of the key.
        - linux,code: Keycode to emit.
-       - press-threshold-microvolt: Voltage ADC input when this key is pressed.
+       - press-threshold-microvolt: voltage above or equal to which this key is
+                                    considered pressed.
+
+No two values of press-threshold-microvolt may be the same.
+All values of press-threshold-microvolt must be less than
+keyup-threshold-microvolt.
 
 Example:
 
@@ -47,3 +53,15 @@ Example:
                        press-threshold-microvolt = <500000>;
                };
        };
+
++--------------------------------+------------------------+
+| 2.000.000 <= value             | no key pressed         |
++--------------------------------+------------------------+
+| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed   |
++--------------------------------+------------------------+
+| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
++--------------------------------+------------------------+
+|   500.000 <= value < 1.000.000 | KEY_ENTER pressed      |
++--------------------------------+------------------------+
+|              value <   500.000 | no key pressed         |
++--------------------------------+------------------------+
index da5b0d87e16d08aefec0c59826ff2253b6852c2e..93f2ce3130ae7e9c55806162d994a0414c3e94b4 100644 (file)
@@ -26,6 +26,7 @@ properties:
       - goodix,gt927
       - goodix,gt9271
       - goodix,gt928
+      - goodix,gt9286
       - goodix,gt967
 
   reg:
index a771a15f053fa2c582cb9f7156a225a9ed1715bb..046ace461cc9d4d0450c94241e74ca66ef3dbb1e 100644 (file)
@@ -70,11 +70,9 @@ properties:
 
   touchscreen-x-mm:
     description: horizontal length in mm of the touchscreen
-    $ref: /schemas/types.yaml#/definitions/uint32
 
   touchscreen-y-mm:
     description: vertical length in mm of the touchscreen
-    $ref: /schemas/types.yaml#/definitions/uint32
 
 dependencies:
   touchscreen-size-x: [ touchscreen-size-y ]
diff --git a/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml b/Documentation/devicetree/bindings/leds/richtek,rt8515.yaml
new file mode 100644 (file)
index 0000000..68c328e
--- /dev/null
@@ -0,0 +1,111 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/richtek,rt8515.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT8515 1.5A dual channel LED driver
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  The Richtek RT8515 is a dual channel (two mode) LED driver that
+  supports driving a white LED in flash or torch mode. The maximum
+  current for each mode is defined in hardware using two resistors
+  RFS and RTS.
+
+properties:
+  compatible:
+    const: richtek,rt8515
+
+  enf-gpios:
+    maxItems: 1
+    description: A connection to the 'ENF' (enable flash) pin.
+
+  ent-gpios:
+    maxItems: 1
+    description: A connection to the 'ENT' (enable torch) pin.
+
+  richtek,rfs-ohms:
+    minimum: 7680
+    maximum: 367000
+    description: The resistance value of the RFS resistor. This
+      resistors limits the maximum flash current. This must be set
+      for the property flash-max-microamp to work, the RFS resistor
+      defines the range of the dimmer setting (brightness) of the
+      flash LED.
+
+  richtek,rts-ohms:
+    minimum: 7680
+    maximum: 367000
+    description: The resistance value of the RTS resistor. This
+      resistors limits the maximum torch current. This must be set
+      for the property torch-max-microamp to work, the RTS resistor
+      defines the range of the dimmer setting (brightness) of the
+      torch LED.
+
+  led:
+    type: object
+    $ref: common.yaml#
+    properties:
+      function: true
+      color: true
+      flash-max-timeout-us: true
+
+      flash-max-microamp:
+        maximum: 700000
+        description: The maximum current for flash mode
+          is hardwired to the component using the RFS resistor to
+          ground. The maximum hardware current setting is calculated
+          according to the formula Imax = 5500 / RFS. The lowest
+          allowed resistance value is 7.86 kOhm giving an absolute
+          maximum current of 700mA. By setting this attribute in
+          the device tree, you can further restrict the maximum
+          current below the hardware limit. This requires the RFS
+          to be defined as it defines the maximum range.
+
+      led-max-microamp:
+        maximum: 700000
+        description: The maximum current for torch mode
+          is hardwired to the component using the RTS resistor to
+          ground. The maximum hardware current setting is calculated
+          according to the formula Imax = 5500 / RTS. The lowest
+          allowed resistance value is 7.86 kOhm giving an absolute
+          maximum current of 700mA. By setting this attribute in
+          the device tree, you can further restrict the maximum
+          current below the hardware limit. This requires the RTS
+          to be defined as it defines the maximum range.
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - ent-gpios
+  - enf-gpios
+  - led
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/leds/common.h>
+
+    led-controller {
+        compatible = "richtek,rt8515";
+        enf-gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>;
+        ent-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>;
+        richtek,rfs-ohms = <16000>;
+        richtek,rts-ohms = <100000>;
+
+        led {
+            function = LED_FUNCTION_FLASH;
+            color = <LED_COLOR_ID_WHITE>;
+            flash-max-timeout-us = <250000>;
+            flash-max-microamp = <150000>;
+            led-max-microamp = <25000>;
+        };
+    };
+
+...
index 044b11913c49b8fa5ef2843b6bb7d42d0583f6d6..cf60c5acc0e4e0844ff77719123cc7357fd58751 100644 (file)
@@ -16,7 +16,7 @@ Required properties:
 - power-domains: a phandle to the power domain, see
   Documentation/devicetree/bindings/power/power_domain.txt for details.
 - mediatek,larb: must contain the local arbiters in the current Socs, see
-  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
   for details.
 - iommus: should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index 736be7cad3857b893f11fb39943b208ead4d317a..acfb50375b8acdced638980d9525a64802a8d445 100644 (file)
@@ -14,7 +14,7 @@ Required properties:
 - power-domains: a phandle to the power domain, see
   Documentation/devicetree/bindings/power/power_domain.txt for details.
 - mediatek,larb: must contain the local arbiters in the current SoCs, see
-  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
   for details.
 - iommus: should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
index 0d03e3ae2be2f23a294a27fbc63425d3f540eb05..f4798d04e92523552d85874796637d8b48fc99b9 100644 (file)
@@ -28,7 +28,7 @@ Required properties (DMA function blocks, child node):
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
   for details.
 - mediatek,larb: must contain the local arbiters in the current Socs, see
-  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
+  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
   for details.
 
 Example:
index 186f04ba935796758e20fa94376ce7057a4a0886..e674bba52ee97a1202754aa4b93151e56a0034a4 100644 (file)
@@ -259,7 +259,6 @@ properties:
       waiting for I/O signalling and card power supply to be stable,
       regardless of whether pwrseq-simple is used. Default to 10ms if
       no available.
-    $ref: /schemas/types.yaml#/definitions/uint32
     default: 10
 
   supports-cqe:
index 6cd57863c1dbdbdc669ef2174fc7f344cd84a0a9..226fb191913d2a5dd7b757509a2e10b3edb7a9a9 100644 (file)
@@ -41,13 +41,11 @@ properties:
     description:
       Delay in ms after powering the card and de-asserting the
       reset-gpios (if any).
-    $ref: /schemas/types.yaml#/definitions/uint32
 
   power-off-delay-us:
     description:
       Delay in us after asserting the reset-gpios (if any)
       during power off of the card.
-    $ref: /schemas/types.yaml#/definitions/uint32
 
 required:
   - compatible
index 0965f6515f9ec1d70a0eca3ee5e00b41df12577c..dac4aadb6e2e70ba6c147446481afb47a98d6479 100644 (file)
@@ -122,7 +122,6 @@ properties:
       such as flow control thresholds.
 
   rx-internal-delay-ps:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description: |
       RGMII Receive Clock Delay defined in pico seconds.
       This is used for controllers that have configurable RX internal delays.
@@ -140,7 +139,6 @@ properties:
       is used for components that can have configurable fifo sizes.
 
   tx-internal-delay-ps:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description: |
       RGMII Transmit Clock Delay defined in pico seconds.
       This is used for controllers that have configurable TX internal delays.
index dfbf5fe4547ab611a7004ee2baeb4914d93ce61e..0642b0f59491036d649af5f7d1513b2047c05619 100644 (file)
@@ -212,7 +212,6 @@ properties:
       Triplet of delays. The 1st cell is reset pre-delay in micro
       seconds. The 2nd cell is reset pulse in micro seconds. The 3rd
       cell is reset post-delay in micro seconds.
-    $ref: /schemas/types.yaml#/definitions/uint32-array
     minItems: 3
     maxItems: 3
 
index 0c7e2e44793baa5cd5c0260d6ed6233420d53f51..c3b4b754359186ab8dae6c1bc685926b34592ec8 100644 (file)
@@ -83,21 +83,18 @@ properties:
       for each of the battery capacity lookup table.
 
   operating-range-celsius:
-    $ref: /schemas/types.yaml#/definitions/uint32-array
     description: operating temperature range of a battery
     items:
       - description: minimum temperature at which battery can operate
       - description: maximum temperature at which battery can operate
 
   ambient-celsius:
-    $ref: /schemas/types.yaml#/definitions/uint32-array
     description: safe range of ambient temperature
     items:
       - description: alert when ambient temperature is lower than this value
       - description: alert when ambient temperature is higher than this value
 
   alert-celsius:
-    $ref: /schemas/types.yaml#/definitions/uint32-array
     description: safe range of battery temperature
     items:
       - description: alert when battery temperature is lower than this value
index 75a56773be4a0a364909feff196b2e81dc6288e6..813d6afde6069239458cb0506a436ee8f3a9daa4 100644 (file)
@@ -50,7 +50,6 @@ properties:
     maxItems: 1
 
   input-current-limit-microamp:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description: Maximum input current in micro Amps.
     minimum: 50000
     maximum: 500000
index 6f2164f7bc577fc6dbe04b47ce4b9b521c40acba..228018c87bea891a0958ef35e7bef5d3447bf553 100644 (file)
@@ -62,7 +62,6 @@ properties:
     description: IRQ line information.
 
   dlg,irq-polling-delay-passive-ms:
-    $ref: "/schemas/types.yaml#/definitions/uint32"
     minimum: 1000
     maximum: 10000
     description: |
index d3d0dc13dd8b80192f4860d930e89319da27ca2d..8850c01bd47060c2aad7cefa74d37fa303a286a8 100644 (file)
@@ -72,11 +72,9 @@ properties:
 
   startup-delay-us:
     description: startup time in microseconds
-    $ref: /schemas/types.yaml#/definitions/uint32
 
   off-on-delay-us:
     description: off delay time in microseconds
-    $ref: /schemas/types.yaml#/definitions/uint32
 
   enable-active-high:
     description:
index d30dc045aac6489ba18e4b2c246b77d3d636088b..0ec3551f12dd306fd06c6caa288eb78ca479ed6f 100644 (file)
@@ -27,7 +27,6 @@ properties:
       1: chargeable
 
   quartz-load-femtofarads:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description:
       The capacitive load of the quartz(x-tal), expressed in femto
       Farad (fF). The default value shall be listed (if optional),
@@ -47,7 +46,6 @@ properties:
     deprecated: true
 
   trickle-resistor-ohms:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Selected resistor for trickle charger. Should be given
       if trickle charger should be enabled.
index c23c93b400f062f82501a09d3363cc14faab1dec..07fa6d26f2b43c8091f0a4d61701930bee44364c 100644 (file)
@@ -88,14 +88,12 @@ properties:
     description:
       Rate at which poll occurs when auto-poll is set.
       default 100ms.
-    $ref: /schemas/types.yaml#/definitions/uint32
     default: 100
 
   poll-timeout-ms:
     description:
       Poll timeout when auto-poll is set, default
       3000ms.
-    $ref: /schemas/types.yaml#/definitions/uint32
     default: 3000
 
 required:
index bf8c8ba25009dcc90c26f9049492c29a1e6e46c4..54650823b29a41de10061ad664ac2080eefdab66 100644 (file)
@@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver
 
 maintainers:
-   - Jiaxin Yu <jiaxin.yu@mediatek.com>
-   - Shane Chien <shane.chien@mediatek.com>
+  - Jiaxin Yu <jiaxin.yu@mediatek.com>
+  - Shane Chien <shane.chien@mediatek.com>
 
 description:
   This binding describes the MT8192 sound card.
index d116c174b545f412556143b5c775b392f0cde1d7..70b4a8831073233a4c45828395226ce542225bed 100644 (file)
@@ -41,14 +41,12 @@ properties:
       values of 2k, 4k or 8k. If set to 0 it will be off. If this node is not
       mentioned or if the value is unknown, then micbias resistor is set to
       4k.
-    $ref: "/schemas/types.yaml#/definitions/uint32"
     enum: [ 0, 2, 4, 8 ]
 
   micbias-voltage-m-volts:
     description: The bias voltage to be used in mVolts. The voltage can take
       values from 1.25V to 3V by 250mV steps. If this node is not mentioned
       or the value is unknown, then the value is set to 1.25V.
-    $ref: "/schemas/types.yaml#/definitions/uint32"
     enum: [ 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 ]
 
   lrclk-strength:
index 148b3fb4ceaf85f69a57883efc0962f434dce008..c80a835719196b6ec1ca1eef6d1bbaa61e704872 100644 (file)
@@ -21,6 +21,8 @@ properties:
   reg:
     description: module registers
 
+  ranges: true
+
   power-domains:
     description:
       PM domain provider node and an args specifier containing
@@ -62,6 +64,8 @@ properties:
   '#size-cells':
     const: 2
 
+  dma-coherent: true
+
 patternProperties:
   "^usb@":
     type: object
index 4e2c26cd981d90653c22fb7390c8638692404d7c..e3dfb02f0ca52467ea3276dee2b2b8ce34bf5779 100644 (file)
@@ -19,7 +19,6 @@ properties:
     pattern: "^watchdog(@.*|-[0-9a-f])?$"
 
   timeout-sec:
-    $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Contains the watchdog timeout in seconds.
 
index 587a939739290628f7c236443493f570c6df7040..78240e29b0bb676963ffe1dfb023d5e501fd1e51 100644 (file)
@@ -586,6 +586,14 @@ without significant effort.
 The advantage of mounting with the "volatile" option is that all forms of
 sync calls to the upper filesystem are omitted.
 
+In order to avoid a giving a false sense of safety, the syncfs (and fsync)
+semantics of volatile mounts are slightly different than that of the rest of
+VFS.  If any writeback error occurs on the upperdir's filesystem after a
+volatile mount takes place, all sync functions will return an error.  Once this
+condition is reached, the filesystem will not recover, and every subsequent sync
+call will return an error, even if the upperdir has not experience a new error
+since the last sync call.
+
 When overlay is mounted with "volatile" option, the directory
 "$workdir/work/incompat/volatile" is created.  During next mount, overlay
 checks for this directory and refuses to mount if present. This is a strong
index 4b1c10f88e304ee8e03bb0855e7491c4c123538c..3349966f213dcff110e855fcc42efbb638a9cae6 100644 (file)
@@ -11,16 +11,13 @@ compiler [1]_. They are useful for runtime instrumentation and static analysis.
 We can analyse, change and add further code during compilation via
 callbacks [2]_, GIMPLE [3]_, IPA [4]_ and RTL passes [5]_.
 
-The GCC plugin infrastructure of the kernel supports all gcc versions from
-4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a
-separate directory.
-Plugin source files have to be compilable by both a C and a C++ compiler as well
-because gcc versions 4.5 and 4.6 are compiled by a C compiler,
-gcc-4.7 can be compiled by a C or a C++ compiler,
-and versions 4.8+ can only be compiled by a C++ compiler.
+The GCC plugin infrastructure of the kernel supports building out-of-tree
+modules, cross-compilation and building in a separate directory.
+Plugin source files have to be compilable by a C++ compiler.
 
-Currently the GCC plugin infrastructure supports only the x86, arm, arm64 and
-powerpc architectures.
+Currently the GCC plugin infrastructure supports only some architectures.
+Grep "select HAVE_GCC_PLUGINS" to find out which architectures support
+GCC plugins.
 
 This infrastructure was ported from grsecurity [6]_ and PaX [7]_.
 
@@ -47,20 +44,13 @@ Files
        This is a compatibility header for GCC plugins.
        It should be always included instead of individual gcc headers.
 
-**$(src)/scripts/gcc-plugin.sh**
-
-       This script checks the availability of the included headers in
-       gcc-common.h and chooses the proper host compiler to build the plugins
-       (gcc-4.7 can be built by either gcc or g++).
-
 **$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h,
 $(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h,
 $(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h,
 $(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h**
 
        These headers automatically generate the registration structures for
-       GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions
-       from 4.5 to 6.0.
+       GIMPLE, SIMPLE_IPA, IPA and RTL passes.
        They should be preferred to creating the structures by hand.
 
 
@@ -68,21 +58,25 @@ Usage
 =====
 
 You must install the gcc plugin headers for your gcc version,
-e.g., on Ubuntu for gcc-4.9::
+e.g., on Ubuntu for gcc-10::
 
-       apt-get install gcc-4.9-plugin-dev
+       apt-get install gcc-10-plugin-dev
 
 Or on Fedora::
 
        dnf install gcc-plugin-devel
 
-Enable a GCC plugin based feature in the kernel config::
+Enable the GCC plugin infrastructure and some plugin(s) you want to use
+in the kernel config::
 
-       CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y
+       CONFIG_GCC_PLUGINS=y
+       CONFIG_GCC_PLUGIN_CYC_COMPLEXITY=y
+       CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
+       ...
 
-To compile only the plugin(s)::
+To compile the minimum tool set including the plugin(s)::
 
-       make gcc-plugins
+       make scripts
 
 or just run the kernel make and compile the whole kernel with
 the cyclomatic complexity GCC plugin.
@@ -91,7 +85,8 @@ the cyclomatic complexity GCC plugin.
 4. How to add a new GCC plugin
 ==============================
 
-The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a directory
-here. It must be added to $(src)/scripts/gcc-plugins/Makefile,
-$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig.
+The GCC plugins are in scripts/gcc-plugins/. You need to put plugin source files
+right under scripts/gcc-plugins/. Creating subdirectories is not supported.
+It must be added to scripts/gcc-plugins/Makefile, scripts/Makefile.gcc-plugins
+and a relevant Kconfig file.
 See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin.
index 21c847890d03c4a337ec2824a1a152ede3b300f7..b18401d2ba8204bb66551f5e5c67bc22c13a52f4 100644 (file)
@@ -63,6 +63,50 @@ They can be enabled individually. The full list of the parameters: ::
 Currently, the integrated assembler is disabled by default. You can pass
 ``LLVM_IAS=1`` to enable it.
 
+Supported Architectures
+-----------------------
+
+LLVM does not target all of the architectures that Linux supports and
+just because a target is supported in LLVM does not mean that the kernel
+will build or work without any issues. Below is a general summary of
+architectures that currently work with ``CC=clang`` or ``LLVM=1``. Level
+of support corresponds to "S" values in the MAINTAINERS files. If an
+architecture is not present, it either means that LLVM does not target
+it or there are known issues. Using the latest stable version of LLVM or
+even the development tree will generally yield the best results.
+An architecture's ``defconfig`` is generally expected to work well,
+certain configurations may have problems that have not been uncovered
+yet. Bug reports are always welcome at the issue tracker below!
+
+.. list-table::
+   :widths: 10 10 10
+   :header-rows: 1
+
+   * - Architecture
+     - Level of support
+     - ``make`` command
+   * - arm
+     - Supported
+     - ``LLVM=1``
+   * - arm64
+     - Supported
+     - ``LLVM=1``
+   * - mips
+     - Maintained
+     - ``CC=clang``
+   * - powerpc
+     - Maintained
+     - ``CC=clang``
+   * - riscv
+     - Maintained
+     - ``CC=clang``
+   * - s390
+     - Maintained
+     - ``CC=clang``
+   * - x86
+     - Supported
+     - ``LLVM=1``
+
 Getting Help
 ------------
 
index 9f6a1188195136089fda768bf2ab88cc60c5dae4..300d8edcb994e5f286b3e890d296496d82fd3768 100644 (file)
@@ -755,7 +755,7 @@ more details, with real examples.
        bits on the scripts nonetheless.
 
        Kbuild provides variables $(CONFIG_SHELL), $(AWK), $(PERL),
-       $(PYTHON) and $(PYTHON3) to refer to interpreters for the respective
+       and $(PYTHON3) to refer to interpreters for the respective
        scripts.
 
        Example::
index dd2b12a32b73903b1fe6a422214c7d832bb30d05..fa544e9037b995f9cb0041184643166ed92f086d 100644 (file)
@@ -1196,7 +1196,7 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN
 
        If non-zero, the message will be sent with the primary address of
        the interface that received the packet that caused the icmp error.
-       This is the behaviour network many administrators will expect from
+       This is the behaviour many network administrators will expect from
        a router. And it can make debugging complicated network layouts
        much easier.
 
@@ -1807,12 +1807,24 @@ seg6_flowlabel - INTEGER
 ``conf/default/*``:
        Change the interface-specific default settings.
 
+       These settings would be used during creating new interfaces.
+
 
 ``conf/all/*``:
        Change all the interface-specific settings.
 
        [XXX:  Other special features than forwarding?]
 
+conf/all/disable_ipv6 - BOOLEAN
+       Changing this value is same as changing ``conf/default/disable_ipv6``
+       setting and also all per-interface ``disable_ipv6`` settings to the same
+       value.
+
+       Reading this value does not have any particular meaning. It does not say
+       whether IPv6 support is enabled or disabled. Returned value can be 1
+       also in the case when some interface has ``disable_ipv6`` set to 0 and
+       has configured IPv6 addresses.
+
 conf/all/forwarding - BOOLEAN
        Enable global IPv6 forwarding between all interfaces.
 
index c136e254b4960270863e86ecc01325771ab5ab6a..99ceb978c8b0804b63dc9bb74d144f28dba17f49 100644 (file)
@@ -360,10 +360,9 @@ since the last call to this ioctl.  Bit 0 is the first page in the
 memory slot.  Ensure the entire structure is cleared to avoid padding
 issues.
 
-If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies
-the address space for which you want to return the dirty bitmap.
-They must be less than the value that KVM_CHECK_EXTENSION returns for
-the KVM_CAP_MULTI_ADDRESS_SPACE capability.
+If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies
+the address space for which you want to return the dirty bitmap.  See
+KVM_SET_USER_MEMORY_REGION for details on the usage of slot field.
 
 The bits in the dirty bitmap are cleared before the ioctl returns, unless
 KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is enabled.  For more information,
@@ -1281,6 +1280,9 @@ field userspace_addr, which must point at user addressable memory for
 the entire memory slot size.  Any object may back this memory, including
 anonymous memory, ordinary files, and hugetlbfs.
 
+On architectures that support a form of address tagging, userspace_addr must
+be an untagged address.
+
 It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr
 be identical.  This allows large pages in the guest to be backed by large
 pages in the host.
@@ -1333,7 +1335,7 @@ documentation when it pops into existence).
 
 :Capability: KVM_CAP_ENABLE_CAP_VM
 :Architectures: all
-:Type: vcpu ioctl
+:Type: vm ioctl
 :Parameters: struct kvm_enable_cap (in)
 :Returns: 0 on success; -1 on error
 
@@ -4432,7 +4434,7 @@ to I/O ports.
 :Capability: KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2
 :Architectures: x86, arm, arm64, mips
 :Type: vm ioctl
-:Parameters: struct kvm_dirty_log (in)
+:Parameters: struct kvm_clear_dirty_log (in)
 :Returns: 0 on success, -1 on error
 
 ::
@@ -4459,10 +4461,9 @@ in KVM's dirty bitmap, and dirty tracking is re-enabled for that page
 (for example via write-protection, or by clearing the dirty bit in
 a page table entry).
 
-If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 specifies
-the address space for which you want to return the dirty bitmap.
-They must be less than the value that KVM_CHECK_EXTENSION returns for
-the KVM_CAP_MULTI_ADDRESS_SPACE capability.
+If KVM_CAP_MULTI_ADDRESS_SPACE is available, bits 16-31 of slot field specifies
+the address space for which you want to clear the dirty status.  See
+KVM_SET_USER_MEMORY_REGION for details on the usage of slot field.
 
 This ioctl is mostly useful when KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2
 is enabled; for more information, see the description of the capability.
index 6ab4e35cee233c408338d3d7efbff4d6c9f065a9..ac2095d41f020c9095918bede118a72b34b118a1 100644 (file)
@@ -37,8 +37,10 @@ call L2.
 Running nested VMX
 ------------------
 
-The nested VMX feature is disabled by default. It can be enabled by giving
-the "nested=1" option to the kvm-intel module.
+The nested VMX feature is enabled by default since Linux kernel v4.20. For
+older Linux kernel, it can be enabled by giving the "nested=1" option to the
+kvm-intel module.
+
 
 No modifications are required to user space (qemu). However, qemu's default
 emulated CPU type (qemu64) does not list the "VMX" CPU feature, so it must be
index d0a1fc754c84f4addc328e359d4d4f41319ec45b..bd70c69468aebb236937232d41adce56654e3149 100644 (file)
@@ -74,7 +74,7 @@ few:
 Enabling "nested" (x86)
 -----------------------
 
-From Linux kernel v4.19 onwards, the ``nested`` KVM parameter is enabled
+From Linux kernel v4.20 onwards, the ``nested`` KVM parameter is enabled
 by default for Intel and AMD.  (Though your Linux distribution might
 override this default.)
 
index 992fe3b0900af299f799b6a1c776d1bda6ae1013..667d03852191fbbcb6827eaa7bdbd9bbfc8c0a4f 100644 (file)
@@ -2616,8 +2616,8 @@ S:        Maintained
 F:     drivers/power/reset/keystone-reset.c
 
 ARM/TEXAS INSTRUMENTS K3 ARCHITECTURE
-M:     Tero Kristo <t-kristo@ti.com>
 M:     Nishanth Menon <nm@ti.com>
+M:     Tero Kristo <kristo@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 F:     Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -3239,6 +3239,7 @@ L:        netdev@vger.kernel.org
 S:     Supported
 W:     http://sourceforge.net/projects/bonding/
 F:     drivers/net/bonding/
+F:     include/net/bonding.h
 F:     include/uapi/linux/if_bonding.h
 
 BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER
@@ -3411,7 +3412,7 @@ F:        Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
 F:     drivers/pci/controller/pcie-brcmstb.c
 F:     drivers/staging/vc04_services
 N:     bcm2711
-N:     bcm2835
+N:     bcm283*
 
 BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE
 M:     Florian Fainelli <f.fainelli@gmail.com>
@@ -4303,7 +4304,7 @@ S:        Maintained
 F:     .clang-format
 
 CLANG/LLVM BUILD SUPPORT
-M:     Nathan Chancellor <natechancellor@gmail.com>
+M:     Nathan Chancellor <nathan@kernel.org>
 M:     Nick Desaulniers <ndesaulniers@google.com>
 L:     clang-built-linux@googlegroups.com
 S:     Supported
@@ -6473,9 +6474,9 @@ S:        Maintained
 F:     drivers/edac/skx_*.[ch]
 
 EDAC-TI
-M:     Tero Kristo <t-kristo@ti.com>
+M:     Tero Kristo <kristo@kernel.org>
 L:     linux-edac@vger.kernel.org
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/edac/ti_edac.c
 
 EDIROL UA-101/UA-1000 DRIVER
@@ -8433,11 +8434,8 @@ F:       drivers/i3c/
 F:     include/linux/i3c/
 
 IA64 (Itanium) PLATFORM
-M:     Tony Luck <tony.luck@intel.com>
-M:     Fenghua Yu <fenghua.yu@intel.com>
 L:     linux-ia64@vger.kernel.org
-S:     Odd Fixes
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git
+S:     Orphan
 F:     Documentation/ia64/
 F:     arch/ia64/
 
@@ -12415,6 +12413,7 @@ F:      tools/testing/selftests/net/ipsec.c
 NETWORKING [IPv4/IPv6]
 M:     "David S. Miller" <davem@davemloft.net>
 M:     Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
+M:     David Ahern <dsahern@kernel.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
@@ -17573,7 +17572,7 @@ F:      include/linux/dma/k3-psil.h
 
 TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER
 M:     Nishanth Menon <nm@ti.com>
-M:     Tero Kristo <t-kristo@ti.com>
+M:     Tero Kristo <kristo@kernel.org>
 M:     Santosh Shilimkar <ssantosh@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org
 S:     Maintained
@@ -17717,9 +17716,9 @@ S:      Maintained
 F:     drivers/clk/clk-cdce706.c
 
 TI CLOCK DRIVER
-M:     Tero Kristo <t-kristo@ti.com>
+M:     Tero Kristo <kristo@kernel.org>
 L:     linux-omap@vger.kernel.org
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/clk/ti/
 F:     include/linux/clk/ti.h
 
index 51c2bf34142deb50150359b4aade8c5939697282..70035c522bd3e20bb6fa7118a762fab880a4bc9a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 11
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Kleptomaniac Octopus
 
 # *DOCUMENTATION*
@@ -452,7 +452,6 @@ AWK         = awk
 INSTALLKERNEL  := installkernel
 DEPMOD         = depmod
 PERL           = perl
-PYTHON         = python
 PYTHON3                = python3
 CHECK          = sparse
 BASH           = bash
@@ -508,7 +507,7 @@ CLANG_FLAGS :=
 
 export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC
 export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
-export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
+export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
 export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
 export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
 
@@ -812,10 +811,12 @@ KBUILD_CFLAGS     += -ftrivial-auto-var-init=zero
 KBUILD_CFLAGS  += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
 endif
 
+DEBUG_CFLAGS   :=
+
 # Workaround for GCC versions < 5.0
 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61801
 ifdef CONFIG_CC_IS_GCC
-DEBUG_CFLAGS   := $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments))
+DEBUG_CFLAGS   += $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments))
 endif
 
 ifdef CONFIG_DEBUG_INFO
index 8452753efebe5621e2569db95df2b4c30b26df99..31927d2fe297281a47f810e96b06e541043e90d4 100644 (file)
@@ -15,7 +15,8 @@ static int node_offset(void *fdt, const char *node_path)
 {
        int offset = fdt_path_offset(fdt, node_path);
        if (offset == -FDT_ERR_NOTFOUND)
-               offset = fdt_add_subnode(fdt, 0, node_path);
+               /* Add the node to root if not found, dropping the leading '/' */
+               offset = fdt_add_subnode(fdt, 0, node_path + 1);
        return offset;
 }
 
index 861e05d53157e94a3203db81bbed827953cc2a53..343364d3e4f7d3d59d3592cabca17bafb3b7b0cb 100644 (file)
                stdout-path = &uart1;
        };
 
+       aliases {
+               mmc0 = &usdhc2;
+               mmc1 = &usdhc3;
+               mmc2 = &usdhc4;
+               /delete-property/ mmc3;
+       };
+
        memory@10000000 {
                device_type = "memory";
                reg = <0x10000000 0x80000000>;
index 736074f1c3ef940c101160dcd5f0e79c56baebaa..959d8ac2e393bfa9afca68f71c4d7c1d8c360edb 100644 (file)
 
                        /* VDD_AUD_1P8: Audio codec */
                        reg_aud_1p8v: ldo3 {
-                               regulator-name = "vdd1p8";
+                               regulator-name = "vdd1p8a";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
                                regulator-boot-on;
index d6df598bd1c29b728ca8ffa1e194df95f2826c14..b167b33bd108dc0f197a493a6c8f6c5207910338 100644 (file)
 
        lcd_backlight: lcd-backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                pwm-names = "LCD_BKLT_PWM";
 
                brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
                i2c-gpio,delay-us = <2>; /* ~100 kHz */
                #address-cells = <1>;
                #size-cells = <0>;
-               status = "disabld";
+               status = "disabled";
        };
 
        i2c_cam: i2c-gpio-cam {
                i2c-gpio,delay-us = <2>; /* ~100 kHz */
                #address-cells = <1>;
                #size-cells = <0>;
-               status = "disabld";
+               status = "disabled";
        };
 };
 
index b06577808ff4eb13b644a489af529b2df7ee7ea7..7e4e5fd0143a1272b9f83067f7b2f02339193533 100644 (file)
@@ -53,7 +53,6 @@
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_microsom_enet_ar8035>;
-       phy-handle = <&phy>;
        phy-mode = "rgmii-id";
        phy-reset-duration = <2>;
        phy-reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
                #address-cells = <1>;
                #size-cells = <0>;
 
-               phy: ethernet-phy@0 {
+               /*
+                * The PHY can appear at either address 0 or 4 due to the
+                * configuration (LED) pin not being pulled sufficiently.
+                */
+               ethernet-phy@0 {
                        reg = <0>;
                        qca,clk-out-frequency = <125000000>;
                };
+
+               ethernet-phy@4 {
+                       reg = <4>;
+                       qca,clk-out-frequency = <125000000>;
+               };
        };
 };
 
index 84b095279e656397445ad92a4099f8eb64459dbe..bd6b5285aa8d27b0debd4e73e70251c21159c46d 100644 (file)
                compatible = "nxp,pcf2127";
                reg = <0>;
                spi-max-frequency = <2000000>;
+               reset-source;
        };
 };
 
index 3a5cfb0ddb20ae691b38ceb1b2a3d1ac44a45a22..c87066d6c9950c51fce95b6681379eb446bfcf2f 100644 (file)
 
                                        clocks = <&xtal_32k>, <&xtal>;
                                        clock-names = "xtal_32k", "xtal";
-
-                                       assigned-clocks = <&clk LPC32XX_CLK_HCLK_PLL>;
-                                       assigned-clock-rates = <208000000>;
                                };
                        };
 
index c8745bc800f717530fccdf2da9b42fd9b8816ff9..7b8c18e6605e406339776d88b6e3b1b35213fac4 100644 (file)
                gpio-sck = <&gpio1 12 GPIO_ACTIVE_HIGH>;
                gpio-miso = <&gpio1 18 GPIO_ACTIVE_HIGH>;
                gpio-mosi = <&gpio1 20 GPIO_ACTIVE_HIGH>;
-               cs-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
+               cs-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
                num-chipselects = <1>;
 
                /* lcd panel */
                        spi-max-frequency = <100000>;
                        spi-cpol;
                        spi-cpha;
-                       spi-cs-high;
 
                        backlight= <&backlight>;
                        label = "lcd";
index 3ea4c5b9fd31961d1037d40924652e9dc311d4ed..e833c21f1c01491956bc1949d385ad673edf0011 100644 (file)
                        debounce-interval = <10>;
                };
 
+               /*
+                * We use pad 0x4a100116 abe_dmic_din3.gpio_122 as the irq instead
+                * of the gpio interrupt to avoid lost events in deeper idle states.
+               */
                slider {
                        label = "Keypad Slide";
+                       interrupts-extended = <&omap4_pmx_core 0xd6>;
                        gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */
                        linux,input-type = <EV_SW>;
                        linux,code = <SW_KEYPAD_SLIDE>;
index d309fad32229d9adc3c88ff7c789d04aa7b6b3cd..344d29853bf76f1300872822fd4ba6d0297f903d 100644 (file)
                                            200000 0>;
                };
        };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /* Modem trace memory */
+               ram@06000000 {
+                       reg = <0x06000000 0x00f00000>;
+                       no-map;
+               };
+
+               /* Modem shared memory */
+               ram@06f00000 {
+                       reg = <0x06f00000 0x00100000>;
+                       no-map;
+               };
+
+               /* Modem private memory */
+               ram@07000000 {
+                       reg = <0x07000000 0x01000000>;
+                       no-map;
+               };
+
+               /*
+                * Initial Secure Software ISSW memory
+                *
+                * This is probably only used if the kernel tries
+                * to actually call into trustzone to run secure
+                * applications, which the mainline kernel probably
+                * will not do on this old chipset. But you can never
+                * be too careful, so reserve this memory anyway.
+                */
+               ram@17f00000 {
+                       reg = <0x17f00000 0x00100000>;
+                       no-map;
+               };
+       };
 };
index 48bd8728ae27fd377931c2240883a050b56de517..287804e9e1836775364650c402bf01fdf4fcf742 100644 (file)
                                            200000 0>;
                };
        };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /* Modem trace memory */
+               ram@06000000 {
+                       reg = <0x06000000 0x00f00000>;
+                       no-map;
+               };
+
+               /* Modem shared memory */
+               ram@06f00000 {
+                       reg = <0x06f00000 0x00100000>;
+                       no-map;
+               };
+
+               /* Modem private memory */
+               ram@07000000 {
+                       reg = <0x07000000 0x01000000>;
+                       no-map;
+               };
+
+               /*
+                * Initial Secure Software ISSW memory
+                *
+                * This is probably only used if the kernel tries
+                * to actually call into trustzone to run secure
+                * applications, which the mainline kernel probably
+                * will not do on this old chipset. But you can never
+                * be too careful, so reserve this memory anyway.
+                */
+               ram@17f00000 {
+                       reg = <0x17f00000 0x00100000>;
+                       no-map;
+               };
+       };
 };
diff --git a/arch/arm/boot/dts/ste-db9500.dtsi b/arch/arm/boot/dts/ste-db9500.dtsi
new file mode 100644 (file)
index 0000000..0afff70
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "ste-dbx5x0.dtsi"
+
+/ {
+       cpus {
+               cpu@300 {
+                       /* cpufreq controls */
+                       operating-points = <1152000 0
+                                           800000 0
+                                           400000 0
+                                           200000 0>;
+               };
+       };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /*
+                * Initial Secure Software ISSW memory
+                *
+                * This is probably only used if the kernel tries
+                * to actually call into trustzone to run secure
+                * applications, which the mainline kernel probably
+                * will not do on this old chipset. But you can never
+                * be too careful, so reserve this memory anyway.
+                */
+               ram@17f00000 {
+                       reg = <0x17f00000 0x00100000>;
+                       no-map;
+               };
+       };
+};
index be90e73c923ec255e156996f1b0990f5d37886c4..27d8a07718a001c31b9f38ef21c6c2f33b12425f 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /dts-v1/;
-#include "ste-db8500.dtsi"
+#include "ste-db9500.dtsi"
 #include "ste-href-ab8500.dtsi"
 #include "ste-href-family-pinctrl.dtsi"
 
index 62ab23824a3e747e1525a5f1309f32fce51f9d2f..5088dd3a301b7d18110a3ed11716721003434860 100644 (file)
@@ -33,9 +33,9 @@
         * during TX anyway and that it only controls drive enable DE
         * line. Hence, the RX is always enabled here.
         */
-       rs485-rx-en {
+       rs485-rx-en-hog {
                gpio-hog;
-               gpios = <8 GPIO_ACTIVE_HIGH>;
+               gpios = <8 0>;
                output-low;
                line-name = "rs485-rx-en";
        };
@@ -61,9 +61,9 @@
         * order to reset the Hub when USB bus is powered down, but
         * so far there is no such functionality.
         */
-       usb-hub {
+       usb-hub-hog {
                gpio-hog;
-               gpios = <2 GPIO_ACTIVE_HIGH>;
+               gpios = <2 0>;
                output-high;
                line-name = "usb-hub-reset";
        };
        };
 };
 
+&i2c4 {
+       touchscreen@49 {
+               status = "disabled";
+       };
+};
+
 &i2c5 {        /* TP7/TP8 */
        pinctrl-names = "default";
        pinctrl-0 = <&i2c5_pins_a>;
         * are used for on-board microSD slot instead.
         */
        /delete-property/broken-cd;
-       cd-gpios = <&gpioi 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+       cd-gpios = <&gpioi 10 GPIO_ACTIVE_HIGH>;
        disable-wp;
 };
 
index 356150d28c420952d9941998092346616629f708..32700cca24c8207e3ae52a2a21694218ef877585 100644 (file)
@@ -43,9 +43,9 @@
         * in order to turn on port power when USB bus is powered up, but so
         * far there is no such functionality.
         */
-       usb-port-power {
+       usb-port-power-hog {
                gpio-hog;
-               gpios = <13 GPIO_ACTIVE_LOW>;
+               gpios = <13 0>;
                output-low;
                line-name = "usb-port-power";
        };
index ac46ab363e1b49807764b73441b96d164dd17304..daff5318f301ec0a3dfe7fbd2bb15a97dd0d3a8c 100644 (file)
        pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
        pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_a>;
        pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_a>;
-       broken-cd;
+       cd-gpios = <&gpiog 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+       disable-wp;
        st,sig-dir;
        st,neg-edge;
        st,use-ckin;
index 01ccff756996d83ac7d843f6fe61d7dcab5bad37..5740f9442705c47acd39883e57a0dca6efb1acd6 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
        phy-handle = <&phy1>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
 };
diff --git a/arch/arm/include/asm/kexec-internal.h b/arch/arm/include/asm/kexec-internal.h
new file mode 100644 (file)
index 0000000..ecc2322
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ARM_KEXEC_INTERNAL_H
+#define _ARM_KEXEC_INTERNAL_H
+
+struct kexec_relocate_data {
+       unsigned long kexec_start_address;
+       unsigned long kexec_indirection_page;
+       unsigned long kexec_mach_type;
+       unsigned long kexec_r2;
+};
+
+#endif
index 98daa7f483148bf5a972743dc4d569446fb3e023..7454480d084b2ec63a9ee0547eb94fa1aec56bd7 100644 (file)
 
                .align
 99:            .word   .
+#if defined(ZIMAGE)
+               .word   . + 4
+/*
+ * Storage for the state maintained by the macro.
+ *
+ * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
+ * That's because this header is included from multiple files, and we only
+ * want a single copy of the data. In particular, the UART probing code above
+ * assumes it's running using physical addresses. This is true when this file
+ * is included from head.o, but not when included from debug.o. So we need
+ * to share the probe results between the two copies, rather than having
+ * to re-run the probing again later.
+ *
+ * In the decompressor, we put the storage right here, since common.c
+ * isn't included in the decompressor build. This storage data gets put in
+ * .text even though it's really data, since .data is discarded from the
+ * decompressor. Luckily, .text is writeable in the decompressor, unless
+ * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
+ */
+               /* Debug UART initialization required */
+               .word   1
+               /* Debug UART physical address */
+               .word   0
+               /* Debug UART virtual address */
+               .word   0
+#else
                .word   tegra_uart_config
+#endif
                .ltorg
 
                /* Load previously selected UART address */
 
                .macro  waituarttxrdy,rd,rx
                .endm
-
-/*
- * Storage for the state maintained by the macros above.
- *
- * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
- * That's because this header is included from multiple files, and we only
- * want a single copy of the data. In particular, the UART probing code above
- * assumes it's running using physical addresses. This is true when this file
- * is included from head.o, but not when included from debug.o. So we need
- * to share the probe results between the two copies, rather than having
- * to re-run the probing again later.
- *
- * In the decompressor, we put the symbol/storage right here, since common.c
- * isn't included in the decompressor build. This symbol gets put in .text
- * even though it's really data, since .data is discarded from the
- * decompressor. Luckily, .text is writeable in the decompressor, unless
- * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
- */
-#if defined(ZIMAGE)
-tegra_uart_config:
-       /* Debug UART initialization required */
-       .word 1
-       /* Debug UART physical address */
-       .word 0
-       /* Debug UART virtual address */
-       .word 0
-#endif
index a1570c8bab25acd9bdbfbc7f26db705fa923f873..be8050b0c3dfbfb3e2d9e70705e014a0ec7ff915 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <asm/cacheflush.h>
+#include <asm/kexec-internal.h>
 #include <asm/glue-df.h>
 #include <asm/glue-pf.h>
 #include <asm/mach/arch.h>
@@ -170,5 +171,9 @@ int main(void)
   DEFINE(MPU_RGN_PRBAR,        offsetof(struct mpu_rgn, prbar));
   DEFINE(MPU_RGN_PRLAR,        offsetof(struct mpu_rgn, prlar));
 #endif
+  DEFINE(KEXEC_START_ADDR,     offsetof(struct kexec_relocate_data, kexec_start_address));
+  DEFINE(KEXEC_INDIR_PAGE,     offsetof(struct kexec_relocate_data, kexec_indirection_page));
+  DEFINE(KEXEC_MACH_TYPE,      offsetof(struct kexec_relocate_data, kexec_mach_type));
+  DEFINE(KEXEC_R2,             offsetof(struct kexec_relocate_data, kexec_r2));
   return 0; 
 }
index 5d84ad333f050aa6cd85446cedc3613a873d5e82..2b09dad7935eb4ed3496f77be46b5748bfdd7cc4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/of_fdt.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
+#include <asm/kexec-internal.h>
 #include <asm/fncpy.h>
 #include <asm/mach-types.h>
 #include <asm/smp_plat.h>
 extern void relocate_new_kernel(void);
 extern const unsigned int relocate_new_kernel_size;
 
-extern unsigned long kexec_start_address;
-extern unsigned long kexec_indirection_page;
-extern unsigned long kexec_mach_type;
-extern unsigned long kexec_boot_atags;
-
 static atomic_t waiting_for_crash_ipi;
 
 /*
@@ -159,6 +155,7 @@ void (*kexec_reinit)(void);
 void machine_kexec(struct kimage *image)
 {
        unsigned long page_list, reboot_entry_phys;
+       struct kexec_relocate_data *data;
        void (*reboot_entry)(void);
        void *reboot_code_buffer;
 
@@ -174,18 +171,17 @@ void machine_kexec(struct kimage *image)
 
        reboot_code_buffer = page_address(image->control_code_page);
 
-       /* Prepare parameters for reboot_code_buffer*/
-       set_kernel_text_rw();
-       kexec_start_address = image->start;
-       kexec_indirection_page = page_list;
-       kexec_mach_type = machine_arch_type;
-       kexec_boot_atags = image->arch.kernel_r2;
-
        /* copy our kernel relocation code to the control code page */
        reboot_entry = fncpy(reboot_code_buffer,
                             &relocate_new_kernel,
                             relocate_new_kernel_size);
 
+       data = reboot_code_buffer + relocate_new_kernel_size;
+       data->kexec_start_address = image->start;
+       data->kexec_indirection_page = page_list;
+       data->kexec_mach_type = machine_arch_type;
+       data->kexec_r2 = image->arch.kernel_r2;
+
        /* get the identity mapping physical address for the reboot code */
        reboot_entry_phys = virt_to_idmap(reboot_entry);
 
index 72a08786e16eb0bbc172e144e9300c75a6b6f988..218d524360fcd3f3a752fd3168665d20e4507a2f 100644 (file)
@@ -5,14 +5,16 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/asm-offsets.h>
 #include <asm/kexec.h>
 
        .align  3       /* not needed for this code, but keeps fncpy() happy */
 
 ENTRY(relocate_new_kernel)
 
-       ldr     r0,kexec_indirection_page
-       ldr     r1,kexec_start_address
+       adr     r7, relocate_new_kernel_end
+       ldr     r0, [r7, #KEXEC_INDIR_PAGE]
+       ldr     r1, [r7, #KEXEC_START_ADDR]
 
        /*
         * If there is no indirection page (we are doing crashdumps)
@@ -57,34 +59,16 @@ ENTRY(relocate_new_kernel)
 
 2:
        /* Jump to relocated kernel */
-       mov lr,r1
-       mov r0,#0
-       ldr r1,kexec_mach_type
-       ldr r2,kexec_boot_atags
- ARM(  ret lr  )
- THUMB(        bx lr           )
-
-       .align
-
-       .globl kexec_start_address
-kexec_start_address:
-       .long   0x0
-
-       .globl kexec_indirection_page
-kexec_indirection_page:
-       .long   0x0
-
-       .globl kexec_mach_type
-kexec_mach_type:
-       .long   0x0
-
-       /* phy addr of the atags for the new kernel */
-       .globl kexec_boot_atags
-kexec_boot_atags:
-       .long   0x0
+       mov     lr, r1
+       mov     r0, #0
+       ldr     r1, [r7, #KEXEC_MACH_TYPE]
+       ldr     r2, [r7, #KEXEC_R2]
+ ARM(  ret     lr      )
+ THUMB(        bx      lr      )
 
 ENDPROC(relocate_new_kernel)
 
+       .align  3
 relocate_new_kernel_end:
 
        .globl relocate_new_kernel_size
index 9d2e916121be4ebfc331b9771a553c66a6aa2e28..a3a38d0a4c853332102aefd01c02b0967e0ccc3f 100644 (file)
@@ -693,18 +693,20 @@ struct page *get_signal_page(void)
 
        addr = page_address(page);
 
+       /* Poison the entire page */
+       memset32(addr, __opcode_to_mem_arm(0xe7fddef1),
+                PAGE_SIZE / sizeof(u32));
+
        /* Give the signal return code some randomness */
        offset = 0x200 + (get_random_int() & 0x7fc);
        signal_return_offset = offset;
 
-       /*
-        * Copy signal return handlers into the vector page, and
-        * set sigreturn to be a pointer to these.
-        */
+       /* Copy signal return handlers into the page */
        memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
 
-       ptr = (unsigned long)addr + offset;
-       flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
+       /* Flush out all instructions in this page */
+       ptr = (unsigned long)addr;
+       flush_icache_range(ptr, ptr + PAGE_SIZE);
 
        return page;
 }
index 416462e3f5d63676fe8f00abca7aaa94c17f3e90..f9713dc561cf77447dc1ad65cce249b3ea3ca0dd 100644 (file)
@@ -65,15 +65,15 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
        if (addr)
                switch (size) {
                case 1:
-                       asm("ldrb       %0, [%1, %2]"
+                       asm volatile("ldrb      %0, [%1, %2]"
                                : "=r" (v) : "r" (addr), "r" (where) : "cc");
                        break;
                case 2:
-                       asm("ldrh       %0, [%1, %2]"
+                       asm volatile("ldrh      %0, [%1, %2]"
                                : "=r" (v) : "r" (addr), "r" (where) : "cc");
                        break;
                case 4:
-                       asm("ldr        %0, [%1, %2]"
+                       asm volatile("ldr       %0, [%1, %2]"
                                : "=r" (v) : "r" (addr), "r" (where) : "cc");
                        break;
                }
@@ -99,17 +99,17 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
        if (addr)
                switch (size) {
                case 1:
-                       asm("strb       %0, [%1, %2]"
+                       asm volatile("strb      %0, [%1, %2]"
                                : : "r" (value), "r" (addr), "r" (where)
                                : "cc");
                        break;
                case 2:
-                       asm("strh       %0, [%1, %2]"
+                       asm volatile("strh      %0, [%1, %2]"
                                : : "r" (value), "r" (addr), "r" (where)
                                : "cc");
                        break;
                case 4:
-                       asm("str        %0, [%1, %2]"
+                       asm volatile("str       %0, [%1, %2]"
                                : : "r" (value), "r" (addr), "r" (where)
                                : "cc");
                        break;
index 1eabf2d2834be79c6a6a695262ca4f1af2edcfc2..e06f946b75b96a9455d34facbf019b16121edb82 100644 (file)
@@ -67,6 +67,7 @@
 #define MX6Q_CCM_CCR   0x0
 
        .align 3
+       .arm
 
        .macro  sync_l2_cache
 
index a720259099edfb4bd5c226b104a761dae341dfca..0a4c9b0b13b0cfbaa57c78388447746344253733 100644 (file)
@@ -203,6 +203,8 @@ static int osk_tps_setup(struct i2c_client *client, void *context)
         */
        gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en");
        gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1);
+       /* Free the GPIO again as the driver will request it */
+       gpio_free(OSK_TPS_GPIO_USB_PWR_EN);
 
        /* Set GPIO 2 high so LED D3 is off by default */
        tps65010_set_gpio_out_value(GPIO2, HIGH);
index 4a59c169a11394a57bd4c52bed23b07ded5ef0cc..4178c0ee46eba5a63ee33f8923ea431268a76ced 100644 (file)
@@ -17,11 +17,10 @@ config ARCH_OMAP3
        bool "TI OMAP3"
        depends on ARCH_MULTI_V7
        select ARCH_OMAP2PLUS
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND
        select OMAP_HWMOD
        select OMAP_INTERCONNECT
-       select PM_OPP if PM
-       select PM if CPU_IDLE
+       select PM_OPP
        select SOC_HAS_OMAP2_SDRC
        select ARM_ERRATA_430973
 
@@ -30,7 +29,7 @@ config ARCH_OMAP4
        depends on ARCH_MULTI_V7
        select ARCH_OMAP2PLUS
        select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND
        select ARM_ERRATA_720789
        select ARM_GIC
        select HAVE_ARM_SCU if SMP
@@ -40,7 +39,7 @@ config ARCH_OMAP4
        select OMAP_INTERCONNECT_BARRIER
        select PL310_ERRATA_588369 if CACHE_L2X0
        select PL310_ERRATA_727915 if CACHE_L2X0
-       select PM_OPP if PM
+       select PM_OPP
        select PM if CPU_IDLE
        select ARM_ERRATA_754322
        select ARM_ERRATA_775420
@@ -50,7 +49,7 @@ config SOC_OMAP5
        bool "TI OMAP5"
        depends on ARCH_MULTI_V7
        select ARCH_OMAP2PLUS
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND
        select ARM_GIC
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_ARCH_TIMER
@@ -58,14 +57,14 @@ config SOC_OMAP5
        select OMAP_HWMOD
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
-       select PM_OPP if PM
+       select PM_OPP
        select ZONE_DMA if ARM_LPAE
 
 config SOC_AM33XX
        bool "TI AM33XX"
        depends on ARCH_MULTI_V7
        select ARCH_OMAP2PLUS
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND
 
 config SOC_AM43XX
        bool "TI AM43x"
@@ -79,13 +78,13 @@ config SOC_AM43XX
        select ARM_ERRATA_754322
        select ARM_ERRATA_775420
        select OMAP_INTERCONNECT
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND
 
 config SOC_DRA7XX
        bool "TI DRA7XX"
        depends on ARCH_MULTI_V7
        select ARCH_OMAP2PLUS
-       select ARM_CPU_SUSPEND if PM
+       select ARM_CPU_SUSPEND
        select ARM_GIC
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_ARCH_TIMER
@@ -94,7 +93,7 @@ config SOC_DRA7XX
        select OMAP_HWMOD
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
-       select PM_OPP if PM
+       select PM_OPP
        select ZONE_DMA if ARM_LPAE
        select PINCTRL_TI_IODELAY if OF && PINCTRL
 
@@ -112,9 +111,11 @@ config ARCH_OMAP2PLUS
        select OMAP_DM_TIMER
        select OMAP_GPMC
        select PINCTRL
-       select PM_GENERIC_DOMAINS if PM
-       select PM_GENERIC_DOMAINS_OF if PM
+       select PM
+       select PM_GENERIC_DOMAINS
+       select PM_GENERIC_DOMAINS_OF
        select RESET_CONTROLLER
+       select SIMPLE_PM_BUS
        select SOC_BUS
        select TI_SYSC
        select OMAP_IRQCHIP
@@ -140,7 +141,6 @@ config ARCH_OMAP2PLUS_TYPICAL
        select I2C_OMAP
        select MENELAUS if ARCH_OMAP2
        select NEON if CPU_V7
-       select PM
        select REGULATOR
        select REGULATOR_FIXED_VOLTAGE
        select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
index c8d317fafe2eaf21cd0f1926ddf48604f301d2e8..de37027ad75870dd1d0ffebca6901dca635a094c 100644 (file)
@@ -151,10 +151,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
                                 (cx->mpu_logic_state == PWRDM_POWER_OFF);
 
        /* Enter broadcast mode for periodic timers */
-       tick_broadcast_enable();
+       RCU_NONIDLE(tick_broadcast_enable());
 
        /* Enter broadcast mode for one-shot timers */
-       tick_broadcast_enter();
+       RCU_NONIDLE(tick_broadcast_enter());
 
        /*
         * Call idle CPU PM enter notifier chain so that
@@ -166,7 +166,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 
        if (dev->cpu == 0) {
                pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
-               omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+               RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state));
 
                /*
                 * Call idle CPU cluster PM enter notifier chain
@@ -178,7 +178,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
                                index = 0;
                                cx = state_ptr + index;
                                pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
-                               omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+                               RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state));
                                mpuss_can_lose_context = 0;
                        }
                }
@@ -194,9 +194,9 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
                    mpuss_can_lose_context)
                        gic_dist_disable();
 
-               clkdm_deny_idle(cpu_clkdm[1]);
-               omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
-               clkdm_allow_idle(cpu_clkdm[1]);
+               RCU_NONIDLE(clkdm_deny_idle(cpu_clkdm[1]));
+               RCU_NONIDLE(omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON));
+               RCU_NONIDLE(clkdm_allow_idle(cpu_clkdm[1]));
 
                if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) &&
                    mpuss_can_lose_context) {
@@ -222,7 +222,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
        cpu_pm_exit();
 
 cpu_pm_out:
-       tick_broadcast_exit();
+       RCU_NONIDLE(tick_broadcast_exit());
 
 fail:
        cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
index cd38bf07c094d568613a8503e37500dc03703f8d..2e3a10914c40aaa6cb47d6745c607e78f4dcade4 100644 (file)
@@ -522,6 +522,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
                       &dra7_ipu1_dsp_iommu_pdata),
 #endif
        /* Common auxdata */
+       OF_DEV_AUXDATA("simple-pm-bus", 0, NULL, omap_auxdata_lookup),
        OF_DEV_AUXDATA("ti,sysc", 0, NULL, &ti_sysc_pdata),
        OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata),
        OF_DEV_AUXDATA("ti,omap-prm-inst", 0, NULL, &ti_prm_pdata),
index ba1c6dfdc4b6b7d2f585556779f9eb6f676a6cb7..d945c84ab697ae944df92923d3e6ca18b3ba57aa 100644 (file)
                                      "timing-adjustment";
                        rx-fifo-depth = <4096>;
                        tx-fifo-depth = <2048>;
-                       resets = <&reset RESET_ETHERNET>;
-                       reset-names = "stmmaceth";
                        power-domains = <&pwrc PWRC_AXG_ETHERNET_MEM_ID>;
                        status = "disabled";
                };
index 9c90d562ada1a31e82756224bf6fc1b53af5078a..b858c5e43cc88fb1e593b28fe5a93a908331b196 100644 (file)
                                      "timing-adjustment";
                        rx-fifo-depth = <4096>;
                        tx-fifo-depth = <2048>;
-                       resets = <&reset RESET_ETHERNET>;
-                       reset-names = "stmmaceth";
                        status = "disabled";
 
                        mdio0: mdio {
                                interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                                dr_mode = "host";
                                snps,dis_u2_susphy_quirk;
-                               snps,quirk-frame-length-adjustment;
+                               snps,quirk-frame-length-adjustment = <0x20>;
                                snps,parkmode-disable-ss-quirk;
                        };
                };
index 726b91d3a905a5cfd9a9322654570a2074ff58d0..0edd137151f89eb6ba63695d28abdfaf18cf6434 100644 (file)
@@ -13,7 +13,6 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/power/meson-gxbb-power.h>
-#include <dt-bindings/reset/amlogic,meson-gxbb-reset.h>
 #include <dt-bindings/thermal/thermal.h>
 
 / {
                        interrupt-names = "macirq";
                        rx-fifo-depth = <4096>;
                        tx-fifo-depth = <2048>;
-                       resets = <&reset RESET_ETHERNET>;
-                       reset-names = "stmmaceth";
                        power-domains = <&pwrc PWRC_GXBB_ETHERNET_MEM_ID>;
                        status = "disabled";
                };
index cf5a98f0e47c8e4bb1a12ce142a76cf0d889fe79..a712273c905afc72aff9a7e663ed64a81f234031 100644 (file)
@@ -52,7 +52,7 @@
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
 
-               gpio = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+               gpio = <&gpio_ao GPIOAO_3 GPIO_OPEN_DRAIN>;
                enable-active-high;
                regulator-always-on;
        };
index aef8f2b00778d718e360344f68ae9f0c71c639c5..5401a646c8406f2a4ef4d6d438920607b6eb5241 100644 (file)
@@ -4,11 +4,16 @@
  */
        usb {
                compatible = "simple-bus";
-               dma-ranges;
                #address-cells = <2>;
                #size-cells = <2>;
                ranges = <0x0 0x0 0x0 0x68500000 0x0 0x00400000>;
 
+               /*
+                * Internally, USB bus to the interconnect can only address up
+                * to 40-bit
+                */
+               dma-ranges = <0 0 0 0 0x100 0x0>;
+
                usbphy0: usb-phy@0 {
                        compatible = "brcm,sr-usb-combo-phy";
                        reg = <0x0 0x00000000 0x0 0x100>;
index 60ff19fa53b40fb0eab33454886f5a8a203949a5..6c8a61c2cc740406c7bbd29a38c6c61a115b91ff 100644 (file)
        reboot {
                compatible ="syscon-reboot";
                regmap = <&rst>;
-               offset = <0xb0>;
+               offset = <0>;
                mask = <0x02>;
        };
 
index 025e1f5876627eb84e2b676ca29232edca88cfbc..565934cbfa280feb07a3b91cd0bb5397e2181759 100644 (file)
 
                dcfg: dcfg@1ee0000 {
                        compatible = "fsl,ls1046a-dcfg", "syscon";
-                       reg = <0x0 0x1ee0000 0x0 0x10000>;
+                       reg = <0x0 0x1ee0000 0x0 0x1000>;
                        big-endian;
                };
 
index ee1790230490d418d603aaa19da047b231631000..2a79e89f821ee317cf775bc221d4b2fd2c3fc726 100644 (file)
                        #size-cells = <1>;
                        ranges;
 
-                       spba: bus@30000000 {
+                       spba: spba-bus@30000000 {
                                compatible = "fsl,spba-bus", "simple-bus";
                                #address-cells = <1>;
                                #size-cells = <1>;
index ecccfbb4f5ad6831c5d00af1f56201ad99fe5f9d..23f5a5e37167bfd431ae496e6be768f21747cc5e 100644 (file)
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
-                               gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 0 144 4>;
+                               gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 26 144 4>;
                        };
 
                        gpio4: gpio@30230000 {
index 7cc236575ee203e58622f622fd4d85dc9b39a21b..c0b93813ea9acd42f66f9fa173b99ae9ae8b722d 100644 (file)
 &gcc {
        protected-clocks = <GCC_QSPI_CORE_CLK>,
                           <GCC_QSPI_CORE_CLK_SRC>,
-                          <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
+                          <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+                          <GCC_LPASS_Q6_AXI_CLK>,
+                          <GCC_LPASS_SWAY_CLK>;
 };
 
 &gpu {
index 13fdd02cffe6320428486539059b89805229aeff..8b40f96e978025168752bcea8a1000e8944be647 100644 (file)
 &gcc {
        protected-clocks = <GCC_QSPI_CORE_CLK>,
                           <GCC_QSPI_CORE_CLK_SRC>,
-                          <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
+                          <GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+                          <GCC_LPASS_Q6_AXI_CLK>,
+                          <GCC_LPASS_SWAY_CLK>;
 };
 
 &gpu {
 &i2c3 {
        status = "okay";
        clock-frequency = <400000>;
+       /* Overwrite pinctrl-0 from sdm845.dtsi */
+       pinctrl-0 = <&qup_i2c3_default &i2c3_hid_active>;
 
        tsel: hid@15 {
                compatible = "hid-over-i2c";
                hid-descr-addr = <0x1>;
 
                interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&i2c3_hid_active>;
        };
 
        tsc2: hid@2c {
                hid-descr-addr = <0x20>;
 
                interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&i2c3_hid_active>;
-
-               status = "disabled";
        };
 };
 
index 2695ea8cda142c8600d21ebd93720ee519b1903c..64193292d26c32f8dbff6957634a9eb4124b7df3 100644 (file)
        vopl_mmu: iommu@ff470f00 {
                compatible = "rockchip,iommu";
                reg = <0x0 0xff470f00 0x0 0x100>;
-               interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "vopl_mmu";
                clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>;
                clock-names = "aclk", "iface";
index 2ee07d15a6e375e0f07cf8ed60354bcacb4c4d0a..1eecad724f04c74cea2e01369b528e9c7632ecd8 100644 (file)
        cpu-supply = <&vdd_arm>;
 };
 
+&display_subsystem {
+       status = "disabled";
+};
+
 &gmac2io {
        assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
        assigned-clock-parents = <&gmac_clk>, <&gmac_clk>;
index 06d48338c83622f5e3da4a938dde256bf56f7eb4..219b7507a10fb7732f1a1cbc56cc52c07ef0893b 100644 (file)
 &pcie0 {
        bus-scan-delay-ms = <1000>;
        ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
-       max-link-speed = <2>;
        num-lanes = <4>;
        pinctrl-names = "default";
        pinctrl-0 = <&pcie_clkreqn_cpm>;
index f5dee5f447bbacb5b4f69fcf04f18e020ef86813..2551b238b97c6ab708ae5f2bd20701d10591cf2a 100644 (file)
                reg = <0x0 0xf8000000 0x0 0x2000000>,
                      <0x0 0xfd000000 0x0 0x1000000>;
                reg-names = "axi-base", "apb-base";
+               device_type = "pci";
                #address-cells = <3>;
                #size-cells = <2>;
                #interrupt-cells = <1>;
                                <0 0 0 2 &pcie0_intc 1>,
                                <0 0 0 3 &pcie0_intc 2>,
                                <0 0 0 4 &pcie0_intc 3>;
-               linux,pci-domain = <0>;
                max-link-speed = <1>;
                msi-map = <0x0 &its 0x0 0x1000>;
                phys = <&pcie_phy 0>, <&pcie_phy 1>,
                compatible = "rockchip,rk3399-vdec";
                reg = <0x0 0xff660000 0x0 0x400>;
                interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
-               interrupt-names = "vdpu";
                clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>,
                         <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>;
                clock-names = "axi", "ahb", "cabac", "core";
index 838301650a794681264b5e3a75b46f7f759d14f9..01aa3eee90e8e75ee9b19e21cb9d9ea8a534a6da 100644 (file)
@@ -991,8 +991,6 @@ CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_ARCH_TEGRA_186_SOC=y
 CONFIG_ARCH_TEGRA_194_SOC=y
 CONFIG_ARCH_TEGRA_234_SOC=y
-CONFIG_ARCH_K3_AM6_SOC=y
-CONFIG_ARCH_K3_J721E_SOC=y
 CONFIG_TI_SCI_PM_DOMAINS=y
 CONFIG_EXTCON_PTN5150=m
 CONFIG_EXTCON_USB_GPIO=y
@@ -1078,7 +1076,7 @@ CONFIG_INTERCONNECT=y
 CONFIG_INTERCONNECT_QCOM=y
 CONFIG_INTERCONNECT_QCOM_MSM8916=m
 CONFIG_INTERCONNECT_QCOM_OSM_L3=m
-CONFIG_INTERCONNECT_QCOM_SDM845=m
+CONFIG_INTERCONNECT_QCOM_SDM845=y
 CONFIG_INTERCONNECT_QCOM_SM8150=m
 CONFIG_INTERCONNECT_QCOM_SM8250=m
 CONFIG_EXT2_FS=y
index 18fce223b67b2746d08b1d5f64ee3c54e456989d..ff4732785c32f9650f381e9b6338e49df3ca64b4 100644 (file)
@@ -247,11 +247,13 @@ static inline const void *__tag_set(const void *addr, u8 tag)
 
 
 /*
- * The linear kernel range starts at the bottom of the virtual address space.
+ * Check whether an arbitrary address is within the linear map, which
+ * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the
+ * kernel's TTBR1 address range.
  */
-#define __is_lm_address(addr)  (((u64)(addr) & ~PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))
+#define __is_lm_address(addr)  (((u64)(addr) PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))
 
-#define __lm_to_phys(addr)     (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+#define __lm_to_phys(addr)     (((addr) PAGE_OFFSET) + PHYS_OFFSET)
 #define __kimg_to_phys(addr)   ((addr) - kimage_voffset)
 
 #define __virt_to_phys_nodebug(x) ({                                   \
@@ -330,7 +332,7 @@ static inline void *phys_to_virt(phys_addr_t x)
 #endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */
 
 #define virt_addr_valid(addr)  ({                                      \
-       __typeof__(addr) __addr = addr;                                 \
+       __typeof__(addr) __addr = __tag_reset(addr);                    \
        __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr));      \
 })
 
index 04c44853b103b1681d600d853f5d10160147552c..fe60d25c000e4f7148fd36e762932f4e923745f4 100644 (file)
@@ -1396,8 +1396,9 @@ static void cpu_init_hyp_mode(void)
         * Calculate the raw per-cpu offset without a translation from the
         * kernel's mapping to the linear mapping, and store it in tpidr_el2
         * so that we can use adr_l to access per-cpu variables in EL2.
+        * Also drop the KASAN tag which gets in the way...
         */
-       params->tpidr_el2 = (unsigned long)this_cpu_ptr_nvhe_sym(__per_cpu_start) -
+       params->tpidr_el2 = (unsigned long)kasan_reset_tag(this_cpu_ptr_nvhe_sym(__per_cpu_start)) -
                            (unsigned long)kvm_ksym_ref(CHOOSE_NVHE_SYM(__per_cpu_start));
 
        params->mair_el2 = read_sysreg(mair_el1);
index 31b060a4404524720cf5ae05f1e21014a35de0c6..b17bf19217f1100b962bb5794c05a9214262cb54 100644 (file)
@@ -47,6 +47,8 @@ __invalid:
        b       .
 
        /*
+        * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers.
+        *
         * x0: SMCCC function ID
         * x1: struct kvm_nvhe_init_params PA
         */
@@ -70,9 +72,9 @@ __do_hyp_init:
        eret
 
 1:     mov     x0, x1
-       mov     x4, lr
-       bl      ___kvm_hyp_init
-       mov     lr, x4
+       mov     x3, lr
+       bl      ___kvm_hyp_init                 // Clobbers x0..x2
+       mov     lr, x3
 
        /* Hello, World! */
        mov     x0, #SMCCC_RET_SUCCESS
@@ -82,8 +84,8 @@ SYM_CODE_END(__kvm_hyp_init)
 /*
  * Initialize the hypervisor in EL2.
  *
- * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers
- * and leave x4 for the caller.
+ * Only uses x0..x2 so as to not clobber callee-saved SMCCC registers
+ * and leave x3 for the caller.
  *
  * x0: struct kvm_nvhe_init_params PA
  */
@@ -112,9 +114,9 @@ alternative_else_nop_endif
        /*
         * Set the PS bits in TCR_EL2.
         */
-       ldr     x1, [x0, #NVHE_INIT_TCR_EL2]
-       tcr_compute_pa_size x1, #TCR_EL2_PS_SHIFT, x2, x3
-       msr     tcr_el2, x1
+       ldr     x0, [x0, #NVHE_INIT_TCR_EL2]
+       tcr_compute_pa_size x0, #TCR_EL2_PS_SHIFT, x1, x2
+       msr     tcr_el2, x0
 
        isb
 
@@ -193,7 +195,7 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)
 
        /* Enable MMU, set vectors and stack. */
        mov     x0, x28
-       bl      ___kvm_hyp_init                 // Clobbers x0..x3
+       bl      ___kvm_hyp_init                 // Clobbers x0..x2
 
        /* Leave idmap. */
        mov     x0, x29
index e3947846ffcb9acd8d4528190741fdb48325e711..8e7128cb76678f8697abc0bfe4a9e7c57a899afd 100644 (file)
@@ -77,12 +77,6 @@ static unsigned long psci_forward(struct kvm_cpu_context *host_ctxt)
                         cpu_reg(host_ctxt, 2), cpu_reg(host_ctxt, 3));
 }
 
-static __noreturn unsigned long psci_forward_noreturn(struct kvm_cpu_context *host_ctxt)
-{
-       psci_forward(host_ctxt);
-       hyp_panic(); /* unreachable */
-}
-
 static unsigned int find_cpu_id(u64 mpidr)
 {
        unsigned int i;
@@ -251,10 +245,13 @@ static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_
        case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
        case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
                return psci_forward(host_ctxt);
+       /*
+        * SYSTEM_OFF/RESET should not return according to the spec.
+        * Allow it so as to stay robust to broken firmware.
+        */
        case PSCI_0_2_FN_SYSTEM_OFF:
        case PSCI_0_2_FN_SYSTEM_RESET:
-               psci_forward_noreturn(host_ctxt);
-               unreachable();
+               return psci_forward(host_ctxt);
        case PSCI_0_2_FN64_CPU_SUSPEND:
                return psci_cpu_suspend(func_id, host_ctxt);
        case PSCI_0_2_FN64_CPU_ON:
index 4ad66a532e38b37007fd75610e15a426b7123bd8..247422ac78a9e5c01e543146076428d81db061fc 100644 (file)
@@ -788,7 +788,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 {
        unsigned long *bmap = vcpu->kvm->arch.pmu_filter;
        u64 val, mask = 0;
-       int base, i;
+       int base, i, nr_events;
 
        if (!pmceid1) {
                val = read_sysreg(pmceid0_el0);
@@ -801,13 +801,17 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
        if (!bmap)
                return val;
 
+       nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1;
+
        for (i = 0; i < 32; i += 8) {
                u64 byte;
 
                byte = bitmap_get_value8(bmap, base + i);
                mask |= byte << i;
-               byte = bitmap_get_value8(bmap, 0x4000 + base + i);
-               mask |= byte << (32 + i);
+               if (nr_events >= (0x4000 + base + 32)) {
+                       byte = bitmap_get_value8(bmap, 0x4000 + base + i);
+                       mask |= byte << (32 + i);
+               }
        }
 
        return val & mask;
index 42ccc27fb684cad8bce5c5587fa5291468ee0b92..7c4f79532406b5ca865e4fdaf37bcc8e5cea9bd2 100644 (file)
  * 64bit interface.
  */
 
+#define reg_to_encoding(x)                                             \
+       sys_reg((u32)(x)->Op0, (u32)(x)->Op1,                           \
+               (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
+
 static bool read_from_write_only(struct kvm_vcpu *vcpu,
                                 struct sys_reg_params *params,
                                 const struct sys_reg_desc *r)
@@ -273,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
                          const struct sys_reg_desc *r)
 {
        u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
-       u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1,
-                        (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
+       u32 sr = reg_to_encoding(r);
 
        if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
                kvm_inject_undefined(vcpu);
@@ -590,6 +593,15 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
        vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1);
 }
 
+static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu,
+                                  const struct sys_reg_desc *r)
+{
+       if (kvm_vcpu_has_pmu(vcpu))
+               return 0;
+
+       return REG_HIDDEN;
+}
+
 static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 {
        u64 pmcr, val;
@@ -613,9 +625,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 static bool check_pmu_access_disabled(struct kvm_vcpu *vcpu, u64 flags)
 {
        u64 reg = __vcpu_sys_reg(vcpu, PMUSERENR_EL0);
-       bool enabled = kvm_vcpu_has_pmu(vcpu);
+       bool enabled = (reg & flags) || vcpu_mode_priv(vcpu);
 
-       enabled &= (reg & flags) || vcpu_mode_priv(vcpu);
        if (!enabled)
                kvm_inject_undefined(vcpu);
 
@@ -900,11 +911,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
                             const struct sys_reg_desc *r)
 {
-       if (!kvm_vcpu_has_pmu(vcpu)) {
-               kvm_inject_undefined(vcpu);
-               return false;
-       }
-
        if (p->is_write) {
                if (!vcpu_mode_priv(vcpu)) {
                        kvm_inject_undefined(vcpu);
@@ -921,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
        return true;
 }
 
-#define reg_to_encoding(x)                                             \
-       sys_reg((u32)(x)->Op0, (u32)(x)->Op1,                           \
-               (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
-
 /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
 #define DBG_BCR_BVR_WCR_WVR_EL1(n)                                     \
        { SYS_DESC(SYS_DBGBVRn_EL1(n)),                                 \
@@ -936,15 +938,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
        { SYS_DESC(SYS_DBGWCRn_EL1(n)),                                 \
          trap_wcr, reset_wcr, 0, 0,  get_wcr, set_wcr }
 
+#define PMU_SYS_REG(r)                                         \
+       SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility
+
 /* Macro to expand the PMEVCNTRn_EL0 register */
 #define PMU_PMEVCNTR_EL0(n)                                            \
-       { SYS_DESC(SYS_PMEVCNTRn_EL0(n)),                                       \
-         access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), }
+       { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)),                            \
+         .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
 
 /* Macro to expand the PMEVTYPERn_EL0 register */
 #define PMU_PMEVTYPER_EL0(n)                                           \
-       { SYS_DESC(SYS_PMEVTYPERn_EL0(n)),                                      \
-         access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
+       { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)),                           \
+         .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), }
 
 static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
                         const struct sys_reg_desc *r)
@@ -1020,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
                struct sys_reg_desc const *r, bool raz)
 {
-       u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
-                        (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
+       u32 id = reg_to_encoding(r);
        u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
 
        if (id == SYS_ID_AA64PFR0_EL1) {
@@ -1062,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
                                  const struct sys_reg_desc *r)
 {
-       u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
-                        (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
+       u32 id = reg_to_encoding(r);
 
        switch (id) {
        case SYS_ID_AA64ZFR0_EL1:
@@ -1486,8 +1489,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
        { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
 
-       { SYS_DESC(SYS_PMINTENSET_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 },
-       { SYS_DESC(SYS_PMINTENCLR_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 },
+       { PMU_SYS_REG(SYS_PMINTENSET_EL1),
+         .access = access_pminten, .reg = PMINTENSET_EL1 },
+       { PMU_SYS_REG(SYS_PMINTENCLR_EL1),
+         .access = access_pminten, .reg = PMINTENSET_EL1 },
 
        { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
        { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
@@ -1526,23 +1531,36 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
        { SYS_DESC(SYS_CTR_EL0), access_ctr },
 
-       { SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 },
-       { SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
-       { SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
-       { SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 },
-       { SYS_DESC(SYS_PMSWINC_EL0), access_pmswinc, reset_unknown, PMSWINC_EL0 },
-       { SYS_DESC(SYS_PMSELR_EL0), access_pmselr, reset_unknown, PMSELR_EL0 },
-       { SYS_DESC(SYS_PMCEID0_EL0), access_pmceid },
-       { SYS_DESC(SYS_PMCEID1_EL0), access_pmceid },
-       { SYS_DESC(SYS_PMCCNTR_EL0), access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 },
-       { SYS_DESC(SYS_PMXEVTYPER_EL0), access_pmu_evtyper },
-       { SYS_DESC(SYS_PMXEVCNTR_EL0), access_pmu_evcntr },
+       { PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr,
+         .reset = reset_pmcr, .reg = PMCR_EL0 },
+       { PMU_SYS_REG(SYS_PMCNTENSET_EL0),
+         .access = access_pmcnten, .reg = PMCNTENSET_EL0 },
+       { PMU_SYS_REG(SYS_PMCNTENCLR_EL0),
+         .access = access_pmcnten, .reg = PMCNTENSET_EL0 },
+       { PMU_SYS_REG(SYS_PMOVSCLR_EL0),
+         .access = access_pmovs, .reg = PMOVSSET_EL0 },
+       { PMU_SYS_REG(SYS_PMSWINC_EL0),
+         .access = access_pmswinc, .reg = PMSWINC_EL0 },
+       { PMU_SYS_REG(SYS_PMSELR_EL0),
+         .access = access_pmselr, .reg = PMSELR_EL0 },
+       { PMU_SYS_REG(SYS_PMCEID0_EL0),
+         .access = access_pmceid, .reset = NULL },
+       { PMU_SYS_REG(SYS_PMCEID1_EL0),
+         .access = access_pmceid, .reset = NULL },
+       { PMU_SYS_REG(SYS_PMCCNTR_EL0),
+         .access = access_pmu_evcntr, .reg = PMCCNTR_EL0 },
+       { PMU_SYS_REG(SYS_PMXEVTYPER_EL0),
+         .access = access_pmu_evtyper, .reset = NULL },
+       { PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
+         .access = access_pmu_evcntr, .reset = NULL },
        /*
         * PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero
         * in 32bit mode. Here we choose to reset it as zero for consistency.
         */
-       { SYS_DESC(SYS_PMUSERENR_EL0), access_pmuserenr, reset_val, PMUSERENR_EL0, 0 },
-       { SYS_DESC(SYS_PMOVSSET_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 },
+       { PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr,
+         .reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 },
+       { PMU_SYS_REG(SYS_PMOVSSET_EL0),
+         .access = access_pmovs, .reg = PMOVSSET_EL0 },
 
        { SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
        { SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
@@ -1694,7 +1712,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
         * PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero
         * in 32bit mode. Here we choose to reset it as zero for consistency.
         */
-       { SYS_DESC(SYS_PMCCFILTR_EL0), access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 },
+       { PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
+         .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
 
        { SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
        { SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 },
index 67a9ba9eaa96bd1b900732e6c134010a5bf9c3a6..cde44c13dda1bc0924d2d50369ad87f544a0a802 100644 (file)
@@ -9,7 +9,7 @@
 
 phys_addr_t __virt_to_phys(unsigned long x)
 {
-       WARN(!__is_lm_address(x),
+       WARN(!__is_lm_address(__tag_reset(x)),
             "virt_to_phys used for non-linear address: %pK (%pS)\n",
              (void *)x,
              (void *)x);
index 703b1c4f6d12355f1115f33f45c2433c6db16ab0..45d5368d6a99c895d6ac815868baf5896a31b4ff 100644 (file)
@@ -69,7 +69,7 @@ vmlinux.bin: vmlinux FORCE
        $(call if_changed,objcopy)
 
 unwcheck: vmlinux
-       -$(Q)READELF=$(READELF) $(PYTHON) $(srctree)/arch/ia64/scripts/unwcheck.py $<
+       -$(Q)READELF=$(READELF) $(PYTHON3) $(srctree)/arch/ia64/scripts/unwcheck.py $<
 
 archclean:
 
index d69c979936d41e4a3225091efcd31b46cde5c230..5d90307fd6e073642313b8f0d0c2e4386ea2e717 100644 (file)
@@ -54,7 +54,7 @@ extern void ia64_xchg_called_with_bad_pointer(void);
 })
 
 #define xchg(ptr, x)                                                   \
-((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr))))
+({(__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)));})
 
 /*
  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
index ed9fc3d057a6db70de9e4a72b7b02d252e9b6ab0..43e8050145bef2bf45a8b5f11b34b4e281ad4e64 100644 (file)
@@ -171,29 +171,34 @@ void vtime_account_hardirq(struct task_struct *tsk)
 static irqreturn_t
 timer_interrupt (int irq, void *dev_id)
 {
-       unsigned long cur_itm, new_itm, ticks;
+       unsigned long new_itm;
 
        if (cpu_is_offline(smp_processor_id())) {
                return IRQ_HANDLED;
        }
 
        new_itm = local_cpu_data->itm_next;
-       cur_itm = ia64_get_itc();
 
-       if (!time_after(cur_itm, new_itm)) {
+       if (!time_after(ia64_get_itc(), new_itm))
                printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
-                      cur_itm, new_itm);
-               ticks = 1;
-       } else {
-               ticks = DIV_ROUND_UP(cur_itm - new_itm,
-                                    local_cpu_data->itm_delta);
-               new_itm += ticks * local_cpu_data->itm_delta;
-       }
+                      ia64_get_itc(), new_itm);
+
+       while (1) {
+               new_itm += local_cpu_data->itm_delta;
+
+               legacy_timer_tick(smp_processor_id() == time_keeper_id);
 
-       if (smp_processor_id() != time_keeper_id)
-               ticks = 0;
+               local_cpu_data->itm_next = new_itm;
 
-       legacy_timer_tick(ticks);
+               if (time_after(new_itm, ia64_get_itc()))
+                       break;
+
+               /*
+                * Allow IPIs to interrupt the timer loop.
+                */
+               local_irq_enable();
+               local_irq_disable();
+       }
 
        do {
                /*
index bfd1b671e35fcb96f5b56c332f802a00b9d5f374..9581742f0db23c21c811a0c1802044125e78b23d 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0
 #
 # Usage: unwcheck.py FILE
index 78b17621ee4a5e5a67588b522fe5a13c115e84b3..278462186ac4759c43c704d6d07d5f6189a663d9 100644 (file)
@@ -202,9 +202,8 @@ config PREFETCH
        depends on PA8X00 || PA7200
 
 config MLONGCALLS
-       bool "Enable the -mlong-calls compiler option for big kernels"
-       default y if !MODULES || UBSAN || FTRACE
-       default n
+       def_bool y if !MODULES || UBSAN || FTRACE
+       bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE
        depends on PA8X00
        help
          If you configure the kernel to include many drivers built-in instead
index 959e79cd2c1488a08f5cd9a0aacb52c933f2eb0e..378f63c4015b49921a34cdfdd2612e79894a0df5 100644 (file)
@@ -47,7 +47,4 @@ extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
 extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *);
 extern int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest);
 
-/* soft power switch support (power.c) */
-extern struct tasklet_struct power_tasklet;
-
 #endif /* _ASM_PARISC_IRQ_H */
index beba9816cc6c160b7f573f4e19224871894201eb..4d37cc9cba37c4b9c3b62d55fc9e39964e4d34cd 100644 (file)
@@ -997,10 +997,17 @@ intr_do_preempt:
        bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
        nop
 
+       /* ssm PSW_SM_I done later in intr_restore */
+#ifdef CONFIG_MLONGCALLS
+       ldil    L%intr_restore, %r2
+       load32  preempt_schedule_irq, %r1
+       bv      %r0(%r1)
+       ldo     R%intr_restore(%r2), %r2
+#else
+       ldil    L%intr_restore, %r1
        BL      preempt_schedule_irq, %r2
-       nop
-
-       b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
+       ldo     R%intr_restore(%r1), %r2
+#endif
 #endif /* CONFIG_PREEMPTION */
 
        /*
index fe2ef598e2ead0a5f429cd30a90e0edd48e22664..79ee7750937db06bade246afd710016a6fef2f1b 100644 (file)
@@ -51,7 +51,7 @@ obj-y                         += ptrace/
 obj-$(CONFIG_PPC64)            += setup_64.o \
                                   paca.o nvram_64.o note.o syscall_64.o
 obj-$(CONFIG_COMPAT)           += sys_ppc32.o signal_32.o
-obj-$(CONFIG_VDSO32)           += vdso32/
+obj-$(CONFIG_VDSO32)           += vdso32_wrapper.o
 obj-$(CONFIG_PPC_WATCHDOG)     += watchdog.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)       += hw_breakpoint.o
 obj-$(CONFIG_PPC_DAWR)         += dawr.o
@@ -60,7 +60,7 @@ obj-$(CONFIG_PPC_BOOK3S_64)   += cpu_setup_power.o
 obj-$(CONFIG_PPC_BOOK3S_64)    += mce.o mce_power.o
 obj-$(CONFIG_PPC_BOOK3E_64)    += exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o
-obj-$(CONFIG_PPC64)            += vdso64/
+obj-$(CONFIG_PPC64)            += vdso64_wrapper.o
 obj-$(CONFIG_ALTIVEC)          += vecemu.o
 obj-$(CONFIG_PPC_BOOK3S_IDLE)  += idle_book3s.o
 procfs-y                       := proc_powerpc.o
index 6b1eca53e36cc834b853822a9ee7faf886bf7e04..cc7a6271b6b4ec5408bfd2ed07a41432f0cc5a37 100644 (file)
@@ -180,13 +180,18 @@ void notrace restore_interrupts(void)
 
 void replay_soft_interrupts(void)
 {
+       struct pt_regs regs;
+
        /*
-        * We use local_paca rather than get_paca() to avoid all
-        * the debug_smp_processor_id() business in this low level
-        * function
+        * Be careful here, calling these interrupt handlers can cause
+        * softirqs to be raised, which they may run when calling irq_exit,
+        * which will cause local_irq_enable() to be run, which can then
+        * recurse into this function. Don't keep any state across
+        * interrupt handler calls which may change underneath us.
+        *
+        * We use local_paca rather than get_paca() to avoid all the
+        * debug_smp_processor_id() business in this low level function.
         */
-       unsigned char happened = local_paca->irq_happened;
-       struct pt_regs regs;
 
        ppc_save_regs(&regs);
        regs.softe = IRQS_ENABLED;
@@ -209,7 +214,7 @@ again:
         * This is a higher priority interrupt than the others, so
         * replay it first.
         */
-       if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_HMI)) {
+       if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_HMI)) {
                local_paca->irq_happened &= ~PACA_IRQ_HMI;
                regs.trap = 0xe60;
                handle_hmi_exception(&regs);
@@ -217,7 +222,7 @@ again:
                        hard_irq_disable();
        }
 
-       if (happened & PACA_IRQ_DEC) {
+       if (local_paca->irq_happened & PACA_IRQ_DEC) {
                local_paca->irq_happened &= ~PACA_IRQ_DEC;
                regs.trap = 0x900;
                timer_interrupt(&regs);
@@ -225,7 +230,7 @@ again:
                        hard_irq_disable();
        }
 
-       if (happened & PACA_IRQ_EE) {
+       if (local_paca->irq_happened & PACA_IRQ_EE) {
                local_paca->irq_happened &= ~PACA_IRQ_EE;
                regs.trap = 0x500;
                do_IRQ(&regs);
@@ -233,7 +238,7 @@ again:
                        hard_irq_disable();
        }
 
-       if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (happened & PACA_IRQ_DBELL)) {
+       if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (local_paca->irq_happened & PACA_IRQ_DBELL)) {
                local_paca->irq_happened &= ~PACA_IRQ_DBELL;
                if (IS_ENABLED(CONFIG_PPC_BOOK3E))
                        regs.trap = 0x280;
@@ -245,7 +250,7 @@ again:
        }
 
        /* Book3E does not support soft-masking PMI interrupts */
-       if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (happened & PACA_IRQ_PMI)) {
+       if (IS_ENABLED(CONFIG_PPC_BOOK3S) && (local_paca->irq_happened & PACA_IRQ_PMI)) {
                local_paca->irq_happened &= ~PACA_IRQ_PMI;
                regs.trap = 0xf00;
                performance_monitor_exception(&regs);
@@ -253,8 +258,7 @@ again:
                        hard_irq_disable();
        }
 
-       happened = local_paca->irq_happened;
-       if (happened & ~PACA_IRQ_HARD_DIS) {
+       if (local_paca->irq_happened & ~PACA_IRQ_HARD_DIS) {
                /*
                 * We are responding to the next interrupt, so interrupt-off
                 * latencies should be reset here.
index 9cb6f524854b9d6f480e32f3cf346fe7d7a57071..7d9a6fee0e3dc1a01e066314721f09e732af8ae6 100644 (file)
@@ -30,7 +30,7 @@ CC32FLAGS += -m32
 KBUILD_CFLAGS := $(filter-out -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc,$(KBUILD_CFLAGS))
 endif
 
-targets := $(obj-vdso32) vdso32.so.dbg
+targets := $(obj-vdso32) vdso32.so.dbg vgettimeofday.o
 obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
 
 GCOV_PROFILE := n
@@ -46,9 +46,6 @@ obj-y += vdso32_wrapper.o
 targets += vdso32.lds
 CPPFLAGS_vdso32.lds += -P -C -Upowerpc
 
-# Force dependency (incbin is bad)
-$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so.dbg
-
 # link rule for the .so file, .lds has to be first
 $(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday.o FORCE
        $(call if_changed,vdso32ld_and_check)
diff --git a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S
deleted file mode 100644 (file)
index 3f5ef03..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <linux/linkage.h>
-#include <asm/page.h>
-
-       __PAGE_ALIGNED_DATA
-
-       .globl vdso32_start, vdso32_end
-       .balign PAGE_SIZE
-vdso32_start:
-       .incbin "arch/powerpc/kernel/vdso32/vdso32.so.dbg"
-       .balign PAGE_SIZE
-vdso32_end:
-
-       .previous
diff --git a/arch/powerpc/kernel/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32_wrapper.S
new file mode 100644 (file)
index 0000000..3f5ef03
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/page.h>
+
+       __PAGE_ALIGNED_DATA
+
+       .globl vdso32_start, vdso32_end
+       .balign PAGE_SIZE
+vdso32_start:
+       .incbin "arch/powerpc/kernel/vdso32/vdso32.so.dbg"
+       .balign PAGE_SIZE
+vdso32_end:
+
+       .previous
index bf363ff371521c65477853f89c8f4a16d3a0d3de..2813e3f98db65611e0c83ac1891fe5b30b445820 100644 (file)
@@ -17,7 +17,7 @@ endif
 
 # Build rules
 
-targets := $(obj-vdso64) vdso64.so.dbg
+targets := $(obj-vdso64) vdso64.so.dbg vgettimeofday.o
 obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
 
 GCOV_PROFILE := n
@@ -29,15 +29,9 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
        -Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both
 asflags-y := -D__VDSO64__ -s
 
-obj-y += vdso64_wrapper.o
 targets += vdso64.lds
 CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
 
-$(obj)/vgettimeofday.o: %.o: %.c FORCE
-
-# Force dependency (incbin is bad)
-$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so.dbg
-
 # link rule for the .so file, .lds has to be first
 $(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday.o FORCE
        $(call if_changed,vdso64ld_and_check)
index bbf68cd01088b5ab04092c099c922709c44eef1f..2d4067561293ea76645e57ba5748819992108ad8 100644 (file)
 
        .text
 
+/*
+ * __kernel_start_sigtramp_rt64 and __kernel_sigtramp_rt64 together
+ * are one function split in two parts. The kernel jumps to the former
+ * and the signal handler indirectly (by blr) returns to the latter.
+ * __kernel_sigtramp_rt64 needs to point to the return address so
+ * glibc can correctly identify the trampoline stack frame.
+ */
        .balign 8
        .balign IFETCH_ALIGN_BYTES
-V_FUNCTION_BEGIN(__kernel_sigtramp_rt64)
+V_FUNCTION_BEGIN(__kernel_start_sigtramp_rt64)
 .Lsigrt_start:
        bctrl   /* call the handler */
+V_FUNCTION_END(__kernel_start_sigtramp_rt64)
+V_FUNCTION_BEGIN(__kernel_sigtramp_rt64)
        addi    r1, r1, __SIGNAL_FRAMESIZE
        li      r0,__NR_rt_sigreturn
        sc
index 6164d1a1ba11b7d8d0a303411cd9519b41089c60..2f3c359cacd3a850a373141f37a46a9238fbd58d 100644 (file)
@@ -131,4 +131,4 @@ VERSION
 /*
  * Make the sigreturn code visible to the kernel.
  */
-VDSO_sigtramp_rt64     = __kernel_sigtramp_rt64;
+VDSO_sigtramp_rt64     = __kernel_start_sigtramp_rt64;
diff --git a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S
deleted file mode 100644 (file)
index 1d56d81..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <linux/linkage.h>
-#include <asm/page.h>
-
-       __PAGE_ALIGNED_DATA
-
-       .globl vdso64_start, vdso64_end
-       .balign PAGE_SIZE
-vdso64_start:
-       .incbin "arch/powerpc/kernel/vdso64/vdso64.so.dbg"
-       .balign PAGE_SIZE
-vdso64_end:
-
-       .previous
diff --git a/arch/powerpc/kernel/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64_wrapper.S
new file mode 100644 (file)
index 0000000..1d56d81
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/page.h>
+
+       __PAGE_ALIGNED_DATA
+
+       .globl vdso64_start, vdso64_end
+       .balign PAGE_SIZE
+vdso64_start:
+       .incbin "arch/powerpc/kernel/vdso64/vdso64.so.dbg"
+       .balign PAGE_SIZE
+vdso64_end:
+
+       .previous
index bf7a7d62ae8b5d5bb367926ebb3dd120ff76a4b7..ede093e9623472f1f9652d98843ef9f48fcc7aaa 100644 (file)
@@ -818,13 +818,15 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
                        break;
                if (rev) {
                        /* reverse 32 bytes */
-                       buf.d[0] = byterev_8(reg->d[3]);
-                       buf.d[1] = byterev_8(reg->d[2]);
-                       buf.d[2] = byterev_8(reg->d[1]);
-                       buf.d[3] = byterev_8(reg->d[0]);
-                       reg = &buf;
+                       union vsx_reg buf32[2];
+                       buf32[0].d[0] = byterev_8(reg[1].d[1]);
+                       buf32[0].d[1] = byterev_8(reg[1].d[0]);
+                       buf32[1].d[0] = byterev_8(reg[0].d[1]);
+                       buf32[1].d[1] = byterev_8(reg[0].d[0]);
+                       memcpy(mem, buf32, size);
+               } else {
+                       memcpy(mem, reg, size);
                }
-               memcpy(mem, reg, size);
                break;
        case 16:
                /* stxv, stxvx, stxvl, stxvll */
index e9e2c1f0a690594389a2d034a56f59f8a376a89f..e0a34eb5ed3b37a199d44fd661a4dabd57be603b 100644 (file)
@@ -252,8 +252,10 @@ choice
        default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY
 
        config MAXPHYSMEM_1GB
+               depends on 32BIT
                bool "1GiB"
        config MAXPHYSMEM_2GB
+               depends on 64BIT && CMODEL_MEDLOW
                bool "2GiB"
        config MAXPHYSMEM_128GB
                depends on 64BIT && CMODEL_MEDANY
index 2d50f76efe4819ffa8645ac1aa1d1c7473fe400f..64a675c5c30acb2c9806645ba9f3f5e7297cef21 100644 (file)
@@ -135,7 +135,10 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x);
 
 #endif /* __ASSEMBLY__ */
 
-#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))
+#define virt_addr_valid(vaddr) ({                                              \
+       unsigned long _addr = (unsigned long)vaddr;                             \
+       (unsigned long)(_addr) >= PAGE_OFFSET && pfn_valid(virt_to_pfn(_addr)); \
+})
 
 #define VM_DATA_DEFAULT_FLAGS  VM_DATA_FLAGS_NON_EXEC
 
index 211eb8244a454bd4038e6a9867643d4232b3fd4e..8b80c80c7f1acad9d9e1b3cb29d28a005fd83cd3 100644 (file)
@@ -32,14 +32,14 @@ bool kernel_page_present(struct page *page);
 
 #endif /* __ASSEMBLY__ */
 
-#ifdef CONFIG_ARCH_HAS_STRICT_KERNEL_RWX
+#ifdef CONFIG_STRICT_KERNEL_RWX
 #ifdef CONFIG_64BIT
 #define SECTION_ALIGN (1 << 21)
 #else
 #define SECTION_ALIGN (1 << 22)
 #endif
-#else /* !CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */
+#else /* !CONFIG_STRICT_KERNEL_RWX */
 #define SECTION_ALIGN L1_CACHE_BYTES
-#endif /* CONFIG_ARCH_HAS_STRICT_KERNEL_RWX */
+#endif /* CONFIG_STRICT_KERNEL_RWX */
 
 #endif /* _ASM_RISCV_SET_MEMORY_H */
index 3fa3f26dde85664a6ccd993d9ee3bdcdf118eee3..c7c0655dd45b0f617a34d89b315e5829638c43af 100644 (file)
@@ -293,6 +293,8 @@ void free_initmem(void)
        unsigned long init_begin = (unsigned long)__init_begin;
        unsigned long init_end = (unsigned long)__init_end;
 
-       set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT);
+       if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
+               set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT);
+
        free_initmem_default(POISON_FREE_INITMEM);
 }
index 7cd4993f4ff21a932b6ef29512f685ea4e947f9a..f9f9568d689ef53e215c44de8b4468ae3033cfa9 100644 (file)
@@ -196,7 +196,7 @@ void __init setup_bootmem(void)
        max_pfn = PFN_DOWN(dram_end);
        max_low_pfn = max_pfn;
        dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
-       set_max_mapnr(max_low_pfn);
+       set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
 
 #ifdef CONFIG_BLK_DEV_INITRD
        setup_initrd();
index a15c033f53ca42a4228e4a30265749c69747bb4f..87641dd65ccf915e8d11aa5062dcc0433f34eeb4 100644 (file)
@@ -35,7 +35,7 @@ void uv_query_info(void)
                uv_info.guest_cpu_stor_len = uvcb.cpu_stor_len;
                uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE);
                uv_info.max_num_sec_conf = uvcb.max_num_sec_conf;
-               uv_info.max_guest_cpus = uvcb.max_guest_cpus;
+               uv_info.max_guest_cpu_id = uvcb.max_guest_cpu_id;
        }
 
 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
index 0325fc0469b7b021613d1d1837b62b85378665f4..7b98d4caee779cfd128182f62a6f56fbc4dae1e2 100644 (file)
@@ -96,7 +96,7 @@ struct uv_cb_qui {
        u32 max_num_sec_conf;
        u64 max_guest_stor_addr;
        u8  reserved88[158 - 136];
-       u16 max_guest_cpus;
+       u16 max_guest_cpu_id;
        u8  reserveda0[200 - 160];
 } __packed __aligned(8);
 
@@ -273,7 +273,7 @@ struct uv_info {
        unsigned long guest_cpu_stor_len;
        unsigned long max_sec_stor_addr;
        unsigned int max_num_sec_conf;
-       unsigned short max_guest_cpus;
+       unsigned short max_guest_cpu_id;
 };
 
 extern struct uv_info uv_info;
index 883bfed9f5c2ce38e25ebc24d4e408fbcaccb6cd..b2d2ad1530676ddad2142c3963bdd41bd0a72da7 100644 (file)
@@ -368,7 +368,7 @@ static ssize_t uv_query_max_guest_cpus(struct kobject *kobj,
                                       struct kobj_attribute *attr, char *page)
 {
        return scnprintf(page, PAGE_SIZE, "%d\n",
-                       uv_info.max_guest_cpus);
+                       uv_info.max_guest_cpu_id + 1);
 }
 
 static struct kobj_attribute uv_query_max_guest_cpus_attr =
index 34d302d1a07ff865c46b9b4320bcc70fe77846e1..c3030db3325f157a91c4cfae256183b041b5bcd1 100644 (file)
@@ -15,7 +15,6 @@ config UML
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DEBUG_BUGVERBOSE
        select NO_DMA
-       select ARCH_HAS_SET_MEMORY
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
        select HAVE_GCC_PLUGINS
index 13b1fe694b90494dab3d8034709172fbe9125616..8e0b43cf089f4761b3defb1fb1721bd37d3c2464 100644 (file)
@@ -375,11 +375,11 @@ break_loop:
                file = NULL;
 
        backing_file = strsep(&str, ",:");
-       if (*backing_file == '\0')
+       if (backing_file && *backing_file == '\0')
                backing_file = NULL;
 
        serial = strsep(&str, ",:");
-       if (*serial == '\0')
+       if (serial && *serial == '\0')
                serial = NULL;
 
        if (backing_file && ubd_dev->no_cow) {
@@ -1241,7 +1241,7 @@ static int __init ubd_driver_init(void){
                /* Letting ubd=sync be like using ubd#s= instead of ubd#= is
                 * enough. So use anyway the io thread. */
        }
-       stack = alloc_stack(0);
+       stack = alloc_stack(0, 0);
        io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
                                 &thread_fd);
        if(io_pid < 0){
index 27e92d3881ff4ef608a6a51dc8a8a9e2b63467a4..5d957b7e7fd5279a2344254693b9b136931f8401 100644 (file)
@@ -1084,6 +1084,7 @@ static void virtio_uml_release_dev(struct device *d)
        }
 
        os_close_file(vu_dev->sock);
+       kfree(vu_dev);
 }
 
 /* Platform device */
@@ -1097,7 +1098,7 @@ static int virtio_uml_probe(struct platform_device *pdev)
        if (!pdata)
                return -EINVAL;
 
-       vu_dev = devm_kzalloc(&pdev->dev, sizeof(*vu_dev), GFP_KERNEL);
+       vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL);
        if (!vu_dev)
                return -ENOMEM;
 
index 96f77b5232aafe01e1f73cf3641683160b8b1ba5..cef03e3aa0f994ae58fe3cab6ab47b7b19630017 100644 (file)
@@ -5,7 +5,7 @@
 #define ioremap ioremap
 static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
 {
-       return (void __iomem *)(unsigned long)offset;
+       return NULL;
 }
 
 #define iounmap iounmap
index 39376bb63abf58596e30dcdd35971d66c4aaf707..def376194dce63a3c7b80f8986033e59d3a81be8 100644 (file)
@@ -55,15 +55,12 @@ extern unsigned long end_iomem;
 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
 #define __PAGE_KERNEL_EXEC                                              \
         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
-#define __PAGE_KERNEL_RO                                               \
-        (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
 #define PAGE_NONE      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
 #define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 #define PAGE_KERNEL_EXEC       __pgprot(__PAGE_KERNEL_EXEC)
-#define PAGE_KERNEL_RO         __pgprot(__PAGE_KERNEL_RO)
 
 /*
  * The i386 can't do page protection for execute, and considers that the same
diff --git a/arch/um/include/asm/set_memory.h b/arch/um/include/asm/set_memory.h
deleted file mode 100644 (file)
index 24266c6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/set_memory.h>
index d8c279e3312fe69ab409b35331aa34632e0dd8a7..2888ec812f6ece8721f63fb5818b5f1bef19b501 100644 (file)
@@ -19,7 +19,7 @@ extern int kmalloc_ok;
 #define UML_ROUND_UP(addr) \
        ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK)
 
-extern unsigned long alloc_stack(int atomic);
+extern unsigned long alloc_stack(int order, int atomic);
 extern void free_stack(unsigned long stack, int order);
 
 struct pt_regs;
index e4abac6c9727cc274647b47da116c1dfeae4e6d8..6516ef1f827457b61f743a449931c2d9fc387361 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/kmsg_dump.h>
 #include <linux/console.h>
+#include <linux/string.h>
 #include <shared/init.h>
 #include <shared/kern.h>
 #include <os.h>
@@ -16,8 +17,12 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
        if (!console_trylock())
                return;
 
-       for_each_console(con)
-               break;
+       for_each_console(con) {
+               if(strcmp(con->name, "tty") == 0 &&
+                  (con->flags & (CON_ENABLED | CON_CONSDEV)) != 0) {
+                       break;
+               }
+       }
 
        console_unlock();
 
index 2a986ece54780ddb55e436e1097c93337d57a5b1..81d508daf67cbc4299e28899a8811dfb143180d5 100644 (file)
@@ -32,7 +32,6 @@
 #include <os.h>
 #include <skas.h>
 #include <linux/time-internal.h>
-#include <asm/set_memory.h>
 
 /*
  * This is a per-cpu array.  A processor only modifies its entry and it only
@@ -63,18 +62,16 @@ void free_stack(unsigned long stack, int order)
        free_pages(stack, order);
 }
 
-unsigned long alloc_stack(int atomic)
+unsigned long alloc_stack(int order, int atomic)
 {
-       unsigned long addr;
+       unsigned long page;
        gfp_t flags = GFP_KERNEL;
 
        if (atomic)
                flags = GFP_ATOMIC;
-       addr = __get_free_pages(flags, 1);
+       page = __get_free_pages(flags, order);
 
-       set_memory_ro(addr, 1);
-
-       return addr + PAGE_SIZE;
+       return page;
 }
 
 static inline void set_current(struct task_struct *task)
index f4db89b5b5a6f5a61675bee36f1646cb1a744038..315248b039414c9a3d93b754adb8abfed24c9e7e 100644 (file)
@@ -535,6 +535,31 @@ invalid_number:
 
        return 1;
 }
+
+static void time_travel_set_start(void)
+{
+       if (time_travel_start_set)
+               return;
+
+       switch (time_travel_mode) {
+       case TT_MODE_EXTERNAL:
+               time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1);
+               /* controller gave us the *current* time, so adjust by that */
+               time_travel_ext_get_time();
+               time_travel_start -= time_travel_time;
+               break;
+       case TT_MODE_INFCPU:
+       case TT_MODE_BASIC:
+               if (!time_travel_start_set)
+                       time_travel_start = os_persistent_clock_emulation();
+               break;
+       case TT_MODE_OFF:
+               /* we just read the host clock with os_persistent_clock_emulation() */
+               break;
+       }
+
+       time_travel_start_set = true;
+}
 #else /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
 #define time_travel_start_set 0
 #define time_travel_start 0
@@ -553,6 +578,10 @@ static void time_travel_set_interval(unsigned long long interval)
 {
 }
 
+static inline void time_travel_set_start(void)
+{
+}
+
 /* fail link if this actually gets used */
 extern u64 time_travel_ext_req(u32 op, u64 time);
 
@@ -731,6 +760,8 @@ void read_persistent_clock64(struct timespec64 *ts)
 {
        long long nsecs;
 
+       time_travel_set_start();
+
        if (time_travel_mode != TT_MODE_OFF)
                nsecs = time_travel_start + time_travel_time;
        else
@@ -742,25 +773,6 @@ void read_persistent_clock64(struct timespec64 *ts)
 
 void __init time_init(void)
 {
-#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
-       switch (time_travel_mode) {
-       case TT_MODE_EXTERNAL:
-               time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1);
-               /* controller gave us the *current* time, so adjust by that */
-               time_travel_ext_get_time();
-               time_travel_start -= time_travel_time;
-               break;
-       case TT_MODE_INFCPU:
-       case TT_MODE_BASIC:
-               if (!time_travel_start_set)
-                       time_travel_start = os_persistent_clock_emulation();
-               break;
-       case TT_MODE_OFF:
-               /* we just read the host clock with os_persistent_clock_emulation() */
-               break;
-       }
-#endif
-
        timer_set_signal_handler();
        late_time_init = um_timer_setup;
 }
index 437d1f1cc5ecd862890d8d0405d49f668bd75e29..61776790cd678110f4a2a8af3953778598362b18 100644 (file)
@@ -608,57 +608,3 @@ void force_flush_all(void)
                vma = vma->vm_next;
        }
 }
-
-struct page_change_data {
-       unsigned int set_mask, clear_mask;
-};
-
-static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
-{
-       struct page_change_data *cdata = data;
-       pte_t pte = READ_ONCE(*ptep);
-
-       pte_clear_bits(pte, cdata->clear_mask);
-       pte_set_bits(pte, cdata->set_mask);
-
-       set_pte(ptep, pte);
-       return 0;
-}
-
-static int change_memory(unsigned long start, unsigned long pages,
-                        unsigned int set_mask, unsigned int clear_mask)
-{
-       unsigned long size = pages * PAGE_SIZE;
-       struct page_change_data data;
-       int ret;
-
-       data.set_mask = set_mask;
-       data.clear_mask = clear_mask;
-
-       ret = apply_to_page_range(&init_mm, start, size, change_page_range,
-                                 &data);
-
-       flush_tlb_kernel_range(start, start + size);
-
-       return ret;
-}
-
-int set_memory_ro(unsigned long addr, int numpages)
-{
-       return change_memory(addr, numpages, 0, _PAGE_RW);
-}
-
-int set_memory_rw(unsigned long addr, int numpages)
-{
-       return change_memory(addr, numpages, _PAGE_RW, 0);
-}
-
-int set_memory_nx(unsigned long addr, int numpages)
-{
-       return -EOPNOTSUPP;
-}
-
-int set_memory_x(unsigned long addr, int numpages)
-{
-       return -EOPNOTSUPP;
-}
index 31d356b1ffd8253375aa738c4aa1e24d178ac7bc..80e2660782a05964fd34381d80d5d2ad220771a2 100644 (file)
@@ -26,7 +26,8 @@
 #include <mem_user.h>
 #include <os.h>
 
-#define DEFAULT_COMMAND_LINE "root=98:0"
+#define DEFAULT_COMMAND_LINE_ROOT "root=98:0"
+#define DEFAULT_COMMAND_LINE_CONSOLE "console=tty"
 
 /* Changed in add_arg and setup_arch, which run before SMP is started */
 static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 };
@@ -109,7 +110,8 @@ unsigned long end_vm;
 int ncpus = 1;
 
 /* Set in early boot */
-static int have_root __initdata = 0;
+static int have_root __initdata;
+static int have_console __initdata;
 
 /* Set in uml_mem_setup and modified in linux_main */
 long long physmem_size = 32 * 1024 * 1024;
@@ -161,6 +163,17 @@ __uml_setup("debug", no_skas_debug_setup,
 "    this flag is not needed to run gdb on UML in skas mode\n\n"
 );
 
+static int __init uml_console_setup(char *line, int *add)
+{
+       have_console = 1;
+       return 0;
+}
+
+__uml_setup("console=", uml_console_setup,
+"console=<preferred console>\n"
+"    Specify the preferred console output driver\n\n"
+);
+
 static int __init Usage(char *line, int *add)
 {
        const char **p;
@@ -264,7 +277,10 @@ int __init linux_main(int argc, char **argv)
                        add_arg(argv[i]);
        }
        if (have_root == 0)
-               add_arg(DEFAULT_COMMAND_LINE);
+               add_arg(DEFAULT_COMMAND_LINE_ROOT);
+
+       if (have_console == 0)
+               add_arg(DEFAULT_COMMAND_LINE_CONSOLE);
 
        host_task_size = os_get_top_address();
        /*
index feb48d796e0050e1803fe1b637b3334447fcb7e3..9fa6e4187d4fb4bcd0d116169a0527c73d020e92 100644 (file)
@@ -45,7 +45,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
        unsigned long stack, sp;
        int pid, fds[2], ret, n;
 
-       stack = alloc_stack(__cant_sleep());
+       stack = alloc_stack(0, __cant_sleep());
        if (stack == 0)
                return -ENOMEM;
 
@@ -116,7 +116,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
        unsigned long stack, sp;
        int pid, status, err;
 
-       stack = alloc_stack(__cant_sleep());
+       stack = alloc_stack(0, __cant_sleep());
        if (stack == 0)
                return -ENOMEM;
 
index a61cbf73a179dec6a4bf55595c3d5906057c3c38..6c5041c5560b28a16cac11bdfa7a0403b31528b0 100644 (file)
@@ -104,5 +104,18 @@ long long os_nsecs(void)
  */
 void os_idle_sleep(void)
 {
-       pause();
+       struct itimerspec its;
+       sigset_t set, old;
+
+       /* block SIGALRM while we analyze the timer state */
+       sigemptyset(&set);
+       sigaddset(&set, SIGALRM);
+       sigprocmask(SIG_BLOCK, &set, &old);
+
+       /* check the timer, and if it'll fire then wait for it */
+       timer_gettime(event_high_res_timer, &its);
+       if (its.it_value.tv_sec || its.it_value.tv_nsec)
+               sigsuspend(&old);
+       /* either way, restore the signal mask */
+       sigprocmask(SIG_UNBLOCK, &set, NULL);
 }
index ccd32877a3c4141faaf97ad4dfec58217ac2cf48..496b11ec469def7b22e0948b60f07d6f7746e1b6 100644 (file)
@@ -10,7 +10,7 @@
 #include <asm/export.h>
 
        /* rdi: arg1 ... normal C conventions. rax is saved/restored. */
-       .macro THUNK name, func, put_ret_addr_in_rdi=0
+       .macro THUNK name, func
 SYM_FUNC_START_NOALIGN(\name)
        pushq %rbp
        movq %rsp, %rbp
@@ -25,13 +25,8 @@ SYM_FUNC_START_NOALIGN(\name)
        pushq %r10
        pushq %r11
 
-       .if \put_ret_addr_in_rdi
-       /* 8(%rbp) is return addr on stack */
-       movq 8(%rbp), %rdi
-       .endif
-
        call \func
-       jmp  .L_restore
+       jmp  __thunk_restore
 SYM_FUNC_END(\name)
        _ASM_NOKPROBE(\name)
        .endm
@@ -44,7 +39,7 @@ SYM_FUNC_END(\name)
 #endif
 
 #ifdef CONFIG_PREEMPTION
-SYM_CODE_START_LOCAL_NOALIGN(.L_restore)
+SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore)
        popq %r11
        popq %r10
        popq %r9
@@ -56,6 +51,6 @@ SYM_CODE_START_LOCAL_NOALIGN(.L_restore)
        popq %rdi
        popq %rbp
        ret
-       _ASM_NOKPROBE(.L_restore)
-SYM_CODE_END(.L_restore)
+       _ASM_NOKPROBE(__thunk_restore)
+SYM_CODE_END(__thunk_restore)
 #endif
index 247a60a47331774e34e4fbc85fbcfbc3c86e58bc..f656aabd1545cc8eb0d7ea8abf46686e5834e91e 100644 (file)
@@ -613,6 +613,7 @@ DECLARE_IDTENTRY_VC(X86_TRAP_VC,    exc_vmm_communication);
 
 #ifdef CONFIG_XEN_PV
 DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER, exc_xen_hypervisor_callback);
+DECLARE_IDTENTRY_RAW(X86_TRAP_OTHER,   exc_xen_unknown_trap);
 #endif
 
 /* Device interrupts common/spurious */
index 3412c4595efd812314f63db00168e279e3124562..740f3bdb3f61939d28da1e8bdd47552a6912b298 100644 (file)
@@ -660,6 +660,17 @@ static void __init trim_platform_memory_ranges(void)
 
 static void __init trim_bios_range(void)
 {
+       /*
+        * A special case is the first 4Kb of memory;
+        * This is a BIOS owned area, not kernel ram, but generally
+        * not listed as such in the E820 table.
+        *
+        * This typically reserves additional memory (64KiB by default)
+        * since some BIOSes are known to corrupt low memory.  See the
+        * Kconfig help text for X86_RESERVE_LOW.
+        */
+       e820__range_update(0, PAGE_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
+
        /*
         * special case: Some BIOSes report the PC BIOS
         * area (640Kb -> 1Mb) as RAM even though it is not.
@@ -717,15 +728,6 @@ early_param("reservelow", parse_reservelow);
 
 static void __init trim_low_memory_range(void)
 {
-       /*
-        * A special case is the first 4Kb of memory;
-        * This is a BIOS owned area, not kernel ram, but generally
-        * not listed as such in the E820 table.
-        *
-        * This typically reserves additional memory (64KiB by default)
-        * since some BIOSes are known to corrupt low memory.  See the
-        * Kconfig help text for X86_RESERVE_LOW.
-        */
        memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE));
 }
        
index 13036cf0b9124587002b4bf50a1796f6171539d6..38172ca627d36d2199fdfc64d7fa41ebba2f0e07 100644 (file)
@@ -321,7 +321,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
        if (cpuid->nent < vcpu->arch.cpuid_nent)
                goto out;
        r = -EFAULT;
-       if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
+       if (copy_to_user(entries, vcpu->arch.cpuid_entries,
                         vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
                goto out;
        return 0;
index 56cae1ff9e3fe46362947f0911b39573d44397a8..66a08322988f223a179edb33cf97c190c6136a54 100644 (file)
@@ -2879,6 +2879,8 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
        ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data);
        *reg_write(ctxt, VCPU_REGS_RSP) = (efer & EFER_LMA) ? msr_data :
                                                              (u32)msr_data;
+       if (efer & EFER_LMA)
+               ctxt->mode = X86EMUL_MODE_PROT64;
 
        return X86EMUL_CONTINUE;
 }
index f15bc16de07c3318061727eb1ee71b27e131ab78..a889563ad02d5e49bdfed32d30fdc8edcae1233c 100644 (file)
@@ -9,31 +9,6 @@
        (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR  \
         | X86_CR4_OSXMMEXCPT | X86_CR4_PGE | X86_CR4_TSD | X86_CR4_FSGSBASE)
 
-static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu,
-                                            enum kvm_reg reg)
-{
-       return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
-}
-
-static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu,
-                                        enum kvm_reg reg)
-{
-       return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
-}
-
-static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu,
-                                              enum kvm_reg reg)
-{
-       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
-}
-
-static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu,
-                                          enum kvm_reg reg)
-{
-       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
-       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
-}
-
 #define BUILD_KVM_GPR_ACCESSORS(lname, uname)                                \
 static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)\
 {                                                                            \
@@ -43,7 +18,6 @@ static __always_inline void kvm_##lname##_write(struct kvm_vcpu *vcpu,              \
                                                unsigned long val)            \
 {                                                                            \
        vcpu->arch.regs[VCPU_REGS_##uname] = val;                             \
-       kvm_register_mark_dirty(vcpu, VCPU_REGS_##uname);                     \
 }
 BUILD_KVM_GPR_ACCESSORS(rax, RAX)
 BUILD_KVM_GPR_ACCESSORS(rbx, RBX)
@@ -63,6 +37,31 @@ BUILD_KVM_GPR_ACCESSORS(r14, R14)
 BUILD_KVM_GPR_ACCESSORS(r15, R15)
 #endif
 
+static inline bool kvm_register_is_available(struct kvm_vcpu *vcpu,
+                                            enum kvm_reg reg)
+{
+       return test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
+}
+
+static inline bool kvm_register_is_dirty(struct kvm_vcpu *vcpu,
+                                        enum kvm_reg reg)
+{
+       return test_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
+}
+
+static inline void kvm_register_mark_available(struct kvm_vcpu *vcpu,
+                                              enum kvm_reg reg)
+{
+       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
+}
+
+static inline void kvm_register_mark_dirty(struct kvm_vcpu *vcpu,
+                                          enum kvm_reg reg)
+{
+       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
+       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
+}
+
 static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg)
 {
        if (WARN_ON_ONCE((unsigned int)reg >= NR_VCPU_REGS))
index 581925e476d6c57ccc7af45f61761b55e8686c8e..261be1d2032ba8ca9d8a73b81beec3b9bf50f7ca 100644 (file)
 #define PT32_ROOT_LEVEL 2
 #define PT32E_ROOT_LEVEL 3
 
-static inline u64 rsvd_bits(int s, int e)
+static __always_inline u64 rsvd_bits(int s, int e)
 {
+       BUILD_BUG_ON(__builtin_constant_p(e) && __builtin_constant_p(s) && e < s);
+
+       if (__builtin_constant_p(e))
+               BUILD_BUG_ON(e > 63);
+       else
+               e &= 63;
+
        if (e < s)
                return 0;
 
index 2ef8615f9dba87bca72d4912df6e4cd9394def56..b56d604809b8afdf2d7080e4cf471ed649e675d7 100644 (file)
@@ -1049,8 +1049,8 @@ bool kvm_tdp_mmu_slot_set_dirty(struct kvm *kvm, struct kvm_memory_slot *slot)
 }
 
 /*
- * Clear non-leaf entries (and free associated page tables) which could
- * be replaced by large mappings, for GFNs within the slot.
+ * Clear leaf entries which could be replaced by large mappings, for
+ * GFNs within the slot.
  */
 static void zap_collapsible_spte_range(struct kvm *kvm,
                                       struct kvm_mmu_page *root,
@@ -1062,7 +1062,7 @@ static void zap_collapsible_spte_range(struct kvm *kvm,
 
        tdp_root_for_each_pte(iter, root, start, end) {
                if (!is_shadow_present_pte(iter.old_spte) ||
-                   is_last_spte(iter.old_spte, iter.level))
+                   !is_last_spte(iter.old_spte, iter.level))
                        continue;
 
                pfn = spte_to_pfn(iter.old_spte);
index cb4c6ee10029c96d97460250315516468d187d83..db30670dd8c4a8ccf2ca611f513e056a0480e696 100644 (file)
@@ -200,6 +200,9 @@ static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
+       if (WARN_ON(!is_guest_mode(vcpu)))
+               return true;
+
        if (!nested_svm_vmrun_msrpm(svm)) {
                vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
                vcpu->run->internal.suberror =
@@ -228,6 +231,7 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control)
 
 static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12)
 {
+       struct kvm_vcpu *vcpu = &svm->vcpu;
        bool vmcb12_lma;
 
        if ((vmcb12->save.efer & EFER_SVME) == 0)
@@ -241,18 +245,10 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12)
 
        vmcb12_lma = (vmcb12->save.efer & EFER_LME) && (vmcb12->save.cr0 & X86_CR0_PG);
 
-       if (!vmcb12_lma) {
-               if (vmcb12->save.cr4 & X86_CR4_PAE) {
-                       if (vmcb12->save.cr3 & MSR_CR3_LEGACY_PAE_RESERVED_MASK)
-                               return false;
-               } else {
-                       if (vmcb12->save.cr3 & MSR_CR3_LEGACY_RESERVED_MASK)
-                               return false;
-               }
-       } else {
+       if (vmcb12_lma) {
                if (!(vmcb12->save.cr4 & X86_CR4_PAE) ||
                    !(vmcb12->save.cr0 & X86_CR0_PE) ||
-                   (vmcb12->save.cr3 & MSR_CR3_LONG_MBZ_MASK))
+                   (vmcb12->save.cr3 & vcpu->arch.cr3_lm_rsvd_bits))
                        return false;
        }
        if (!kvm_is_valid_cr4(&svm->vcpu, vmcb12->save.cr4))
index c8ffdbc81709ee75f88824b26c1dda9d7d165dc6..48017fef1cd9ccd0fff5c207031da4f6bf12588f 100644 (file)
@@ -342,6 +342,8 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
        unsigned long first, last;
        int ret;
 
+       lockdep_assert_held(&kvm->lock);
+
        if (ulen == 0 || uaddr + ulen < uaddr)
                return ERR_PTR(-EINVAL);
 
@@ -1119,12 +1121,20 @@ int svm_register_enc_region(struct kvm *kvm,
        if (!region)
                return -ENOMEM;
 
+       mutex_lock(&kvm->lock);
        region->pages = sev_pin_memory(kvm, range->addr, range->size, &region->npages, 1);
        if (IS_ERR(region->pages)) {
                ret = PTR_ERR(region->pages);
+               mutex_unlock(&kvm->lock);
                goto e_free;
        }
 
+       region->uaddr = range->addr;
+       region->size = range->size;
+
+       list_add_tail(&region->list, &sev->regions_list);
+       mutex_unlock(&kvm->lock);
+
        /*
         * The guest may change the memory encryption attribute from C=0 -> C=1
         * or vice versa for this memory range. Lets make sure caches are
@@ -1133,13 +1143,6 @@ int svm_register_enc_region(struct kvm *kvm,
         */
        sev_clflush_pages(region->pages, region->npages);
 
-       region->uaddr = range->addr;
-       region->size = range->size;
-
-       mutex_lock(&kvm->lock);
-       list_add_tail(&region->list, &sev->regions_list);
-       mutex_unlock(&kvm->lock);
-
        return ret;
 
 e_free:
@@ -1415,16 +1418,13 @@ static void sev_es_sync_to_ghcb(struct vcpu_svm *svm)
         * to be returned:
         *   GPRs RAX, RBX, RCX, RDX
         *
-        * Copy their values to the GHCB if they are dirty.
+        * Copy their values, even if they may not have been written during the
+        * VM-Exit.  It's the guest's responsibility to not consume random data.
         */
-       if (kvm_register_is_dirty(vcpu, VCPU_REGS_RAX))
-               ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]);
-       if (kvm_register_is_dirty(vcpu, VCPU_REGS_RBX))
-               ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]);
-       if (kvm_register_is_dirty(vcpu, VCPU_REGS_RCX))
-               ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]);
-       if (kvm_register_is_dirty(vcpu, VCPU_REGS_RDX))
-               ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]);
+       ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]);
+       ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]);
+       ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]);
+       ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]);
 }
 
 static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
index 7ef171790d02b669ffaa677cf0519972774ea384..3442d44ca53b854ca978185a351ef078d416ce80 100644 (file)
@@ -454,6 +454,11 @@ static int has_svm(void)
                return 0;
        }
 
+       if (sev_active()) {
+               pr_info("KVM is unsupported when running as an SEV guest\n");
+               return 0;
+       }
+
        return 1;
 }
 
@@ -3739,6 +3744,8 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
+       trace_kvm_entry(vcpu);
+
        svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX];
        svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP];
        svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP];
index 0fe874ae54982e146ee4ffda756ac80470d73bcb..6e7d070f8b86d17b89e941b175e2d944f9f5978a 100644 (file)
@@ -403,9 +403,6 @@ static inline bool gif_set(struct vcpu_svm *svm)
 }
 
 /* svm.c */
-#define MSR_CR3_LEGACY_RESERVED_MASK           0xfe7U
-#define MSR_CR3_LEGACY_PAE_RESERVED_MASK       0x7U
-#define MSR_CR3_LONG_MBZ_MASK                  0xfff0000000000000U
 #define MSR_INVALID                            0xffffffffU
 
 extern int sev;
index 0fbb46990dfce110aa23e62a84c343b4c408eabc..f2b9bfb5820677aa2a55e0db895c2936e1383fdc 100644 (file)
@@ -3124,13 +3124,9 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
        return 0;
 }
 
-static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
+static bool nested_get_evmcs_page(struct kvm_vcpu *vcpu)
 {
-       struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
        struct vcpu_vmx *vmx = to_vmx(vcpu);
-       struct kvm_host_map *map;
-       struct page *page;
-       u64 hpa;
 
        /*
         * hv_evmcs may end up being not mapped after migration (when
@@ -3153,6 +3149,17 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
                }
        }
 
+       return true;
+}
+
+static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
+{
+       struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+       struct kvm_host_map *map;
+       struct page *page;
+       u64 hpa;
+
        if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
                /*
                 * Translate L1 physical address to host physical
@@ -3221,6 +3228,18 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
                exec_controls_setbit(vmx, CPU_BASED_USE_MSR_BITMAPS);
        else
                exec_controls_clearbit(vmx, CPU_BASED_USE_MSR_BITMAPS);
+
+       return true;
+}
+
+static bool vmx_get_nested_state_pages(struct kvm_vcpu *vcpu)
+{
+       if (!nested_get_evmcs_page(vcpu))
+               return false;
+
+       if (is_guest_mode(vcpu) && !nested_get_vmcs12_pages(vcpu))
+               return false;
+
        return true;
 }
 
@@ -6077,11 +6096,14 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu,
        if (is_guest_mode(vcpu)) {
                sync_vmcs02_to_vmcs12(vcpu, vmcs12);
                sync_vmcs02_to_vmcs12_rare(vcpu, vmcs12);
-       } else if (!vmx->nested.need_vmcs12_to_shadow_sync) {
-               if (vmx->nested.hv_evmcs)
-                       copy_enlightened_to_vmcs12(vmx);
-               else if (enable_shadow_vmcs)
-                       copy_shadow_to_vmcs12(vmx);
+       } else  {
+               copy_vmcs02_to_vmcs12_rare(vcpu, get_vmcs12(vcpu));
+               if (!vmx->nested.need_vmcs12_to_shadow_sync) {
+                       if (vmx->nested.hv_evmcs)
+                               copy_enlightened_to_vmcs12(vmx);
+                       else if (enable_shadow_vmcs)
+                               copy_shadow_to_vmcs12(vmx);
+               }
        }
 
        BUILD_BUG_ON(sizeof(user_vmx_nested_state->vmcs12) < VMCS12_SIZE);
@@ -6602,7 +6624,7 @@ struct kvm_x86_nested_ops vmx_nested_ops = {
        .hv_timer_pending = nested_vmx_preemption_timer_pending,
        .get_state = vmx_get_nested_state,
        .set_state = vmx_set_nested_state,
-       .get_nested_state_pages = nested_get_vmcs12_pages,
+       .get_nested_state_pages = vmx_get_nested_state_pages,
        .write_log_dirty = nested_vmx_write_pml_buffer,
        .enable_evmcs = nested_enable_evmcs,
        .get_evmcs_version = nested_get_evmcs_version,
index a886a47daebdadffa556e44e8e9dd6848abbe733..cdf5f34518f43b4c2e46bf123a489cf6cf002461 100644 (file)
@@ -29,7 +29,7 @@ static struct kvm_event_hw_type_mapping intel_arch_events[] = {
        [4] = { 0x2e, 0x41, PERF_COUNT_HW_CACHE_MISSES },
        [5] = { 0xc4, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
        [6] = { 0xc5, 0x00, PERF_COUNT_HW_BRANCH_MISSES },
-       [7] = { 0x00, 0x30, PERF_COUNT_HW_REF_CPU_CYCLES },
+       [7] = { 0x00, 0x03, PERF_COUNT_HW_REF_CPU_CYCLES },
 };
 
 /* mapping between fixed pmc index and intel_arch_events array */
@@ -345,7 +345,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 
        pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters,
                                         x86_pmu.num_counters_gp);
+       eax.split.bit_width = min_t(int, eax.split.bit_width, x86_pmu.bit_width_gp);
        pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1;
+       eax.split.mask_length = min_t(int, eax.split.mask_length, x86_pmu.events_mask_len);
        pmu->available_event_types = ~entry->ebx &
                                        ((1ull << eax.split.mask_length) - 1);
 
@@ -355,6 +357,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
                pmu->nr_arch_fixed_counters =
                        min_t(int, edx.split.num_counters_fixed,
                              x86_pmu.num_counters_fixed);
+               edx.split.bit_width_fixed = min_t(int,
+                       edx.split.bit_width_fixed, x86_pmu.bit_width_fixed);
                pmu->counter_bitmask[KVM_PMC_FIXED] =
                        ((u64)1 << edx.split.bit_width_fixed) - 1;
        }
index 2af05d3b0590985ce22ee26e6a83b0848b6043ef..eb69fef57485d61b846ba321ef9a34ec056617f8 100644 (file)
@@ -6653,6 +6653,8 @@ reenter_guest:
        if (vmx->emulation_required)
                return EXIT_FASTPATH_NONE;
 
+       trace_kvm_entry(vcpu);
+
        if (vmx->ple_window_dirty) {
                vmx->ple_window_dirty = false;
                vmcs_write32(PLE_WINDOW, vmx->ple_window);
@@ -6858,11 +6860,20 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
                switch (index) {
                case MSR_IA32_TSX_CTRL:
                        /*
-                        * No need to pass TSX_CTRL_CPUID_CLEAR through, so
-                        * let's avoid changing CPUID bits under the host
-                        * kernel's feet.
+                        * TSX_CTRL_CPUID_CLEAR is handled in the CPUID
+                        * interception.  Keep the host value unchanged to avoid
+                        * changing CPUID bits under the host kernel's feet.
+                        *
+                        * hle=0, rtm=0, tsx_ctrl=1 can be found with some
+                        * combinations of new kernel and old userspace.  If
+                        * those guests run on a tsx=off host, do allow guests
+                        * to use TSX_CTRL, but do not change the value on the
+                        * host so that TSX remains always disabled.
                         */
-                       vmx->guest_uret_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR;
+                       if (boot_cpu_has(X86_FEATURE_RTM))
+                               vmx->guest_uret_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR;
+                       else
+                               vmx->guest_uret_msrs[j].mask = 0;
                        break;
                default:
                        vmx->guest_uret_msrs[j].mask = -1ull;
index 9a8969a6dd06362a84ad6989f34d48b51e59ae24..1b404e4d7dd8e0441c436811b42ec1b62a048855 100644 (file)
@@ -105,6 +105,7 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS;
 
 static void update_cr8_intercept(struct kvm_vcpu *vcpu);
 static void process_nmi(struct kvm_vcpu *vcpu);
+static void process_smi(struct kvm_vcpu *vcpu);
 static void enter_smm(struct kvm_vcpu *vcpu);
 static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
 static void store_regs(struct kvm_vcpu *vcpu);
@@ -1393,16 +1394,24 @@ static u64 kvm_get_arch_capabilities(void)
        if (!boot_cpu_has_bug(X86_BUG_MDS))
                data |= ARCH_CAP_MDS_NO;
 
-       /*
-        * On TAA affected systems:
-        *      - nothing to do if TSX is disabled on the host.
-        *      - we emulate TSX_CTRL if present on the host.
-        *        This lets the guest use VERW to clear CPU buffers.
-        */
-       if (!boot_cpu_has(X86_FEATURE_RTM))
-               data &= ~(ARCH_CAP_TAA_NO | ARCH_CAP_TSX_CTRL_MSR);
-       else if (!boot_cpu_has_bug(X86_BUG_TAA))
+       if (!boot_cpu_has(X86_FEATURE_RTM)) {
+               /*
+                * If RTM=0 because the kernel has disabled TSX, the host might
+                * have TAA_NO or TSX_CTRL.  Clear TAA_NO (the guest sees RTM=0
+                * and therefore knows that there cannot be TAA) but keep
+                * TSX_CTRL: some buggy userspaces leave it set on tsx=on hosts,
+                * and we want to allow migrating those guests to tsx=off hosts.
+                */
+               data &= ~ARCH_CAP_TAA_NO;
+       } else if (!boot_cpu_has_bug(X86_BUG_TAA)) {
                data |= ARCH_CAP_TAA_NO;
+       } else {
+               /*
+                * Nothing to do here; we emulate TSX_CTRL if present on the
+                * host so the guest can choose between disabling TSX or
+                * using VERW to clear CPU buffers.
+                */
+       }
 
        return data;
 }
@@ -4230,6 +4239,9 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 {
        process_nmi(vcpu);
 
+       if (kvm_check_request(KVM_REQ_SMI, vcpu))
+               process_smi(vcpu);
+
        /*
         * In guest mode, payload delivery should be deferred,
         * so that the L1 hypervisor can intercept #PF before
@@ -8802,9 +8814,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 
        if (kvm_request_pending(vcpu)) {
                if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) {
-                       if (WARN_ON_ONCE(!is_guest_mode(vcpu)))
-                               ;
-                       else if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) {
+                       if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) {
                                r = 0;
                                goto out;
                        }
@@ -8988,8 +8998,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                kvm_x86_ops.request_immediate_exit(vcpu);
        }
 
-       trace_kvm_entry(vcpu);
-
        fpregs_assert_state_consistent();
        if (test_thread_flag(TIF_NEED_FPU_LOAD))
                switch_fpu_return();
@@ -9616,6 +9624,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
                 */
                if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA))
                        return false;
+               if (sregs->cr3 & vcpu->arch.cr3_lm_rsvd_bits)
+                       return false;
        } else {
                /*
                 * Not in 64-bit mode: EFER.LMA is clear and the code
@@ -9993,6 +10003,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
        fx_init(vcpu);
 
        vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
+       vcpu->arch.cr3_lm_rsvd_bits = rsvd_bits(cpuid_maxphyaddr(vcpu), 63);
 
        vcpu->arch.pat = MSR_IA32_CR_PAT_DEFAULT;
 
@@ -10494,7 +10505,7 @@ void __user * __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
                        return 0;
 
                old_npages = slot->npages;
-               hva = 0;
+               hva = slot->userspace_addr;
        }
 
        for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
@@ -11556,6 +11567,7 @@ int kvm_sev_es_string_io(struct kvm_vcpu *vcpu, unsigned int size,
 }
 EXPORT_SYMBOL_GPL(kvm_sev_es_string_io);
 
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_entry);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
index c5ee0f5ce0f13e236c43cbd4886ef39f3a67c855..0f727b50bd3d2dcabbcf3d661b9b6aefe02e924a 100644 (file)
@@ -425,6 +425,8 @@ bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type);
                __reserved_bits |= X86_CR4_UMIP;        \
        if (!__cpu_has(__c, X86_FEATURE_VMX))           \
                __reserved_bits |= X86_CR4_VMXE;        \
+       if (!__cpu_has(__c, X86_FEATURE_PCID))          \
+               __reserved_bits |= X86_CR4_PCIDE;       \
        __reserved_bits;                                \
 })
 
index c79e5736ab2b7ebf43182e773c9c35457edcf366..c3d5f0236f353cd42159ab487163d5bc511df95b 100644 (file)
@@ -382,6 +382,7 @@ bool sev_active(void)
 {
        return sev_status & MSR_AMD64_SEV_ENABLED;
 }
+EXPORT_SYMBOL_GPL(sev_active);
 
 /* Needs to be called from non-instrumentable code */
 bool noinstr sev_es_active(void)
index 4409306364dc3cd5c774ee190efe83a6079a9cc2..9a5a50cdaab596c08a24a749ab7c6a086933d142 100644 (file)
@@ -583,6 +583,13 @@ DEFINE_IDTENTRY_RAW(xenpv_exc_debug)
                exc_debug(regs);
 }
 
+DEFINE_IDTENTRY_RAW(exc_xen_unknown_trap)
+{
+       /* This should never happen and there is no way to handle it. */
+       pr_err("Unknown trap in Xen PV mode.");
+       BUG();
+}
+
 struct trap_array_entry {
        void (*orig)(void);
        void (*xen)(void);
@@ -631,6 +638,7 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist)
 {
        unsigned int nr;
        bool ist_okay = false;
+       bool found = false;
 
        /*
         * Replace trap handler addresses by Xen specific ones.
@@ -645,6 +653,7 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist)
                if (*addr == entry->orig) {
                        *addr = entry->xen;
                        ist_okay = entry->ist_okay;
+                       found = true;
                        break;
                }
        }
@@ -655,9 +664,13 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist)
                nr = (*addr - (void *)early_idt_handler_array[0]) /
                     EARLY_IDT_HANDLER_SIZE;
                *addr = (void *)xen_early_idt_handler_array[nr];
+               found = true;
        }
 
-       if (WARN_ON(ist != 0 && !ist_okay))
+       if (!found)
+               *addr = (void *)xen_asm_exc_xen_unknown_trap;
+
+       if (WARN_ON(found && ist != 0 && !ist_okay))
                return false;
 
        return true;
index 1cb0e84b91610a33be6978b75c986729848876dc..53cf8aa35032d69948093f97c1f0836a3bc4075c 100644 (file)
@@ -178,6 +178,7 @@ xen_pv_trap asm_exc_simd_coprocessor_error
 #ifdef CONFIG_IA32_EMULATION
 xen_pv_trap entry_INT80_compat
 #endif
+xen_pv_trap asm_exc_xen_unknown_trap
 xen_pv_trap asm_exc_xen_hypervisor_callback
 
        __INIT
index 9e4eb0fc1c16e7fb2ecce1091c499de6a0878912..9e81d1052091fcbc9a71bdf6aa36bcfa50a221f7 100644 (file)
@@ -6332,13 +6332,13 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd,
         * limit 'something'.
         */
        /* no more than 50% of tags for async I/O */
-       bfqd->word_depths[0][0] = max(bt->sb.depth >> 1, 1U);
+       bfqd->word_depths[0][0] = max((1U << bt->sb.shift) >> 1, 1U);
        /*
         * no more than 75% of tags for sync writes (25% extra tags
         * w.r.t. async I/O, to prevent async I/O from starving sync
         * writes)
         */
-       bfqd->word_depths[0][1] = max((bt->sb.depth * 3) >> 2, 1U);
+       bfqd->word_depths[0][1] = max(((1U << bt->sb.shift) * 3) >> 2, 1U);
 
        /*
         * In-word depths in case some bfq_queue is being weight-
@@ -6348,9 +6348,9 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd,
         * shortage.
         */
        /* no more than ~18% of tags for async I/O */
-       bfqd->word_depths[1][0] = max((bt->sb.depth * 3) >> 4, 1U);
+       bfqd->word_depths[1][0] = max(((1U << bt->sb.shift) * 3) >> 4, 1U);
        /* no more than ~37% of tags for sync writes (~20% extra tags) */
-       bfqd->word_depths[1][1] = max((bt->sb.depth * 6) >> 4, 1U);
+       bfqd->word_depths[1][1] = max(((1U << bt->sb.shift) * 6) >> 4, 1U);
 
        for (i = 0; i < 2; i++)
                for (j = 0; j < 2; j++)
index 031114d454a6046c2d336f37a2d615c52ed5fdf1..4221a1539391c8eb1dfaf63e30e22aa2418ba00f 100644 (file)
@@ -1016,6 +1016,8 @@ static void blkcg_css_offline(struct cgroup_subsys_state *css)
  */
 void blkcg_destroy_blkgs(struct blkcg *blkcg)
 {
+       might_sleep();
+
        spin_lock_irq(&blkcg->lock);
 
        while (!hlist_empty(&blkcg->blkg_list)) {
@@ -1023,14 +1025,20 @@ void blkcg_destroy_blkgs(struct blkcg *blkcg)
                                                struct blkcg_gq, blkcg_node);
                struct request_queue *q = blkg->q;
 
-               if (spin_trylock(&q->queue_lock)) {
-                       blkg_destroy(blkg);
-                       spin_unlock(&q->queue_lock);
-               } else {
+               if (need_resched() || !spin_trylock(&q->queue_lock)) {
+                       /*
+                        * Given that the system can accumulate a huge number
+                        * of blkgs in pathological cases, check to see if we
+                        * need to rescheduling to avoid softlockup.
+                        */
                        spin_unlock_irq(&blkcg->lock);
-                       cpu_relax();
+                       cond_resched();
                        spin_lock_irq(&blkcg->lock);
+                       continue;
                }
+
+               blkg_destroy(blkg);
+               spin_unlock(&q->queue_lock);
        }
 
        spin_unlock_irq(&blkcg->lock);
index c1458d9502f1c6566cfa22d4acd268f87457e08f..3616453ca28c8f3be4763b30ccc3acf7f700d127 100644 (file)
@@ -304,7 +304,7 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx,
                struct request_queue *q = hctx->queue;
                struct blk_mq_tag_set *set = q->tag_set;
 
-               if (!test_bit(BLK_MQ_S_TAG_ACTIVE, &q->queue_flags))
+               if (!test_bit(QUEUE_FLAG_HCTX_ACTIVE, &q->queue_flags))
                        return true;
                users = atomic_read(&set->active_queues_shared_sbitmap);
        } else {
index 419548e92d82f6216995293928b1c0e2f63f1d4c..9e741a4f351bed030e9a4804a0f2e0ff8493dd47 100644 (file)
@@ -45,10 +45,11 @@ static void disk_release_events(struct gendisk *disk);
 void set_capacity(struct gendisk *disk, sector_t sectors)
 {
        struct block_device *bdev = disk->part0;
+       unsigned long flags;
 
-       spin_lock(&bdev->bd_size_lock);
+       spin_lock_irqsave(&bdev->bd_size_lock, flags);
        i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT);
-       spin_unlock(&bdev->bd_size_lock);
+       spin_unlock_irqrestore(&bdev->bd_size_lock, flags);
 }
 EXPORT_SYMBOL(set_capacity);
 
index e7d776db803b12f7e784235a20fdc5989cbe6cc6..4601a845cd79edde9f4f86a57dd6fbcfae1eb954 100644 (file)
@@ -88,9 +88,11 @@ static int (*check_part[])(struct parsed_partitions *) = {
 
 static void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors)
 {
-       spin_lock(&bdev->bd_size_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&bdev->bd_size_lock, flags);
        i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT);
-       spin_unlock(&bdev->bd_size_lock);
+       spin_unlock_irqrestore(&bdev->bd_size_lock, flags);
 }
 
 static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
@@ -384,7 +386,7 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
 
        err = blk_alloc_devt(bdev, &devt);
        if (err)
-               goto out_bdput;
+               goto out_put;
        pdev->devt = devt;
 
        /* delay uevent until 'holders' subdir is created */
index d4eac6d7e9fbc5659bc494402212d0d9eedca66e..2494138a6905ed105009894a8eb49ed2ee4ac4e6 100644 (file)
@@ -1107,6 +1107,11 @@ static int nc_dma_get_range(struct device *dev, u64 *size)
 
        ncomp = (struct acpi_iort_named_component *)node->node_data;
 
+       if (!ncomp->memory_address_limit) {
+               pr_warn(FW_BUG "Named component missing memory address limit\n");
+               return -EINVAL;
+       }
+
        *size = ncomp->memory_address_limit >= 64 ? U64_MAX :
                        1ULL<<ncomp->memory_address_limit;
 
@@ -1126,6 +1131,11 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
 
        rc = (struct acpi_iort_root_complex *)node->node_data;
 
+       if (!rc->memory_address_limit) {
+               pr_warn(FW_BUG "Root complex missing memory address limit\n");
+               return -EINVAL;
+       }
+
        *size = rc->memory_address_limit >= 64 ? U64_MAX :
                        1ULL<<rc->memory_address_limit;
 
@@ -1173,8 +1183,8 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
                end = dmaaddr + size - 1;
                mask = DMA_BIT_MASK(ilog2(end) + 1);
                dev->bus_dma_limit = end;
-               dev->coherent_dma_mask = mask;
-               *dev->dma_mask = mask;
+               dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
+               *dev->dma_mask = min(*dev->dma_mask, mask);
        }
 
        *dma_addr = dmaaddr;
index 96869f1538b93a1e6500f62df4b1fb4d41b78684..bfca116482b8bb5d22defaf301cca48384700740 100644 (file)
@@ -251,20 +251,12 @@ int __acpi_device_uevent_modalias(struct acpi_device *adev,
        if (add_uevent_var(env, "MODALIAS="))
                return -ENOMEM;
 
-       len = create_pnp_modalias(adev, &env->buf[env->buflen - 1],
-                                 sizeof(env->buf) - env->buflen);
-       if (len < 0)
-               return len;
-
-       env->buflen += len;
-       if (!adev->data.of_compatible)
-               return 0;
-
-       if (len > 0 && add_uevent_var(env, "MODALIAS="))
-               return -ENOMEM;
-
-       len = create_of_modalias(adev, &env->buf[env->buflen - 1],
-                                sizeof(env->buf) - env->buflen);
+       if (adev->data.of_compatible)
+               len = create_of_modalias(adev, &env->buf[env->buflen - 1],
+                                        sizeof(env->buf) - env->buflen);
+       else
+               len = create_pnp_modalias(adev, &env->buf[env->buflen - 1],
+                                         sizeof(env->buf) - env->buflen);
        if (len < 0)
                return len;
 
index 1db063b02f63eb8d61076b44cfc00fe40b8a5b65..22566b4b3150ada418ed25f377c7b585d58ce50b 100644 (file)
@@ -2123,12 +2123,12 @@ void acpi_walk_dep_device_list(acpi_handle handle)
        list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
                if (dep->supplier == handle) {
                        acpi_bus_get_device(dep->consumer, &adev);
-                       if (!adev)
-                               continue;
 
-                       adev->dep_unmet--;
-                       if (!adev->dep_unmet)
-                               acpi_bus_attach(adev, true);
+                       if (adev) {
+                               adev->dep_unmet--;
+                               if (!adev->dep_unmet)
+                                       acpi_bus_attach(adev, true);
+                       }
 
                        list_del(&dep->node);
                        kfree(dep);
index 12c0ece746f04ac763bf2630185d40fe9ac36fe7..859b1de31ddc0cfdaf04d8f4dc36c4210f6ca2f2 100644 (file)
@@ -174,6 +174,8 @@ struct acpi_thermal {
        struct thermal_zone_device *thermal_zone;
        int kelvin_offset;      /* in millidegrees */
        struct work_struct thermal_check_work;
+       struct mutex thermal_check_lock;
+       refcount_t thermal_check_count;
 };
 
 /* --------------------------------------------------------------------------
@@ -495,14 +497,6 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
        return 0;
 }
 
-static void acpi_thermal_check(void *data)
-{
-       struct acpi_thermal *tz = data;
-
-       thermal_zone_device_update(tz->thermal_zone,
-                                  THERMAL_EVENT_UNSPECIFIED);
-}
-
 /* sys I/F for generic thermal sysfs support */
 
 static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp)
@@ -900,6 +894,12 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
                                  Driver Interface
    -------------------------------------------------------------------------- */
 
+static void acpi_queue_thermal_check(struct acpi_thermal *tz)
+{
+       if (!work_pending(&tz->thermal_check_work))
+               queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
+}
+
 static void acpi_thermal_notify(struct acpi_device *device, u32 event)
 {
        struct acpi_thermal *tz = acpi_driver_data(device);
@@ -910,17 +910,17 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event)
 
        switch (event) {
        case ACPI_THERMAL_NOTIFY_TEMPERATURE:
-               acpi_thermal_check(tz);
+               acpi_queue_thermal_check(tz);
                break;
        case ACPI_THERMAL_NOTIFY_THRESHOLDS:
                acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
-               acpi_thermal_check(tz);
+               acpi_queue_thermal_check(tz);
                acpi_bus_generate_netlink_event(device->pnp.device_class,
                                                  dev_name(&device->dev), event, 0);
                break;
        case ACPI_THERMAL_NOTIFY_DEVICES:
                acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
-               acpi_thermal_check(tz);
+               acpi_queue_thermal_check(tz);
                acpi_bus_generate_netlink_event(device->pnp.device_class,
                                                  dev_name(&device->dev), event, 0);
                break;
@@ -1020,7 +1020,25 @@ static void acpi_thermal_check_fn(struct work_struct *work)
 {
        struct acpi_thermal *tz = container_of(work, struct acpi_thermal,
                                               thermal_check_work);
-       acpi_thermal_check(tz);
+
+       /*
+        * In general, it is not sufficient to check the pending bit, because
+        * subsequent instances of this function may be queued after one of them
+        * has started running (e.g. if _TMP sleeps).  Avoid bailing out if just
+        * one of them is running, though, because it may have done the actual
+        * check some time ago, so allow at least one of them to block on the
+        * mutex while another one is running the update.
+        */
+       if (!refcount_dec_not_one(&tz->thermal_check_count))
+               return;
+
+       mutex_lock(&tz->thermal_check_lock);
+
+       thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED);
+
+       refcount_inc(&tz->thermal_check_count);
+
+       mutex_unlock(&tz->thermal_check_lock);
 }
 
 static int acpi_thermal_add(struct acpi_device *device)
@@ -1052,6 +1070,8 @@ static int acpi_thermal_add(struct acpi_device *device)
        if (result)
                goto free_memory;
 
+       refcount_set(&tz->thermal_check_count, 3);
+       mutex_init(&tz->thermal_check_lock);
        INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn);
 
        pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device),
@@ -1117,7 +1137,7 @@ static int acpi_thermal_resume(struct device *dev)
                tz->state.active |= tz->trips.active[i].flags.enabled;
        }
 
-       queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
+       acpi_queue_thermal_check(tz);
 
        return AE_OK;
 }
index 6727358e147dd8f8d3fb738951276f5881c20a66..e6ea5d344f87b6190e1c5aaf335875bbf7dc45f9 100644 (file)
@@ -1022,6 +1022,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
        if (!sock)
                return err;
 
+       /*
+        * We need to make sure we don't get any errant requests while we're
+        * reallocating the ->socks array.
+        */
+       blk_mq_freeze_queue(nbd->disk->queue);
+
        if (!netlink && !nbd->task_setup &&
            !test_bit(NBD_RT_BOUND, &config->runtime_flags))
                nbd->task_setup = current;
@@ -1060,10 +1066,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
        nsock->cookie = 0;
        socks[config->num_connections++] = nsock;
        atomic_inc(&config->live_connections);
+       blk_mq_unfreeze_queue(nbd->disk->queue);
 
        return 0;
 
 put_socket:
+       blk_mq_unfreeze_queue(nbd->disk->queue);
        sockfd_put(sock);
        return err;
 }
index 148b871f263ba91629b52001786074a96fe13a55..fce0a54df0e5ff4a204e98106451c5b9bc6cfb29 100644 (file)
@@ -6,7 +6,10 @@
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
-#define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT)
+static inline sector_t mb_to_sects(unsigned long mb)
+{
+       return ((sector_t)mb * SZ_1M) >> SECTOR_SHIFT;
+}
 
 static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect)
 {
@@ -77,12 +80,11 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
                return -EINVAL;
        }
 
-       zone_capacity_sects = MB_TO_SECTS(dev->zone_capacity);
-       dev_capacity_sects = MB_TO_SECTS(dev->size);
-       dev->zone_size_sects = MB_TO_SECTS(dev->zone_size);
-       dev->nr_zones = dev_capacity_sects >> ilog2(dev->zone_size_sects);
-       if (dev_capacity_sects & (dev->zone_size_sects - 1))
-               dev->nr_zones++;
+       zone_capacity_sects = mb_to_sects(dev->zone_capacity);
+       dev_capacity_sects = mb_to_sects(dev->size);
+       dev->zone_size_sects = mb_to_sects(dev->zone_size);
+       dev->nr_zones = round_up(dev_capacity_sects, dev->zone_size_sects)
+               >> ilog2(dev->zone_size_sects);
 
        dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct nullb_zone),
                                    GFP_KERNEL | __GFP_ZERO);
index 5265975b3fba5c0c726b7ed5bd5f595cd6bd5145..e1c6798889f48afe9e6fc14a8ef5d93f919d365c 100644 (file)
@@ -945,7 +945,8 @@ static void blkif_set_queue_limits(struct blkfront_info *info)
        if (info->feature_discard) {
                blk_queue_flag_set(QUEUE_FLAG_DISCARD, rq);
                blk_queue_max_discard_sectors(rq, get_capacity(gd));
-               rq->limits.discard_granularity = info->discard_granularity;
+               rq->limits.discard_granularity = info->discard_granularity ?:
+                                                info->physical_sector_size;
                rq->limits.discard_alignment = info->discard_alignment;
                if (info->feature_secdiscard)
                        blk_queue_flag_set(QUEUE_FLAG_SECERASE, rq);
@@ -2179,19 +2180,12 @@ static void blkfront_closing(struct blkfront_info *info)
 
 static void blkfront_setup_discard(struct blkfront_info *info)
 {
-       int err;
-       unsigned int discard_granularity;
-       unsigned int discard_alignment;
-
        info->feature_discard = 1;
-       err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-               "discard-granularity", "%u", &discard_granularity,
-               "discard-alignment", "%u", &discard_alignment,
-               NULL);
-       if (!err) {
-               info->discard_granularity = discard_granularity;
-               info->discard_alignment = discard_alignment;
-       }
+       info->discard_granularity = xenbus_read_unsigned(info->xbdev->otherend,
+                                                        "discard-granularity",
+                                                        0);
+       info->discard_alignment = xenbus_read_unsigned(info->xbdev->otherend,
+                                                      "discard-alignment", 0);
        info->feature_secdiscard =
                !!xenbus_read_unsigned(info->xbdev->otherend, "discard-secure",
                                       0);
index 845b6c43fef897bc1cf562d6f2251c01fb8c9861..2344d560b1449c0f8115dbba82f96ac9ae068aaa 100644 (file)
@@ -54,6 +54,7 @@ static int integrator_lm_populate(int num, struct device *dev)
                        ret = of_platform_default_populate(child, NULL, dev);
                        if (ret) {
                                dev_err(dev, "failed to populate module\n");
+                               of_node_put(child);
                                return ret;
                        }
                }
index c5eb46cbf388b507608f96ed1b55082d42d54981..01a3d0cd08edc7271215e0e61c5a1d5497ac33ac 100644 (file)
@@ -16,6 +16,7 @@
 
 static int simple_pm_bus_probe(struct platform_device *pdev)
 {
+       const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev);
        struct device_node *np = pdev->dev.of_node;
 
        dev_dbg(&pdev->dev, "%s\n", __func__);
@@ -23,7 +24,7 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
 
        if (np)
-               of_platform_populate(np, NULL, NULL, &pdev->dev);
+               of_platform_populate(np, NULL, lookup, &pdev->dev);
 
        return 0;
 }
index 3061896503f300accf3dda9782864e2e19288c84..47d9ec3abd2f7d8a31a5624d3ada4f18268d8418 100644 (file)
@@ -6,8 +6,6 @@ config MXC_CLK
 
 config MXC_CLK_SCU
        tristate
-       depends on ARCH_MXC
-       depends on IMX_SCU && HAVE_ARM_SMCCC
 
 config CLK_IMX1
        def_bool SOC_IMX1
index eea69d498bd273887d04bd6b85cab3ad5c23bf2c..7aa7f4a9564fde8617f9e2fd5819219dfadbc20d 100644 (file)
@@ -392,7 +392,8 @@ static int mmp2_audio_clk_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static int mmp2_audio_clk_suspend(struct device *dev)
 {
        struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
 
@@ -404,7 +405,7 @@ static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev)
        return 0;
 }
 
-static int __maybe_unused mmp2_audio_clk_resume(struct device *dev)
+static int mmp2_audio_clk_resume(struct device *dev)
 {
        struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
 
@@ -415,6 +416,7 @@ static int __maybe_unused mmp2_audio_clk_resume(struct device *dev)
 
        return 0;
 }
+#endif
 
 static const struct dev_pm_ops mmp2_audio_clk_pm_ops = {
        SET_RUNTIME_PM_OPS(mmp2_audio_clk_suspend, mmp2_audio_clk_resume, NULL)
index d82d725ac2319f43e29fa96c37ad9663f1315b3d..b05901b249172221fb464f74272c31042e12f4c2 100644 (file)
@@ -891,21 +891,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
        },
 };
 
-static struct clk_branch gcc_camera_ahb_clk = {
-       .halt_reg = 0xb008,
-       .halt_check = BRANCH_HALT,
-       .hwcg_reg = 0xb008,
-       .hwcg_bit = 1,
-       .clkr = {
-               .enable_reg = 0xb008,
-               .enable_mask = BIT(0),
-               .hw.init = &(struct clk_init_data){
-                       .name = "gcc_camera_ahb_clk",
-                       .ops = &clk_branch2_ops,
-               },
-       },
-};
-
 static struct clk_branch gcc_camera_hf_axi_clk = {
        .halt_reg = 0xb020,
        .halt_check = BRANCH_HALT,
@@ -2317,7 +2302,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = {
        [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
        [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
        [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
-       [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
        [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr,
        [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr,
        [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr,
@@ -2519,11 +2503,12 @@ static int gcc_sc7180_probe(struct platform_device *pdev)
 
        /*
         * Keep the clocks always-ON
-        * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_DISP_AHB_CLK
-        * GCC_GPU_CFG_AHB_CLK
+        * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_CAMERA_AHB_CLK,
+        * GCC_DISP_AHB_CLK, GCC_GPU_CFG_AHB_CLK
         */
        regmap_update_bits(regmap, 0x48004, BIT(0), BIT(0));
        regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0));
        regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0));
        regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0));
 
index 6cb6617b8d88c25cf61cb66ea0560b40b7dbd162..ab594a0f0c4084aeb30931f2956407d921da73c3 100644 (file)
@@ -722,7 +722,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
                .name = "gcc_sdcc2_apps_clk_src",
                .parent_data = gcc_parent_data_4,
                .num_parents = 5,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
@@ -745,7 +745,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = {
                .name = "gcc_sdcc4_apps_clk_src",
                .parent_data = gcc_parent_data_0,
                .num_parents = 3,
-               .ops = &clk_rcg2_ops,
+               .ops = &clk_rcg2_floor_ops,
        },
 };
 
index fabfaaccca8720574134f3531d2ac32270e46983..fa56b45620c7962dc45e3efef9792929e1574f38 100644 (file)
@@ -300,11 +300,11 @@ struct mv_cesa_tdma_desc {
        __le32 byte_cnt;
        union {
                __le32 src;
-               dma_addr_t src_dma;
+               u32 src_dma;
        };
        union {
                __le32 dst;
-               dma_addr_t dst_dma;
+               u32 dst_dma;
        };
        __le32 next_dma;
 
index 34f53d898acb0f9f61c1ff3573d7428be52701df..e1926483ae2fdc910a1cc785ac390c11c2ebd408 100644 (file)
@@ -3,8 +3,9 @@
  * apple-properties.c - EFI device properties on Macs
  * Copyright (C) 2016 Lukas Wunner <lukas@wunner.de>
  *
- * Note, all properties are considered as u8 arrays.
- * To get a value of any of them the caller must use device_property_read_u8_array().
+ * Properties are stored either as:
+ * u8 arrays which can be retrieved with device_property_read_u8_array() or
+ * booleans which can be queried with device_property_present().
  */
 
 #define pr_fmt(fmt) "apple-properties: " fmt
@@ -88,8 +89,12 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header,
 
                entry_data = ptr + key_len + sizeof(val_len);
                entry_len = val_len - sizeof(val_len);
-               entry[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(key, entry_data,
-                                                      entry_len);
+               if (entry_len)
+                       entry[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(key, entry_data,
+                                                              entry_len);
+               else
+                       entry[i] = PROPERTY_ENTRY_BOOL(key);
+
                if (dump_properties) {
                        dev_info(dev, "property: %s\n", key);
                        print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET,
index 1d2e5b85d7ca8458f3d67bac38b964f4f9100ef6..c027d99f2a599ea81f478dfa1c6c8b0ea2a970dd 100644 (file)
@@ -13,6 +13,7 @@ config IMX_DSP
 config IMX_SCU
        bool "IMX SCU Protocol driver"
        depends on IMX_MBOX
+       select SOC_BUS
        help
          The System Controller Firmware (SCFW) is a low-level system function
          which runs on a dedicated Cortex-M core to provide power, clock, and
index 1a7b51163528b5a29bfb9c201459a3c959a21d9a..1631727bf0da1ce90d87b36aa3625cc79d12fab1 100644 (file)
@@ -776,6 +776,8 @@ static void edge_detector_stop(struct line *line)
        cancel_delayed_work_sync(&line->work);
        WRITE_ONCE(line->sw_debounced, 0);
        WRITE_ONCE(line->eflags, 0);
+       if (line->desc)
+               WRITE_ONCE(line->desc->debounce_period_us, 0);
        /* do not change line->level - see comment in debounced_value() */
 }
 
index b78a634cca2401daa86a081403d0304f95c74fff..97eec8d8dbdc42bb8b3100d1c338c5811f264396 100644 (file)
@@ -603,7 +603,11 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
                ret = gdev->id;
                goto err_free_gdev;
        }
-       dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+
+       ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+       if (ret)
+               goto err_free_ida;
+
        device_initialize(&gdev->dev);
        dev_set_drvdata(&gdev->dev, gdev);
        if (gc->parent && gc->parent->driver)
@@ -617,7 +621,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
        gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
        if (!gdev->descs) {
                ret = -ENOMEM;
-               goto err_free_ida;
+               goto err_free_dev_name;
        }
 
        if (gc->ngpio == 0) {
@@ -768,6 +772,8 @@ err_free_label:
        kfree_const(gdev->label);
 err_free_descs:
        kfree(gdev->descs);
+err_free_dev_name:
+       kfree(dev_name(&gdev->dev));
 err_free_ida:
        ida_free(&gpio_ida, gdev->id);
 err_free_gdev:
@@ -2551,7 +2557,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
                struct gpio_chip *gc = desc_array[i]->gdev->chip;
                unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)];
                unsigned long *mask, *bits;
-               int first, j, ret;
+               int first, j;
 
                if (likely(gc->ngpio <= FASTPATH_NGPIO)) {
                        mask = fastpath;
index 2d991da2cead7ed7386f8e7828d7a89d27e56d55..d1ed4f8df2b76d7dd41286b52426dfbde175f33f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/sched/task.h>
 
 #include "amdgpu_object.h"
+#include "amdgpu_gem.h"
 #include "amdgpu_vm.h"
 #include "amdgpu_amdkfd.h"
 #include "amdgpu_dma_buf.h"
@@ -1152,7 +1153,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
        struct sg_table *sg = NULL;
        uint64_t user_addr = 0;
        struct amdgpu_bo *bo;
-       struct amdgpu_bo_param bp;
+       struct drm_gem_object *gobj;
        u32 domain, alloc_domain;
        u64 alloc_flags;
        int ret;
@@ -1220,19 +1221,14 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
        pr_debug("\tcreate BO VA 0x%llx size 0x%llx domain %s\n",
                        va, size, domain_string(alloc_domain));
 
-       memset(&bp, 0, sizeof(bp));
-       bp.size = size;
-       bp.byte_align = 1;
-       bp.domain = alloc_domain;
-       bp.flags = alloc_flags;
-       bp.type = bo_type;
-       bp.resv = NULL;
-       ret = amdgpu_bo_create(adev, &bp, &bo);
+       ret = amdgpu_gem_object_create(adev, size, 1, alloc_domain, alloc_flags,
+                                      bo_type, NULL, &gobj);
        if (ret) {
                pr_debug("Failed to create BO on domain %s. ret %d\n",
-                               domain_string(alloc_domain), ret);
+                        domain_string(alloc_domain), ret);
                goto err_bo_create;
        }
+       bo = gem_to_amdgpu_bo(gobj);
        if (bo_type == ttm_bo_type_sg) {
                bo->tbo.sg = sg;
                bo->tbo.ttm->sg = sg;
index f764803c53a4bb2466485d12e0f7c75099bf0e41..48cb33e5b3826caac252debfc011dc6b2c91c322 100644 (file)
@@ -926,8 +926,10 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
                                       struct drm_file *file_priv,
                                       const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-       struct drm_gem_object *obj;
        struct amdgpu_framebuffer *amdgpu_fb;
+       struct drm_gem_object *obj;
+       struct amdgpu_bo *bo;
+       uint32_t domains;
        int ret;
 
        obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
@@ -938,7 +940,9 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
        }
 
        /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
-       if (obj->import_attach) {
+       bo = gem_to_amdgpu_bo(obj);
+       domains = amdgpu_display_supported_domains(drm_to_adev(dev), bo->flags);
+       if (obj->import_attach && !(domains & AMDGPU_GEM_DOMAIN_GTT)) {
                drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n");
                return ERR_PTR(-EINVAL);
        }
index d0a1fee1f5f6f9761dc0c56ea9d7013329ab946b..174a73eb23f08117528f8a458a68e57d50f89a72 100644 (file)
@@ -269,8 +269,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
                resv = vm->root.base.bo->tbo.base.resv;
        }
 
-retry:
        initial_domain = (u32)(0xffffffff & args->in.domains);
+retry:
        r = amdgpu_gem_object_create(adev, size, args->in.alignment,
                                     initial_domain,
                                     flags, ttm_bo_type_device, resv, &gobj);
index 25ec4d57333f6a9786e98551044e2476cb8fc39f..b4c8e5d5c763cd5416b712e60c3a7ec2a10ed44a 100644 (file)
@@ -897,7 +897,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
                return -EINVAL;
 
        /* A shared bo cannot be migrated to VRAM */
-       if (bo->prime_shared_count) {
+       if (bo->prime_shared_count || bo->tbo.base.import_attach) {
                if (domain & AMDGPU_GEM_DOMAIN_GTT)
                        domain = AMDGPU_GEM_DOMAIN_GTT;
                else
index 346963e3cf7313cf056e9de612e45dfc74873147..d86b42a36560183b4d1ef0bde1a199800bec4285 100644 (file)
 #define mmGCR_GENERAL_CNTL_Sienna_Cichlid                      0x1580
 #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX     0
 
+#define mmCGTS_TCC_DISABLE_Vangogh                0x5006
+#define mmCGTS_TCC_DISABLE_Vangogh_BASE_IDX       1
+#define mmCGTS_USER_TCC_DISABLE_Vangogh                0x5007
+#define mmCGTS_USER_TCC_DISABLE_Vangogh_BASE_IDX       1
 #define mmGOLDEN_TSC_COUNT_UPPER_Vangogh                0x0025
 #define mmGOLDEN_TSC_COUNT_UPPER_Vangogh_BASE_IDX       1
 #define mmGOLDEN_TSC_COUNT_LOWER_Vangogh                0x0026
@@ -4936,8 +4940,18 @@ static void gfx_v10_0_tcp_harvest(struct amdgpu_device *adev)
 static void gfx_v10_0_get_tcc_info(struct amdgpu_device *adev)
 {
        /* TCCs are global (not instanced). */
-       uint32_t tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) |
-                              RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE);
+       uint32_t tcc_disable;
+
+       switch (adev->asic_type) {
+       case CHIP_VANGOGH:
+               tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE_Vangogh) |
+                               RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE_Vangogh);
+               break;
+       default:
+               tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) |
+                               RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE);
+               break;
+       }
 
        adev->gfx.config.tcc_disabled_mask =
                REG_GET_FIELD(tcc_disable, CGTS_TCC_DISABLE, TCC_DISABLE) |
index c6da89df055de87c89ba0ba05ed8739993a1c97b..961abf1cf040cc0372d0d9c74d456684f81cb07d 100644 (file)
@@ -1833,8 +1833,8 @@ static void emulated_link_detect(struct dc_link *link)
        link->type = dc_connection_none;
        prev_sink = link->local_sink;
 
-       if (prev_sink != NULL)
-               dc_sink_retain(prev_sink);
+       if (prev_sink)
+               dc_sink_release(prev_sink);
 
        switch (link->connector_signal) {
        case SIGNAL_TYPE_HDMI_TYPE_A: {
@@ -1934,7 +1934,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
                dc_commit_updates_for_stream(
                        dm->dc, bundle->surface_updates,
                        dc_state->stream_status->plane_count,
-                       dc_state->streams[k], &bundle->stream_update, dc_state);
+                       dc_state->streams[k], &bundle->stream_update);
        }
 
 cleanup:
@@ -1965,8 +1965,7 @@ static void dm_set_dpms_off(struct dc_link *link)
 
        stream_update.stream = stream_state;
        dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0,
-                                    stream_state, &stream_update,
-                                    stream_state->ctx->dc->current_state);
+                                    stream_state, &stream_update);
        mutex_unlock(&adev->dm.dc_lock);
 }
 
@@ -2330,8 +2329,10 @@ void amdgpu_dm_update_connector_after_detect(
                 * TODO: check if we still need the S3 mode update workaround.
                 * If yes, put it here.
                 */
-               if (aconnector->dc_sink)
+               if (aconnector->dc_sink) {
                        amdgpu_dm_update_freesync_caps(connector, NULL);
+                       dc_sink_release(aconnector->dc_sink);
+               }
 
                aconnector->dc_sink = sink;
                dc_sink_retain(aconnector->dc_sink);
@@ -2347,8 +2348,6 @@ void amdgpu_dm_update_connector_after_detect(
 
                        drm_connector_update_edid_property(connector,
                                                           aconnector->edid);
-                       drm_add_edid_modes(connector, aconnector->edid);
-
                        if (aconnector->dc_link->aux_mode)
                                drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
                                                    aconnector->edid);
@@ -7549,7 +7548,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
                                    struct drm_crtc *pcrtc,
                                    bool wait_for_vblank)
 {
-       uint32_t i;
+       int i;
        uint64_t timestamp_ns;
        struct drm_plane *plane;
        struct drm_plane_state *old_plane_state, *new_plane_state;
@@ -7590,7 +7589,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
                amdgpu_dm_commit_cursors(state);
 
        /* update planes when needed */
-       for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+       for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
                struct drm_crtc *crtc = new_plane_state->crtc;
                struct drm_crtc_state *new_crtc_state;
                struct drm_framebuffer *fb = new_plane_state->fb;
@@ -7813,8 +7812,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
                                                     bundle->surface_updates,
                                                     planes_count,
                                                     acrtc_state->stream,
-                                                    &bundle->stream_update,
-                                                    dc_state);
+                                                    &bundle->stream_update);
 
                /**
                 * Enable or disable the interrupts on the backend.
@@ -8150,13 +8148,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
                struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
                struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
                struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
-               struct dc_surface_update dummy_updates[MAX_SURFACES];
+               struct dc_surface_update surface_updates[MAX_SURFACES];
                struct dc_stream_update stream_update;
                struct dc_info_packet hdr_packet;
                struct dc_stream_status *status = NULL;
                bool abm_changed, hdr_changed, scaling_changed;
 
-               memset(&dummy_updates, 0, sizeof(dummy_updates));
+               memset(&surface_updates, 0, sizeof(surface_updates));
                memset(&stream_update, 0, sizeof(stream_update));
 
                if (acrtc) {
@@ -8213,16 +8211,15 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
                 * To fix this, DC should permit updating only stream properties.
                 */
                for (j = 0; j < status->plane_count; j++)
-                       dummy_updates[j].surface = status->plane_states[0];
+                       surface_updates[j].surface = status->plane_states[j];
 
 
                mutex_lock(&dm->dc_lock);
                dc_commit_updates_for_stream(dm->dc,
-                                                    dummy_updates,
+                                               surface_updates,
                                                     status->plane_count,
                                                     dm_new_crtc_state->stream,
-                                                    &stream_update,
-                                                    dc_state);
+                                                    &stream_update);
                mutex_unlock(&dm->dc_lock);
        }
 
@@ -8359,14 +8356,14 @@ static int dm_force_atomic_commit(struct drm_connector *connector)
 
        ret = PTR_ERR_OR_ZERO(conn_state);
        if (ret)
-               goto err;
+               goto out;
 
        /* Attach crtc to drm_atomic_state*/
        crtc_state = drm_atomic_get_crtc_state(state, &disconnected_acrtc->base);
 
        ret = PTR_ERR_OR_ZERO(crtc_state);
        if (ret)
-               goto err;
+               goto out;
 
        /* force a restore */
        crtc_state->mode_changed = true;
@@ -8376,17 +8373,15 @@ static int dm_force_atomic_commit(struct drm_connector *connector)
 
        ret = PTR_ERR_OR_ZERO(plane_state);
        if (ret)
-               goto err;
-
+               goto out;
 
        /* Call commit internally with the state we just constructed */
        ret = drm_atomic_commit(state);
-       if (!ret)
-               return 0;
 
-err:
-       DRM_ERROR("Restoring old state failed with %i\n", ret);
+out:
        drm_atomic_state_put(state);
+       if (ret)
+               DRM_ERROR("Restoring old state failed with %i\n", ret);
 
        return ret;
 }
index 8ab0b9060d2bbabcfc714af6917f4ad9efbc9ae6..f2d8cf34be46e92bbd2c83cf832835389a8936b6 100644 (file)
@@ -833,6 +833,9 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
                if (computed_streams[i])
                        continue;
 
+               if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK)
+                       return false;
+
                mutex_lock(&aconnector->mst_mgr.lock);
                if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link)) {
                        mutex_unlock(&aconnector->mst_mgr.lock);
@@ -850,7 +853,8 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
                stream = dc_state->streams[i];
 
                if (stream->timing.flags.DSC == 1)
-                       dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream);
+                       if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK)
+                               return false;
        }
 
        return true;
index 58eb0d69873a6225698486a1038ed58d085d502f..6cf1a5a2a5ecc0f5dda72f60930325b1df4de9cb 100644 (file)
@@ -2679,8 +2679,7 @@ void dc_commit_updates_for_stream(struct dc *dc,
                struct dc_surface_update *srf_updates,
                int surface_count,
                struct dc_stream_state *stream,
-               struct dc_stream_update *stream_update,
-               struct dc_state *state)
+               struct dc_stream_update *stream_update)
 {
        const struct dc_stream_status *stream_status;
        enum surface_update_type update_type;
@@ -2699,6 +2698,12 @@ void dc_commit_updates_for_stream(struct dc *dc,
 
 
        if (update_type >= UPDATE_TYPE_FULL) {
+               struct dc_plane_state *new_planes[MAX_SURFACES];
+
+               memset(new_planes, 0, sizeof(new_planes));
+
+               for (i = 0; i < surface_count; i++)
+                       new_planes[i] = srf_updates[i].surface;
 
                /* initialize scratch memory for building context */
                context = dc_create_state(dc);
@@ -2707,15 +2712,21 @@ void dc_commit_updates_for_stream(struct dc *dc,
                        return;
                }
 
-               dc_resource_state_copy_construct(state, context);
+               dc_resource_state_copy_construct(
+                               dc->current_state, context);
 
-               for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                       struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
-                       struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+               /*remove old surfaces from context */
+               if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
+                       DC_ERROR("Failed to remove streams for new validate context!\n");
+                       return;
+               }
 
-                       if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
-                               new_pipe->plane_state->force_full_update = true;
+               /* add surface to context */
+               if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
+                       DC_ERROR("Failed to add streams for new validate context!\n");
+                       return;
                }
+
        }
 
 
index f95bade5962429b1c4c352aca4a3f1295d952903..1e4794e2825caf2b23b330255b899ec6c5614a05 100644 (file)
@@ -892,13 +892,13 @@ static uint32_t translate_training_aux_read_interval(uint32_t dpcd_aux_read_inte
 
        switch (dpcd_aux_read_interval) {
        case 0x01:
-               aux_rd_interval_us = 400;
+               aux_rd_interval_us = 4000;
                break;
        case 0x02:
-               aux_rd_interval_us = 4000;
+               aux_rd_interval_us = 8000;
                break;
        case 0x03:
-               aux_rd_interval_us = 8000;
+               aux_rd_interval_us = 12000;
                break;
        case 0x04:
                aux_rd_interval_us = 16000;
index b7910976b81a74ab2ef78bc39fae2fc112e98afd..e243c01b9672eee14e92e384e300d61213c4a601 100644 (file)
@@ -283,8 +283,7 @@ void dc_commit_updates_for_stream(struct dc *dc,
                struct dc_surface_update *srf_updates,
                int surface_count,
                struct dc_stream_state *stream,
-               struct dc_stream_update *stream_update,
-               struct dc_state *state);
+               struct dc_stream_update *stream_update);
 /*
  * Log the current stream state.
  */
index b000b43a820d470bf6e0ee6ae33fd3c4656876bd..6743764289167a06639268284dba98356c883f8f 100644 (file)
@@ -906,6 +906,8 @@ enum dcn20_clk_src_array_id {
        DCN20_CLK_SRC_PLL0,
        DCN20_CLK_SRC_PLL1,
        DCN20_CLK_SRC_PLL2,
+       DCN20_CLK_SRC_PLL3,
+       DCN20_CLK_SRC_PLL4,
        DCN20_CLK_SRC_TOTAL_DCN21
 };
 
@@ -2030,6 +2032,14 @@ static bool dcn21_resource_construct(
                        dcn21_clock_source_create(ctx, ctx->dc_bios,
                                CLOCK_SOURCE_COMBO_PHY_PLL2,
                                &clk_src_regs[2], false);
+       pool->base.clock_sources[DCN20_CLK_SRC_PLL3] =
+                       dcn21_clock_source_create(ctx, ctx->dc_bios,
+                               CLOCK_SOURCE_COMBO_PHY_PLL3,
+                               &clk_src_regs[3], false);
+       pool->base.clock_sources[DCN20_CLK_SRC_PLL4] =
+                       dcn21_clock_source_create(ctx, ctx->dc_bios,
+                               CLOCK_SOURCE_COMBO_PHY_PLL4,
+                               &clk_src_regs[4], false);
 
        pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21;
 
index c20331eb62e01e6f66cc9e1eeda2c6022c3b807f..dfd77b3cc84d8c36f88fa218a8a6b9a2c8c50078 100644 (file)
@@ -32,8 +32,8 @@ DCN30 = dcn30_init.o dcn30_hubbub.o dcn30_hubp.o dcn30_dpp.o dcn30_optc.o \
 
 
 ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -mhard-float -msse
-CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -mhard-float -msse
+CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o := -msse
+CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o := -msse
 endif
 
 ifdef CONFIG_PPC64
@@ -45,6 +45,8 @@ ifdef CONFIG_CC_IS_GCC
 ifeq ($(call cc-ifversion, -lt, 0701, y), y)
 IS_OLD_GCC = 1
 endif
+CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -mhard-float
+CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -mhard-float
 endif
 
 ifdef CONFIG_X86
index 3ca7d911d25c440c5b8862660b25a0749355c718..09264716d1dc9d06da1060de0494c1af16b29597 100644 (file)
@@ -14,7 +14,7 @@ DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \
                dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o
 
 ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -msse
+CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -msse
 endif
 
 ifdef CONFIG_PPC64
@@ -25,6 +25,7 @@ ifdef CONFIG_CC_IS_GCC
 ifeq ($(call cc-ifversion, -lt, 0701, y), y)
 IS_OLD_GCC = 1
 endif
+CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mhard-float
 endif
 
 ifdef CONFIG_X86
index 8d4924b7dc2216312f5b82be65b4133e705df30a..101620a8867aa9796742e32cb1f50d61812478b7 100644 (file)
@@ -13,7 +13,7 @@
 DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o
 
 ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -mhard-float -msse
+CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o := -msse
 endif
 
 ifdef CONFIG_PPC64
@@ -24,6 +24,7 @@ ifdef CONFIG_CC_IS_GCC
 ifeq ($(call cc-ifversion, -lt, 0701, y), y)
 IS_OLD_GCC = 1
 endif
+CFLAGS_$(AMDDALPATH)/dc/dcn302/dcn302_resource.o += -mhard-float
 endif
 
 ifdef CONFIG_X86
index 4bdbcce7092d17c67523d943a71f2915860e7605..0d797fa9f5cc69dd37314151d48d955a89e1e7d9 100644 (file)
@@ -553,6 +553,7 @@ struct pptable_funcs {
                                             *clock_req);
        uint32_t (*get_fan_control_mode)(struct smu_context *smu);
        int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode);
+       int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed);
        int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed);
        int (*set_xgmi_pstate)(struct smu_context *smu, uint32_t pstate);
        int (*gfx_off_control)(struct smu_context *smu, bool enable);
index 13de692a421363ef33b589add8f5678bbeca29f8..5d0b29653ffa13ccf8b4ae265b69512331a5dc27 100644 (file)
@@ -203,6 +203,9 @@ int
 smu_v11_0_set_fan_control_mode(struct smu_context *smu,
                               uint32_t mode);
 
+int
+smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed);
+
 int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
                                       uint32_t speed);
 
index 8b867a6d52b57f0f6e3b9aa1f136494f82ac81d5..e84c737e39673b35b429f85ea7076d320ebc1597 100644 (file)
@@ -2151,19 +2151,14 @@ int smu_get_fan_speed_percent(struct smu_context *smu, uint32_t *speed)
 int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
 {
        int ret = 0;
-       uint32_t rpm;
 
        if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
                return -EOPNOTSUPP;
 
        mutex_lock(&smu->mutex);
 
-       if (smu->ppt_funcs->set_fan_speed_rpm) {
-               if (speed > 100)
-                       speed = 100;
-               rpm = speed * smu->fan_max_rpm / 100;
-               ret = smu->ppt_funcs->set_fan_speed_rpm(smu, rpm);
-       }
+       if (smu->ppt_funcs->set_fan_speed_percent)
+               ret = smu->ppt_funcs->set_fan_speed_percent(smu, speed);
 
        mutex_unlock(&smu->mutex);
 
index cd7b411457ffac308882acf71fa7ba045e82eb2d..16db0b506b0de0a6ee3be4a80f385e861169e8c5 100644 (file)
@@ -2326,6 +2326,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
        .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
        .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
        .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
+       .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
        .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
        .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
        .gfx_off_control = smu_v11_0_gfx_off_control,
index 51e83123f72a1057bffb54f98fa8dfeed294a405..cd7efa923195e3fa2a94414adf096fbfc1eccd0b 100644 (file)
@@ -2456,6 +2456,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
        .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
        .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
        .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
+       .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
        .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
        .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
        .gfx_off_control = smu_v11_0_gfx_off_control,
index 12b36eb0ff6a52b09d5d05349adf21c8d80d3607..d68d3dfee51d47c0c92c364c4495c332c7e37439 100644 (file)
@@ -2802,6 +2802,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
        .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
        .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
        .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
+       .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
        .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
        .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
        .gfx_off_control = smu_v11_0_gfx_off_control,
index b279dbbbce6ba408a3250eb513ce5e942be814af..5aeb5f5a04478a04f75dc94bfcee685a672c3ee5 100644 (file)
@@ -1173,6 +1173,35 @@ smu_v11_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode)
        return 0;
 }
 
+int
+smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
+{
+       struct amdgpu_device *adev = smu->adev;
+       uint32_t duty100, duty;
+       uint64_t tmp64;
+
+       if (speed > 100)
+               speed = 100;
+
+       if (smu_v11_0_auto_fan_control(smu, 0))
+               return -EINVAL;
+
+       duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
+                               CG_FDO_CTRL1, FMAX_DUTY100);
+       if (!duty100)
+               return -EINVAL;
+
+       tmp64 = (uint64_t)speed * duty100;
+       do_div(tmp64, 100);
+       duty = (uint32_t)tmp64;
+
+       WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,
+                    REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),
+                                  CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));
+
+       return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC);
+}
+
 int
 smu_v11_0_set_fan_control_mode(struct smu_context *smu,
                               uint32_t mode)
@@ -1181,7 +1210,7 @@ smu_v11_0_set_fan_control_mode(struct smu_context *smu,
 
        switch (mode) {
        case AMD_FAN_CTRL_NONE:
-               ret = smu_v11_0_set_fan_speed_rpm(smu, smu->fan_max_rpm);
+               ret = smu_v11_0_set_fan_speed_percent(smu, 100);
                break;
        case AMD_FAN_CTRL_MANUAL:
                ret = smu_v11_0_auto_fan_control(smu, 0);
index 5c1482d4ca43e3af916596de68571092c25ea276..92ad2cdbae107c18aef29ac906e3ea4a14e08ba4 100644 (file)
@@ -591,14 +591,17 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu,
        gpu_metrics->average_socket_power = metrics.CurrentSocketPower;
        gpu_metrics->average_cpu_power = metrics.Power[0];
        gpu_metrics->average_soc_power = metrics.Power[1];
+       gpu_metrics->average_gfx_power = metrics.Power[2];
        memcpy(&gpu_metrics->average_core_power[0],
                &metrics.CorePower[0],
                sizeof(uint16_t) * 8);
 
        gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency;
        gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency;
+       gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency;
        gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency;
        gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
+       gpu_metrics->average_dclk_frequency = metrics.DclkFrequency;
 
        memcpy(&gpu_metrics->current_coreclk[0],
                &metrics.CoreFrequency[0],
index 0c98d27f84ac7da2b4b23b557e7e28c24377e70a..fee27952ec6d1f01c2d48b7b8a8694bd451f8805 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <sound/hdmi-codec.h>
 
@@ -36,6 +37,7 @@ struct lt9611uxc {
        struct mutex ocm_lock;
 
        struct wait_queue_head wq;
+       struct work_struct work;
 
        struct device_node *dsi0_node;
        struct device_node *dsi1_node;
@@ -52,6 +54,8 @@ struct lt9611uxc {
 
        bool hpd_supported;
        bool edid_read;
+       /* can be accessed from different threads, so protect this with ocm_lock */
+       bool hdmi_connected;
        uint8_t fw_version;
 };
 
@@ -143,21 +147,41 @@ static irqreturn_t lt9611uxc_irq_thread_handler(int irq, void *dev_id)
        if (irq_status)
                regmap_write(lt9611uxc->regmap, 0xb022, 0);
 
-       lt9611uxc_unlock(lt9611uxc);
-
-       if (irq_status & BIT(0))
+       if (irq_status & BIT(0)) {
                lt9611uxc->edid_read = !!(hpd_status & BIT(0));
+               wake_up_all(&lt9611uxc->wq);
+       }
 
        if (irq_status & BIT(1)) {
-               if (lt9611uxc->connector.dev)
-                       drm_kms_helper_hotplug_event(lt9611uxc->connector.dev);
-               else
-                       drm_bridge_hpd_notify(&lt9611uxc->bridge, !!(hpd_status & BIT(1)));
+               lt9611uxc->hdmi_connected = hpd_status & BIT(1);
+               schedule_work(&lt9611uxc->work);
        }
 
+       lt9611uxc_unlock(lt9611uxc);
+
        return IRQ_HANDLED;
 }
 
+static void lt9611uxc_hpd_work(struct work_struct *work)
+{
+       struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work);
+       bool connected;
+
+       if (lt9611uxc->connector.dev)
+               drm_kms_helper_hotplug_event(lt9611uxc->connector.dev);
+       else {
+
+               mutex_lock(&lt9611uxc->ocm_lock);
+               connected = lt9611uxc->hdmi_connected;
+               mutex_unlock(&lt9611uxc->ocm_lock);
+
+               drm_bridge_hpd_notify(&lt9611uxc->bridge,
+                                     connected ?
+                                     connector_status_connected :
+                                     connector_status_disconnected);
+       }
+}
+
 static void lt9611uxc_reset(struct lt9611uxc *lt9611uxc)
 {
        gpiod_set_value_cansleep(lt9611uxc->reset_gpio, 1);
@@ -445,18 +469,21 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid
        struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
        unsigned int reg_val = 0;
        int ret;
-       int connected = 1;
+       bool connected = true;
+
+       lt9611uxc_lock(lt9611uxc);
 
        if (lt9611uxc->hpd_supported) {
-               lt9611uxc_lock(lt9611uxc);
                ret = regmap_read(lt9611uxc->regmap, 0xb023, &reg_val);
-               lt9611uxc_unlock(lt9611uxc);
 
                if (ret)
                        dev_err(lt9611uxc->dev, "failed to read hpd status: %d\n", ret);
                else
                        connected  = reg_val & BIT(1);
        }
+       lt9611uxc->hdmi_connected = connected;
+
+       lt9611uxc_unlock(lt9611uxc);
 
        return connected ?  connector_status_connected :
                                connector_status_disconnected;
@@ -465,7 +492,7 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid
 static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc)
 {
        return wait_event_interruptible_timeout(lt9611uxc->wq, lt9611uxc->edid_read,
-                       msecs_to_jiffies(100));
+                       msecs_to_jiffies(500));
 }
 
 static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
@@ -503,7 +530,10 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge,
        ret = lt9611uxc_wait_for_edid(lt9611uxc);
        if (ret < 0) {
                dev_err(lt9611uxc->dev, "wait for EDID failed: %d\n", ret);
-               return ERR_PTR(ret);
+               return NULL;
+       } else if (ret == 0) {
+               dev_err(lt9611uxc->dev, "wait for EDID timeout\n");
+               return NULL;
        }
 
        return drm_do_get_edid(connector, lt9611uxc_get_edid_block, lt9611uxc);
@@ -926,6 +956,8 @@ retry:
        lt9611uxc->fw_version = ret;
 
        init_waitqueue_head(&lt9611uxc->wq);
+       INIT_WORK(&lt9611uxc->work, lt9611uxc_hpd_work);
+
        ret = devm_request_threaded_irq(dev, client->irq, NULL,
                                        lt9611uxc_irq_thread_handler,
                                        IRQF_ONESHOT, "lt9611uxc", lt9611uxc);
@@ -962,6 +994,7 @@ static int lt9611uxc_remove(struct i2c_client *client)
        struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client);
 
        disable_irq(client->irq);
+       flush_scheduled_work();
        lt9611uxc_audio_exit(lt9611uxc);
        drm_bridge_remove(&lt9611uxc->bridge);
 
index 0401b2f47500274ad73f337298624988167aefd3..8781deefeae3e69642930fb2013b61fea149cafd 100644 (file)
@@ -3629,14 +3629,26 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr,
        return 0;
 }
 
-static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8  dp_link_count)
+/**
+ * drm_dp_get_vc_payload_bw - get the VC payload BW for an MST link
+ * @link_rate: link rate in 10kbits/s units
+ * @link_lane_count: lane count
+ *
+ * Calculate the total bandwidth of a MultiStream Transport link. The returned
+ * value is in units of PBNs/(timeslots/1 MTP). This value can be used to
+ * convert the number of PBNs required for a given stream to the number of
+ * timeslots this stream requires in each MTP.
+ */
+int drm_dp_get_vc_payload_bw(int link_rate, int link_lane_count)
 {
-       if (dp_link_bw == 0 || dp_link_count == 0)
-               DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n",
-                             dp_link_bw, dp_link_count);
+       if (link_rate == 0 || link_lane_count == 0)
+               DRM_DEBUG_KMS("invalid link rate/lane count: (%d / %d)\n",
+                             link_rate, link_lane_count);
 
-       return dp_link_bw * dp_link_count / 2;
+       /* See DP v2.0 2.6.4.2, VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */
+       return link_rate * link_lane_count / 54000;
 }
+EXPORT_SYMBOL(drm_dp_get_vc_payload_bw);
 
 /**
  * drm_dp_read_mst_cap() - check whether or not a sink supports MST
@@ -3692,7 +3704,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
                        goto out_unlock;
                }
 
-               mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr->dpcd[1],
+               mgr->pbn_div = drm_dp_get_vc_payload_bw(drm_dp_bw_code_to_link_rate(mgr->dpcd[1]),
                                                        mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK);
                if (mgr->pbn_div == 0) {
                        ret = -EINVAL;
index d5ace48b1acee3f0283feaf817ccdcee2fa30f32..dc13d1814d95d6c2074709754df8f71ee463655f 100644 (file)
@@ -2754,13 +2754,15 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
        int n_entries, ln;
        u32 val;
 
+       if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT)
+               return;
+
        ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
-       /* The table does not have values for level 3 and level 9. */
-       if (level >= n_entries || level == 3 || level == 9) {
+       if (level >= n_entries) {
                drm_dbg_kms(&dev_priv->drm,
                            "DDI translation not found for level %d. Using %d instead.",
-                           level, n_entries - 2);
-               level = n_entries - 2;
+                           level, n_entries - 1);
+               level = n_entries - 1;
        }
 
        /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */
@@ -2891,6 +2893,9 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
        u32 val, dpcnt_mask, dpcnt_val;
        int n_entries, ln;
 
+       if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT)
+               return;
+
        ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
 
        if (level >= n_entries)
@@ -3532,6 +3537,23 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
        intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 }
 
+static void intel_ddi_power_up_lanes(struct intel_encoder *encoder,
+                                    const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+       enum phy phy = intel_port_to_phy(i915, encoder->port);
+
+       if (intel_phy_is_combo(i915, phy)) {
+               bool lane_reversal =
+                       dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
+
+               intel_combo_phy_power_up_lanes(i915, phy, false,
+                                              crtc_state->lane_count,
+                                              lane_reversal);
+       }
+}
+
 static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
                                  struct intel_encoder *encoder,
                                  const struct intel_crtc_state *crtc_state,
@@ -3621,14 +3643,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
         * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
         * the used lanes of the DDI.
         */
-       if (intel_phy_is_combo(dev_priv, phy)) {
-               bool lane_reversal =
-                       dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
-
-               intel_combo_phy_power_up_lanes(dev_priv, phy, false,
-                                              crtc_state->lane_count,
-                                              lane_reversal);
-       }
+       intel_ddi_power_up_lanes(encoder, crtc_state);
 
        /*
         * 7.g Configure and enable DDI_BUF_CTL
@@ -3713,14 +3728,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
        else
                intel_prepare_dp_ddi_buffers(encoder, crtc_state);
 
-       if (intel_phy_is_combo(dev_priv, phy)) {
-               bool lane_reversal =
-                       dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
-
-               intel_combo_phy_power_up_lanes(dev_priv, phy, false,
-                                              crtc_state->lane_count,
-                                              lane_reversal);
-       }
+       intel_ddi_power_up_lanes(encoder, crtc_state);
 
        intel_ddi_init_dp_buf_reg(encoder, crtc_state);
        if (!is_mst)
@@ -4206,6 +4214,8 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
                intel_de_write(dev_priv, reg, val);
        }
 
+       intel_ddi_power_up_lanes(encoder, crtc_state);
+
        /* In HDMI/DVI mode, the port width, and swing/emphasis values
         * are ignored so nothing special needs to be done besides
         * enabling the port.
index 53a00cf3fa325ef280f649bed2bbd98b3aae20bc..61be6bed916291d614245b10a8cbe1299ff7eda1 100644 (file)
@@ -2309,7 +2309,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
                 */
                ret = i915_vma_pin_fence(vma);
                if (ret != 0 && INTEL_GEN(dev_priv) < 4) {
-                       i915_gem_object_unpin_from_display_plane(vma);
+                       i915_vma_unpin(vma);
                        vma = ERR_PTR(ret);
                        goto err;
                }
@@ -2327,12 +2327,9 @@ err:
 
 void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
 {
-       i915_gem_object_lock(vma->obj, NULL);
        if (flags & PLANE_HAS_FENCE)
                i915_vma_unpin_fence(vma);
-       i915_gem_object_unpin_from_display_plane(vma);
-       i915_gem_object_unlock(vma->obj);
-
+       i915_vma_unpin(vma);
        i915_vma_put(vma);
 }
 
@@ -4807,6 +4804,8 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
                        plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
        } else if (fb->format->is_yuv) {
                plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
+               if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
+                       plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
        }
 
        return plane_color_ctl;
index 09123e8625c498f8f01fcb27ebd29563813d5461..8a26307c48960110b678af7075db41ad3e65de6f 100644 (file)
@@ -4637,24 +4637,6 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp,
        intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
-void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
-                               const struct intel_crtc_state *crtc_state)
-{
-       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-       u8 train_set = intel_dp->train_set[0];
-
-       drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s\n",
-                   train_set & DP_TRAIN_VOLTAGE_SWING_MASK,
-                   train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : "");
-       drm_dbg_kms(&dev_priv->drm, "Using pre-emphasis level %d%s\n",
-                   (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
-                   DP_TRAIN_PRE_EMPHASIS_SHIFT,
-                   train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
-                   " (max)" : "");
-
-       intel_dp->set_signal_levels(intel_dp, crtc_state);
-}
-
 void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
                                       const struct intel_crtc_state *crtc_state,
@@ -5703,7 +5685,7 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
 
        intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state);
 
-       intel_dp_set_signal_levels(intel_dp, crtc_state);
+       intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX);
 
        intel_dp_phy_pattern_update(intel_dp, crtc_state);
 
index 05f7ddf7a79527620b9cc2db5e6e1ee570fcb539..6620f9efdcbbaebb525ee3425bfc58ce08fd7a91 100644 (file)
@@ -96,9 +96,6 @@ void
 intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
                                       const struct intel_crtc_state *crtc_state,
                                       u8 dp_train_pat);
-void
-intel_dp_set_signal_levels(struct intel_dp *intel_dp,
-                          const struct intel_crtc_state *crtc_state);
 void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
                           u8 *link_bw, u8 *rate_select);
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
index 91d3979902d03cb891474ad587a79c760118797c..d8c6d7054d11d929ff8d4170b10b96dcd2c6dcda 100644 (file)
@@ -334,6 +334,27 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
        return drm_dp_dpcd_write(&intel_dp->aux, reg, buf, len) == len;
 }
 
+void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
+                               const struct intel_crtc_state *crtc_state,
+                               enum drm_dp_phy dp_phy)
+{
+       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+       u8 train_set = intel_dp->train_set[0];
+       char phy_name[10];
+
+       drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s, pre-emphasis level %d%s, at %s\n",
+                   train_set & DP_TRAIN_VOLTAGE_SWING_MASK,
+                   train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : "",
+                   (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+                   DP_TRAIN_PRE_EMPHASIS_SHIFT,
+                   train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
+                   " (max)" : "",
+                   intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)));
+
+       if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy))
+               intel_dp->set_signal_levels(intel_dp, crtc_state);
+}
+
 static bool
 intel_dp_reset_link_train(struct intel_dp *intel_dp,
                          const struct intel_crtc_state *crtc_state,
@@ -341,7 +362,7 @@ intel_dp_reset_link_train(struct intel_dp *intel_dp,
                          u8 dp_train_pat)
 {
        memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
-       intel_dp_set_signal_levels(intel_dp, crtc_state);
+       intel_dp_set_signal_levels(intel_dp, crtc_state, dp_phy);
        return intel_dp_set_link_train(intel_dp, crtc_state, dp_phy, dp_train_pat);
 }
 
@@ -355,7 +376,7 @@ intel_dp_update_link_train(struct intel_dp *intel_dp,
                            DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy);
        int ret;
 
-       intel_dp_set_signal_levels(intel_dp, crtc_state);
+       intel_dp_set_signal_levels(intel_dp, crtc_state, dp_phy);
 
        ret = drm_dp_dpcd_write(&intel_dp->aux, reg,
                                intel_dp->train_set, crtc_state->lane_count);
index 86905aa24db76a6c079118b32fca14beb91cc65f..6a1f76bd8c7586a6f40fea2e4b8b61cb30e97225 100644 (file)
@@ -17,6 +17,9 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
                               const struct intel_crtc_state *crtc_state,
                               enum drm_dp_phy dp_phy,
                               const u8 link_status[DP_LINK_STATUS_SIZE]);
+void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
+                               const struct intel_crtc_state *crtc_state,
+                               enum drm_dp_phy dp_phy);
 void intel_dp_start_link_train(struct intel_dp *intel_dp,
                               const struct intel_crtc_state *crtc_state);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp,
index 27f04aed8764a87287175ab3c51fbc8f200f2208..3286b232be0b8f0d1dbb1340a9408fea82b1fc9c 100644 (file)
@@ -69,7 +69,9 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 
                slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
                                                      connector->port,
-                                                     crtc_state->pbn, 0);
+                                                     crtc_state->pbn,
+                                                     drm_dp_get_vc_payload_bw(crtc_state->port_clock,
+                                                                              crtc_state->lane_count));
                if (slots == -EDEADLK)
                        return slots;
                if (slots >= 0)
index 52b4f6193b4ce5a32b5de8001a1e88a734d00cb5..0095c8cac9b40f1e0856151d958f26516226e25f 100644 (file)
@@ -359,7 +359,7 @@ static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
        intel_frontbuffer_flip_complete(overlay->i915,
                                        INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
 
-       i915_gem_object_unpin_from_display_plane(vma);
+       i915_vma_unpin(vma);
        i915_vma_put(vma);
 }
 
@@ -860,7 +860,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
        return 0;
 
 out_unpin:
-       i915_gem_object_unpin_from_display_plane(vma);
+       i915_vma_unpin(vma);
 out_pin_section:
        atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
 
index 019a2d6d807a6873fe7a184f12a52c6c6f62aeb8..3da2544fa1c0b6dfdadb206fb1ee9cd48762a359 100644 (file)
@@ -618,13 +618,19 @@ skl_program_scaler(struct intel_plane *plane,
 
 /* Preoffset values for YUV to RGB Conversion */
 #define PREOFF_YUV_TO_RGB_HI           0x1800
-#define PREOFF_YUV_TO_RGB_ME           0x1F00
+#define PREOFF_YUV_TO_RGB_ME           0x0000
 #define PREOFF_YUV_TO_RGB_LO           0x1800
 
 #define  ROFF(x)          (((x) & 0xffff) << 16)
 #define  GOFF(x)          (((x) & 0xffff) << 0)
 #define  BOFF(x)          (((x) & 0xffff) << 16)
 
+/*
+ * Programs the input color space conversion stage for ICL HDR planes.
+ * Note that it is assumed that this stage always happens after YUV
+ * range correction. Thus, the input to this stage is assumed to be
+ * in full-range YCbCr.
+ */
 static void
 icl_program_input_csc(struct intel_plane *plane,
                      const struct intel_crtc_state *crtc_state,
@@ -672,52 +678,7 @@ icl_program_input_csc(struct intel_plane *plane,
                        0x0, 0x7800, 0x7F10,
                },
        };
-
-       /* Matrix for Limited Range to Full Range Conversion */
-       static const u16 input_csc_matrix_lr[][9] = {
-               /*
-                * BT.601 Limted range YCbCr -> full range RGB
-                * The matrix required is :
-                * [1.164384, 0.000, 1.596027,
-                *  1.164384, -0.39175, -0.812813,
-                *  1.164384, 2.017232, 0.0000]
-                */
-               [DRM_COLOR_YCBCR_BT601] = {
-                       0x7CC8, 0x7950, 0x0,
-                       0x8D00, 0x7950, 0x9C88,
-                       0x0, 0x7950, 0x6810,
-               },
-               /*
-                * BT.709 Limited range YCbCr -> full range RGB
-                * The matrix required is :
-                * [1.164384, 0.000, 1.792741,
-                *  1.164384, -0.213249, -0.532909,
-                *  1.164384, 2.112402, 0.0000]
-                */
-               [DRM_COLOR_YCBCR_BT709] = {
-                       0x7E58, 0x7950, 0x0,
-                       0x8888, 0x7950, 0xADA8,
-                       0x0, 0x7950,  0x6870,
-               },
-               /*
-                * BT.2020 Limited range YCbCr -> full range RGB
-                * The matrix required is :
-                * [1.164, 0.000, 1.678,
-                *  1.164, -0.1873, -0.6504,
-                *  1.164, 2.1417, 0.0000]
-                */
-               [DRM_COLOR_YCBCR_BT2020] = {
-                       0x7D70, 0x7950, 0x0,
-                       0x8A68, 0x7950, 0xAC00,
-                       0x0, 0x7950, 0x6890,
-               },
-       };
-       const u16 *csc;
-
-       if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
-               csc = input_csc_matrix[plane_state->hw.color_encoding];
-       else
-               csc = input_csc_matrix_lr[plane_state->hw.color_encoding];
+       const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding];
 
        intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
                          ROFF(csc[0]) | GOFF(csc[1]));
@@ -734,14 +695,8 @@ icl_program_input_csc(struct intel_plane *plane,
 
        intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
                          PREOFF_YUV_TO_RGB_HI);
-       if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
-               intel_de_write_fw(dev_priv,
-                                 PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
-                                 0);
-       else
-               intel_de_write_fw(dev_priv,
-                                 PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
-                                 PREOFF_YUV_TO_RGB_ME);
+       intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
+                         PREOFF_YUV_TO_RGB_ME);
        intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
                          PREOFF_YUV_TO_RGB_LO);
        intel_de_write_fw(dev_priv,
index fcce6909f201769876dea539f22681ff37d80ec6..3d435bfff7649aeaf279164b8b16ce3fe6391c54 100644 (file)
@@ -387,48 +387,6 @@ err:
        return vma;
 }
 
-static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj)
-{
-       struct drm_i915_private *i915 = to_i915(obj->base.dev);
-       struct i915_vma *vma;
-
-       if (list_empty(&obj->vma.list))
-               return;
-
-       mutex_lock(&i915->ggtt.vm.mutex);
-       spin_lock(&obj->vma.lock);
-       for_each_ggtt_vma(vma, obj) {
-               if (!drm_mm_node_allocated(&vma->node))
-                       continue;
-
-               GEM_BUG_ON(vma->vm != &i915->ggtt.vm);
-               list_move_tail(&vma->vm_link, &vma->vm->bound_list);
-       }
-       spin_unlock(&obj->vma.lock);
-       mutex_unlock(&i915->ggtt.vm.mutex);
-
-       if (i915_gem_object_is_shrinkable(obj)) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&i915->mm.obj_lock, flags);
-
-               if (obj->mm.madv == I915_MADV_WILLNEED &&
-                   !atomic_read(&obj->mm.shrink_pin))
-                       list_move_tail(&obj->mm.link, &i915->mm.shrink_list);
-
-               spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
-       }
-}
-
-void
-i915_gem_object_unpin_from_display_plane(struct i915_vma *vma)
-{
-       /* Bump the LRU to try and avoid premature eviction whilst flipping  */
-       i915_gem_object_bump_inactive_ggtt(vma->obj);
-
-       i915_vma_unpin(vma);
-}
-
 /**
  * Moves a single object to the CPU read, and possibly write domain.
  * @obj: object to act on
@@ -569,9 +527,6 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
        else
                err = i915_gem_object_set_to_cpu_domain(obj, write_domain);
 
-       /* And bump the LRU for this access */
-       i915_gem_object_bump_inactive_ggtt(obj);
-
        i915_gem_object_unlock(obj);
 
        if (write_domain)
index be14486f63a7aa1e157625a7d34a3573112abbd7..4556afe18f16d41779e043d904ca02408649b013 100644 (file)
@@ -486,7 +486,6 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
                                     u32 alignment,
                                     const struct i915_ggtt_view *view,
                                     unsigned int flags);
-void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
 
 void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj);
 void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj);
index 94465374ca2fe5505c67804bf697d5b88f9c102f..e961ad6a312944a89c09adcd5c57e29466d7e43d 100644 (file)
@@ -390,6 +390,16 @@ static void emit_batch(struct i915_vma * const vma,
                                                     &cb_kernel_ivb,
                                                     desc_count);
 
+       /* Reset inherited context registers */
+       gen7_emit_pipeline_invalidate(&cmds);
+       batch_add(&cmds, MI_LOAD_REGISTER_IMM(2));
+       batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7));
+       batch_add(&cmds, 0xffff0000);
+       batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1));
+       batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
+       gen7_emit_pipeline_flush(&cmds);
+
+       /* Switch to the media pipeline and our base address */
        gen7_emit_pipeline_invalidate(&cmds);
        batch_add(&cmds, PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
        batch_add(&cmds, MI_NOOP);
@@ -399,9 +409,11 @@ static void emit_batch(struct i915_vma * const vma,
        gen7_emit_state_base_address(&cmds, descriptors);
        gen7_emit_pipeline_invalidate(&cmds);
 
+       /* Set the clear-residual kernel state */
        gen7_emit_vfe_state(&cmds, bv, urb_size - 1, 0, 0);
        gen7_emit_interface_descriptor_load(&cmds, descriptors, desc_count);
 
+       /* Execute the kernel on all HW threads */
        for (i = 0; i < num_primitives(bv); i++)
                gen7_emit_media_object(&cmds, i);
 
index 0625cbb3b431202b33373f7af3367e015c8c42a3..1d1757584f49026d7f3b6fb7cedfb875fce68a0f 100644 (file)
@@ -187,18 +187,6 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl)
                intel_engine_add_retire(b->irq_engine, tl);
 }
 
-static bool __signal_request(struct i915_request *rq)
-{
-       GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
-
-       if (!__dma_fence_signal(&rq->fence)) {
-               i915_request_put(rq);
-               return false;
-       }
-
-       return true;
-}
-
 static struct llist_node *
 slist_add(struct llist_node *node, struct llist_node *head)
 {
@@ -269,9 +257,11 @@ static void signal_irq_work(struct irq_work *work)
                        release = remove_signaling_context(b, ce);
                        spin_unlock(&ce->signal_lock);
 
-                       if (__signal_request(rq))
+                       if (__dma_fence_signal(&rq->fence))
                                /* We own signal_node now, xfer to local list */
                                signal = slist_add(&rq->signal_node, signal);
+                       else
+                               i915_request_put(rq);
 
                        if (release) {
                                add_retire(b, ce->timeline);
@@ -358,6 +348,17 @@ void intel_breadcrumbs_free(struct intel_breadcrumbs *b)
        kfree(b);
 }
 
+static void irq_signal_request(struct i915_request *rq,
+                              struct intel_breadcrumbs *b)
+{
+       if (!__dma_fence_signal(&rq->fence))
+               return;
+
+       i915_request_get(rq);
+       if (llist_add(&rq->signal_node, &b->signaled_requests))
+               irq_work_queue(&b->irq_work);
+}
+
 static void insert_breadcrumb(struct i915_request *rq)
 {
        struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs;
@@ -367,17 +368,13 @@ static void insert_breadcrumb(struct i915_request *rq)
        if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags))
                return;
 
-       i915_request_get(rq);
-
        /*
         * If the request is already completed, we can transfer it
         * straight onto a signaled list, and queue the irq worker for
         * its signal completion.
         */
        if (__i915_request_is_complete(rq)) {
-               if (__signal_request(rq) &&
-                   llist_add(&rq->signal_node, &b->signaled_requests))
-                       irq_work_queue(&b->irq_work);
+               irq_signal_request(rq, b);
                return;
        }
 
@@ -408,6 +405,8 @@ static void insert_breadcrumb(struct i915_request *rq)
                                break;
                }
        }
+
+       i915_request_get(rq);
        list_add_rcu(&rq->signal_link, pos);
        GEM_BUG_ON(!check_signal_order(ce, rq));
        GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags));
@@ -448,19 +447,25 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq)
 
 void i915_request_cancel_breadcrumb(struct i915_request *rq)
 {
+       struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs;
        struct intel_context *ce = rq->context;
        bool release;
 
-       if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags))
+       spin_lock(&ce->signal_lock);
+       if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags)) {
+               spin_unlock(&ce->signal_lock);
                return;
+       }
 
-       spin_lock(&ce->signal_lock);
        list_del_rcu(&rq->signal_link);
-       release = remove_signaling_context(rq->engine->breadcrumbs, ce);
+       release = remove_signaling_context(b, ce);
        spin_unlock(&ce->signal_lock);
        if (release)
                intel_context_put(ce);
 
+       if (__i915_request_is_complete(rq))
+               irq_signal_request(rq, b);
+
        i915_request_put(rq);
 }
 
index cf94525be2c18c5f19abe623c6143810b83d5182..db8c66dde6558cbee274f72257cf5a5442ed14a1 100644 (file)
@@ -526,16 +526,39 @@ static int init_ggtt(struct i915_ggtt *ggtt)
 
        mutex_init(&ggtt->error_mutex);
        if (ggtt->mappable_end) {
-               /* Reserve a mappable slot for our lockless error capture */
-               ret = drm_mm_insert_node_in_range(&ggtt->vm.mm,
-                                                 &ggtt->error_capture,
-                                                 PAGE_SIZE, 0,
-                                                 I915_COLOR_UNEVICTABLE,
-                                                 0, ggtt->mappable_end,
-                                                 DRM_MM_INSERT_LOW);
-               if (ret)
-                       return ret;
+               /*
+                * Reserve a mappable slot for our lockless error capture.
+                *
+                * We strongly prefer taking address 0x0 in order to protect
+                * other critical buffers against accidental overwrites,
+                * as writing to address 0 is a very common mistake.
+                *
+                * Since 0 may already be in use by the system (e.g. the BIOS
+                * framebuffer), we let the reservation fail quietly and hope
+                * 0 remains reserved always.
+                *
+                * If we fail to reserve 0, and then fail to find any space
+                * for an error-capture, remain silent. We can afford not
+                * to reserve an error_capture node as we have fallback
+                * paths, and we trust that 0 will remain reserved. However,
+                * the only likely reason for failure to insert is a driver
+                * bug, which we expect to cause other failures...
+                */
+               ggtt->error_capture.size = I915_GTT_PAGE_SIZE;
+               ggtt->error_capture.color = I915_COLOR_UNEVICTABLE;
+               if (drm_mm_reserve_node(&ggtt->vm.mm, &ggtt->error_capture))
+                       drm_mm_insert_node_in_range(&ggtt->vm.mm,
+                                                   &ggtt->error_capture,
+                                                   ggtt->error_capture.size, 0,
+                                                   ggtt->error_capture.color,
+                                                   0, ggtt->mappable_end,
+                                                   DRM_MM_INSERT_LOW);
        }
+       if (drm_mm_node_allocated(&ggtt->error_capture))
+               drm_dbg(&ggtt->vm.i915->drm,
+                       "Reserved GGTT:[%llx, %llx] for use by error capture\n",
+                       ggtt->error_capture.start,
+                       ggtt->error_capture.start + ggtt->error_capture.size);
 
        /*
         * The upper portion of the GuC address space has a sizeable hole
@@ -548,9 +571,9 @@ static int init_ggtt(struct i915_ggtt *ggtt)
 
        /* Clear any non-preallocated blocks */
        drm_mm_for_each_hole(entry, &ggtt->vm.mm, hole_start, hole_end) {
-               drm_dbg_kms(&ggtt->vm.i915->drm,
-                           "clearing unused GTT space: [%lx, %lx]\n",
-                           hole_start, hole_end);
+               drm_dbg(&ggtt->vm.i915->drm,
+                       "clearing unused GTT space: [%lx, %lx]\n",
+                       hole_start, hole_end);
                ggtt->vm.clear_range(&ggtt->vm, hole_start,
                                     hole_end - hole_start);
        }
index 10a865f3dc09ac4ba90993aa420b23af1650faf3..9ed19b8bca60093a3ff9ab666ecf0f445dcf8183 100644 (file)
@@ -631,24 +631,26 @@ static int flush_lazy_signals(struct i915_active *ref)
 
 int __i915_active_wait(struct i915_active *ref, int state)
 {
-       int err;
-
        might_sleep();
 
-       if (!i915_active_acquire_if_busy(ref))
-               return 0;
-
        /* Any fence added after the wait begins will not be auto-signaled */
-       err = flush_lazy_signals(ref);
-       i915_active_release(ref);
-       if (err)
-               return err;
+       if (i915_active_acquire_if_busy(ref)) {
+               int err;
 
-       if (!i915_active_is_idle(ref) &&
-           ___wait_var_event(ref, i915_active_is_idle(ref),
-                             state, 0, 0, schedule()))
-               return -EINTR;
+               err = flush_lazy_signals(ref);
+               i915_active_release(ref);
+               if (err)
+                       return err;
 
+               if (___wait_var_event(ref, i915_active_is_idle(ref),
+                                     state, 0, 0, schedule()))
+                       return -EINTR;
+       }
+
+       /*
+        * After the wait is complete, the caller may free the active.
+        * We have to flush any concurrent retirement before returning.
+        */
        flush_work(&ref->work);
        return 0;
 }
index 632c713227dc7011bb0fa1f6017d78e76ce0ac74..c6964f82a1bb68268d837d311dad592a37d33e92 100644 (file)
@@ -1346,7 +1346,7 @@ intel_subplatform(const struct intel_runtime_info *info, enum intel_platform p)
 {
        const unsigned int pi = __platform_mask_index(info, p);
 
-       return info->platform_mask[pi] & INTEL_SUBPLATFORM_BITS;
+       return info->platform_mask[pi] & ((1 << INTEL_SUBPLATFORM_BITS) - 1);
 }
 
 static __always_inline bool
index c53a222e3dece33793deec5f182e5a84929e333c..713770fb2b92d4846acfd2b1e69fe413cb03b74e 100644 (file)
@@ -1880,7 +1880,7 @@ static int igt_cs_tlb(void *arg)
        vma = i915_vma_instance(out, vm, NULL);
        if (IS_ERR(vma)) {
                err = PTR_ERR(vma);
-               goto out_put_batch;
+               goto out_put_out;
        }
 
        err = i915_vma_pin(vma, 0, 0,
index 302d4e6fc52f1a0bd2e90121818c15aa7b48f10e..788db043a34299e41ac692189bcfc0caa6dab774 100644 (file)
@@ -88,7 +88,11 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
                          NVVAL(NV507C, SET_CONVERSION, OFS, 0x64));
        } else {
                PUSH_MTHD(push, NV507C, SET_PROCESSING,
-                         NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
+                         NVDEF(NV507C, SET_PROCESSING, USE_GAIN_OFS, DISABLE),
+
+                                       SET_CONVERSION,
+                         NVVAL(NV507C, SET_CONVERSION, GAIN, 0) |
+                         NVVAL(NV507C, SET_CONVERSION, OFS, 0));
        }
 
        PUSH_MTHD(push, NV507C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8);
index 18d34096f1258f1285e36f4f21223890b6b0855b..093d4ba6910ec40ec556eeea003e5d83261d6b52 100644 (file)
@@ -49,7 +49,11 @@ base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
                          NVVAL(NV827C, SET_CONVERSION, OFS, 0x64));
        } else {
                PUSH_MTHD(push, NV827C, SET_PROCESSING,
-                         NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE));
+                         NVDEF(NV827C, SET_PROCESSING, USE_GAIN_OFS, DISABLE),
+
+                                       SET_CONVERSION,
+                         NVVAL(NV827C, SET_CONVERSION, GAIN, 0) |
+                         NVVAL(NV827C, SET_CONVERSION, OFS, 0));
        }
 
        PUSH_MTHD(push, NV827C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8,
index c6367035970eb5e6a14fcf4e4d3c531c28de91b7..5f4f09a601d4c38ca5d1dbebb46e052807cd8af6 100644 (file)
@@ -2663,6 +2663,14 @@ nv50_display_create(struct drm_device *dev)
        else
                nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
 
+       if (disp->disp->object.oclass >= GK104_DISP) {
+               dev->mode_config.cursor_width = 256;
+               dev->mode_config.cursor_height = 256;
+       } else {
+               dev->mode_config.cursor_width = 64;
+               dev->mode_config.cursor_height = 64;
+       }
+
        /* create crtc objects to represent the hw heads */
        if (disp->disp->object.oclass >= GV100_DISP)
                crtcs = nvif_rd32(&device->object, 0x610060) & 0xff;
index a5d8274036609cc86305e80b2053efd7f5b78bd6..ea9f8667305ecb9fc80c02930b0f43c60c92bd87 100644 (file)
@@ -22,6 +22,7 @@
 #include "head.h"
 #include "core.h"
 
+#include "nvif/push.h"
 #include <nvif/push507c.h>
 
 #include <nvhw/class/cl917d.h>
@@ -73,6 +74,31 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
        return 0;
 }
 
+static int
+head917d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
+{
+       struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
+       const int i = head->base.index;
+       int ret;
+
+       ret = PUSH_WAIT(push, 5);
+       if (ret)
+               return ret;
+
+       PUSH_MTHD(push, NV917D, HEAD_SET_CONTROL_CURSOR(i),
+                 NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) |
+                 NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) |
+                 NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) |
+                 NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) |
+                 NVVAL(NV917D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) |
+                 NVDEF(NV917D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND),
+
+                               HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8);
+
+       PUSH_MTHD(push, NV917D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle);
+       return 0;
+}
+
 int
 head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
                     struct nv50_head_atom *asyh)
@@ -101,7 +127,7 @@ head917d = {
        .core_clr = head907d_core_clr,
        .curs_layout = head917d_curs_layout,
        .curs_format = head507d_curs_format,
-       .curs_set = head907d_curs_set,
+       .curs_set = head917d_curs_set,
        .curs_clr = head907d_curs_clr,
        .base = head917d_base,
        .ovly = head907d_ovly,
index ce451242f79eb2fc16403a5cf1d039b70ede0ced..271de3a63f21c2158645e415014759f548d965fa 100644 (file)
@@ -702,6 +702,11 @@ nv50_wndw_init(struct nv50_wndw *wndw)
        nvif_notify_get(&wndw->notify);
 }
 
+static const u64 nv50_cursor_format_modifiers[] = {
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID,
+};
+
 int
 nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
               enum drm_plane_type type, const char *name, int index,
@@ -713,6 +718,7 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
        struct nvif_mmu *mmu = &drm->client.mmu;
        struct nv50_disp *disp = nv50_disp(dev);
        struct nv50_wndw *wndw;
+       const u64 *format_modifiers;
        int nformat;
        int ret;
 
@@ -728,10 +734,13 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
 
        for (nformat = 0; format[nformat]; nformat++);
 
-       ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw,
-                                      format, nformat,
-                                      nouveau_display(dev)->format_modifiers,
-                                      type, "%s-%d", name, index);
+       if (type == DRM_PLANE_TYPE_CURSOR)
+               format_modifiers = nv50_cursor_format_modifiers;
+       else
+               format_modifiers = nouveau_display(dev)->format_modifiers;
+
+       ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, format, nformat,
+                                      format_modifiers, type, "%s-%d", name, index);
        if (ret) {
                kfree(*pwndw);
                *pwndw = NULL;
index 2a2612d6e1e0e6f6fd687f5212eca2ec49730568..fb223723a38add00ef3419b9bd0a16c398f31ef1 100644 (file)
 #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_ALPHA_BLEND                  (0x00000000)
 #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_PREMULT_ALPHA_BLEND          (0x00000001)
 #define NV917D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_XOR                          (0x00000002)
+#define NV917D_HEAD_SET_OFFSET_CURSOR(a)                                        (0x00000484 + (a)*0x00000300)
+#define NV917D_HEAD_SET_OFFSET_CURSOR_ORIGIN                                    31:0
+#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR(a)                                   (0x0000048C + (a)*0x00000300)
+#define NV917D_HEAD_SET_CONTEXT_DMA_CURSOR_HANDLE                               31:0
 #define NV917D_HEAD_SET_DITHER_CONTROL(a)                                       (0x000004A0 + (a)*0x00000300)
 #define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE                                   0:0
 #define NV917D_HEAD_SET_DITHER_CONTROL_ENABLE_DISABLE                           (0x00000000)
index 168d7694ede5cc7de4d77e9ad56b71eb4d7d05c4..6d3a8a3d2087b5310a75e18466373d6a40364f12 100644 (file)
@@ -123,131 +123,131 @@ PUSH_KICK(struct nvif_push *push)
 } while(0)
 #endif
 
-#define PUSH_1(X,f,ds,n,c,o,p,s,mA,dA) do {                            \
-       PUSH_##o##_HDR((p), s, mA, (c)+(n));                           \
-       PUSH_##f(X, (p), X##mA, 1, o, (dA), ds, "");                   \
+#define PUSH_1(X,f,ds,n,o,p,s,mA,dA) do {                             \
+       PUSH_##o##_HDR((p), s, mA, (ds)+(n));                         \
+       PUSH_##f(X, (p), X##mA, 1, o, (dA), ds, "");                  \
 } while(0)
-#define PUSH_2(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (1?PUSH_##o##_INC), "mthd1");       \
-       PUSH_1(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_2(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (1?PUSH_##o##_INC), "mthd1");      \
+       PUSH_1(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_3(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd2");       \
-       PUSH_2(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_3(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd2");      \
+       PUSH_2(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_4(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd3");       \
-       PUSH_3(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_4(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd3");      \
+       PUSH_3(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_5(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd4");       \
-       PUSH_4(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_5(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd4");      \
+       PUSH_4(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_6(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd5");       \
-       PUSH_5(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_6(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd5");      \
+       PUSH_5(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_7(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd6");       \
-       PUSH_6(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_7(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd6");      \
+       PUSH_6(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_8(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd7");       \
-       PUSH_7(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_8(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd7");      \
+       PUSH_7(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_9(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                 \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd8");       \
-       PUSH_8(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_9(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                  \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd8");      \
+       PUSH_8(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
-#define PUSH_10(X,f,ds,n,c,o,p,s,mB,dB,mA,dA,a...) do {                \
-       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd9");       \
-       PUSH_9(X, DATA_, 1, ds, (c)+(n), o, (p), s, X##mA, (dA), ##a); \
-       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                   \
+#define PUSH_10(X,f,ds,n,o,p,s,mB,dB,mA,dA,a...) do {                 \
+       PUSH_ASSERT((mB) - (mA) == (0?PUSH_##o##_INC), "mthd9");      \
+       PUSH_9(X, DATA_, 1, (ds) + (n), o, (p), s, X##mA, (dA), ##a); \
+       PUSH_##f(X, (p), X##mB, 0, o, (dB), ds, "");                  \
 } while(0)
 
-#define PUSH_1D(X,o,p,s,mA,dA)                            \
-       PUSH_1(X, DATA_, 1, 1, 0, o, (p), s, X##mA, (dA))
-#define PUSH_2D(X,o,p,s,mA,dA,mB,dB)                      \
-       PUSH_2(X, DATA_, 1, 1, 0, o, (p), s, X##mB, (dB), \
-                                            X##mA, (dA))
-#define PUSH_3D(X,o,p,s,mA,dA,mB,dB,mC,dC)                \
-       PUSH_3(X, DATA_, 1, 1, 0, o, (p), s, X##mC, (dC), \
-                                            X##mB, (dB), \
-                                            X##mA, (dA))
-#define PUSH_4D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD)          \
-       PUSH_4(X, DATA_, 1, 1, 0, o, (p), s, X##mD, (dD), \
-                                            X##mC, (dC), \
-                                            X##mB, (dB), \
-                                            X##mA, (dA))
-#define PUSH_5D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE)    \
-       PUSH_5(X, DATA_, 1, 1, 0, o, (p), s, X##mE, (dE), \
-                                            X##mD, (dD), \
-                                            X##mC, (dC), \
-                                            X##mB, (dB), \
-                                            X##mA, (dA))
+#define PUSH_1D(X,o,p,s,mA,dA)                         \
+       PUSH_1(X, DATA_, 1, 0, o, (p), s, X##mA, (dA))
+#define PUSH_2D(X,o,p,s,mA,dA,mB,dB)                   \
+       PUSH_2(X, DATA_, 1, 0, o, (p), s, X##mB, (dB), \
+                                         X##mA, (dA))
+#define PUSH_3D(X,o,p,s,mA,dA,mB,dB,mC,dC)             \
+       PUSH_3(X, DATA_, 1, 0, o, (p), s, X##mC, (dC), \
+                                         X##mB, (dB), \
+                                         X##mA, (dA))
+#define PUSH_4D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD)       \
+       PUSH_4(X, DATA_, 1, 0, o, (p), s, X##mD, (dD), \
+                                         X##mC, (dC), \
+                                         X##mB, (dB), \
+                                         X##mA, (dA))
+#define PUSH_5D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE) \
+       PUSH_5(X, DATA_, 1, 0, o, (p), s, X##mE, (dE), \
+                                         X##mD, (dD), \
+                                         X##mC, (dC), \
+                                         X##mB, (dB), \
+                                         X##mA, (dA))
 #define PUSH_6D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF) \
-       PUSH_6(X, DATA_, 1, 1, 0, o, (p), s, X##mF, (dF),    \
-                                            X##mE, (dE),    \
-                                            X##mD, (dD),    \
-                                            X##mC, (dC),    \
-                                            X##mB, (dB),    \
-                                            X##mA, (dA))
+       PUSH_6(X, DATA_, 1, 0, o, (p), s, X##mF, (dF),       \
+                                         X##mE, (dE),       \
+                                         X##mD, (dD),       \
+                                         X##mC, (dC),       \
+                                         X##mB, (dB),       \
+                                         X##mA, (dA))
 #define PUSH_7D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG) \
-       PUSH_7(X, DATA_, 1, 1, 0, o, (p), s, X##mG, (dG),          \
-                                            X##mF, (dF),          \
-                                            X##mE, (dE),          \
-                                            X##mD, (dD),          \
-                                            X##mC, (dC),          \
-                                            X##mB, (dB),          \
-                                            X##mA, (dA))
+       PUSH_7(X, DATA_, 1, 0, o, (p), s, X##mG, (dG),             \
+                                         X##mF, (dF),             \
+                                         X##mE, (dE),             \
+                                         X##mD, (dD),             \
+                                         X##mC, (dC),             \
+                                         X##mB, (dB),             \
+                                         X##mA, (dA))
 #define PUSH_8D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH) \
-       PUSH_8(X, DATA_, 1, 1, 0, o, (p), s, X##mH, (dH),                \
-                                            X##mG, (dG),                \
-                                            X##mF, (dF),                \
-                                            X##mE, (dE),                \
-                                            X##mD, (dD),                \
-                                            X##mC, (dC),                \
-                                            X##mB, (dB),                \
-                                            X##mA, (dA))
+       PUSH_8(X, DATA_, 1, 0, o, (p), s, X##mH, (dH),                   \
+                                         X##mG, (dG),                   \
+                                         X##mF, (dF),                   \
+                                         X##mE, (dE),                   \
+                                         X##mD, (dD),                   \
+                                         X##mC, (dC),                   \
+                                         X##mB, (dB),                   \
+                                         X##mA, (dA))
 #define PUSH_9D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI) \
-       PUSH_9(X, DATA_, 1, 1, 0, o, (p), s, X##mI, (dI),                      \
-                                            X##mH, (dH),                      \
-                                            X##mG, (dG),                      \
-                                            X##mF, (dF),                      \
-                                            X##mE, (dE),                      \
-                                            X##mD, (dD),                      \
-                                            X##mC, (dC),                      \
-                                            X##mB, (dB),                      \
-                                            X##mA, (dA))
+       PUSH_9(X, DATA_, 1, 0, o, (p), s, X##mI, (dI),                         \
+                                         X##mH, (dH),                         \
+                                         X##mG, (dG),                         \
+                                         X##mF, (dF),                         \
+                                         X##mE, (dE),                         \
+                                         X##mD, (dD),                         \
+                                         X##mC, (dC),                         \
+                                         X##mB, (dB),                         \
+                                         X##mA, (dA))
 #define PUSH_10D(X,o,p,s,mA,dA,mB,dB,mC,dC,mD,dD,mE,dE,mF,dF,mG,dG,mH,dH,mI,dI,mJ,dJ) \
-       PUSH_10(X, DATA_, 1, 1, 0, o, (p), s, X##mJ, (dJ),                            \
-                                             X##mI, (dI),                            \
-                                             X##mH, (dH),                            \
-                                             X##mG, (dG),                            \
-                                             X##mF, (dF),                            \
-                                             X##mE, (dE),                            \
-                                             X##mD, (dD),                            \
-                                             X##mC, (dC),                            \
-                                             X##mB, (dB),                            \
-                                             X##mA, (dA))
+       PUSH_10(X, DATA_, 1, 0, o, (p), s, X##mJ, (dJ),                               \
+                                          X##mI, (dI),                               \
+                                          X##mH, (dH),                               \
+                                          X##mG, (dG),                               \
+                                          X##mF, (dF),                               \
+                                          X##mE, (dE),                               \
+                                          X##mD, (dD),                               \
+                                          X##mC, (dC),                               \
+                                          X##mB, (dB),                               \
+                                          X##mA, (dA))
 
-#define PUSH_1P(X,o,p,s,mA,dp,ds)                           \
-       PUSH_1(X, DATAp, ds, ds, 0, o, (p), s, X##mA, (dp))
-#define PUSH_2P(X,o,p,s,mA,dA,mB,dp,ds)                     \
-       PUSH_2(X, DATAp, ds, ds, 0, o, (p), s, X##mB, (dp), \
-                                              X##mA, (dA))
-#define PUSH_3P(X,o,p,s,mA,dA,mB,dB,mC,dp,ds)               \
-       PUSH_3(X, DATAp, ds, ds, 0, o, (p), s, X##mC, (dp), \
-                                              X##mB, (dB), \
-                                              X##mA, (dA))
+#define PUSH_1P(X,o,p,s,mA,dp,ds)                       \
+       PUSH_1(X, DATAp, ds, 0, o, (p), s, X##mA, (dp))
+#define PUSH_2P(X,o,p,s,mA,dA,mB,dp,ds)                 \
+       PUSH_2(X, DATAp, ds, 0, o, (p), s, X##mB, (dp), \
+                                          X##mA, (dA))
+#define PUSH_3P(X,o,p,s,mA,dA,mB,dB,mC,dp,ds)           \
+       PUSH_3(X, DATAp, ds, 0, o, (p), s, X##mC, (dp), \
+                                          X##mB, (dB), \
+                                          X##mA, (dA))
 
 #define PUSH_(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,IMPL,...) IMPL
 #define PUSH(A...) PUSH_(A, PUSH_10P, PUSH_10D,          \
index c85b1af06b7bf97627a9248651032f05a431aeaf..7ea367a5444dd3e26d96a601200e3670ff663f72 100644 (file)
@@ -547,7 +547,7 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo)
 {
        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm;
-       int i;
+       int i, j;
 
        if (!ttm_dma)
                return;
@@ -556,10 +556,21 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo)
        if (nvbo->force_coherent)
                return;
 
-       for (i = 0; i < ttm_dma->num_pages; i++)
+       for (i = 0; i < ttm_dma->num_pages; ++i) {
+               struct page *p = ttm_dma->pages[i];
+               size_t num_pages = 1;
+
+               for (j = i + 1; j < ttm_dma->num_pages; ++j) {
+                       if (++p != ttm_dma->pages[j])
+                               break;
+
+                       ++num_pages;
+               }
                dma_sync_single_for_device(drm->dev->dev,
                                           ttm_dma->dma_address[i],
-                                          PAGE_SIZE, DMA_TO_DEVICE);
+                                          num_pages * PAGE_SIZE, DMA_TO_DEVICE);
+               i += num_pages;
+       }
 }
 
 void
@@ -567,7 +578,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
 {
        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_tt *ttm_dma = (struct ttm_tt *)nvbo->bo.ttm;
-       int i;
+       int i, j;
 
        if (!ttm_dma)
                return;
@@ -576,9 +587,21 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
        if (nvbo->force_coherent)
                return;
 
-       for (i = 0; i < ttm_dma->num_pages; i++)
+       for (i = 0; i < ttm_dma->num_pages; ++i) {
+               struct page *p = ttm_dma->pages[i];
+               size_t num_pages = 1;
+
+               for (j = i + 1; j < ttm_dma->num_pages; ++j) {
+                       if (++p != ttm_dma->pages[j])
+                               break;
+
+                       ++num_pages;
+               }
+
                dma_sync_single_for_cpu(drm->dev->dev, ttm_dma->dma_address[i],
-                                       PAGE_SIZE, DMA_FROM_DEVICE);
+                                       num_pages * PAGE_SIZE, DMA_FROM_DEVICE);
+               i += num_pages;
+       }
 }
 
 void nouveau_bo_add_io_reserve_lru(struct ttm_buffer_object *bo)
index 4f69e4c3dafde298f6f7707b719a074a5dca5076..1c3f890377d2c283220c2868c389c4135c332eae 100644 (file)
@@ -315,6 +315,10 @@ nouveau_svmm_init(struct drm_device *dev, void *data,
        struct drm_nouveau_svm_init *args = data;
        int ret;
 
+       /* We need to fail if svm is disabled */
+       if (!cli->drm->svm)
+               return -ENOSYS;
+
        /* Allocate tracking for SVM-enabled VMM. */
        if (!(svmm = kzalloc(sizeof(*svmm), GFP_KERNEL)))
                return -ENOMEM;
index 11e0313db0ea681d4a100b583597c20fad09eee9..74bf1c84b63742065c546a8442e973169c31db8f 100644 (file)
@@ -84,7 +84,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
         * put_page() on a TTM allocated page is illegal.
         */
        if (order)
-               gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY |
+               gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN |
                        __GFP_KSWAPD_RECLAIM;
 
        if (!pool->use_dma_alloc) {
index cccd341e5d6707858141dc60278a5051e9f77e9d..3b722252d1fbe1090ecba3d4059a2fd7765c476e 100644 (file)
@@ -620,11 +620,11 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
         * for now we just allocate globally.
         */
        if (!hvs->hvs5)
-               /* 96kB */
-               drm_mm_init(&hvs->lbm_mm, 0, 96 * 1024);
+               /* 48k words of 2x12-bit pixels */
+               drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024);
        else
-               /* 70k words */
-               drm_mm_init(&hvs->lbm_mm, 0, 70 * 2 * 1024);
+               /* 60k words of 4x12-bit pixels */
+               drm_mm_init(&hvs->lbm_mm, 0, 60 * 1024);
 
        /* Upload filter kernels.  We only have the one for now, so we
         * keep it around for the lifetime of the driver.
index 6b39cc2ca18d0953bebf8b4c3d0aeacf74d500cb..5612cab552270d68f35e31b6828293c37bca72d4 100644 (file)
@@ -437,6 +437,7 @@ static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
 static u32 vc4_lbm_size(struct drm_plane_state *state)
 {
        struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+       struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev);
        u32 pix_per_line;
        u32 lbm;
 
@@ -472,7 +473,11 @@ static u32 vc4_lbm_size(struct drm_plane_state *state)
                lbm = pix_per_line * 16;
        }
 
-       lbm = roundup(lbm, 32);
+       /* Align it to 64 or 128 (hvs5) bytes */
+       lbm = roundup(lbm, vc4->hvs->hvs5 ? 128 : 64);
+
+       /* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */
+       lbm /= vc4->hvs->hvs5 ? 4 : 2;
 
        return lbm;
 }
@@ -912,9 +917,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
                if (!vc4_state->is_unity) {
                        vc4_dlist_write(vc4_state,
                                        VC4_SET_FIELD(vc4_state->crtc_w,
-                                                     SCALER_POS1_SCL_WIDTH) |
+                                                     SCALER5_POS1_SCL_WIDTH) |
                                        VC4_SET_FIELD(vc4_state->crtc_h,
-                                                     SCALER_POS1_SCL_HEIGHT));
+                                                     SCALER5_POS1_SCL_HEIGHT));
                }
 
                /* Position Word 2: Source Image Size */
index 0743ef51d3b246ab2086ca3dda387a842b79e19e..8429ebe7097e4c8f9235c35a22e5ab2ace6eb6f6 100644 (file)
@@ -758,7 +758,8 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
                        MT_STORE_FIELD(inrange_state);
                        return 1;
                case HID_DG_CONFIDENCE:
-                       if (cls->name == MT_CLS_WIN_8 &&
+                       if ((cls->name == MT_CLS_WIN_8 ||
+                            cls->name == MT_CLS_WIN_8_FORCE_MULTI_INPUT) &&
                                (field->application == HID_DG_TOUCHPAD ||
                                 field->application == HID_DG_TOUCHSCREEN))
                                app->quirks |= MT_QUIRK_CONFIDENCE;
index e8acd235db2a90f156ec516d37990921a759e0db..aa9e48876cedaaa6b4b3abbbef924b27a9c913d1 100644 (file)
@@ -147,9 +147,9 @@ static int wacom_wac_pen_serial_enforce(struct hid_device *hdev,
        }
 
        if (flush)
-               wacom_wac_queue_flush(hdev, &wacom_wac->pen_fifo);
+               wacom_wac_queue_flush(hdev, wacom_wac->pen_fifo);
        else if (insert)
-               wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo,
+               wacom_wac_queue_insert(hdev, wacom_wac->pen_fifo,
                                       raw_data, report_size);
 
        return insert && !flush;
@@ -1280,7 +1280,7 @@ static void wacom_devm_kfifo_release(struct device *dev, void *res)
 static int wacom_devm_kfifo_alloc(struct wacom *wacom)
 {
        struct wacom_wac *wacom_wac = &wacom->wacom_wac;
-       struct kfifo_rec_ptr_2 *pen_fifo = &wacom_wac->pen_fifo;
+       struct kfifo_rec_ptr_2 *pen_fifo;
        int error;
 
        pen_fifo = devres_alloc(wacom_devm_kfifo_release,
@@ -1297,6 +1297,7 @@ static int wacom_devm_kfifo_alloc(struct wacom *wacom)
        }
 
        devres_add(&wacom->hdev->dev, pen_fifo);
+       wacom_wac->pen_fifo = pen_fifo;
 
        return 0;
 }
index da612b6e9c7796f32202c37e7b2a0b56b6db4eec..195910dd2154e2e5471df45a17f4454ffa219787 100644 (file)
@@ -342,7 +342,7 @@ struct wacom_wac {
        struct input_dev *pen_input;
        struct input_dev *touch_input;
        struct input_dev *pad_input;
-       struct kfifo_rec_ptr_2 pen_fifo;
+       struct kfifo_rec_ptr_2 *pen_fifo;
        int pid;
        int num_contacts_left;
        u8 bt_features;
index 0818d3e50734771b854b875b78bcc60c37ded121..2ffd2f354d0ae3e3edbcd552e191d72626a21fa4 100644 (file)
@@ -1275,7 +1275,8 @@ static int mtk_i2c_probe(struct platform_device *pdev)
        mtk_i2c_clock_disable(i2c);
 
        ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
-                              IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c);
+                              IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
+                              I2C_DRV_NAME, i2c);
        if (ret < 0) {
                dev_err(&pdev->dev,
                        "Request I2C IRQ %d fail\n", irq);
@@ -1302,7 +1303,16 @@ static int mtk_i2c_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int mtk_i2c_resume(struct device *dev)
+static int mtk_i2c_suspend_noirq(struct device *dev)
+{
+       struct mtk_i2c *i2c = dev_get_drvdata(dev);
+
+       i2c_mark_adapter_suspended(&i2c->adap);
+
+       return 0;
+}
+
+static int mtk_i2c_resume_noirq(struct device *dev)
 {
        int ret;
        struct mtk_i2c *i2c = dev_get_drvdata(dev);
@@ -1317,12 +1327,15 @@ static int mtk_i2c_resume(struct device *dev)
 
        mtk_i2c_clock_disable(i2c);
 
+       i2c_mark_adapter_resumed(&i2c->adap);
+
        return 0;
 }
 #endif
 
 static const struct dev_pm_ops mtk_i2c_pm = {
-       SET_SYSTEM_SLEEP_PM_OPS(NULL, mtk_i2c_resume)
+       SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq,
+                                     mtk_i2c_resume_noirq)
 };
 
 static struct platform_driver mtk_i2c_driver = {
index a7401398cb344a0dc128d50787697ecf3b941f55..d109bb3822a5f862235d18ba004f9ba530df3a89 100644 (file)
@@ -2474,7 +2474,7 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        init_attr->cap.max_send_wr = qhp->attr.sq_num_entries;
        init_attr->cap.max_recv_wr = qhp->attr.rq_num_entries;
        init_attr->cap.max_send_sge = qhp->attr.sq_max_sges;
-       init_attr->cap.max_recv_sge = qhp->attr.sq_max_sges;
+       init_attr->cap.max_recv_sge = qhp->attr.rq_max_sges;
        init_attr->cap.max_inline_data = T4_MAX_SEND_INLINE;
        init_attr->sq_sig_type = qhp->sq_sig_all ? IB_SIGNAL_ALL_WR : 0;
        return 0;
index 55d538625e36139c40ab93122944699816b0d95d..ad8253245a85fd73963c4c9d78034d5de2344884 100644 (file)
@@ -532,7 +532,7 @@ struct hns_roce_qp_table {
        struct hns_roce_hem_table       sccc_table;
        struct mutex                    scc_mutex;
        struct hns_roce_bank bank[HNS_ROCE_QP_BANK_NUM];
-       spinlock_t bank_lock;
+       struct mutex bank_mutex;
 };
 
 struct hns_roce_cq_table {
index d8e2fe5558d29d371ac31776a564f8638e21c17c..1116371adf74f4bc267aa5b7e2c8085a5c54356e 100644 (file)
@@ -209,7 +209,7 @@ static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
 
                hr_qp->doorbell_qpn = 1;
        } else {
-               spin_lock(&qp_table->bank_lock);
+               mutex_lock(&qp_table->bank_mutex);
                bankid = get_least_load_bankid_for_qp(qp_table->bank);
 
                ret = alloc_qpn_with_bankid(&qp_table->bank[bankid], bankid,
@@ -217,12 +217,12 @@ static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
                if (ret) {
                        ibdev_err(&hr_dev->ib_dev,
                                  "failed to alloc QPN, ret = %d\n", ret);
-                       spin_unlock(&qp_table->bank_lock);
+                       mutex_unlock(&qp_table->bank_mutex);
                        return ret;
                }
 
                qp_table->bank[bankid].inuse++;
-               spin_unlock(&qp_table->bank_lock);
+               mutex_unlock(&qp_table->bank_mutex);
 
                hr_qp->doorbell_qpn = (u32)num;
        }
@@ -408,9 +408,9 @@ static void free_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
 
        ida_free(&hr_dev->qp_table.bank[bankid].ida, hr_qp->qpn >> 3);
 
-       spin_lock(&hr_dev->qp_table.bank_lock);
+       mutex_lock(&hr_dev->qp_table.bank_mutex);
        hr_dev->qp_table.bank[bankid].inuse--;
-       spin_unlock(&hr_dev->qp_table.bank_lock);
+       mutex_unlock(&hr_dev->qp_table.bank_mutex);
 }
 
 static int set_rq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap,
@@ -1371,6 +1371,7 @@ int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev)
        unsigned int i;
 
        mutex_init(&qp_table->scc_mutex);
+       mutex_init(&qp_table->bank_mutex);
        xa_init(&hr_dev->qp_table_xa);
 
        reserved_from_bot = hr_dev->caps.reserved_qps;
index d26f3f3e0462a03e8cc38058124add5bcb0f86d8..aabdc07e475374fbe591fa15a42a0e20b931c497 100644 (file)
@@ -3311,8 +3311,7 @@ static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)
        int err;
 
        dev->port[port_num].roce.nb.notifier_call = mlx5_netdev_event;
-       err = register_netdevice_notifier_net(mlx5_core_net(dev->mdev),
-                                             &dev->port[port_num].roce.nb);
+       err = register_netdevice_notifier(&dev->port[port_num].roce.nb);
        if (err) {
                dev->port[port_num].roce.nb.notifier_call = NULL;
                return err;
@@ -3324,8 +3323,7 @@ static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)
 static void mlx5_remove_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)
 {
        if (dev->port[port_num].roce.nb.notifier_call) {
-               unregister_netdevice_notifier_net(mlx5_core_net(dev->mdev),
-                                                 &dev->port[port_num].roce.nb);
+               unregister_netdevice_notifier(&dev->port[port_num].roce.nb);
                dev->port[port_num].roce.nb.notifier_call = NULL;
        }
 }
index e59615a4c9d98e2451e25b790d605b057967f33b..586b0e52ba7f8eb804d09711a7392a6a090351b4 100644 (file)
@@ -214,7 +214,7 @@ static ssize_t summary_show(struct usnic_ib_qp_grp *qp_grp, char *buf)
        struct usnic_vnic_res *vnic_res;
        int len;
 
-       len = sysfs_emit(buf, "QPN: %d State: (%s) PID: %u VF Idx: %hu ",
+       len = sysfs_emit(buf, "QPN: %d State: (%s) PID: %u VF Idx: %hu",
                         qp_grp->ibqp.qp_num,
                         usnic_ib_qp_grp_state_to_string(qp_grp->state),
                         qp_grp->owner_pid,
@@ -224,14 +224,13 @@ static ssize_t summary_show(struct usnic_ib_qp_grp *qp_grp, char *buf)
                res_chunk = qp_grp->res_chunk_list[i];
                for (j = 0; j < res_chunk->cnt; j++) {
                        vnic_res = res_chunk->res[j];
-                       len += sysfs_emit_at(
-                               buf, len, "%s[%d] ",
+                       len += sysfs_emit_at(buf, len, " %s[%d]",
                                usnic_vnic_res_type_to_str(vnic_res->type),
                                vnic_res->vnic_idx);
                }
        }
 
-       len = sysfs_emit_at(buf, len, "\n");
+       len += sysfs_emit_at(buf, len, "\n");
 
        return len;
 }
index c142f5e7f25f82d0d163570c5eb5663e1172e54c..de57f2fed743755b8d29ca4b7ae75563cd1c81ba 100644 (file)
@@ -509,6 +509,20 @@ static inline int ib_send_flags_to_pvrdma(int flags)
        return flags & PVRDMA_MASK(PVRDMA_SEND_FLAGS_MAX);
 }
 
+static inline int pvrdma_network_type_to_ib(enum pvrdma_network_type type)
+{
+       switch (type) {
+       case PVRDMA_NETWORK_ROCE_V1:
+               return RDMA_NETWORK_ROCE_V1;
+       case PVRDMA_NETWORK_IPV4:
+               return RDMA_NETWORK_IPV4;
+       case PVRDMA_NETWORK_IPV6:
+               return RDMA_NETWORK_IPV6;
+       default:
+               return RDMA_NETWORK_IPV6;
+       }
+}
+
 void pvrdma_qp_cap_to_ib(struct ib_qp_cap *dst,
                         const struct pvrdma_qp_cap *src);
 void ib_qp_cap_to_pvrdma(struct pvrdma_qp_cap *dst,
index a119ac3e103c8d6aebbaf945750a9c26cefc106e..6aa40bd2fd52d3dd921b32b7425adf338e1b0188 100644 (file)
@@ -367,7 +367,7 @@ retry:
        wc->dlid_path_bits = cqe->dlid_path_bits;
        wc->port_num = cqe->port_num;
        wc->vendor_err = cqe->vendor_err;
-       wc->network_hdr_type = cqe->network_hdr_type;
+       wc->network_hdr_type = pvrdma_network_type_to_ib(cqe->network_hdr_type);
 
        /* Update shared ring state */
        pvrdma_idx_ring_inc(&cq->ring_state->rx.cons_head, cq->ibcq.cqe);
index c4b06ced30a75b1b7441d130adfaa3a6d7bc1d8d..943914c2a50c70bd18e19306b743cc6709040fb5 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
 #include <linux/if.h>
+#include <linux/if_vlan.h>
 #include <net/udp_tunnel.h>
 #include <net/sch_generic.h>
 #include <linux/netfilter.h>
@@ -153,9 +154,14 @@ static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct udphdr *udph;
        struct net_device *ndev = skb->dev;
+       struct net_device *rdev = ndev;
        struct rxe_dev *rxe = rxe_get_dev_from_net(ndev);
        struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);
 
+       if (!rxe && is_vlan_dev(rdev)) {
+               rdev = vlan_dev_real_dev(ndev);
+               rxe = rxe_get_dev_from_net(rdev);
+       }
        if (!rxe)
                goto drop;
 
index 5a098083a9d225517de7b02dfeaf10587060076d..c7e3b6a4af38f929e9e9018465705cd75b069f34 100644 (file)
@@ -872,6 +872,11 @@ static enum resp_states do_complete(struct rxe_qp *qp,
                        else
                                wc->network_hdr_type = RDMA_NETWORK_IPV6;
 
+                       if (is_vlan_dev(skb->dev)) {
+                               wc->wc_flags |= IB_WC_WITH_VLAN;
+                               wc->vlan_id = vlan_dev_vlan_id(skb->dev);
+                       }
+
                        if (pkt->mask & RXE_IMMDT_MASK) {
                                wc->wc_flags |= IB_WC_WITH_IMM;
                                wc->ex.imm_data = immdt_imm(pkt);
index 0687f0ed60b838a96a00f6d015c192467fd0696a..8cc8ca4a9ac01d68dc8b82f753feb8f18f7cbac7 100644 (file)
@@ -215,9 +215,17 @@ static const struct xpad_device {
        { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
-       { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02a0, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02a1, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02a2, "PDP Wired Controller for Xbox One - Crimson Red", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x02a6, "PDP Wired Controller for Xbox One - Camo Series", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02a7, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02a8, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02ad, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02b3, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02b8, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
@@ -296,6 +304,9 @@ static const struct xpad_device {
        { 0x1bad, 0xfa01, "MadCatz GamePad", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
+       { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
+       { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
        { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
@@ -429,8 +440,12 @@ static const struct usb_device_id xpad_table[] = {
        XPAD_XBOX360_VENDOR(0x162e),            /* Joytech X-Box 360 controllers */
        XPAD_XBOX360_VENDOR(0x1689),            /* Razer Onza */
        XPAD_XBOX360_VENDOR(0x1bad),            /* Harminix Rock Band Guitar and Drums */
+       XPAD_XBOX360_VENDOR(0x20d6),            /* PowerA Controllers */
+       XPAD_XBOXONE_VENDOR(0x20d6),            /* PowerA Controllers */
        XPAD_XBOX360_VENDOR(0x24c6),            /* PowerA Controllers */
        XPAD_XBOXONE_VENDOR(0x24c6),            /* PowerA Controllers */
+       XPAD_XBOXONE_VENDOR(0x2e24),            /* Hyperkin Duke X-Box One pad */
+       XPAD_XBOX360_VENDOR(0x2f24),            /* GameSir Controllers */
        { }
 };
 
index eda86ab552b9cea04e49afffd9f63bfd05a39a69..17bbaac8b80c892692264cc63772f0a5f25879d3 100644 (file)
@@ -149,12 +149,6 @@ static const struct of_device_id ariel_pwrbutton_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, ariel_pwrbutton_of_match);
 
-static const struct spi_device_id ariel_pwrbutton_id_table[] = {
-       { "wyse-ariel-ec-input", 0 },
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ariel_pwrbutton_id_table);
-
 static struct spi_driver ariel_pwrbutton_driver = {
        .driver = {
                .name = "dell-wyse-ariel-ec-input",
index 3a2dcf0805f12386116d46a99a65d1ab5b0c60c7..c74b020796a94134434d79014c48e562136144d1 100644 (file)
@@ -219,6 +219,8 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
                },
+       },
+       {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"),
index 19765f1c04f7e3bad7b0e8357b5332545a01c89e..c682b028f0a29d2edb623030c790ebea4540e574 100644 (file)
@@ -157,6 +157,7 @@ static const struct goodix_chip_id goodix_chip_ids[] = {
        { .id = "5663", .data = &gt1x_chip_data },
        { .id = "5688", .data = &gt1x_chip_data },
        { .id = "917S", .data = &gt1x_chip_data },
+       { .id = "9286", .data = &gt1x_chip_data },
 
        { .id = "911", .data = &gt911_chip_data },
        { .id = "9271", .data = &gt911_chip_data },
@@ -1448,6 +1449,7 @@ static const struct of_device_id goodix_of_match[] = {
        { .compatible = "goodix,gt927" },
        { .compatible = "goodix,gt9271" },
        { .compatible = "goodix,gt928" },
+       { .compatible = "goodix,gt9286" },
        { .compatible = "goodix,gt967" },
        { }
 };
index 199cf3daec10661d13e248cec654b3fddd3b4ae6..d8fccf048bf449b465422922e96deaaf71a2a40f 100644 (file)
@@ -29,11 +29,13 @@ struct ili2xxx_chip {
                        void *buf, size_t len);
        int (*get_touch_data)(struct i2c_client *client, u8 *data);
        bool (*parse_touch_data)(const u8 *data, unsigned int finger,
-                                unsigned int *x, unsigned int *y);
+                                unsigned int *x, unsigned int *y,
+                                unsigned int *z);
        bool (*continue_polling)(const u8 *data, bool touch);
        unsigned int max_touches;
        unsigned int resolution;
        bool has_calibrate_reg;
+       bool has_pressure_reg;
 };
 
 struct ili210x {
@@ -82,7 +84,8 @@ static int ili210x_read_touch_data(struct i2c_client *client, u8 *data)
 
 static bool ili210x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        if (touchdata[0] & BIT(finger))
                return false;
@@ -137,7 +140,8 @@ static int ili211x_read_touch_data(struct i2c_client *client, u8 *data)
 
 static bool ili211x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        u32 data;
 
@@ -169,7 +173,8 @@ static const struct ili2xxx_chip ili211x_chip = {
 
 static bool ili212x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        u16 val;
 
@@ -235,7 +240,8 @@ static int ili251x_read_touch_data(struct i2c_client *client, u8 *data)
 
 static bool ili251x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        u16 val;
 
@@ -245,6 +251,7 @@ static bool ili251x_touchdata_to_coords(const u8 *touchdata,
 
        *x = val & 0x3fff;
        *y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2);
+       *z = touchdata[1 + (finger * 5) + 4];
 
        return true;
 }
@@ -261,6 +268,7 @@ static const struct ili2xxx_chip ili251x_chip = {
        .continue_polling       = ili251x_check_continue_polling,
        .max_touches            = 10,
        .has_calibrate_reg      = true,
+       .has_pressure_reg       = true,
 };
 
 static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
@@ -268,14 +276,16 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
        struct input_dev *input = priv->input;
        int i;
        bool contact = false, touch;
-       unsigned int x = 0, y = 0;
+       unsigned int x = 0, y = 0, z = 0;
 
        for (i = 0; i < priv->chip->max_touches; i++) {
-               touch = priv->chip->parse_touch_data(touchdata, i, &x, &y);
+               touch = priv->chip->parse_touch_data(touchdata, i, &x, &y, &z);
 
                input_mt_slot(input, i);
                if (input_mt_report_slot_state(input, MT_TOOL_FINGER, touch)) {
                        touchscreen_report_pos(input, &priv->prop, x, y, true);
+                       if (priv->chip->has_pressure_reg)
+                               input_report_abs(input, ABS_MT_PRESSURE, z);
                        contact = true;
                }
        }
@@ -437,6 +447,8 @@ static int ili210x_i2c_probe(struct i2c_client *client,
        max_xy = (chip->resolution ?: SZ_64K) - 1;
        input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0);
        input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0);
+       if (priv->chip->has_pressure_reg)
+               input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xa, 0, 0);
        touchscreen_parse_properties(input, true, &priv->prop);
 
        error = input_mt_init_slots(input, priv->chip->max_touches,
index bda96762744e6da3e9c3d9a1549a5fc54c9c35b8..b4e7bcbe9b91d9c5e527ccb4d773e20ae4b8d847 100644 (file)
 #define ST1232_TS_NAME "st1232-ts"
 #define ST1633_TS_NAME "st1633-ts"
 
+#define REG_STATUS             0x01    /* Device Status | Error Code */
+
+#define STATUS_NORMAL          0x00
+#define STATUS_INIT            0x01
+#define STATUS_ERROR           0x02
+#define STATUS_AUTO_TUNING     0x03
+#define STATUS_IDLE            0x04
+#define STATUS_POWER_DOWN      0x05
+
+#define ERROR_NONE             0x00
+#define ERROR_INVALID_ADDRESS  0x10
+#define ERROR_INVALID_VALUE    0x20
+#define ERROR_INVALID_PLATFORM 0x30
+
 #define REG_XY_RESOLUTION      0x04
 #define REG_XY_COORDINATES     0x12
 #define ST_TS_MAX_FINGERS      10
@@ -47,7 +61,8 @@ struct st1232_ts_data {
        u8 *read_buf;
 };
 
-static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg)
+static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg,
+                              unsigned int n)
 {
        struct i2c_client *client = ts->client;
        struct i2c_msg msg[] = {
@@ -59,7 +74,7 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg)
                {
                        .addr   = client->addr,
                        .flags  = I2C_M_RD | I2C_M_DMA_SAFE,
-                       .len    = ts->read_buf_len,
+                       .len    = n,
                        .buf    = ts->read_buf,
                }
        };
@@ -72,6 +87,22 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg)
        return 0;
 }
 
+static int st1232_ts_wait_ready(struct st1232_ts_data *ts)
+{
+       unsigned int retries;
+       int error;
+
+       for (retries = 10; retries; retries--) {
+               error = st1232_ts_read_data(ts, REG_STATUS, 1);
+               if (!error && ts->read_buf[0] == (STATUS_NORMAL | ERROR_NONE))
+                       return 0;
+
+               usleep_range(1000, 2000);
+       }
+
+       return -ENXIO;
+}
+
 static int st1232_ts_read_resolution(struct st1232_ts_data *ts, u16 *max_x,
                                     u16 *max_y)
 {
@@ -79,14 +110,14 @@ static int st1232_ts_read_resolution(struct st1232_ts_data *ts, u16 *max_x,
        int error;
 
        /* select resolution register */
-       error = st1232_ts_read_data(ts, REG_XY_RESOLUTION);
+       error = st1232_ts_read_data(ts, REG_XY_RESOLUTION, 3);
        if (error)
                return error;
 
        buf = ts->read_buf;
 
-       *max_x = ((buf[0] & 0x0070) << 4) | buf[1];
-       *max_y = ((buf[0] & 0x0007) << 8) | buf[2];
+       *max_x = (((buf[0] & 0x0070) << 4) | buf[1]) - 1;
+       *max_y = (((buf[0] & 0x0007) << 8) | buf[2]) - 1;
 
        return 0;
 }
@@ -140,7 +171,7 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
        int count;
        int error;
 
-       error = st1232_ts_read_data(ts, REG_XY_COORDINATES);
+       error = st1232_ts_read_data(ts, REG_XY_COORDINATES, ts->read_buf_len);
        if (error)
                goto out;
 
@@ -251,6 +282,11 @@ static int st1232_ts_probe(struct i2c_client *client,
        input_dev->name = "st1232-touchscreen";
        input_dev->id.bustype = BUS_I2C;
 
+       /* Wait until device is ready */
+       error = st1232_ts_wait_ready(ts);
+       if (error)
+               return error;
+
        /* Read resolution from the chip */
        error = st1232_ts_read_resolution(ts, &max_x, &max_y);
        if (error) {
index 6b8cbdf7171407bfbe8f6114cf7cc40a8b02b897..b4adab69856323b3f9158720dac5dc673249974e 100644 (file)
@@ -84,12 +84,9 @@ static inline bool is_rd890_iommu(struct pci_dev *pdev)
               (pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
 }
 
-static inline bool iommu_feature(struct amd_iommu *iommu, u64 f)
+static inline bool iommu_feature(struct amd_iommu *iommu, u64 mask)
 {
-       if (!(iommu->cap & (1 << IOMMU_CAP_EFR)))
-               return false;
-
-       return !!(iommu->features & f);
+       return !!(iommu->features & mask);
 }
 
 static inline u64 iommu_virt_to_phys(void *vaddr)
index 5535878277710e4dbf9abe666a9b34254d6287b3..1a0495dd5fcbc1a3568a93cda4eb799fb5baf92e 100644 (file)
 #define IOMMU_CAP_NPCACHE 26
 #define IOMMU_CAP_EFR     27
 
+/* IOMMU IVINFO */
+#define IOMMU_IVINFO_OFFSET     36
+#define IOMMU_IVINFO_EFRSUP     BIT(0)
+
 /* IOMMU Feature Reporting Field (for IVHD type 10h */
 #define IOMMU_FEAT_GASUP_SHIFT 6
 
index 6a1f7048dacc6642ddca950bbdd497eafb9463e6..83d8ab2aed9f45e32e505350a511ca10d7a41d80 100644 (file)
@@ -257,6 +257,8 @@ static void init_device_table_dma(void);
 
 static bool amd_iommu_pre_enabled = true;
 
+static u32 amd_iommu_ivinfo __initdata;
+
 bool translation_pre_enabled(struct amd_iommu *iommu)
 {
        return (iommu->flags & AMD_IOMMU_FLAG_TRANS_PRE_ENABLED);
@@ -296,6 +298,18 @@ int amd_iommu_get_num_iommus(void)
        return amd_iommus_present;
 }
 
+/*
+ * For IVHD type 0x11/0x40, EFR is also available via IVHD.
+ * Default to IVHD EFR since it is available sooner
+ * (i.e. before PCI init).
+ */
+static void __init early_iommu_features_init(struct amd_iommu *iommu,
+                                            struct ivhd_header *h)
+{
+       if (amd_iommu_ivinfo & IOMMU_IVINFO_EFRSUP)
+               iommu->features = h->efr_reg;
+}
+
 /* Access to l1 and l2 indexed register spaces */
 
 static u32 iommu_read_l1(struct amd_iommu *iommu, u16 l1, u8 address)
@@ -1577,6 +1591,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
 
                if (h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT))
                        amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
+
+               early_iommu_features_init(iommu, h);
+
                break;
        default:
                return -EINVAL;
@@ -1770,6 +1787,35 @@ static const struct attribute_group *amd_iommu_groups[] = {
        NULL,
 };
 
+/*
+ * Note: IVHD 0x11 and 0x40 also contains exact copy
+ * of the IOMMU Extended Feature Register [MMIO Offset 0030h].
+ * Default to EFR in IVHD since it is available sooner (i.e. before PCI init).
+ */
+static void __init late_iommu_features_init(struct amd_iommu *iommu)
+{
+       u64 features;
+
+       if (!(iommu->cap & (1 << IOMMU_CAP_EFR)))
+               return;
+
+       /* read extended feature bits */
+       features = readq(iommu->mmio_base + MMIO_EXT_FEATURES);
+
+       if (!iommu->features) {
+               iommu->features = features;
+               return;
+       }
+
+       /*
+        * Sanity check and warn if EFR values from
+        * IVHD and MMIO conflict.
+        */
+       if (features != iommu->features)
+               pr_warn(FW_WARN "EFR mismatch. Use IVHD EFR (%#llx : %#llx\n).",
+                       features, iommu->features);
+}
+
 static int __init iommu_init_pci(struct amd_iommu *iommu)
 {
        int cap_ptr = iommu->cap_ptr;
@@ -1789,8 +1835,7 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
        if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))
                amd_iommu_iotlb_sup = false;
 
-       /* read extended feature bits */
-       iommu->features = readq(iommu->mmio_base + MMIO_EXT_FEATURES);
+       late_iommu_features_init(iommu);
 
        if (iommu_feature(iommu, FEATURE_GT)) {
                int glxval;
@@ -2607,6 +2652,11 @@ static void __init free_dma_resources(void)
        free_unity_maps();
 }
 
+static void __init ivinfo_init(void *ivrs)
+{
+       amd_iommu_ivinfo = *((u32 *)(ivrs + IOMMU_IVINFO_OFFSET));
+}
+
 /*
  * This is the hardware init function for AMD IOMMU in the system.
  * This function is called either from amd_iommu_init or from the interrupt
@@ -2661,6 +2711,8 @@ static int __init early_amd_iommu_init(void)
        if (ret)
                goto out;
 
+       ivinfo_init(ivrs_base);
+
        amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base);
        DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type);
 
index 004feaed3c72cf0304b3392f51955143926e7f94..02e7c10a4224b0b351965ff4bd760c55b46885a5 100644 (file)
@@ -1496,7 +1496,7 @@ void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid,
         * Max Invs Pending (MIP) is set to 0 for now until we have DIT in
         * ECAP.
         */
-       if (addr & GENMASK_ULL(size_order + VTD_PAGE_SHIFT, 0))
+       if (!IS_ALIGNED(addr, VTD_PAGE_SIZE << size_order))
                pr_warn_ratelimited("Invalidate non-aligned address %llx, order %d\n",
                                    addr, size_order);
 
index f665322a09919fbaea5dd3eae59c7ac87a7fe04d..06b00b5363d8630ebe7421fc78c127f517f2074d 100644 (file)
@@ -5440,6 +5440,36 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain,
        return ret;
 }
 
+static bool domain_use_flush_queue(void)
+{
+       struct dmar_drhd_unit *drhd;
+       struct intel_iommu *iommu;
+       bool r = true;
+
+       if (intel_iommu_strict)
+               return false;
+
+       /*
+        * The flush queue implementation does not perform page-selective
+        * invalidations that are required for efficient TLB flushes in virtual
+        * environments. The benefit of batching is likely to be much lower than
+        * the overhead of synchronizing the virtual and physical IOMMU
+        * page-tables.
+        */
+       rcu_read_lock();
+       for_each_active_iommu(iommu, drhd) {
+               if (!cap_caching_mode(iommu->cap))
+                       continue;
+
+               pr_warn_once("IOMMU batching is disabled due to virtualization");
+               r = false;
+               break;
+       }
+       rcu_read_unlock();
+
+       return r;
+}
+
 static int
 intel_iommu_domain_get_attr(struct iommu_domain *domain,
                            enum iommu_attr attr, void *data)
@@ -5450,7 +5480,7 @@ intel_iommu_domain_get_attr(struct iommu_domain *domain,
        case IOMMU_DOMAIN_DMA:
                switch (attr) {
                case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE:
-                       *(int *)data = !intel_iommu_strict;
+                       *(int *)data = domain_use_flush_queue();
                        return 0;
                default:
                        return -ENODEV;
index 849d3c5f908e4d597f4cf0225d596549ccdee770..6c1d8b69a465a12bd8d19a0e77e3a1b3747cc1eb 100644 (file)
@@ -928,6 +928,9 @@ config LEDS_ACER_A500
          This option enables support for the Power Button LED of
          Acer Iconia Tab A500.
 
+comment "Flash and Torch LED drivers"
+source "drivers/leds/flash/Kconfig"
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
index 73e603e1727e7440ae1d43d072ff4a2ee6096ea0..156c0b4e60d95db595bc806780e11efc0c5e3050 100644 (file)
@@ -103,5 +103,8 @@ obj-$(CONFIG_LEDS_SPI_BYTE)         += leds-spi-byte.o
 # LED Userspace Drivers
 obj-$(CONFIG_LEDS_USER)                        += uleds.o
 
+# Flash and Torch LED Drivers
+obj-$(CONFIG_LEDS_CLASS_FLASH)         += flash/
+
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGERS)            += trigger/
diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig
new file mode 100644 (file)
index 0000000..d21d273
--- /dev/null
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if LEDS_CLASS_FLASH
+
+config LEDS_RT8515
+       tristate "LED support for Richtek RT8515 flash/torch LED"
+       depends on GPIOLIB
+       help
+         This option enables support for the Richtek RT8515 flash
+         and torch LEDs found on some mobile phones.
+
+         To compile this driver as a module, choose M here: the module
+         will be called leds-rt8515.
+
+endif # LEDS_CLASS_FLASH
diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile
new file mode 100644 (file)
index 0000000..e990e25
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_LEDS_RT8515)      += leds-rt8515.o
diff --git a/drivers/leds/flash/leds-rt8515.c b/drivers/leds/flash/leds-rt8515.c
new file mode 100644 (file)
index 0000000..590bfa1
--- /dev/null
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * LED driver for Richtek RT8515 flash/torch white LEDs
+ * found on some Samsung mobile phones.
+ *
+ * This is a 1.5A Boost dual channel driver produced around 2011.
+ *
+ * The component lacks a datasheet, but in the schematic picture
+ * from the LG P970 service manual you can see the connections
+ * from the RT8515 to the LED, with two resistors connected
+ * from the pins "RFS" and "RTS" to ground.
+ *
+ * On the LG P970:
+ * RFS (resistance flash setting?) is 20 kOhm
+ * RTS (resistance torch setting?) is 39 kOhm
+ *
+ * Some sleuthing finds us the RT9387A which we have a datasheet for:
+ * https://static5.arrow.com/pdfs/2014/7/27/8/21/12/794/rtt_/manual/94download_ds.jspprt9387a.jspprt9387a.pdf
+ * This apparently works the same way so in theory this driver
+ * should cover RT9387A as well. This has not been tested, please
+ * update the compatibles if you add RT9387A support.
+ *
+ * Linus Walleij <linus.walleij@linaro.org>
+ */
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/led-class-flash.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+
+#include <media/v4l2-flash-led-class.h>
+
+/* We can provide 15-700 mA out to the LED */
+#define RT8515_MIN_IOUT_MA     15
+#define RT8515_MAX_IOUT_MA     700
+/* The maximum intensity is 1-16 for flash and 1-100 for torch */
+#define RT8515_FLASH_MAX       16
+#define RT8515_TORCH_MAX       100
+
+#define RT8515_TIMEOUT_US      250000U
+#define RT8515_MAX_TIMEOUT_US  300000U
+
+struct rt8515 {
+       struct led_classdev_flash fled;
+       struct device *dev;
+       struct v4l2_flash *v4l2_flash;
+       struct mutex lock;
+       struct regulator *reg;
+       struct gpio_desc *enable_torch;
+       struct gpio_desc *enable_flash;
+       struct timer_list powerdown_timer;
+       u32 max_timeout; /* Flash max timeout */
+       int flash_max_intensity;
+       int torch_max_intensity;
+};
+
+static struct rt8515 *to_rt8515(struct led_classdev_flash *fled)
+{
+       return container_of(fled, struct rt8515, fled);
+}
+
+static void rt8515_gpio_led_off(struct rt8515 *rt)
+{
+       gpiod_set_value(rt->enable_flash, 0);
+       gpiod_set_value(rt->enable_torch, 0);
+}
+
+static void rt8515_gpio_brightness_commit(struct gpio_desc *gpiod,
+                                         int brightness)
+{
+       int i;
+
+       /*
+        * Toggling a GPIO line with a small delay increases the
+        * brightness one step at a time.
+        */
+       for (i = 0; i < brightness; i++) {
+               gpiod_set_value(gpiod, 0);
+               udelay(1);
+               gpiod_set_value(gpiod, 1);
+               udelay(1);
+       }
+}
+
+/* This is setting the torch light level */
+static int rt8515_led_brightness_set(struct led_classdev *led,
+                                    enum led_brightness brightness)
+{
+       struct led_classdev_flash *fled = lcdev_to_flcdev(led);
+       struct rt8515 *rt = to_rt8515(fled);
+
+       mutex_lock(&rt->lock);
+
+       if (brightness == LED_OFF) {
+               /* Off */
+               rt8515_gpio_led_off(rt);
+       } else if (brightness < RT8515_TORCH_MAX) {
+               /* Step it up to movie mode brightness using the flash pin */
+               rt8515_gpio_brightness_commit(rt->enable_torch, brightness);
+       } else {
+               /* Max torch brightness requested */
+               gpiod_set_value(rt->enable_torch, 1);
+       }
+
+       mutex_unlock(&rt->lock);
+
+       return 0;
+}
+
+static int rt8515_led_flash_strobe_set(struct led_classdev_flash *fled,
+                                      bool state)
+{
+       struct rt8515 *rt = to_rt8515(fled);
+       struct led_flash_setting *timeout = &fled->timeout;
+       int brightness = rt->flash_max_intensity;
+
+       mutex_lock(&rt->lock);
+
+       if (state) {
+               /* Enable LED flash mode and set brightness */
+               rt8515_gpio_brightness_commit(rt->enable_flash, brightness);
+               /* Set timeout */
+               mod_timer(&rt->powerdown_timer,
+                         jiffies + usecs_to_jiffies(timeout->val));
+       } else {
+               del_timer_sync(&rt->powerdown_timer);
+               /* Turn the LED off */
+               rt8515_gpio_led_off(rt);
+       }
+
+       fled->led_cdev.brightness = LED_OFF;
+       /* After this the torch LED will be disabled */
+
+       mutex_unlock(&rt->lock);
+
+       return 0;
+}
+
+static int rt8515_led_flash_strobe_get(struct led_classdev_flash *fled,
+                                      bool *state)
+{
+       struct rt8515 *rt = to_rt8515(fled);
+
+       *state = timer_pending(&rt->powerdown_timer);
+
+       return 0;
+}
+
+static int rt8515_led_flash_timeout_set(struct led_classdev_flash *fled,
+                                       u32 timeout)
+{
+       /* The timeout is stored in the led-class-flash core */
+       return 0;
+}
+
+static const struct led_flash_ops rt8515_flash_ops = {
+       .strobe_set = rt8515_led_flash_strobe_set,
+       .strobe_get = rt8515_led_flash_strobe_get,
+       .timeout_set = rt8515_led_flash_timeout_set,
+};
+
+static void rt8515_powerdown_timer(struct timer_list *t)
+{
+       struct rt8515 *rt = from_timer(rt, t, powerdown_timer);
+
+       /* Turn the LED off */
+       rt8515_gpio_led_off(rt);
+}
+
+static void rt8515_init_flash_timeout(struct rt8515 *rt)
+{
+       struct led_classdev_flash *fled = &rt->fled;
+       struct led_flash_setting *s;
+
+       /* Init flash timeout setting */
+       s = &fled->timeout;
+       s->min = 1;
+       s->max = rt->max_timeout;
+       s->step = 1;
+       /*
+        * Set default timeout to RT8515_TIMEOUT_US except if
+        * max_timeout from DT is lower.
+        */
+       s->val = min(rt->max_timeout, RT8515_TIMEOUT_US);
+}
+
+#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
+/* Configure the V2L2 flash subdevice */
+static void rt8515_init_v4l2_flash_config(struct rt8515 *rt,
+                                         struct v4l2_flash_config *v4l2_sd_cfg)
+{
+       struct led_classdev *led = &rt->fled.led_cdev;
+       struct led_flash_setting *s;
+
+       strscpy(v4l2_sd_cfg->dev_name, led->dev->kobj.name,
+               sizeof(v4l2_sd_cfg->dev_name));
+
+       /*
+        * Init flash intensity setting: this is a linear scale
+        * capped from the device tree max intensity setting
+        * 1..flash_max_intensity
+        */
+       s = &v4l2_sd_cfg->intensity;
+       s->min = 1;
+       s->max = rt->flash_max_intensity;
+       s->step = 1;
+       s->val = s->max;
+}
+
+static void rt8515_v4l2_flash_release(struct rt8515 *rt)
+{
+       v4l2_flash_release(rt->v4l2_flash);
+}
+
+#else
+static void rt8515_init_v4l2_flash_config(struct rt8515 *rt,
+                                         struct v4l2_flash_config *v4l2_sd_cfg)
+{
+}
+
+static void rt8515_v4l2_flash_release(struct rt8515 *rt)
+{
+}
+#endif
+
+static void rt8515_determine_max_intensity(struct rt8515 *rt,
+                                          struct fwnode_handle *led,
+                                          const char *resistance,
+                                          const char *max_ua_prop, int hw_max,
+                                          int *max_intensity_setting)
+{
+       u32 res = 0; /* Can't be 0 so 0 is undefined */
+       u32 ua;
+       u32 max_ma;
+       int max_intensity;
+       int ret;
+
+       fwnode_property_read_u32(rt->dev->fwnode, resistance, &res);
+       ret = fwnode_property_read_u32(led, max_ua_prop, &ua);
+
+       /* Missing info in DT, OK go with hardware maxima */
+       if (ret || res == 0) {
+               dev_err(rt->dev,
+                       "either %s or %s missing from DT, using HW max\n",
+                       resistance, max_ua_prop);
+               max_ma = RT8515_MAX_IOUT_MA;
+               max_intensity = hw_max;
+               goto out_assign_max;
+       }
+
+       /*
+        * Formula from the datasheet, this is the maximum current
+        * defined by the hardware.
+        */
+       max_ma = (5500 * 1000) / res;
+       /*
+        * Calculate max intensity (linear scaling)
+        * Formula is ((ua / 1000) / max_ma) * 100, then simplified
+        */
+       max_intensity = (ua / 10) / max_ma;
+
+       dev_info(rt->dev,
+                "current restricted from %u to %u mA, max intensity %d/100\n",
+                max_ma, (ua / 1000), max_intensity);
+
+out_assign_max:
+       dev_info(rt->dev, "max intensity %d/%d = %d mA\n",
+                max_intensity, hw_max, max_ma);
+       *max_intensity_setting = max_intensity;
+}
+
+static int rt8515_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct fwnode_handle *child;
+       struct rt8515 *rt;
+       struct led_classdev *led;
+       struct led_classdev_flash *fled;
+       struct led_init_data init_data = {};
+       struct v4l2_flash_config v4l2_sd_cfg = {};
+       int ret;
+
+       rt = devm_kzalloc(dev, sizeof(*rt), GFP_KERNEL);
+       if (!rt)
+               return -ENOMEM;
+
+       rt->dev = dev;
+       fled = &rt->fled;
+       led = &fled->led_cdev;
+
+       /* ENF - Enable Flash line */
+       rt->enable_flash = devm_gpiod_get(dev, "enf", GPIOD_OUT_LOW);
+       if (IS_ERR(rt->enable_flash))
+               return dev_err_probe(dev, PTR_ERR(rt->enable_flash),
+                                    "cannot get ENF (enable flash) GPIO\n");
+
+       /* ENT - Enable Torch line */
+       rt->enable_torch = devm_gpiod_get(dev, "ent", GPIOD_OUT_LOW);
+       if (IS_ERR(rt->enable_torch))
+               return dev_err_probe(dev, PTR_ERR(rt->enable_torch),
+                                    "cannot get ENT (enable torch) GPIO\n");
+
+       child = fwnode_get_next_available_child_node(dev->fwnode, NULL);
+       if (!child) {
+               dev_err(dev,
+                       "No fwnode child node found for connected LED.\n");
+               return -EINVAL;
+       }
+       init_data.fwnode = child;
+
+       rt8515_determine_max_intensity(rt, child, "richtek,rfs-ohms",
+                                      "flash-max-microamp",
+                                      RT8515_FLASH_MAX,
+                                      &rt->flash_max_intensity);
+       rt8515_determine_max_intensity(rt, child, "richtek,rts-ohms",
+                                      "led-max-microamp",
+                                      RT8515_TORCH_MAX,
+                                      &rt->torch_max_intensity);
+
+       ret = fwnode_property_read_u32(child, "flash-max-timeout-us",
+                                      &rt->max_timeout);
+       if (ret) {
+               rt->max_timeout = RT8515_MAX_TIMEOUT_US;
+               dev_warn(dev,
+                        "flash-max-timeout-us property missing\n");
+       }
+       timer_setup(&rt->powerdown_timer, rt8515_powerdown_timer, 0);
+       rt8515_init_flash_timeout(rt);
+
+       fled->ops = &rt8515_flash_ops;
+
+       led->max_brightness = rt->torch_max_intensity;
+       led->brightness_set_blocking = rt8515_led_brightness_set;
+       led->flags |= LED_CORE_SUSPENDRESUME | LED_DEV_CAP_FLASH;
+
+       mutex_init(&rt->lock);
+
+       platform_set_drvdata(pdev, rt);
+
+       ret = devm_led_classdev_flash_register_ext(dev, fled, &init_data);
+       if (ret) {
+               dev_err(dev, "can't register LED %s\n", led->name);
+               mutex_destroy(&rt->lock);
+               return ret;
+       }
+
+       rt8515_init_v4l2_flash_config(rt, &v4l2_sd_cfg);
+
+       /* Create a V4L2 Flash device if V4L2 flash is enabled */
+       rt->v4l2_flash = v4l2_flash_init(dev, child, fled, NULL, &v4l2_sd_cfg);
+       if (IS_ERR(rt->v4l2_flash)) {
+               ret = PTR_ERR(rt->v4l2_flash);
+               dev_err(dev, "failed to register V4L2 flash device (%d)\n",
+                       ret);
+               /*
+                * Continue without the V4L2 flash
+                * (we still have the classdev)
+                */
+       }
+
+       return 0;
+}
+
+static int rt8515_remove(struct platform_device *pdev)
+{
+       struct rt8515 *rt = platform_get_drvdata(pdev);
+
+       rt8515_v4l2_flash_release(rt);
+       del_timer_sync(&rt->powerdown_timer);
+       mutex_destroy(&rt->lock);
+
+       return 0;
+}
+
+static const struct of_device_id rt8515_match[] = {
+       { .compatible = "richtek,rt8515", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rt8515_match);
+
+static struct platform_driver rt8515_driver = {
+       .driver = {
+               .name  = "rt8515",
+               .of_match_table = rt8515_match,
+       },
+       .probe  = rt8515_probe,
+       .remove = rt8515_remove,
+};
+module_platform_driver(rt8515_driver);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("Richtek RT8515 LED driver");
+MODULE_LICENSE("GPL");
index 91da90cfb11d9f60b9ff564eb387a49419a90a1e..4e7b78a84149be077e10bc4d0119350c2fabf810 100644 (file)
@@ -378,14 +378,15 @@ void led_trigger_event(struct led_trigger *trig,
                        enum led_brightness brightness)
 {
        struct led_classdev *led_cdev;
+       unsigned long flags;
 
        if (!trig)
                return;
 
-       read_lock(&trig->leddev_list_lock);
+       read_lock_irqsave(&trig->leddev_list_lock, flags);
        list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list)
                led_set_brightness(led_cdev, brightness);
-       read_unlock(&trig->leddev_list_lock);
+       read_unlock_irqrestore(&trig->leddev_list_lock, flags);
 }
 EXPORT_SYMBOL_GPL(led_trigger_event);
 
@@ -396,11 +397,12 @@ static void led_trigger_blink_setup(struct led_trigger *trig,
                             int invert)
 {
        struct led_classdev *led_cdev;
+       unsigned long flags;
 
        if (!trig)
                return;
 
-       read_lock(&trig->leddev_list_lock);
+       read_lock_irqsave(&trig->leddev_list_lock, flags);
        list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) {
                if (oneshot)
                        led_blink_set_oneshot(led_cdev, delay_on, delay_off,
@@ -408,7 +410,7 @@ static void led_trigger_blink_setup(struct led_trigger *trig,
                else
                        led_blink_set(led_cdev, delay_on, delay_off);
        }
-       read_unlock(&trig->leddev_list_lock);
+       read_unlock_irqrestore(&trig->leddev_list_lock, flags);
 }
 
 void led_trigger_blink(struct led_trigger *trig,
index bb68ba23a7d448e32a8a97f93356131305559db6..49e1bddaa15e0f6a845c76468b827e91c778c4e7 100644 (file)
@@ -96,14 +96,14 @@ static int ariel_led_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        leds[0].ec_index = EC_BLUE_LED;
-       leds[0].led_cdev.name = "blue:power",
+       leds[0].led_cdev.name = "blue:power";
        leds[0].led_cdev.default_trigger = "default-on";
 
        leds[1].ec_index = EC_AMBER_LED;
-       leds[1].led_cdev.name = "amber:status",
+       leds[1].led_cdev.name = "amber:status";
 
        leds[2].ec_index = EC_GREEN_LED;
-       leds[2].led_cdev.name = "green:status",
+       leds[2].led_cdev.name = "green:status";
        leds[2].led_cdev.default_trigger = "default-on";
 
        for (i = 0; i < NLEDS; i++) {
index b3edee7031931eae380a762f30d866ac3af36da3..9dd205870525c4f753d656b169e94d2754fbb768 100644 (file)
@@ -679,7 +679,7 @@ static int lm3533_led_probe(struct platform_device *pdev)
        led->cdev.brightness_get = lm3533_led_get;
        led->cdev.blink_set = lm3533_led_blink_set;
        led->cdev.brightness = LED_OFF;
-       led->cdev.groups = lm3533_led_attribute_groups,
+       led->cdev.groups = lm3533_led_attribute_groups;
        led->id = pdev->id;
 
        mutex_init(&led->mutex);
index 84fc2c0f01015b280ed86ba702c99ef29db95465..d1c8fd3977fc64461215673c18e67ef9f937d03d 100644 (file)
@@ -33,6 +33,8 @@
 #define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \
 static inline int bch_has_feature_##name(struct cache_sb *sb) \
 { \
+       if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
+               return 0; \
        return (((sb)->feature_compat & \
                BCH##_FEATURE_COMPAT_##flagname) != 0); \
 } \
@@ -50,6 +52,8 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \
 #define BCH_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
 static inline int bch_has_feature_##name(struct cache_sb *sb) \
 { \
+       if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
+               return 0; \
        return (((sb)->feature_ro_compat & \
                BCH##_FEATURE_RO_COMPAT_##flagname) != 0); \
 } \
@@ -67,6 +71,8 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \
 #define BCH_FEATURE_INCOMPAT_FUNCS(name, flagname) \
 static inline int bch_has_feature_##name(struct cache_sb *sb) \
 { \
+       if (sb->version < BCACHE_SB_VERSION_CDEV_WITH_FEATURES) \
+               return 0; \
        return (((sb)->feature_incompat & \
                BCH##_FEATURE_INCOMPAT_##flagname) != 0); \
 } \
index 3a947159b25ac95e2804c8a6d890408840a48427..ea6f8ee8161c963ccab70588871ab0519af1d974 100644 (file)
@@ -10,5 +10,6 @@ obj-$(CONFIG_CEC_MESON_AO)    += meson/
 obj-$(CONFIG_CEC_SAMSUNG_S5P)  += s5p/
 obj-$(CONFIG_CEC_SECO)         += seco/
 obj-$(CONFIG_CEC_STI)          += sti/
+obj-$(CONFIG_CEC_STM32)                += stm32/
 obj-$(CONFIG_CEC_TEGRA)                += tegra/
 
index 96d3b2b2aa31882869448b83ae8a0f66cb46d90a..3f61f5863bf7748caa0855eb0bfe02f71a2fe8ec 100644 (file)
@@ -118,8 +118,7 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
                                return -EINVAL;
                }
        } else {
-               length = (b->memory == VB2_MEMORY_USERPTR ||
-                         b->memory == VB2_MEMORY_DMABUF)
+               length = (b->memory == VB2_MEMORY_USERPTR)
                        ? b->length : vb->planes[0].length;
 
                if (b->bytesused > length)
index eb7b6f01f6231ccbdb1d32f463be79ab34e9b3af..58ca47e904a1496ad3837ba509ee1ed3a789fcd6 100644 (file)
@@ -772,14 +772,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
 
        switch (pll->bus_type) {
        case CCS_PLL_BUS_TYPE_CSI2_DPHY:
-               /* CSI transfers 2 bits per clock per lane; thus times 2 */
-               op_sys_clk_freq_hz_sdr = pll->link_freq * 2
-                       * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
-                          1 : pll->csi2.lanes);
-               break;
        case CCS_PLL_BUS_TYPE_CSI2_CPHY:
-               op_sys_clk_freq_hz_sdr =
-                       pll->link_freq
+               op_sys_clk_freq_hz_sdr = pll->link_freq * 2
                        * (pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL ?
                           1 : pll->csi2.lanes);
                break;
index 9a6097b088bdfb69d69f9f1d26da62149e0a6a7a..6555bd4b325a61c4dd93218010cdb1df83e8ac64 100644 (file)
@@ -152,7 +152,7 @@ static int ccs_data_parse_version(struct bin_container *bin,
        vv->version_major = ((u16)v->static_data_version_major[0] << 8) +
                v->static_data_version_major[1];
        vv->version_minor = ((u16)v->static_data_version_minor[0] << 8) +
-               v->static_data_version_major[1];
+               v->static_data_version_minor[1];
        vv->date_year =  ((u16)v->year[0] << 8) + v->year[1];
        vv->date_month = v->month;
        vv->date_day = v->day;
index 36e354ecf71ecdcae1e9b378c26cd184088c95e8..6cada8a6e50cc21989ac7be9359da9a47f537ea2 100644 (file)
@@ -302,7 +302,7 @@ static int cio2_csi2_calc_timing(struct cio2_device *cio2, struct cio2_queue *q,
        if (!q->sensor)
                return -ENODEV;
 
-       freq = v4l2_get_link_rate(q->sensor->ctrl_handler, bpp, lanes);
+       freq = v4l2_get_link_freq(q->sensor->ctrl_handler, bpp, lanes);
        if (freq < 0) {
                dev_err(dev, "error %lld, invalid link_freq\n", freq);
                return freq;
index bdd293faaad0f5e2441754e7faaf93cd6dafb143..7233a731175774001148411217efb8690a1f3461 100644 (file)
@@ -349,8 +349,10 @@ static void venus_core_shutdown(struct platform_device *pdev)
 {
        struct venus_core *core = platform_get_drvdata(pdev);
 
+       pm_runtime_get_sync(core->dev);
        venus_shutdown(core);
        venus_firmware_deinit(core);
+       pm_runtime_put_sync(core->dev);
 }
 
 static __maybe_unused int venus_runtime_suspend(struct device *dev)
index 98bff765b02e67d9c5c4cba841ddd506eec4de87..e48d666f2c63abefe1746ac7bb4ac4bef64d006f 100644 (file)
@@ -654,7 +654,7 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin)
 out:
        fwnode_handle_put(fwnode);
 
-       return 0;
+       return ret;
 }
 
 static int rvin_parallel_init(struct rvin_dev *vin)
index 68da1eed753dc87bb0565ae8af658467d530942f..f7e9fd3055485fe897c694ff2599af08ee51d1e3 100644 (file)
 struct rkisp1_match_data {
        const char * const *clks;
        unsigned int size;
+       enum rkisp1_cif_isp_version isp_ver;
 };
 
 /* ----------------------------------------------------------------------------
@@ -411,15 +412,16 @@ static const char * const rk3399_isp_clks[] = {
        "hclk",
 };
 
-static const struct rkisp1_match_data rk3399_isp_clk_data = {
+static const struct rkisp1_match_data rk3399_isp_match_data = {
        .clks = rk3399_isp_clks,
        .size = ARRAY_SIZE(rk3399_isp_clks),
+       .isp_ver = RKISP1_V10,
 };
 
 static const struct of_device_id rkisp1_of_match[] = {
        {
                .compatible = "rockchip,rk3399-cif-isp",
-               .data = &rk3399_isp_clk_data,
+               .data = &rk3399_isp_match_data,
        },
        {},
 };
@@ -457,15 +459,15 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
 
 static int rkisp1_probe(struct platform_device *pdev)
 {
-       const struct rkisp1_match_data *clk_data;
+       const struct rkisp1_match_data *match_data;
        struct device *dev = &pdev->dev;
        struct rkisp1_device *rkisp1;
        struct v4l2_device *v4l2_dev;
        unsigned int i;
        int ret, irq;
 
-       clk_data = of_device_get_match_data(&pdev->dev);
-       if (!clk_data)
+       match_data = of_device_get_match_data(&pdev->dev);
+       if (!match_data)
                return -ENODEV;
 
        rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL);
@@ -494,15 +496,16 @@ static int rkisp1_probe(struct platform_device *pdev)
 
        rkisp1->irq = irq;
 
-       for (i = 0; i < clk_data->size; i++)
-               rkisp1->clks[i].id = clk_data->clks[i];
-       ret = devm_clk_bulk_get(dev, clk_data->size, rkisp1->clks);
+       for (i = 0; i < match_data->size; i++)
+               rkisp1->clks[i].id = match_data->clks[i];
+       ret = devm_clk_bulk_get(dev, match_data->size, rkisp1->clks);
        if (ret)
                return ret;
-       rkisp1->clk_size = clk_data->size;
+       rkisp1->clk_size = match_data->size;
 
        pm_runtime_enable(&pdev->dev);
 
+       rkisp1->media_dev.hw_revision = match_data->isp_ver;
        strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME,
                sizeof(rkisp1->media_dev.model));
        rkisp1->media_dev.dev = &pdev->dev;
index 6af4d551ffb54714123335718ca4b46db1bb6b30..aa5f45749543b3cc0282f3180aca8d6157762070 100644 (file)
@@ -391,7 +391,7 @@ static void rkisp1_goc_config(struct rkisp1_params *params,
                                RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
        rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE);
 
-       for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES; i++)
+       for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++)
                rkisp1_write(params->rkisp1, arg->gamma_y[i],
                             RKISP1_CIF_ISP_GAMMA_OUT_Y_0 + i * 4);
 }
@@ -589,7 +589,6 @@ static void rkisp1_hst_config(struct rkisp1_params *params,
                RKISP1_CIF_ISP_HIST_WEIGHT_22TO03,
                RKISP1_CIF_ISP_HIST_WEIGHT_13TO43,
                RKISP1_CIF_ISP_HIST_WEIGHT_04TO34,
-               RKISP1_CIF_ISP_HIST_WEIGHT_44,
        };
        const u8 *weight;
        unsigned int i;
@@ -622,6 +621,8 @@ static void rkisp1_hst_config(struct rkisp1_params *params,
                                                            weight[2],
                                                            weight[3]),
                                 hist_weight_regs[i]);
+
+       rkisp1_write(params->rkisp1, weight[0] & 0x1F, RKISP1_CIF_ISP_HIST_WEIGHT_44);
 }
 
 static void
index 8a8d960a679c25d0c0c56c15c12ed4846524268b..fa33080f51db542a2990f8560bd2b2df1992d09d 100644 (file)
 #define RKISP1_CIF_ISP_MAX_HIST_PREDIVIDER             0x0000007F
 #define RKISP1_CIF_ISP_HIST_ROW_NUM                    5
 #define RKISP1_CIF_ISP_HIST_COLUMN_NUM                 5
+#define RKISP1_CIF_ISP_HIST_GET_BIN(x)                 ((x) & 0x000FFFFF)
 
 /* AUTO FOCUS MEASUREMENT:  ISP_AFM_CTRL */
 #define RKISP1_ISP_AFM_CTRL_ENABLE                     BIT(0)
index 3ddab8fa8f2d32bbbddfccd71c7c9ce91cd0175c..c1d07a2e8839fb78a93b7e0f6a1eb9e19402655f 100644 (file)
@@ -203,7 +203,7 @@ static void rkisp1_stats_get_aec_meas(struct rkisp1_stats *stats,
        unsigned int i;
 
        pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP;
-       for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX; i++)
+       for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX_V10; i++)
                pbuf->params.ae.exp_mean[i] =
                        (u8)rkisp1_read(rkisp1,
                                        RKISP1_CIF_ISP_EXP_MEAN_00 + i * 4);
@@ -233,10 +233,11 @@ static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats,
        unsigned int i;
 
        pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST;
-       for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++)
-               pbuf->params.hist.hist_bins[i] =
-                       (u8)rkisp1_read(rkisp1,
-                                       RKISP1_CIF_ISP_HIST_BIN_0 + i * 4);
+       for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10; i++) {
+               u32 reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_HIST_BIN_0 + i * 4);
+
+               pbuf->params.hist.hist_bins[i] = RKISP1_CIF_ISP_HIST_GET_BIN(reg_val);
+       }
 }
 
 static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats,
index be8f2756a444e725579f95e4f8dd59eab88a71dd..1524dc0fc566e25530b6969201ed5a289619f225 100644 (file)
@@ -320,7 +320,7 @@ again:
                                data->body);
                        spin_lock(&data->keylock);
                        if (scancode) {
-                               delay = nsecs_to_jiffies(dev->timeout) +
+                               delay = usecs_to_jiffies(dev->timeout) +
                                        msecs_to_jiffies(100);
                                mod_timer(&data->rx_timeout, jiffies + delay);
                        } else {
index a905113fef6eae0a68fa4b5bb09111068c22856c..0c6229592e132de9046b7230f99a749ef5163729 100644 (file)
@@ -1551,7 +1551,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
        rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
        /* FIFO threshold is 17 bytes, so 17 * 8 samples minimum */
        rdev->min_timeout = 17 * 8 * ITE_BAUDRATE_DIVISOR *
-                           itdev->params.sample_period;
+                           itdev->params.sample_period / 1000;
        rdev->timeout = IR_DEFAULT_TIMEOUT;
        rdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
        rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
index 1d811e5ffb557fd5eb6837a68abefa4ec721e900..1fd62c1dac768d705cffa725492d54d477e41f58 100644 (file)
@@ -737,7 +737,7 @@ static unsigned int repeat_period(int protocol)
 void rc_repeat(struct rc_dev *dev)
 {
        unsigned long flags;
-       unsigned int timeout = nsecs_to_jiffies(dev->timeout) +
+       unsigned int timeout = usecs_to_jiffies(dev->timeout) +
                msecs_to_jiffies(repeat_period(dev->last_protocol));
        struct lirc_scancode sc = {
                .scancode = dev->last_scancode, .rc_proto = dev->last_protocol,
@@ -855,7 +855,7 @@ void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
        ir_do_keydown(dev, protocol, scancode, keycode, toggle);
 
        if (dev->keypressed) {
-               dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) +
+               dev->keyup_jiffies = jiffies + usecs_to_jiffies(dev->timeout) +
                        msecs_to_jiffies(repeat_period(protocol));
                mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
        }
@@ -1928,6 +1928,8 @@ int rc_register_device(struct rc_dev *dev)
                        goto out_raw;
        }
 
+       dev->registered = true;
+
        rc = device_add(&dev->dev);
        if (rc)
                goto out_rx_free;
@@ -1937,8 +1939,6 @@ int rc_register_device(struct rc_dev *dev)
                 dev->device_name ?: "Unspecified device", path ?: "N/A");
        kfree(path);
 
-       dev->registered = true;
-
        /*
         * once the the input device is registered in rc_setup_rx_device,
         * userspace can open the input device and rc_open() will be called
index 8cc28c92d05d66623c3b4cbf808313941c158e90..96ae0294ac102a9238b5f9453c6185485343ebed 100644 (file)
@@ -385,7 +385,7 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah)
        } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */
 
        mod_timer(&serial_ir.timeout_timer,
-                 jiffies + nsecs_to_jiffies(serial_ir.rcdev->timeout));
+                 jiffies + usecs_to_jiffies(serial_ir.rcdev->timeout));
 
        ir_raw_event_handle(serial_ir.rcdev);
 
index 78007dba4677cb54ae44bf268494d5d787dada70..133d20e40f82a5f44d5bd37802c33b28cb80c08d 100644 (file)
@@ -442,7 +442,7 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
 }
 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);
 
-s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul,
+s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul,
                       unsigned int div)
 {
        struct v4l2_ctrl *ctrl;
@@ -473,4 +473,4 @@ s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul,
 
        return freq > 0 ? freq : -EINVAL;
 }
-EXPORT_SYMBOL_GPL(v4l2_get_link_rate);
+EXPORT_SYMBOL_GPL(v4l2_get_link_freq);
index 44bea5e4aeda19b05c8e5c8149f2276f7e4e4ae9..b23773583179df8071bce6f64772c0a6e2560159 100644 (file)
@@ -20,6 +20,8 @@
 #include "sdio_cis.h"
 #include "sdio_ops.h"
 
+#define SDIO_READ_CIS_TIMEOUT_MS  (10 * 1000) /* 10s */
+
 static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
                         const unsigned char *buf, unsigned size)
 {
@@ -274,6 +276,8 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
 
        do {
                unsigned char tpl_code, tpl_link;
+               unsigned long timeout = jiffies +
+                       msecs_to_jiffies(SDIO_READ_CIS_TIMEOUT_MS);
 
                ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code);
                if (ret)
@@ -326,6 +330,8 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
                        prev = &this->next;
 
                        if (ret == -ENOENT) {
+                               if (time_after(jiffies, timeout))
+                                       break;
                                /* warn about unknown tuples */
                                pr_warn_ratelimited("%s: queuing unknown"
                                       " CIS tuple 0x%02x (%u bytes)\n",
index 6301b81cf5731b871e1c7d1523e18583d20f0c63..9bd717ff784be7775fdd31dd9e412799ee7e68f0 100644 (file)
@@ -111,8 +111,13 @@ static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
        return host->private;
 }
 
+extern const struct dev_pm_ops sdhci_pltfm_pmops;
+#ifdef CONFIG_PM_SLEEP
 int sdhci_pltfm_suspend(struct device *dev);
 int sdhci_pltfm_resume(struct device *dev);
-extern const struct dev_pm_ops sdhci_pltfm_pmops;
+#else
+static inline int sdhci_pltfm_suspend(struct device *dev) { return 0; }
+static inline int sdhci_pltfm_resume(struct device *dev) { return 0; }
+#endif
 
 #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */
index 98df38fe553ced05b714767d4ad628dcba45819a..12d085405bd052c3621280d97bd3b92575466379 100644 (file)
@@ -332,7 +332,7 @@ static int __init arc_rimi_init(void)
                dev->irq = 9;
 
        if (arcrimi_probe(dev)) {
-               free_netdev(dev);
+               free_arcdev(dev);
                return -EIO;
        }
 
@@ -349,7 +349,7 @@ static void __exit arc_rimi_exit(void)
        iounmap(lp->mem_start);
        release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
        free_irq(dev->irq, dev);
-       free_netdev(dev);
+       free_arcdev(dev);
 }
 
 #ifndef MODULE
index 22a49c6d7ae6ef590b3b0e2d8b6bcf2a10f8b0b7..5d4a4c7efbbff3763193844e2052ca32dcb27490 100644 (file)
@@ -298,6 +298,10 @@ struct arcnet_local {
 
        int excnak_pending;    /* We just got an excesive nak interrupt */
 
+       /* RESET flag handling */
+       int reset_in_progress;
+       struct work_struct reset_work;
+
        struct {
                uint16_t sequence;      /* sequence number (incs with each packet) */
                __be16 aborted_seq;
@@ -350,7 +354,9 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
 
 void arcnet_unregister_proto(struct ArcProto *proto);
 irqreturn_t arcnet_interrupt(int irq, void *dev_id);
+
 struct net_device *alloc_arcdev(const char *name);
+void free_arcdev(struct net_device *dev);
 
 int arcnet_open(struct net_device *dev);
 int arcnet_close(struct net_device *dev);
index e04efc0a5c977ee8b33a0ff77fe15c85ee322119..d76dd7d14299e198f305f4effed8611a8c9b480f 100644 (file)
@@ -387,10 +387,44 @@ static void arcnet_timer(struct timer_list *t)
        struct arcnet_local *lp = from_timer(lp, t, timer);
        struct net_device *dev = lp->dev;
 
-       if (!netif_carrier_ok(dev)) {
+       spin_lock_irq(&lp->lock);
+
+       if (!lp->reset_in_progress && !netif_carrier_ok(dev)) {
                netif_carrier_on(dev);
                netdev_info(dev, "link up\n");
        }
+
+       spin_unlock_irq(&lp->lock);
+}
+
+static void reset_device_work(struct work_struct *work)
+{
+       struct arcnet_local *lp;
+       struct net_device *dev;
+
+       lp = container_of(work, struct arcnet_local, reset_work);
+       dev = lp->dev;
+
+       /* Do not bring the network interface back up if an ifdown
+        * was already done.
+        */
+       if (!netif_running(dev) || !lp->reset_in_progress)
+               return;
+
+       rtnl_lock();
+
+       /* Do another check, in case of an ifdown that was triggered in
+        * the small race window between the exit condition above and
+        * acquiring RTNL.
+        */
+       if (!netif_running(dev) || !lp->reset_in_progress)
+               goto out;
+
+       dev_close(dev);
+       dev_open(dev, NULL);
+
+out:
+       rtnl_unlock();
 }
 
 static void arcnet_reply_tasklet(unsigned long data)
@@ -452,12 +486,25 @@ struct net_device *alloc_arcdev(const char *name)
                lp->dev = dev;
                spin_lock_init(&lp->lock);
                timer_setup(&lp->timer, arcnet_timer, 0);
+               INIT_WORK(&lp->reset_work, reset_device_work);
        }
 
        return dev;
 }
 EXPORT_SYMBOL(alloc_arcdev);
 
+void free_arcdev(struct net_device *dev)
+{
+       struct arcnet_local *lp = netdev_priv(dev);
+
+       /* Do not cancel this at ->ndo_close(), as the workqueue itself
+        * indirectly calls the ifdown path through dev_close().
+        */
+       cancel_work_sync(&lp->reset_work);
+       free_netdev(dev);
+}
+EXPORT_SYMBOL(free_arcdev);
+
 /* Open/initialize the board.  This is called sometime after booting when
  * the 'ifconfig' program is run.
  *
@@ -587,6 +634,10 @@ int arcnet_close(struct net_device *dev)
 
        /* shut down the card */
        lp->hw.close(dev);
+
+       /* reset counters */
+       lp->reset_in_progress = 0;
+
        module_put(lp->hw.owner);
        return 0;
 }
@@ -820,6 +871,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
 
        spin_lock_irqsave(&lp->lock, flags);
 
+       if (lp->reset_in_progress)
+               goto out;
+
        /* RESET flag was enabled - if device is not running, we must
         * clear it right away (but nothing else).
         */
@@ -852,11 +906,14 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
                if (status & RESETflag) {
                        arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n",
                                   status);
-                       arcnet_close(dev);
-                       arcnet_open(dev);
+
+                       lp->reset_in_progress = 1;
+                       netif_stop_queue(dev);
+                       netif_carrier_off(dev);
+                       schedule_work(&lp->reset_work);
 
                        /* get out of the interrupt handler! */
-                       break;
+                       goto out;
                }
                /* RX is inhibited - we must have received something.
                 * Prepare to receive into the next buffer.
@@ -1052,6 +1109,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
        udelay(1);
        lp->hw.intmask(dev, lp->intmask);
 
+out:
        spin_unlock_irqrestore(&lp->lock, flags);
        return retval;
 }
index f983c4ce6b07f186fd2b6cc136df9eabfa7c8df4..be618e4b9ed5e0aa20f949ea23abf416ce5239b6 100644 (file)
@@ -169,7 +169,7 @@ static int __init com20020_init(void)
                dev->irq = 9;
 
        if (com20020isa_probe(dev)) {
-               free_netdev(dev);
+               free_arcdev(dev);
                return -EIO;
        }
 
@@ -182,7 +182,7 @@ static void __exit com20020_exit(void)
        unregister_netdev(my_dev);
        free_irq(my_dev->irq, my_dev);
        release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
-       free_netdev(my_dev);
+       free_arcdev(my_dev);
 }
 
 #ifndef MODULE
index eb7f76753c9c0dbdd2ca07985d9c407b433ab506..8bdc44b7e09a188e678eaade1faf5fe035fd0434 100644 (file)
@@ -291,7 +291,7 @@ static void com20020pci_remove(struct pci_dev *pdev)
 
                unregister_netdev(dev);
                free_irq(dev->irq, dev);
-               free_netdev(dev);
+               free_arcdev(dev);
        }
 }
 
index cf607ffcf358e95eab6a63c3c7bb63382cd57c49..9cc5eb6a8e9051aaaf16e876b34a3803c94d571a 100644 (file)
@@ -177,7 +177,7 @@ static void com20020_detach(struct pcmcia_device *link)
                dev = info->dev;
                if (dev) {
                        dev_dbg(&link->dev, "kfree...\n");
-                       free_netdev(dev);
+                       free_arcdev(dev);
                }
                dev_dbg(&link->dev, "kfree2...\n");
                kfree(info);
index cf214b7306715487b84cd2301fca4de1bada6f48..3856b447d38ed27ca5ef98a1d0b4191f92152d31 100644 (file)
@@ -396,7 +396,7 @@ static int __init com90io_init(void)
        err = com90io_probe(dev);
 
        if (err) {
-               free_netdev(dev);
+               free_arcdev(dev);
                return err;
        }
 
@@ -419,7 +419,7 @@ static void __exit com90io_exit(void)
 
        free_irq(dev->irq, dev);
        release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
-       free_netdev(dev);
+       free_arcdev(dev);
 }
 
 module_init(com90io_init)
index 3dc3d533cb19a258e72f57d46443b9b52d1b8df7..d8dfb9ea0de89bf9929ee334d9f332c9156cef18 100644 (file)
@@ -554,7 +554,7 @@ err_free_irq:
 err_release_mem:
        release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
 err_free_dev:
-       free_netdev(dev);
+       free_arcdev(dev);
        return -EIO;
 }
 
@@ -672,7 +672,7 @@ static void __exit com90xx_exit(void)
                release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
                release_mem_region(dev->mem_start,
                                   dev->mem_end - dev->mem_start + 1);
-               free_netdev(dev);
+               free_arcdev(dev);
        }
 }
 
index 8b1ae023cb218f2db5bd3f58a28f6e91ccfa5104..c73e2a65c90443fe73e8522bca9d9a4e54f62868 100644 (file)
@@ -1163,7 +1163,7 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
 {
        struct can_priv *priv = netdev_priv(dev);
        struct can_ctrlmode cm = {.flags = priv->ctrlmode};
-       struct can_berr_counter bec;
+       struct can_berr_counter bec = { };
        enum can_state state = priv->state;
 
        if (priv->do_get_state)
index 1e9a0adda2d6928fe5c46cdecac25af05af8a0db..445226720ff299899a4ab8b3bc2f85645aec4525 100644 (file)
@@ -509,15 +509,19 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
        /* Find our integrated MDIO bus node */
        dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio");
        priv->master_mii_bus = of_mdio_find_bus(dn);
-       if (!priv->master_mii_bus)
+       if (!priv->master_mii_bus) {
+               of_node_put(dn);
                return -EPROBE_DEFER;
+       }
 
        get_device(&priv->master_mii_bus->dev);
        priv->master_mii_dn = dn;
 
        priv->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
-       if (!priv->slave_mii_bus)
+       if (!priv->slave_mii_bus) {
+               of_node_put(dn);
                return -ENOMEM;
+       }
 
        priv->slave_mii_bus->priv = priv;
        priv->slave_mii_bus->name = "sf2 slave mii";
index c973db101b7291782be7960984833bffce8d8267..a4570ba29c831c95f07b9395e75863cacd5422f0 100644 (file)
@@ -1187,6 +1187,20 @@ static const struct ksz_chip_data ksz8795_switch_chips[] = {
                .port_cnt = 5,          /* total cpu and user ports */
        },
        {
+               /*
+                * WARNING
+                * =======
+                * KSZ8794 is similar to KSZ8795, except the port map
+                * contains a gap between external and CPU ports, the
+                * port map is NOT continuous. The per-port register
+                * map is shifted accordingly too, i.e. registers at
+                * offset 0x40 are NOT used on KSZ8794 and they ARE
+                * used on KSZ8795 for external port 3.
+                *           external  cpu
+                * KSZ8794   0,1,2      4
+                * KSZ8795   0,1,2,3    4
+                * KSZ8765   0,1,2,3    4
+                */
                .chip_id = 0x8794,
                .dev_name = "KSZ8794",
                .num_vlans = 4096,
@@ -1220,9 +1234,13 @@ static int ksz8795_switch_init(struct ksz_device *dev)
                        dev->num_vlans = chip->num_vlans;
                        dev->num_alus = chip->num_alus;
                        dev->num_statics = chip->num_statics;
-                       dev->port_cnt = chip->port_cnt;
+                       dev->port_cnt = fls(chip->cpu_ports);
+                       dev->cpu_port = fls(chip->cpu_ports) - 1;
+                       dev->phy_port_cnt = dev->port_cnt - 1;
                        dev->cpu_ports = chip->cpu_ports;
-
+                       dev->host_mask = chip->cpu_ports;
+                       dev->port_mask = (BIT(dev->phy_port_cnt) - 1) |
+                                        chip->cpu_ports;
                        break;
                }
        }
@@ -1231,17 +1249,9 @@ static int ksz8795_switch_init(struct ksz_device *dev)
        if (!dev->cpu_ports)
                return -ENODEV;
 
-       dev->port_mask = BIT(dev->port_cnt) - 1;
-       dev->port_mask |= dev->host_mask;
-
        dev->reg_mib_cnt = KSZ8795_COUNTER_NUM;
        dev->mib_cnt = ARRAY_SIZE(mib_names);
 
-       dev->phy_port_cnt = dev->port_cnt - 1;
-
-       dev->cpu_port = dev->port_cnt - 1;
-       dev->host_mask = BIT(dev->cpu_port);
-
        dev->ports = devm_kzalloc(dev->dev,
                                  dev->port_cnt * sizeof(struct ksz_port),
                                  GFP_KERNEL);
index cf743133b0b93a0af95b0fa25b368def9184840e..389abfd277702968558d435f482c21c2ec4b30ac 100644 (file)
@@ -400,7 +400,7 @@ int ksz_switch_register(struct ksz_device *dev,
                gpiod_set_value_cansleep(dev->reset_gpio, 1);
                usleep_range(10000, 12000);
                gpiod_set_value_cansleep(dev->reset_gpio, 0);
-               usleep_range(100, 1000);
+               msleep(100);
        }
 
        mutex_init(&dev->dev_mutex);
@@ -434,7 +434,7 @@ int ksz_switch_register(struct ksz_device *dev,
                                if (of_property_read_u32(port, "reg",
                                                         &port_num))
                                        continue;
-                               if (port_num >= dev->port_cnt)
+                               if (!(dev->port_mask & BIT(port_num)))
                                        return -EINVAL;
                                of_get_phy_mode(port,
                                                &dev->ports[port_num].interface);
index eafe6bedc692e283fcf3a125f00d634c3e2c5500..54aa942eedaa6c28d15db3acb95b59520726ee40 100644 (file)
@@ -1676,7 +1676,11 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
                if (!entry.portvec)
                        entry.state = 0;
        } else {
-               entry.portvec |= BIT(port);
+               if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
+                       entry.portvec = BIT(port);
+               else
+                       entry.portvec |= BIT(port);
+
                entry.state = state;
        }
 
index e5cfbe196ba664decb2a32216a47a1803373d947..19dc7dc054a29075fa42e05a92824e9ced2ee7c2 100644 (file)
@@ -1158,11 +1158,9 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
 #endif
        }
        if (!n || !n->dev)
-               goto free_sk;
+               goto free_dst;
 
        ndev = n->dev;
-       if (!ndev)
-               goto free_dst;
        if (is_vlan_dev(ndev))
                ndev = vlan_dev_real_dev(ndev);
 
@@ -1250,7 +1248,8 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
 free_csk:
        chtls_sock_release(&csk->kref);
 free_dst:
-       neigh_release(n);
+       if (n)
+               neigh_release(n);
        dst_release(dst);
 free_sk:
        inet_csk_prepare_forced_close(newsk);
index c527f4ee1d3aed313124d2befbb6a536801e5594..0602d5d5d2eee25cdb1169ea430b18a1a76b3468 100644 (file)
@@ -462,6 +462,11 @@ struct bufdesc_ex {
  */
 #define FEC_QUIRK_CLEAR_SETUP_MII      (1 << 17)
 
+/* Some link partners do not tolerate the momentary reset of the REF_CLK
+ * frequency when the RNCTL register is cleared by hardware reset.
+ */
+#define FEC_QUIRK_NO_HARD_RESET                (1 << 18)
+
 struct bufdesc_prop {
        int qid;
        /* Address of Rx and Tx buffers */
index 04f24c66cf3668113014208d8a2dedc76180f131..9ebdb0e54291b204d5eacb60c3defbc2a8a669b6 100644 (file)
@@ -100,7 +100,8 @@ static const struct fec_devinfo fec_imx27_info = {
 static const struct fec_devinfo fec_imx28_info = {
        .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
                  FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
-                 FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII,
+                 FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII |
+                 FEC_QUIRK_NO_HARD_RESET,
 };
 
 static const struct fec_devinfo fec_imx6q_info = {
@@ -953,7 +954,8 @@ fec_restart(struct net_device *ndev)
         * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
         * instead of reset MAC itself.
         */
-       if (fep->quirks & FEC_QUIRK_HAS_AVB) {
+       if (fep->quirks & FEC_QUIRK_HAS_AVB ||
+           ((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) {
                writel(0, fep->hwp + FEC_ECNTRL);
        } else {
                writel(1, fep->hwp + FEC_ECNTRL);
@@ -2165,9 +2167,9 @@ static int fec_enet_mii_init(struct platform_device *pdev)
        fep->mii_bus->parent = &pdev->dev;
 
        err = of_mdiobus_register(fep->mii_bus, node);
-       of_node_put(node);
        if (err)
                goto err_out_free_mdiobus;
+       of_node_put(node);
 
        mii_cnt++;
 
@@ -2180,6 +2182,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 err_out_free_mdiobus:
        mdiobus_free(fep->mii_bus);
 err_out:
+       of_node_put(node);
        return err;
 }
 
index 9778c83150f1cc4508864d593bb5d33487c416db..f79034c786c847427fbf8bc9ad6921049a9d84e7 100644 (file)
@@ -5084,6 +5084,12 @@ static void ibmvnic_tasklet(struct tasklet_struct *t)
        while (!done) {
                /* Pull all the valid messages off the CRQ */
                while ((crq = ibmvnic_next_crq(adapter)) != NULL) {
+                       /* This barrier makes sure ibmvnic_next_crq()'s
+                        * crq->generic.first & IBMVNIC_CRQ_CMD_RSP is loaded
+                        * before ibmvnic_handle_crq()'s
+                        * switch(gen_crq->first) and switch(gen_crq->cmd).
+                        */
+                       dma_rmb();
                        ibmvnic_handle_crq(crq, adapter);
                        crq->generic.first = 0;
                }
@@ -5438,11 +5444,6 @@ static int ibmvnic_remove(struct vio_dev *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&adapter->state_lock, flags);
-       if (test_bit(0, &adapter->resetting)) {
-               spin_unlock_irqrestore(&adapter->state_lock, flags);
-               return -EBUSY;
-       }
-
        adapter->state = VNIC_REMOVING;
        spin_unlock_irqrestore(&adapter->state_lock, flags);
 
index 21ee56420c3aee60f1428ebf2566611addd34c04..1b6ec9be155a6352eb1a330172c50b70b1bad98a 100644 (file)
@@ -55,12 +55,7 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf)
 
        pfe.event = VIRTCHNL_EVENT_LINK_CHANGE;
        pfe.severity = PF_EVENT_SEVERITY_INFO;
-
-       /* Always report link is down if the VF queues aren't enabled */
-       if (!vf->queues_enabled) {
-               pfe.event_data.link_event.link_status = false;
-               pfe.event_data.link_event.link_speed = 0;
-       } else if (vf->link_forced) {
+       if (vf->link_forced) {
                pfe.event_data.link_event.link_status = vf->link_up;
                pfe.event_data.link_event.link_speed =
                        (vf->link_up ? i40e_virtchnl_link_speed(ls->link_speed) : 0);
@@ -70,7 +65,6 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf)
                pfe.event_data.link_event.link_speed =
                        i40e_virtchnl_link_speed(ls->link_speed);
        }
-
        i40e_aq_send_msg_to_vf(hw, abs_vf_id, VIRTCHNL_OP_EVENT,
                               0, (u8 *)&pfe, sizeof(pfe), NULL);
 }
@@ -2443,8 +2437,6 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg)
                }
        }
 
-       vf->queues_enabled = true;
-
 error_param:
        /* send the response to the VF */
        return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES,
@@ -2466,9 +2458,6 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg)
        struct i40e_pf *pf = vf->pf;
        i40e_status aq_ret = 0;
 
-       /* Immediately mark queues as disabled */
-       vf->queues_enabled = false;
-
        if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
                aq_ret = I40E_ERR_PARAM;
                goto error_param;
@@ -4046,20 +4035,16 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
                goto error_param;
 
        vf = &pf->vf[vf_id];
-       vsi = pf->vsi[vf->lan_vsi_idx];
 
        /* When the VF is resetting wait until it is done.
         * It can take up to 200 milliseconds,
         * but wait for up to 300 milliseconds to be safe.
-        * If the VF is indeed in reset, the vsi pointer has
-        * to show on the newly loaded vsi under pf->vsi[id].
+        * Acquire the VSI pointer only after the VF has been
+        * properly initialized.
         */
        for (i = 0; i < 15; i++) {
-               if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
-                       if (i > 0)
-                               vsi = pf->vsi[vf->lan_vsi_idx];
+               if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states))
                        break;
-               }
                msleep(20);
        }
        if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
@@ -4068,6 +4053,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
                ret = -EAGAIN;
                goto error_param;
        }
+       vsi = pf->vsi[vf->lan_vsi_idx];
 
        if (is_multicast_ether_addr(mac)) {
                dev_err(&pf->pdev->dev,
index 5491215d81debee4f1a9371d3eab7f015da1c0b2..091e32c1bb46fa12dc4a91afa10293ccac535cfe 100644 (file)
@@ -98,7 +98,6 @@ struct i40e_vf {
        unsigned int tx_rate;   /* Tx bandwidth limit in Mbps */
        bool link_forced;
        bool link_up;           /* only valid if VF link is forced */
-       bool queues_enabled;    /* true if the VF queues are enabled */
        bool spoofchk;
        u16 num_vlan;
 
index 56725356a17b80e3bdd0e6ae3a116206c66e43f6..fa1e128c24ecac69b4abb8023b4c4f3b8cee2bf8 100644 (file)
@@ -68,7 +68,9 @@
 #define ICE_INT_NAME_STR_LEN   (IFNAMSIZ + 16)
 #define ICE_AQ_LEN             64
 #define ICE_MBXSQ_LEN          64
-#define ICE_MIN_MSIX           2
+#define ICE_MIN_LAN_TXRX_MSIX  1
+#define ICE_MIN_LAN_OICR_MSIX  1
+#define ICE_MIN_MSIX           (ICE_MIN_LAN_TXRX_MSIX + ICE_MIN_LAN_OICR_MSIX)
 #define ICE_FDIR_MSIX          1
 #define ICE_NO_VSI             0xffff
 #define ICE_VSI_MAP_CONTIG     0
index 9e8e9531cd87185adf80870e70ce473dea460cb4..69c113a4de7e6a57d7e915e48d46c0e7ad659f55 100644 (file)
@@ -3258,8 +3258,8 @@ ice_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key,
  */
 static int ice_get_max_txq(struct ice_pf *pf)
 {
-       return min_t(int, num_online_cpus(),
-                    pf->hw.func_caps.common_cap.num_txq);
+       return min3(pf->num_lan_msix, (u16)num_online_cpus(),
+                   (u16)pf->hw.func_caps.common_cap.num_txq);
 }
 
 /**
@@ -3268,8 +3268,8 @@ static int ice_get_max_txq(struct ice_pf *pf)
  */
 static int ice_get_max_rxq(struct ice_pf *pf)
 {
-       return min_t(int, num_online_cpus(),
-                    pf->hw.func_caps.common_cap.num_rxq);
+       return min3(pf->num_lan_msix, (u16)num_online_cpus(),
+                   (u16)pf->hw.func_caps.common_cap.num_rxq);
 }
 
 /**
index 2d27f66ac8534c422e72885d5f3d7593bc51a622..192729546bbfc4e67757846d598f719669f72af5 100644 (file)
@@ -1576,7 +1576,13 @@ ice_set_fdir_input_set(struct ice_vsi *vsi, struct ethtool_rx_flow_spec *fsp,
                       sizeof(struct in6_addr));
                input->ip.v6.l4_header = fsp->h_u.usr_ip6_spec.l4_4_bytes;
                input->ip.v6.tc = fsp->h_u.usr_ip6_spec.tclass;
-               input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto;
+
+               /* if no protocol requested, use IPPROTO_NONE */
+               if (!fsp->m_u.usr_ip6_spec.l4_proto)
+                       input->ip.v6.proto = IPPROTO_NONE;
+               else
+                       input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto;
+
                memcpy(input->mask.v6.dst_ip, fsp->m_u.usr_ip6_spec.ip6dst,
                       sizeof(struct in6_addr));
                memcpy(input->mask.v6.src_ip, fsp->m_u.usr_ip6_spec.ip6src,
index 3df67486d42d981d829d0989b0a4f9d461e1e8af..ad9c22a1b97a0796983afa989d663fd4e5c619b0 100644 (file)
@@ -161,8 +161,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
 
        switch (vsi->type) {
        case ICE_VSI_PF:
-               vsi->alloc_txq = min_t(int, ice_get_avail_txq_count(pf),
-                                      num_online_cpus());
+               vsi->alloc_txq = min3(pf->num_lan_msix,
+                                     ice_get_avail_txq_count(pf),
+                                     (u16)num_online_cpus());
                if (vsi->req_txq) {
                        vsi->alloc_txq = vsi->req_txq;
                        vsi->num_txq = vsi->req_txq;
@@ -174,8 +175,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
                if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
                        vsi->alloc_rxq = 1;
                } else {
-                       vsi->alloc_rxq = min_t(int, ice_get_avail_rxq_count(pf),
-                                              num_online_cpus());
+                       vsi->alloc_rxq = min3(pf->num_lan_msix,
+                                             ice_get_avail_rxq_count(pf),
+                                             (u16)num_online_cpus());
                        if (vsi->req_rxq) {
                                vsi->alloc_rxq = vsi->req_rxq;
                                vsi->num_rxq = vsi->req_rxq;
@@ -184,7 +186,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
 
                pf->num_lan_rx = vsi->alloc_rxq;
 
-               vsi->num_q_vectors = max_t(int, vsi->alloc_rxq, vsi->alloc_txq);
+               vsi->num_q_vectors = min_t(int, pf->num_lan_msix,
+                                          max_t(int, vsi->alloc_rxq,
+                                                vsi->alloc_txq));
                break;
        case ICE_VSI_VF:
                vf = &pf->vf[vsi->vf_id];
index c52b9bb0e3ab173ba387b2e889b58036b10ee18d..e10ca8929f85e2f5aeda3810326b063d811bebb6 100644 (file)
@@ -3430,18 +3430,14 @@ static int ice_ena_msix_range(struct ice_pf *pf)
        if (v_actual < v_budget) {
                dev_warn(dev, "not enough OS MSI-X vectors. requested = %d, obtained = %d\n",
                         v_budget, v_actual);
-/* 2 vectors each for LAN and RDMA (traffic + OICR), one for flow director */
-#define ICE_MIN_LAN_VECS 2
-#define ICE_MIN_RDMA_VECS 2
-#define ICE_MIN_VECS (ICE_MIN_LAN_VECS + ICE_MIN_RDMA_VECS + 1)
 
-               if (v_actual < ICE_MIN_LAN_VECS) {
+               if (v_actual < ICE_MIN_MSIX) {
                        /* error if we can't get minimum vectors */
                        pci_disable_msix(pf->pdev);
                        err = -ERANGE;
                        goto msix_err;
                } else {
-                       pf->num_lan_msix = ICE_MIN_LAN_VECS;
+                       pf->num_lan_msix = ICE_MIN_LAN_TXRX_MSIX;
                }
        }
 
@@ -4884,9 +4880,15 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi)
                goto err_update_filters;
        }
 
-       /* Add filter for new MAC. If filter exists, just return success */
+       /* Add filter for new MAC. If filter exists, return success */
        status = ice_fltr_add_mac(vsi, mac, ICE_FWD_TO_VSI);
        if (status == ICE_ERR_ALREADY_EXISTS) {
+               /* Although this MAC filter is already present in hardware it's
+                * possible in some cases (e.g. bonding) that dev_addr was
+                * modified outside of the driver and needs to be restored back
+                * to this value.
+                */
+               memcpy(netdev->dev_addr, mac, netdev->addr_len);
                netdev_dbg(netdev, "filter for MAC %pM already exists\n", mac);
                return 0;
        }
index a2d0aad8cfdd765decb8e089bb2660f94e3442e2..b6fa83c619dd723424c540943bb91f2772fe868a 100644 (file)
@@ -1923,12 +1923,15 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
                                  ICE_TX_CTX_EIPT_IPV4_NO_CSUM;
                        l4_proto = ip.v4->protocol;
                } else if (first->tx_flags & ICE_TX_FLAGS_IPV6) {
+                       int ret;
+
                        tunnel |= ICE_TX_CTX_EIPT_IPV6;
                        exthdr = ip.hdr + sizeof(*ip.v6);
                        l4_proto = ip.v6->nexthdr;
-                       if (l4.hdr != exthdr)
-                               ipv6_skip_exthdr(skb, exthdr - skb->data,
-                                                &l4_proto, &frag_off);
+                       ret = ipv6_skip_exthdr(skb, exthdr - skb->data,
+                                              &l4_proto, &frag_off);
+                       if (ret < 0)
+                               return -1;
                }
 
                /* define outer transport */
index 61d331ce38cddc2fb0ddb83cdd42caf133cc3465..ec8cd69d49928e81ac8792d090ac0c5b11991e66 100644 (file)
@@ -1675,12 +1675,18 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev,
        cmd->base.phy_address = hw->phy.addr;
 
        /* advertising link modes */
-       ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half);
-       ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full);
-       ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half);
-       ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full);
-       ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full);
-       ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full);
+       if (hw->phy.autoneg_advertised & ADVERTISE_10_HALF)
+               ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half);
+       if (hw->phy.autoneg_advertised & ADVERTISE_10_FULL)
+               ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full);
+       if (hw->phy.autoneg_advertised & ADVERTISE_100_HALF)
+               ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half);
+       if (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)
+               ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full);
+       if (hw->phy.autoneg_advertised & ADVERTISE_1000_FULL)
+               ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full);
+       if (hw->phy.autoneg_advertised & ADVERTISE_2500_FULL)
+               ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full);
 
        /* set autoneg settings */
        if (hw->mac.autoneg == 1) {
@@ -1708,7 +1714,8 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev,
                                                     Asym_Pause);
        }
 
-       status = rd32(IGC_STATUS);
+       status = pm_runtime_suspended(&adapter->pdev->dev) ?
+                0 : rd32(IGC_STATUS);
 
        if (status & IGC_STATUS_LU) {
                if (status & IGC_STATUS_SPEED_1000) {
@@ -1792,6 +1799,12 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev,
 
        ethtool_convert_link_mode_to_legacy_u32(&advertising,
                                                cmd->link_modes.advertising);
+       /* Converting to legacy u32 drops ETHTOOL_LINK_MODE_2500baseT_Full_BIT.
+        * We have to check this and convert it to ADVERTISE_2500_FULL
+        * (aka ETHTOOL_LINK_MODE_2500baseX_Full_BIT) explicitly.
+        */
+       if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 2500baseT_Full))
+               advertising |= ADVERTISE_2500_FULL;
 
        if (cmd->base.autoneg == AUTONEG_ENABLE) {
                hw->mac.autoneg = 1;
index 8b67d9b49a83a61d76b3fcf44c65b46f33f5dd4f..7ec04e48860c6a52e1c6a09f35a31d3ad3507473 100644 (file)
@@ -219,9 +219,9 @@ static s32 igc_write_nvm_srwr(struct igc_hw *hw, u16 offset, u16 words,
                              u16 *data)
 {
        struct igc_nvm_info *nvm = &hw->nvm;
+       s32 ret_val = -IGC_ERR_NVM;
        u32 attempts = 100000;
        u32 i, k, eewr = 0;
-       s32 ret_val = 0;
 
        /* A check for invalid values:  offset too large, too many words,
         * too many words for the offset, and not enough words.
@@ -229,7 +229,6 @@ static s32 igc_write_nvm_srwr(struct igc_hw *hw, u16 offset, u16 words,
        if (offset >= nvm->word_size || (words > (nvm->word_size - offset)) ||
            words == 0) {
                hw_dbg("nvm parameter(s) out of bounds\n");
-               ret_val = -IGC_ERR_NVM;
                goto out;
        }
 
index 09cd0ec7ee87d8231acef20d6c9a468177057c69..67b8ffd21d8af39d543605ba98a9b70cf06051c4 100644 (file)
@@ -638,7 +638,7 @@ s32 igc_config_fc_after_link_up(struct igc_hw *hw)
        }
 
 out:
-       return 0;
+       return ret_val;
 }
 
 /**
index a30eb90ba3d28a04e57a6a822745bfe232144f48..dd590086fe6a51ef356a8899bfc7a1338410161e 100644 (file)
@@ -29,16 +29,16 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
        /* Clear entry invalidation bit */
        pe->tcam[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK;
 
-       /* Write tcam index - indirect access */
-       mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index);
-       for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)
-               mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam[i]);
-
        /* Write sram index - indirect access */
        mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, pe->index);
        for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)
                mvpp2_write(priv, MVPP2_PRS_SRAM_DATA_REG(i), pe->sram[i]);
 
+       /* Write tcam index - indirect access */
+       mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index);
+       for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)
+               mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam[i]);
+
        return 0;
 }
 
index 73fb94dd5fbcc54cd277635c7ebda39e7c9af531..e6869435e1f323041dd73c40e0ddf27aef27ba93 100644 (file)
@@ -478,10 +478,11 @@ dma_addr_t __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool)
        dma_addr_t iova;
        u8 *buf;
 
-       buf = napi_alloc_frag(pool->rbsize);
+       buf = napi_alloc_frag(pool->rbsize + OTX2_ALIGN);
        if (unlikely(!buf))
                return -ENOMEM;
 
+       buf = PTR_ALIGN(buf, OTX2_ALIGN);
        iova = dma_map_single_attrs(pfvf->dev, buf, pool->rbsize,
                                    DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
        if (unlikely(dma_mapping_error(pfvf->dev, iova))) {
index 718f8c0a4f6b7cc695ccac7aac245e2776a01fca..84e501e057b4f97aa736a7ee64fff10c34d0e7bc 100644 (file)
@@ -273,7 +273,7 @@ int mlx5e_health_rsc_fmsg_dump(struct mlx5e_priv *priv, struct mlx5_rsc_key *key
 
        err = devlink_fmsg_binary_pair_nest_start(fmsg, "data");
        if (err)
-               return err;
+               goto free_page;
 
        cmd = mlx5_rsc_dump_cmd_create(mdev, key);
        if (IS_ERR(cmd)) {
index 072363e73f1cec36da973533bee411d6a0cd7ee0..6bc6b48a56dc79de2a8c0ef818932f4abb3bdedc 100644 (file)
@@ -167,6 +167,12 @@ static const struct rhashtable_params tuples_nat_ht_params = {
        .min_size = 16 * 1024,
 };
 
+static bool
+mlx5_tc_ct_entry_has_nat(struct mlx5_ct_entry *entry)
+{
+       return !!(entry->tuple_nat_node.next);
+}
+
 static int
 mlx5_tc_ct_rule_to_tuple(struct mlx5_ct_tuple *tuple, struct flow_rule *rule)
 {
@@ -911,13 +917,13 @@ mlx5_tc_ct_block_flow_offload_add(struct mlx5_ct_ft *ft,
 err_insert:
        mlx5_tc_ct_entry_del_rules(ct_priv, entry);
 err_rules:
-       rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht,
-                              &entry->tuple_nat_node, tuples_nat_ht_params);
+       if (mlx5_tc_ct_entry_has_nat(entry))
+               rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht,
+                                      &entry->tuple_nat_node, tuples_nat_ht_params);
 err_tuple_nat:
-       if (entry->tuple_node.next)
-               rhashtable_remove_fast(&ct_priv->ct_tuples_ht,
-                                      &entry->tuple_node,
-                                      tuples_ht_params);
+       rhashtable_remove_fast(&ct_priv->ct_tuples_ht,
+                              &entry->tuple_node,
+                              tuples_ht_params);
 err_tuple:
 err_set:
        kfree(entry);
@@ -932,7 +938,7 @@ mlx5_tc_ct_del_ft_entry(struct mlx5_tc_ct_priv *ct_priv,
 {
        mlx5_tc_ct_entry_del_rules(ct_priv, entry);
        mutex_lock(&ct_priv->shared_counter_lock);
-       if (entry->tuple_node.next)
+       if (mlx5_tc_ct_entry_has_nat(entry))
                rhashtable_remove_fast(&ct_priv->ct_tuples_nat_ht,
                                       &entry->tuple_nat_node,
                                       tuples_nat_ht_params);
index 6c5c54bcd9be089ff091e6ad80f3adf58b45eb90..5cb936541b9e9e5da717c441121c7ca6f18e7009 100644 (file)
@@ -76,7 +76,7 @@ static const struct counter_desc mlx5e_ipsec_sw_stats_desc[] = {
 
 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(ipsec_sw)
 {
-       return NUM_IPSEC_SW_COUNTERS;
+       return priv->ipsec ? NUM_IPSEC_SW_COUNTERS : 0;
 }
 
 static inline MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ipsec_sw) {}
@@ -105,7 +105,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(ipsec_sw)
 
 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(ipsec_hw)
 {
-       return (mlx5_fpga_ipsec_device_caps(priv->mdev)) ? NUM_IPSEC_HW_COUNTERS : 0;
+       return (priv->ipsec && mlx5_fpga_ipsec_device_caps(priv->mdev)) ? NUM_IPSEC_HW_COUNTERS : 0;
 }
 
 static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ipsec_hw)
index d20243d6a0326000643b6411d185354bf7bb0655..f23c67575073a5b0a9e58eac93f4594721435747 100644 (file)
@@ -1151,6 +1151,7 @@ static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state)
 {
        struct mlx5e_channels new_channels = {};
        bool reset_channels = true;
+       bool opened;
        int err = 0;
 
        mutex_lock(&priv->state_lock);
@@ -1159,22 +1160,24 @@ static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state)
        mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &new_channels.params,
                                                   trust_state);
 
-       if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
-               priv->channels.params = new_channels.params;
+       opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
+       if (!opened)
                reset_channels = false;
-       }
 
        /* Skip if tx_min_inline is the same */
        if (new_channels.params.tx_min_inline_mode ==
            priv->channels.params.tx_min_inline_mode)
                reset_channels = false;
 
-       if (reset_channels)
+       if (reset_channels) {
                err = mlx5e_safe_switch_channels(priv, &new_channels,
                                                 mlx5e_update_trust_state_hw,
                                                 &trust_state);
-       else
+       } else {
                err = mlx5e_update_trust_state_hw(priv, &trust_state);
+               if (!err && !opened)
+                       priv->channels.params = new_channels.params;
+       }
 
        mutex_unlock(&priv->state_lock);
 
index 2d37742a888c1514a8506a1adf6a87ca0b6ec8f3..302001d6661ea341de628fc9ef1f7dafcc2534f6 100644 (file)
@@ -447,12 +447,18 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
                goto out;
        }
 
-       new_channels.params = priv->channels.params;
+       new_channels.params = *cur_params;
        new_channels.params.num_channels = count;
 
        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
+               struct mlx5e_params old_params;
+
+               old_params = *cur_params;
                *cur_params = new_channels.params;
                err = mlx5e_num_channels_changed(priv);
+               if (err)
+                       *cur_params = old_params;
+
                goto out;
        }
 
index 6a852b4901aa0a742989d9882b37f21f07108750..3fc7d18ac868b20520dc33b46e496981d430afe2 100644 (file)
@@ -3614,18 +3614,23 @@ static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
        new_channels.params.num_tc = tc ? tc : 1;
 
        if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
+               struct mlx5e_params old_params;
+
+               old_params = priv->channels.params;
                priv->channels.params = new_channels.params;
+               err = mlx5e_num_channels_changed(priv);
+               if (err)
+                       priv->channels.params = old_params;
+
                goto out;
        }
 
        err = mlx5e_safe_switch_channels(priv, &new_channels,
                                         mlx5e_num_channels_changed_ctx, NULL);
-       if (err)
-               goto out;
 
-       priv->max_opened_tc = max_t(u8, priv->max_opened_tc,
-                                   new_channels.params.num_tc);
 out:
+       priv->max_opened_tc = max_t(u8, priv->max_opened_tc,
+                                   priv->channels.params.num_tc);
        mutex_unlock(&priv->state_lock);
        return err;
 }
@@ -3757,7 +3762,7 @@ static int set_feature_lro(struct net_device *netdev, bool enable)
        struct mlx5e_priv *priv = netdev_priv(netdev);
        struct mlx5_core_dev *mdev = priv->mdev;
        struct mlx5e_channels new_channels = {};
-       struct mlx5e_params *old_params;
+       struct mlx5e_params *cur_params;
        int err = 0;
        bool reset;
 
@@ -3770,8 +3775,8 @@ static int set_feature_lro(struct net_device *netdev, bool enable)
                goto out;
        }
 
-       old_params = &priv->channels.params;
-       if (enable && !MLX5E_GET_PFLAG(old_params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
+       cur_params = &priv->channels.params;
+       if (enable && !MLX5E_GET_PFLAG(cur_params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
                netdev_warn(netdev, "can't set LRO with legacy RQ\n");
                err = -EINVAL;
                goto out;
@@ -3779,18 +3784,23 @@ static int set_feature_lro(struct net_device *netdev, bool enable)
 
        reset = test_bit(MLX5E_STATE_OPENED, &priv->state);
 
-       new_channels.params = *old_params;
+       new_channels.params = *cur_params;
        new_channels.params.lro_en = enable;
 
-       if (old_params->rq_wq_type != MLX5_WQ_TYPE_CYCLIC) {
-               if (mlx5e_rx_mpwqe_is_linear_skb(mdev, old_params, NULL) ==
+       if (cur_params->rq_wq_type != MLX5_WQ_TYPE_CYCLIC) {
+               if (mlx5e_rx_mpwqe_is_linear_skb(mdev, cur_params, NULL) ==
                    mlx5e_rx_mpwqe_is_linear_skb(mdev, &new_channels.params, NULL))
                        reset = false;
        }
 
        if (!reset) {
-               *old_params = new_channels.params;
+               struct mlx5e_params old_params;
+
+               old_params = *cur_params;
+               *cur_params = new_channels.params;
                err = mlx5e_modify_tirs_lro(priv);
+               if (err)
+                       *cur_params = old_params;
                goto out;
        }
 
@@ -4067,9 +4077,16 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
        }
 
        if (!reset) {
+               unsigned int old_mtu = params->sw_mtu;
+
                params->sw_mtu = new_mtu;
-               if (preactivate)
-                       preactivate(priv, NULL);
+               if (preactivate) {
+                       err = preactivate(priv, NULL);
+                       if (err) {
+                               params->sw_mtu = old_mtu;
+                               goto out;
+                       }
+               }
                netdev->mtu = params->sw_mtu;
                goto out;
        }
@@ -5027,7 +5044,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
            FT_CAP(modify_root) &&
            FT_CAP(identified_miss_table_mode) &&
            FT_CAP(flow_table_modify)) {
-#ifdef CONFIG_MLX5_ESWITCH
+#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
                netdev->hw_features      |= NETIF_F_HW_TC;
 #endif
 #ifdef CONFIG_MLX5_EN_ARFS
index 989c70c1eda37f83ac861e6039d5aa93690754ce..f0ceae65f6cfaba59b04b1053c5588c9b0efa71e 100644 (file)
@@ -737,7 +737,9 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
 
        netdev->features       |= NETIF_F_NETNS_LOCAL;
 
+#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
        netdev->hw_features    |= NETIF_F_HW_TC;
+#endif
        netdev->hw_features    |= NETIF_F_SG;
        netdev->hw_features    |= NETIF_F_IP_CSUM;
        netdev->hw_features    |= NETIF_F_IPV6_CSUM;
index 7f5851c612181e42489dddbaa2e6450950ce64f9..ca4b55839a8a71622deb2b69b0ef568cfbc85005 100644 (file)
@@ -1262,8 +1262,10 @@ static void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
        mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
 
        if (mlx5e_cqe_regb_chain(cqe))
-               if (!mlx5e_tc_update_skb(cqe, skb))
+               if (!mlx5e_tc_update_skb(cqe, skb)) {
+                       dev_kfree_skb_any(skb);
                        goto free_wqe;
+               }
 
        napi_gro_receive(rq->cq.napi, skb);
 
@@ -1316,8 +1318,10 @@ static void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
        if (rep->vlan && skb_vlan_tag_present(skb))
                skb_vlan_pop(skb);
 
-       if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv))
+       if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) {
+               dev_kfree_skb_any(skb);
                goto free_wqe;
+       }
 
        napi_gro_receive(rq->cq.napi, skb);
 
@@ -1371,8 +1375,10 @@ static void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq, struct mlx5_cqe64
 
        mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
 
-       if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv))
+       if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) {
+               dev_kfree_skb_any(skb);
                goto mpwrq_cqe_out;
+       }
 
        napi_gro_receive(rq->cq.napi, skb);
 
@@ -1528,8 +1534,10 @@ static void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cq
        mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
 
        if (mlx5e_cqe_regb_chain(cqe))
-               if (!mlx5e_tc_update_skb(cqe, skb))
+               if (!mlx5e_tc_update_skb(cqe, skb)) {
+                       dev_kfree_skb_any(skb);
                        goto mpwrq_cqe_out;
+               }
 
        napi_gro_receive(rq->cq.napi, skb);
 
index 4cdf834fa74af679a0e2c8a9eb827f2b6882b06e..dd0bfbacad47417149a99a17ed2c38d02b3351db 100644 (file)
@@ -67,6 +67,7 @@
 #include "lib/geneve.h"
 #include "lib/fs_chains.h"
 #include "diag/en_tc_tracepoint.h"
+#include <asm/div64.h>
 
 #define nic_chains(priv) ((priv)->fs.tc.chains)
 #define MLX5_MH_ACT_SZ MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)
@@ -1162,6 +1163,9 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
        struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts;
        struct mlx5_flow_handle *rule;
 
+       if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH)
+               return mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
+
        if (flow_flag_test(flow, CT)) {
                mod_hdr_acts = &attr->parse_attr->mod_hdr_acts;
 
@@ -1192,6 +1196,9 @@ mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
 {
        flow_flag_clear(flow, OFFLOADED);
 
+       if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH)
+               goto offload_rule_0;
+
        if (flow_flag_test(flow, CT)) {
                mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), flow, attr);
                return;
@@ -1200,6 +1207,7 @@ mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
        if (attr->esw_attr->split_count)
                mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr);
 
+offload_rule_0:
        mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr);
 }
 
@@ -2269,8 +2277,8 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
              BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) |
              BIT(FLOW_DISSECTOR_KEY_MPLS))) {
                NL_SET_ERR_MSG_MOD(extack, "Unsupported key");
-               netdev_warn(priv->netdev, "Unsupported key used: 0x%x\n",
-                           dissector->used_keys);
+               netdev_dbg(priv->netdev, "Unsupported key used: 0x%x\n",
+                          dissector->used_keys);
                return -EOPNOTSUPP;
        }
 
@@ -5007,13 +5015,13 @@ errout:
        return err;
 }
 
-static int apply_police_params(struct mlx5e_priv *priv, u32 rate,
+static int apply_police_params(struct mlx5e_priv *priv, u64 rate,
                               struct netlink_ext_ack *extack)
 {
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
        struct mlx5_eswitch *esw;
+       u32 rate_mbps = 0;
        u16 vport_num;
-       u32 rate_mbps;
        int err;
 
        vport_num = rpriv->rep->vport;
@@ -5030,7 +5038,11 @@ static int apply_police_params(struct mlx5e_priv *priv, u32 rate,
         * Moreover, if rate is non zero we choose to configure to a minimum of
         * 1 mbit/sec.
         */
-       rate_mbps = rate ? max_t(u32, (rate * 8 + 500000) / 1000000, 1) : 0;
+       if (rate) {
+               rate = (rate * BITS_PER_BYTE) + 500000;
+               rate_mbps = max_t(u32, do_div(rate, 1000000), 1);
+       }
+
        err = mlx5_esw_modify_vport_rate(esw, vport_num, rate_mbps);
        if (err)
                NL_SET_ERR_MSG_MOD(extack, "failed applying action to hardware");
index b899539a07860778fb8810843abbdc17df6ebcf9..ee4d86c1f436032e34799ed154b18bd71e905428 100644 (file)
@@ -1141,6 +1141,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
 destroy_ft:
        root->cmds->destroy_flow_table(root, ft);
 free_ft:
+       rhltable_destroy(&ft->fgs_hash);
        kfree(ft);
 unlock_root:
        mutex_unlock(&root->chain_lock);
@@ -1759,6 +1760,7 @@ search_again_locked:
                if (!fte_tmp)
                        continue;
                rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte_tmp);
+               /* No error check needed here, because insert_fte() is not called */
                up_write_ref_node(&fte_tmp->node, false);
                tree_put_node(&fte_tmp->node, false);
                kmem_cache_free(steering->ftes_cache, fte);
@@ -1811,6 +1813,8 @@ skip_search:
                up_write_ref_node(&g->node, false);
                rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte);
                up_write_ref_node(&fte->node, false);
+               if (IS_ERR(rule))
+                       tree_put_node(&fte->node, false);
                return rule;
        }
        rule = ERR_PTR(-ENOENT);
@@ -1909,6 +1913,8 @@ search_again_locked:
        up_write_ref_node(&g->node, false);
        rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte);
        up_write_ref_node(&fte->node, false);
+       if (IS_ERR(rule))
+               tree_put_node(&fte->node, false);
        tree_put_node(&g->node, false);
        return rule;
 
index 3a9fa629503f0e0eb889ae0e4b79dc05eafee79e..d046db7bb047d5f9fc9dc59b415bef0a53efb356 100644 (file)
@@ -90,4 +90,9 @@ int mlx5_create_encryption_key(struct mlx5_core_dev *mdev,
                               u32 key_type, u32 *p_key_id);
 void mlx5_destroy_encryption_key(struct mlx5_core_dev *mdev, u32 key_id);
 
+static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev)
+{
+       return devlink_net(priv_to_devlink(dev));
+}
+
 #endif
index eb956ce904bc01e1e9ac2057c805048399a6ae4c..c0656d4782e1c3bc3d5b63091fb21eb13f6d63ba 100644 (file)
@@ -58,7 +58,7 @@ struct fw_page {
        struct rb_node          rb_node;
        u64                     addr;
        struct page            *page;
-       u16                     func_id;
+       u32                     function;
        unsigned long           bitmask;
        struct list_head        list;
        unsigned                free_count;
@@ -74,12 +74,17 @@ enum {
        MLX5_NUM_4K_IN_PAGE             = PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE,
 };
 
-static struct rb_root *page_root_per_func_id(struct mlx5_core_dev *dev, u16 func_id)
+static u32 get_function(u16 func_id, bool ec_function)
+{
+       return (u32)func_id | (ec_function << 16);
+}
+
+static struct rb_root *page_root_per_function(struct mlx5_core_dev *dev, u32 function)
 {
        struct rb_root *root;
        int err;
 
-       root = xa_load(&dev->priv.page_root_xa, func_id);
+       root = xa_load(&dev->priv.page_root_xa, function);
        if (root)
                return root;
 
@@ -87,7 +92,7 @@ static struct rb_root *page_root_per_func_id(struct mlx5_core_dev *dev, u16 func
        if (!root)
                return ERR_PTR(-ENOMEM);
 
-       err = xa_insert(&dev->priv.page_root_xa, func_id, root, GFP_KERNEL);
+       err = xa_insert(&dev->priv.page_root_xa, function, root, GFP_KERNEL);
        if (err) {
                kfree(root);
                return ERR_PTR(err);
@@ -98,7 +103,7 @@ static struct rb_root *page_root_per_func_id(struct mlx5_core_dev *dev, u16 func
        return root;
 }
 
-static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id)
+static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u32 function)
 {
        struct rb_node *parent = NULL;
        struct rb_root *root;
@@ -107,7 +112,7 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u
        struct fw_page *tfp;
        int i;
 
-       root = page_root_per_func_id(dev, func_id);
+       root = page_root_per_function(dev, function);
        if (IS_ERR(root))
                return PTR_ERR(root);
 
@@ -130,7 +135,7 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u
 
        nfp->addr = addr;
        nfp->page = page;
-       nfp->func_id = func_id;
+       nfp->function = function;
        nfp->free_count = MLX5_NUM_4K_IN_PAGE;
        for (i = 0; i < MLX5_NUM_4K_IN_PAGE; i++)
                set_bit(i, &nfp->bitmask);
@@ -143,14 +148,14 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u
 }
 
 static struct fw_page *find_fw_page(struct mlx5_core_dev *dev, u64 addr,
-                                   u32 func_id)
+                                   u32 function)
 {
        struct fw_page *result = NULL;
        struct rb_root *root;
        struct rb_node *tmp;
        struct fw_page *tfp;
 
-       root = xa_load(&dev->priv.page_root_xa, func_id);
+       root = xa_load(&dev->priv.page_root_xa, function);
        if (WARN_ON_ONCE(!root))
                return NULL;
 
@@ -194,14 +199,14 @@ static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id,
        return err;
 }
 
-static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr, u16 func_id)
+static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr, u32 function)
 {
        struct fw_page *fp = NULL;
        struct fw_page *iter;
        unsigned n;
 
        list_for_each_entry(iter, &dev->priv.free_list, list) {
-               if (iter->func_id != func_id)
+               if (iter->function != function)
                        continue;
                fp = iter;
        }
@@ -231,7 +236,7 @@ static void free_fwp(struct mlx5_core_dev *dev, struct fw_page *fwp,
 {
        struct rb_root *root;
 
-       root = xa_load(&dev->priv.page_root_xa, fwp->func_id);
+       root = xa_load(&dev->priv.page_root_xa, fwp->function);
        if (WARN_ON_ONCE(!root))
                return;
 
@@ -244,12 +249,12 @@ static void free_fwp(struct mlx5_core_dev *dev, struct fw_page *fwp,
        kfree(fwp);
 }
 
-static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 func_id)
+static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 function)
 {
        struct fw_page *fwp;
        int n;
 
-       fwp = find_fw_page(dev, addr & MLX5_U64_4K_PAGE_MASK, func_id);
+       fwp = find_fw_page(dev, addr & MLX5_U64_4K_PAGE_MASK, function);
        if (!fwp) {
                mlx5_core_warn_rl(dev, "page not found\n");
                return;
@@ -263,7 +268,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 func_id)
                list_add(&fwp->list, &dev->priv.free_list);
 }
 
-static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
+static int alloc_system_page(struct mlx5_core_dev *dev, u32 function)
 {
        struct device *device = mlx5_core_dma_dev(dev);
        int nid = dev_to_node(device);
@@ -291,7 +296,7 @@ map:
                goto map;
        }
 
-       err = insert_page(dev, addr, page, func_id);
+       err = insert_page(dev, addr, page, function);
        if (err) {
                mlx5_core_err(dev, "failed to track allocated page\n");
                dma_unmap_page(device, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
@@ -328,6 +333,7 @@ static void page_notify_fail(struct mlx5_core_dev *dev, u16 func_id,
 static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
                      int notify_fail, bool ec_function)
 {
+       u32 function = get_function(func_id, ec_function);
        u32 out[MLX5_ST_SZ_DW(manage_pages_out)] = {0};
        int inlen = MLX5_ST_SZ_BYTES(manage_pages_in);
        u64 addr;
@@ -345,10 +351,10 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
 
        for (i = 0; i < npages; i++) {
 retry:
-               err = alloc_4k(dev, &addr, func_id);
+               err = alloc_4k(dev, &addr, function);
                if (err) {
                        if (err == -ENOMEM)
-                               err = alloc_system_page(dev, func_id);
+                               err = alloc_system_page(dev, function);
                        if (err)
                                goto out_4k;
 
@@ -384,7 +390,7 @@ retry:
 
 out_4k:
        for (i--; i >= 0; i--)
-               free_4k(dev, MLX5_GET64(manage_pages_in, in, pas[i]), func_id);
+               free_4k(dev, MLX5_GET64(manage_pages_in, in, pas[i]), function);
 out_free:
        kvfree(in);
        if (notify_fail)
@@ -392,14 +398,15 @@ out_free:
        return err;
 }
 
-static void release_all_pages(struct mlx5_core_dev *dev, u32 func_id,
+static void release_all_pages(struct mlx5_core_dev *dev, u16 func_id,
                              bool ec_function)
 {
+       u32 function = get_function(func_id, ec_function);
        struct rb_root *root;
        struct rb_node *p;
        int npages = 0;
 
-       root = xa_load(&dev->priv.page_root_xa, func_id);
+       root = xa_load(&dev->priv.page_root_xa, function);
        if (WARN_ON_ONCE(!root))
                return;
 
@@ -446,6 +453,7 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
        struct rb_root *root;
        struct fw_page *fwp;
        struct rb_node *p;
+       bool ec_function;
        u32 func_id;
        u32 npages;
        u32 i = 0;
@@ -456,8 +464,9 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
        /* No hard feelings, we want our pages back! */
        npages = MLX5_GET(manage_pages_in, in, input_num_entries);
        func_id = MLX5_GET(manage_pages_in, in, function_id);
+       ec_function = MLX5_GET(manage_pages_in, in, embedded_cpu_function);
 
-       root = xa_load(&dev->priv.page_root_xa, func_id);
+       root = xa_load(&dev->priv.page_root_xa, get_function(func_id, ec_function));
        if (WARN_ON_ONCE(!root))
                return -EEXIST;
 
@@ -473,9 +482,10 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
        return 0;
 }
 
-static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages,
+static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
                         int *nclaimed, bool ec_function)
 {
+       u32 function = get_function(func_id, ec_function);
        int outlen = MLX5_ST_SZ_BYTES(manage_pages_out);
        u32 in[MLX5_ST_SZ_DW(manage_pages_in)] = {};
        int num_claimed;
@@ -514,7 +524,7 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages,
        }
 
        for (i = 0; i < num_claimed; i++)
-               free_4k(dev, MLX5_GET64(manage_pages_out, out, pas[i]), func_id);
+               free_4k(dev, MLX5_GET64(manage_pages_out, out, pas[i]), function);
 
        if (nclaimed)
                *nclaimed = num_claimed;
index c6c5826aba41e8c31f1b8daa1672b9e032959e4d..1892cea05ee7cc94d5597206bed0ca8643cb2984 100644 (file)
@@ -157,6 +157,7 @@ mlxsw_sp1_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
 
 static const
 struct mlxsw_sp_span_entry_ops mlxsw_sp1_span_entry_ops_cpu = {
+       .is_static = true,
        .can_handle = mlxsw_sp1_span_cpu_can_handle,
        .parms_set = mlxsw_sp1_span_entry_cpu_parms,
        .configure = mlxsw_sp1_span_entry_cpu_configure,
@@ -214,6 +215,7 @@ mlxsw_sp_span_entry_phys_deconfigure(struct mlxsw_sp_span_entry *span_entry)
 
 static const
 struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_phys = {
+       .is_static = true,
        .can_handle = mlxsw_sp_port_dev_check,
        .parms_set = mlxsw_sp_span_entry_phys_parms,
        .configure = mlxsw_sp_span_entry_phys_configure,
@@ -721,6 +723,7 @@ mlxsw_sp2_span_entry_cpu_deconfigure(struct mlxsw_sp_span_entry *span_entry)
 
 static const
 struct mlxsw_sp_span_entry_ops mlxsw_sp2_span_entry_ops_cpu = {
+       .is_static = true,
        .can_handle = mlxsw_sp2_span_cpu_can_handle,
        .parms_set = mlxsw_sp2_span_entry_cpu_parms,
        .configure = mlxsw_sp2_span_entry_cpu_configure,
@@ -1036,6 +1039,9 @@ static void mlxsw_sp_span_respin_work(struct work_struct *work)
                if (!refcount_read(&curr->ref_count))
                        continue;
 
+               if (curr->ops->is_static)
+                       continue;
+
                err = curr->ops->parms_set(mlxsw_sp, curr->to_dev, &sparms);
                if (err)
                        continue;
index d907718bc8c584005547c8dcd7c8374e52eebd49..aa1cd409c0e2ea15d585cb10d6cc344bc3dce879 100644 (file)
@@ -60,6 +60,7 @@ struct mlxsw_sp_span_entry {
 };
 
 struct mlxsw_sp_span_entry_ops {
+       bool is_static;
        bool (*can_handle)(const struct net_device *to_dev);
        int (*parms_set)(struct mlxsw_sp *mlxsw_sp,
                         const struct net_device *to_dev,
index a569abe7f5ef2e4f2ba1e578908987362d8a3f56..0d78408b4e269fb0b6a21c5fb91f0eff2a28ff37 100644 (file)
@@ -4046,17 +4046,72 @@ err_out:
        return -EIO;
 }
 
-static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp)
+static bool rtl_skb_is_udp(struct sk_buff *skb)
+{
+       int no = skb_network_offset(skb);
+       struct ipv6hdr *i6h, _i6h;
+       struct iphdr *ih, _ih;
+
+       switch (vlan_get_protocol(skb)) {
+       case htons(ETH_P_IP):
+               ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih);
+               return ih && ih->protocol == IPPROTO_UDP;
+       case htons(ETH_P_IPV6):
+               i6h = skb_header_pointer(skb, no, sizeof(_i6h), &_i6h);
+               return i6h && i6h->nexthdr == IPPROTO_UDP;
+       default:
+               return false;
+       }
+}
+
+#define RTL_MIN_PATCH_LEN      47
+
+/* see rtl8125_get_patch_pad_len() in r8125 vendor driver */
+static unsigned int rtl8125_quirk_udp_padto(struct rtl8169_private *tp,
+                                           struct sk_buff *skb)
 {
+       unsigned int padto = 0, len = skb->len;
+
+       if (rtl_is_8125(tp) && len < 128 + RTL_MIN_PATCH_LEN &&
+           rtl_skb_is_udp(skb) && skb_transport_header_was_set(skb)) {
+               unsigned int trans_data_len = skb_tail_pointer(skb) -
+                                             skb_transport_header(skb);
+
+               if (trans_data_len >= offsetof(struct udphdr, len) &&
+                   trans_data_len < RTL_MIN_PATCH_LEN) {
+                       u16 dest = ntohs(udp_hdr(skb)->dest);
+
+                       /* dest is a standard PTP port */
+                       if (dest == 319 || dest == 320)
+                               padto = len + RTL_MIN_PATCH_LEN - trans_data_len;
+               }
+
+               if (trans_data_len < sizeof(struct udphdr))
+                       padto = max_t(unsigned int, padto,
+                                     len + sizeof(struct udphdr) - trans_data_len);
+       }
+
+       return padto;
+}
+
+static unsigned int rtl_quirk_packet_padto(struct rtl8169_private *tp,
+                                          struct sk_buff *skb)
+{
+       unsigned int padto;
+
+       padto = rtl8125_quirk_udp_padto(tp, skb);
+
        switch (tp->mac_version) {
        case RTL_GIGA_MAC_VER_34:
        case RTL_GIGA_MAC_VER_60:
        case RTL_GIGA_MAC_VER_61:
        case RTL_GIGA_MAC_VER_63:
-               return true;
+               padto = max_t(unsigned int, padto, ETH_ZLEN);
        default:
-               return false;
+               break;
        }
+
+       return padto;
 }
 
 static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts)
@@ -4128,9 +4183,10 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 
                opts[1] |= transport_offset << TCPHO_SHIFT;
        } else {
-               if (unlikely(skb->len < ETH_ZLEN && rtl_test_hw_pad_bug(tp)))
-                       /* eth_skb_pad would free the skb on error */
-                       return !__skb_put_padto(skb, ETH_ZLEN, false);
+               unsigned int padto = rtl_quirk_packet_padto(tp, skb);
+
+               /* skb_padto would free the skb on error */
+               return !__skb_put_padto(skb, padto, false);
        }
 
        return true;
@@ -4307,6 +4363,9 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
                if (skb->len < ETH_ZLEN)
                        features &= ~NETIF_F_CSUM_MASK;
 
+               if (rtl_quirk_packet_padto(tp, skb))
+                       features &= ~NETIF_F_CSUM_MASK;
+
                if (transport_offset > TCPHO_MAX &&
                    rtl_chip_supports_csum_v2(tp))
                        features &= ~NETIF_F_CSUM_MASK;
@@ -4645,10 +4704,10 @@ static int rtl8169_close(struct net_device *dev)
 
        cancel_work_sync(&tp->wk.work);
 
-       phy_disconnect(tp->phydev);
-
        free_irq(pci_irq_vector(pdev, 0), tp);
 
+       phy_disconnect(tp->phydev);
+
        dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
                          tp->RxPhyAddr);
        dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
index 82b1c7a5a7a948eef7615fcf426c11321971b8c7..ba0e4d2b256a4b158b7bddb7bc5a8235c38b97ac 100644 (file)
@@ -129,7 +129,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
                                if (ret) {
                                        dev_err(&pdev->dev,
                                                "Failed to set tx_clk\n");
-                                       return ret;
+                                       goto err_remove_config_dt;
                                }
                        }
                }
@@ -143,7 +143,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
                        if (ret) {
                                dev_err(&pdev->dev,
                                        "Failed to set clk_ptp_ref\n");
-                               return ret;
+                               goto err_remove_config_dt;
                        }
                }
        }
index 9a6a519426a08ade395e09acdd46fc8b83bcdb19..103d2448e9e0dd82d1b11b53e189073c5a9fe99c 100644 (file)
@@ -375,6 +375,7 @@ static int ehl_pse0_common_data(struct pci_dev *pdev,
                                struct plat_stmmacenet_data *plat)
 {
        plat->bus_id = 2;
+       plat->addr64 = 32;
        return ehl_common_data(pdev, plat);
 }
 
@@ -406,6 +407,7 @@ static int ehl_pse1_common_data(struct pci_dev *pdev,
                                struct plat_stmmacenet_data *plat)
 {
        plat->bus_id = 3;
+       plat->addr64 = 32;
        return ehl_common_data(pdev, plat);
 }
 
index 14d9a791924bf9b6b16f53cba222ec6ff20cf2bf..34e5f2155d6206463523624b12c8091839ebba1d 100644 (file)
@@ -440,7 +440,7 @@ static void gsi_evt_ring_de_alloc_command(struct gsi *gsi, u32 evt_ring_id)
 static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel)
 {
        u32 channel_id = gsi_channel_id(channel);
-       void *virt = channel->gsi->virt;
+       void __iomem *virt = channel->gsi->virt;
        u32 val;
 
        val = ioread32(virt + GSI_CH_C_CNTXT_0_OFFSET(channel_id));
@@ -1373,7 +1373,7 @@ static int gsi_ring_alloc(struct gsi *gsi, struct gsi_ring *ring, u32 count)
        /* Hardware requires a 2^n ring size, with alignment equal to size */
        ring->virt = dma_alloc_coherent(dev, size, &addr, GFP_KERNEL);
        if (ring->virt && addr % size) {
-               dma_free_coherent(dev, size, ring->virt, ring->addr);
+               dma_free_coherent(dev, size, ring->virt, addr);
                dev_err(dev, "unable to alloc 0x%zx-aligned ring buffer\n",
                        size);
                return -EINVAL; /* Not a good error value, but distinct */
index 9f4be9812a1f31d48732f96ce27b77624b4f9a2d..612afece303f3519a35fd8fc9c834bc72bd8d7f4 100644 (file)
@@ -588,7 +588,7 @@ static void ipa_endpoint_init_hdr_metadata_mask(struct ipa_endpoint *endpoint)
 
        /* Note that HDR_ENDIANNESS indicates big endian header fields */
        if (endpoint->data->qmap)
-               val = cpu_to_be32(IPA_ENDPOINT_QMAP_METADATA_MASK);
+               val = (__force u32)cpu_to_be32(IPA_ENDPOINT_QMAP_METADATA_MASK);
 
        iowrite32(val, endpoint->ipa->reg_virt + offset);
 }
@@ -1164,8 +1164,8 @@ static bool ipa_endpoint_status_skip(struct ipa_endpoint *endpoint,
                return true;
        if (!status->pkt_len)
                return true;
-       endpoint_id = u32_get_bits(status->endp_dst_idx,
-                                  IPA_STATUS_DST_IDX_FMASK);
+       endpoint_id = u8_get_bits(status->endp_dst_idx,
+                                 IPA_STATUS_DST_IDX_FMASK);
        if (endpoint_id != endpoint->endpoint_id)
                return true;
 
index 0cc3a3374caa260c6d4401b50b82b47f8d14d5a2..f25029b9ec8573e1b92819d5b9c36abe49633728 100644 (file)
@@ -336,7 +336,7 @@ static void ipa_imem_exit(struct ipa *ipa)
 
                size = iommu_unmap(domain, ipa->imem_iova, ipa->imem_size);
                if (size != ipa->imem_size)
-                       dev_warn(dev, "unmapped %zu IMEM bytes, expected %lu\n",
+                       dev_warn(dev, "unmapped %zu IMEM bytes, expected %zu\n",
                                 size, ipa->imem_size);
        } else {
                dev_err(dev, "couldn't get IPA IOMMU domain for IMEM\n");
@@ -440,7 +440,7 @@ static void ipa_smem_exit(struct ipa *ipa)
 
                size = iommu_unmap(domain, ipa->smem_iova, ipa->smem_size);
                if (size != ipa->smem_size)
-                       dev_warn(dev, "unmapped %zu SMEM bytes, expected %lu\n",
+                       dev_warn(dev, "unmapped %zu SMEM bytes, expected %zu\n",
                                 size, ipa->smem_size);
 
        } else {
index c19dac21c468b3e931fbeb05f7a26915817368ea..dd7917cab2b124c2f5e697c221f8308c82235fba 100644 (file)
@@ -992,7 +992,8 @@ static void __team_compute_features(struct team *team)
        unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE |
                                        IFF_XMIT_DST_RELEASE_PERM;
 
-       list_for_each_entry(port, &team->port_list, list) {
+       rcu_read_lock();
+       list_for_each_entry_rcu(port, &team->port_list, list) {
                vlan_features = netdev_increment_features(vlan_features,
                                        port->dev->vlan_features,
                                        TEAM_VLAN_FEATURES);
@@ -1006,6 +1007,7 @@ static void __team_compute_features(struct team *team)
                if (port->dev->hard_header_len > max_hard_header_len)
                        max_hard_header_len = port->dev->hard_header_len;
        }
+       rcu_read_unlock();
 
        team->dev->vlan_features = vlan_features;
        team->dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL |
@@ -1020,9 +1022,7 @@ static void __team_compute_features(struct team *team)
 
 static void team_compute_features(struct team *team)
 {
-       mutex_lock(&team->lock);
        __team_compute_features(team);
-       mutex_unlock(&team->lock);
        netdev_change_features(team->dev);
 }
 
index 6aaa0675c28a397c30991375f22256e9209bb2a3..a9b55102865955761eca676caca4149fdb42cb16 100644 (file)
@@ -968,6 +968,12 @@ static const struct usb_device_id  products[] = {
                                      USB_CDC_SUBCLASS_ETHERNET,
                                      USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long)&wwan_info,
+}, {
+       /* Cinterion PLS83/PLS63 modem by GEMALTO/THALES */
+       USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0069, USB_CLASS_COMM,
+                                     USB_CDC_SUBCLASS_ETHERNET,
+                                     USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long)&wwan_info,
 }, {
        USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
                        USB_CDC_PROTO_NONE),
index af19513a9f75b5a72add34788a7a6134d10b2e09..cc4819282820bf575ae8c8d2f364e8e1c7d898b9 100644 (file)
@@ -1302,6 +1302,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x0b3c, 0xc00a, 6)},    /* Olivetti Olicard 160 */
        {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)},    /* Olivetti Olicard 500 */
        {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)},    /* Cinterion PLxx */
+       {QMI_QUIRK_SET_DTR(0x1e2d, 0x006f, 8)}, /* Cinterion PLS83/PLS63 */
        {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)},    /* Cinterion PHxx,PXxx */
        {QMI_FIXED_INTF(0x1e2d, 0x0063, 10)},   /* Cinterion ALASxx (1 RmNet) */
        {QMI_FIXED_INTF(0x1e2d, 0x0082, 4)},    /* Cinterion PHxx,PXxx (2 RmNet) */
index 7220fc8fd9b0dbee1fb2c483fc0394b9f2aab943..8280092066e7706b0f98c561edbac6df052f75bc 100644 (file)
@@ -314,6 +314,7 @@ const struct iwl_cfg_trans_params iwl_ma_trans_cfg = {
 const char iwl_ax101_name[] = "Intel(R) Wi-Fi 6 AX101";
 const char iwl_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz";
 const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz";
+const char iwl_ax203_name[] = "Intel(R) Wi-Fi 6 AX203";
 const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6 AX211 160MHz";
 const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6 AX411 160MHz";
 const char iwl_ma_name[] = "Intel(R) Wi-Fi 6";
@@ -340,6 +341,18 @@ const struct iwl_cfg iwl_qu_b0_hr1_b0 = {
        .num_rbds = IWL_NUM_RBDS_22000_HE,
 };
 
+const struct iwl_cfg iwl_qu_b0_hr_b0 = {
+       .fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
+       IWL_DEVICE_22500,
+       /*
+        * This device doesn't support receiving BlockAck with a large bitmap
+        * so we need to restrict the size of transmitted aggregation to the
+        * HT size; mac80211 would otherwise pick the HE max (256) by default.
+        */
+       .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+       .num_rbds = IWL_NUM_RBDS_22000_HE,
+};
+
 const struct iwl_cfg iwl_ax201_cfg_qu_hr = {
        .name = "Intel(R) Wi-Fi 6 AX201 160MHz",
        .fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
@@ -366,6 +379,18 @@ const struct iwl_cfg iwl_qu_c0_hr1_b0 = {
        .num_rbds = IWL_NUM_RBDS_22000_HE,
 };
 
+const struct iwl_cfg iwl_qu_c0_hr_b0 = {
+       .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
+       IWL_DEVICE_22500,
+       /*
+        * This device doesn't support receiving BlockAck with a large bitmap
+        * so we need to restrict the size of transmitted aggregation to the
+        * HT size; mac80211 would otherwise pick the HE max (256) by default.
+        */
+       .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+       .num_rbds = IWL_NUM_RBDS_22000_HE,
+};
+
 const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = {
        .name = "Intel(R) Wi-Fi 6 AX201 160MHz",
        .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
index 15248b06438036724b07bbca02f65cb6176e7c81..d8b7776a8dde1fe1797b664abfea43c1e545e1ca 100644 (file)
@@ -80,19 +80,45 @@ static void *iwl_acpi_get_dsm_object(struct device *dev, int rev, int func,
 }
 
 /*
- * Evaluate a DSM with no arguments and a single u8 return value (inside a
- * buffer object), verify and return that value.
+ * Generic function to evaluate a DSM with no arguments
+ * and an integer return value,
+ * (as an integer object or inside a buffer object),
+ * verify and assign the value in the "value" parameter.
+ * return 0 in success and the appropriate errno otherwise.
  */
-int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func)
+static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func,
+                                   u64 *value, size_t expected_size)
 {
        union acpi_object *obj;
-       int ret;
+       int ret = 0;
 
        obj = iwl_acpi_get_dsm_object(dev, rev, func, NULL);
-       if (IS_ERR(obj))
+       if (IS_ERR(obj)) {
+               IWL_DEBUG_DEV_RADIO(dev,
+                                   "Failed to get  DSM object. func= %d\n",
+                                   func);
                return -ENOENT;
+       }
+
+       if (obj->type == ACPI_TYPE_INTEGER) {
+               *value = obj->integer.value;
+       } else if (obj->type == ACPI_TYPE_BUFFER) {
+               __le64 le_value = 0;
 
-       if (obj->type != ACPI_TYPE_BUFFER) {
+               if (WARN_ON_ONCE(expected_size > sizeof(le_value)))
+                       return -EINVAL;
+
+               /* if the buffer size doesn't match the expected size */
+               if (obj->buffer.length != expected_size)
+                       IWL_DEBUG_DEV_RADIO(dev,
+                                           "ACPI: DSM invalid buffer size, padding or truncating (%d)\n",
+                                           obj->buffer.length);
+
+                /* assuming LE from Intel BIOS spec */
+               memcpy(&le_value, obj->buffer.pointer,
+                      min_t(size_t, expected_size, (size_t)obj->buffer.length));
+               *value = le64_to_cpu(le_value);
+       } else {
                IWL_DEBUG_DEV_RADIO(dev,
                                    "ACPI: DSM method did not return a valid object, type=%d\n",
                                    obj->type);
@@ -100,15 +126,6 @@ int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func)
                goto out;
        }
 
-       if (obj->buffer.length != sizeof(u8)) {
-               IWL_DEBUG_DEV_RADIO(dev,
-                                   "ACPI: DSM method returned invalid buffer, length=%d\n",
-                                   obj->buffer.length);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = obj->buffer.pointer[0];
        IWL_DEBUG_DEV_RADIO(dev,
                            "ACPI: DSM method evaluated: func=%d, ret=%d\n",
                            func, ret);
@@ -116,6 +133,24 @@ out:
        ACPI_FREE(obj);
        return ret;
 }
+
+/*
+ * Evaluate a DSM with no arguments and a u8 return value,
+ */
+int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func, u8 *value)
+{
+       int ret;
+       u64 val;
+
+       ret = iwl_acpi_get_dsm_integer(dev, rev, func, &val, sizeof(u8));
+
+       if (ret < 0)
+               return ret;
+
+       /* cast val (u64) to be u8 */
+       *value = (u8)val;
+       return 0;
+}
 IWL_EXPORT_SYMBOL(iwl_acpi_get_dsm_u8);
 
 union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
index 042dd247d387d7dbe047d400898cf638f52fad37..1cce30d1ef5590f6fdb7aed2e20045e846f745a2 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
  * Copyright (C) 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
  */
 #ifndef __iwl_fw_acpi__
 #define __iwl_fw_acpi__
@@ -99,7 +99,7 @@ struct iwl_fw_runtime;
 
 void *iwl_acpi_get_object(struct device *dev, acpi_string method);
 
-int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func);
+int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func, u8 *value);
 
 union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
                                         union acpi_object *data,
@@ -159,7 +159,8 @@ static inline void *iwl_acpi_get_dsm_object(struct device *dev, int rev,
        return ERR_PTR(-ENOENT);
 }
 
-static inline int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func)
+static inline
+int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func, u8 *value)
 {
        return -ENOENT;
 }
index 6d8f7bff12432c5b2ef165c92167b53e60079fce..895a907acdf0fb881b667b0025923b7635c71e50 100644 (file)
@@ -224,40 +224,46 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
 int iwl_pnvm_load(struct iwl_trans *trans,
                  struct iwl_notif_wait_data *notif_wait)
 {
-       const struct firmware *pnvm;
        struct iwl_notification_wait pnvm_wait;
        static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP,
                                                PNVM_INIT_COMPLETE_NTFY) };
-       char pnvm_name[64];
-       int ret;
 
        /* if the SKU_ID is empty, there's nothing to do */
        if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2])
                return 0;
 
-       /* if we already have it, nothing to do either */
-       if (trans->pnvm_loaded)
-               return 0;
+       /* load from disk only if we haven't done it (or tried) before */
+       if (!trans->pnvm_loaded) {
+               const struct firmware *pnvm;
+               char pnvm_name[64];
+               int ret;
+
+               /*
+                * The prefix unfortunately includes a hyphen at the end, so
+                * don't add the dot here...
+                */
+               snprintf(pnvm_name, sizeof(pnvm_name), "%spnvm",
+                        trans->cfg->fw_name_pre);
+
+               /* ...but replace the hyphen with the dot here. */
+               if (strlen(trans->cfg->fw_name_pre) < sizeof(pnvm_name))
+                       pnvm_name[strlen(trans->cfg->fw_name_pre) - 1] = '.';
+
+               ret = firmware_request_nowarn(&pnvm, pnvm_name, trans->dev);
+               if (ret) {
+                       IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n",
+                                    pnvm_name, ret);
+                       /*
+                        * Pretend we've loaded it - at least we've tried and
+                        * couldn't load it at all, so there's no point in
+                        * trying again over and over.
+                        */
+                       trans->pnvm_loaded = true;
+               } else {
+                       iwl_pnvm_parse(trans, pnvm->data, pnvm->size);
 
-       /*
-        * The prefix unfortunately includes a hyphen at the end, so
-        * don't add the dot here...
-        */
-       snprintf(pnvm_name, sizeof(pnvm_name), "%spnvm",
-                trans->cfg->fw_name_pre);
-
-       /* ...but replace the hyphen with the dot here. */
-       if (strlen(trans->cfg->fw_name_pre) < sizeof(pnvm_name))
-               pnvm_name[strlen(trans->cfg->fw_name_pre) - 1] = '.';
-
-       ret = firmware_request_nowarn(&pnvm, pnvm_name, trans->dev);
-       if (ret) {
-               IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n",
-                            pnvm_name, ret);
-       } else {
-               iwl_pnvm_parse(trans, pnvm->data, pnvm->size);
-
-               release_firmware(pnvm);
+                       release_firmware(pnvm);
+               }
        }
 
        iwl_init_notification_wait(notif_wait, &pnvm_wait,
index 27cb0406ba9a216e549da101b92062294a404b6e..86e1d57df65ed54a8dc32f64b78ece02732a255d 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2005-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2021 Intel Corporation
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
 #ifndef __IWL_CONFIG_H__
@@ -445,7 +445,7 @@ struct iwl_cfg {
 #define IWL_CFG_CORES_BT_GNSS          0x5
 
 #define IWL_SUBDEVICE_RF_ID(subdevice) ((u16)((subdevice) & 0x00F0) >> 4)
-#define IWL_SUBDEVICE_NO_160(subdevice)        ((u16)((subdevice) & 0x0100) >> 9)
+#define IWL_SUBDEVICE_NO_160(subdevice)        ((u16)((subdevice) & 0x0200) >> 9)
 #define IWL_SUBDEVICE_CORES(subdevice) ((u16)((subdevice) & 0x1C00) >> 10)
 
 struct iwl_dev_info {
@@ -491,6 +491,7 @@ extern const char iwl9260_killer_1550_name[];
 extern const char iwl9560_killer_1550i_name[];
 extern const char iwl9560_killer_1550s_name[];
 extern const char iwl_ax200_name[];
+extern const char iwl_ax203_name[];
 extern const char iwl_ax201_name[];
 extern const char iwl_ax101_name[];
 extern const char iwl_ax200_killer_1650w_name[];
@@ -574,6 +575,8 @@ extern const struct iwl_cfg iwl9560_2ac_cfg_soc;
 extern const struct iwl_cfg iwl_qu_b0_hr1_b0;
 extern const struct iwl_cfg iwl_qu_c0_hr1_b0;
 extern const struct iwl_cfg iwl_quz_a0_hr1_b0;
+extern const struct iwl_cfg iwl_qu_b0_hr_b0;
+extern const struct iwl_cfg iwl_qu_c0_hr_b0;
 extern const struct iwl_cfg iwl_ax200_cfg_cc;
 extern const struct iwl_cfg iwl_ax201_cfg_qu_hr;
 extern const struct iwl_cfg iwl_ax201_cfg_qu_hr;
index a654147d3cd61a162c9c9cb1a70078cf331e3e6c..a80a35a7740f38927f431d27764669647e6ab9ec 100644 (file)
@@ -180,13 +180,6 @@ static int iwl_dbg_tlv_alloc_region(struct iwl_trans *trans,
        if (le32_to_cpu(tlv->length) < sizeof(*reg))
                return -EINVAL;
 
-       /* For safe using a string from FW make sure we have a
-        * null terminator
-        */
-       reg->name[IWL_FW_INI_MAX_NAME - 1] = 0;
-
-       IWL_DEBUG_FW(trans, "WRT: parsing region: %s\n", reg->name);
-
        if (id >= IWL_FW_INI_MAX_REGION_ID) {
                IWL_ERR(trans, "WRT: Invalid region id %u\n", id);
                return -EINVAL;
index 2ac20d0a30eb654d07de933610215c133b00d6cc..2b7ef1583e7fd44aa3a3294963233421593f6fea 100644 (file)
@@ -150,16 +150,17 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
 }
 IWL_EXPORT_SYMBOL(iwl_read_prph);
 
-void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
+void iwl_write_prph_delay(struct iwl_trans *trans, u32 ofs, u32 val, u32 delay_ms)
 {
        unsigned long flags;
 
        if (iwl_trans_grab_nic_access(trans, &flags)) {
+               mdelay(delay_ms);
                iwl_write_prph_no_grab(trans, ofs, val);
                iwl_trans_release_nic_access(trans, &flags);
        }
 }
-IWL_EXPORT_SYMBOL(iwl_write_prph);
+IWL_EXPORT_SYMBOL(iwl_write_prph_delay);
 
 int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr,
                      u32 bits, u32 mask, int timeout)
@@ -219,8 +220,8 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
 void iwl_force_nmi(struct iwl_trans *trans)
 {
        if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
-               iwl_write_prph(trans, DEVICE_SET_NMI_REG,
-                              DEVICE_SET_NMI_VAL_DRV);
+               iwl_write_prph_delay(trans, DEVICE_SET_NMI_REG,
+                                    DEVICE_SET_NMI_VAL_DRV, 1);
        else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
                iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER,
                                UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER);
index 39bceee4e9e76f64b21d6de3599db52b896253c3..3c21c0e081f8e959f09b99e51b4829215b7b6cad 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2018-2019 Intel Corporation
+ * Copyright (C) 2018-2020 Intel Corporation
  */
 #ifndef __iwl_io_h__
 #define __iwl_io_h__
@@ -37,7 +37,13 @@ u32 iwl_read_prph_no_grab(struct iwl_trans *trans, u32 ofs);
 u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs);
 void iwl_write_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val);
 void iwl_write_prph64_no_grab(struct iwl_trans *trans, u64 ofs, u64 val);
-void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val);
+void iwl_write_prph_delay(struct iwl_trans *trans, u32 ofs,
+                         u32 val, u32 delay_ms);
+static inline void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
+{
+       iwl_write_prph_delay(trans, ofs, val, 0);
+}
+
 int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr,
                      u32 bits, u32 mask, int timeout);
 void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
index 0b03fdedc1f70e4861adc4479926400a9d36fa9f..1158e256f6012b1b2f145a0ef5466755f641cf84 100644 (file)
 #define RADIO_RSP_ADDR_POS             (6)
 #define RADIO_RSP_RD_CMD               (3)
 
+/* LTR control (Qu only) */
+#define HPM_MAC_LTR_CSR                        0xa0348c
+#define HPM_MAC_LRT_ENABLE_ALL         0xf
+/* also uses CSR_LTR_* for values */
+#define HPM_UMAC_LTR                   0xa03480
+
 /* FW monitor */
 #define MON_BUFF_SAMPLE_CTL            (0xa03c00)
 #define MON_BUFF_BASE_ADDR             (0xa03c1c)
index c025188fa9bc5017688f5fe7a097f37cda27dd5d..df018972a46bfa914a8478433130ba7b5c25acf9 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -2032,8 +2032,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
 
        mutex_lock(&mvm->mutex);
 
-       clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
-
        /* get the BSS vif pointer again */
        vif = iwl_mvm_get_bss_vif(mvm);
        if (IS_ERR_OR_NULL(vif))
@@ -2148,6 +2146,8 @@ out_iterate:
                        iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
 
 out:
+       clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
+
        /* no need to reset the device in unified images, if successful */
        if (unified_image && !ret) {
                /* nothing else to do if we already sent D0I3_END_CMD */
index 573e46956c14d6ce9ce80253880c618287aeac58..38d0bfb649ccc7db998bba57e0582e93210ab35a 100644 (file)
@@ -459,7 +459,10 @@ static ssize_t iwl_dbgfs_os_device_timediff_read(struct file *file,
        const size_t bufsz = sizeof(buf);
        int pos = 0;
 
+       mutex_lock(&mvm->mutex);
        iwl_mvm_get_sync_time(mvm, &curr_gp2, &curr_os);
+       mutex_unlock(&mvm->mutex);
+
        do_div(curr_os, NSEC_PER_USEC);
        diff = curr_os - curr_gp2;
        pos += scnprintf(buf + pos, bufsz - pos, "diff=%lld\n", diff);
index 0637eb1cff4e5c7a96f20d4f5cf5fb1bba88687a..313e9f106f4659caae20ab8250540c32ac83a5de 100644 (file)
@@ -1090,20 +1090,22 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
 
 static u8 iwl_mvm_eval_dsm_indonesia_5g2(struct iwl_mvm *mvm)
 {
+       u8 value;
+
        int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0,
-                                     DSM_FUNC_ENABLE_INDONESIA_5G2);
+                                     DSM_FUNC_ENABLE_INDONESIA_5G2, &value);
 
        if (ret < 0)
                IWL_DEBUG_RADIO(mvm,
                                "Failed to evaluate DSM function ENABLE_INDONESIA_5G2, ret=%d\n",
                                ret);
 
-       else if (ret >= DSM_VALUE_INDONESIA_MAX)
+       else if (value >= DSM_VALUE_INDONESIA_MAX)
                IWL_DEBUG_RADIO(mvm,
-                               "DSM function ENABLE_INDONESIA_5G2 return invalid value, ret=%d\n",
-                               ret);
+                               "DSM function ENABLE_INDONESIA_5G2 return invalid value, value=%d\n",
+                               value);
 
-       else if (ret == DSM_VALUE_INDONESIA_ENABLE) {
+       else if (value == DSM_VALUE_INDONESIA_ENABLE) {
                IWL_DEBUG_RADIO(mvm,
                                "Evaluated DSM function ENABLE_INDONESIA_5G2: Enabling 5g2\n");
                return DSM_VALUE_INDONESIA_ENABLE;
@@ -1114,25 +1116,26 @@ static u8 iwl_mvm_eval_dsm_indonesia_5g2(struct iwl_mvm *mvm)
 
 static u8 iwl_mvm_eval_dsm_disable_srd(struct iwl_mvm *mvm)
 {
+       u8 value;
        int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0,
-                                     DSM_FUNC_DISABLE_SRD);
+                                     DSM_FUNC_DISABLE_SRD, &value);
 
        if (ret < 0)
                IWL_DEBUG_RADIO(mvm,
                                "Failed to evaluate DSM function DISABLE_SRD, ret=%d\n",
                                ret);
 
-       else if (ret >= DSM_VALUE_SRD_MAX)
+       else if (value >= DSM_VALUE_SRD_MAX)
                IWL_DEBUG_RADIO(mvm,
-                               "DSM function DISABLE_SRD return invalid value, ret=%d\n",
-                               ret);
+                               "DSM function DISABLE_SRD return invalid value, value=%d\n",
+                               value);
 
-       else if (ret == DSM_VALUE_SRD_PASSIVE) {
+       else if (value == DSM_VALUE_SRD_PASSIVE) {
                IWL_DEBUG_RADIO(mvm,
                                "Evaluated DSM function DISABLE_SRD: setting SRD to passive\n");
                return DSM_VALUE_SRD_PASSIVE;
 
-       } else if (ret == DSM_VALUE_SRD_DISABLE) {
+       } else if (value == DSM_VALUE_SRD_DISABLE) {
                IWL_DEBUG_RADIO(mvm,
                                "Evaluated DSM function DISABLE_SRD: disabling SRD\n");
                return DSM_VALUE_SRD_DISABLE;
index da32937ba9a7898a5517d8418e1daba0f95252b0..43ff0407916affb47eecdb7238b629971013232a 100644 (file)
@@ -4194,6 +4194,9 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
        iwl_mvm_binding_remove_vif(mvm, vif);
 
 out:
+       if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD) &&
+           switching_chanctx)
+               return;
        mvmvif->phy_ctxt = NULL;
        iwl_mvm_power_update_mac(mvm);
 }
index 98f62d78cf9ca3da2d782e74ec40005b33172807..61618f607927d82e435183a4fe31c87c5e8d39c9 100644 (file)
@@ -791,6 +791,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        if (!mvm->scan_cmd)
                goto out_free;
 
+       /* invalidate ids to prevent accidental removal of sta_id 0 */
+       mvm->aux_sta.sta_id = IWL_MVM_INVALID_STA;
+       mvm->snif_sta.sta_id = IWL_MVM_INVALID_STA;
+
        /* Set EBS as successful as long as not stated otherwise by the FW. */
        mvm->last_ebs_successful = true;
 
@@ -1205,6 +1209,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
        reprobe = container_of(wk, struct iwl_mvm_reprobe, work);
        if (device_reprobe(reprobe->dev))
                dev_err(reprobe->dev, "reprobe failed!\n");
+       put_device(reprobe->dev);
        kfree(reprobe);
        module_put(THIS_MODULE);
 }
@@ -1255,7 +1260,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
                        module_put(THIS_MODULE);
                        return;
                }
-               reprobe->dev = mvm->trans->dev;
+               reprobe->dev = get_device(mvm->trans->dev);
                INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
                schedule_work(&reprobe->work);
        } else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
index dc174410bf9c29075f5bdf31ae94ea3beb038021..578c353ae02c9f830ad860b0eb474d59fa8055c5 100644 (file)
@@ -2057,6 +2057,9 @@ int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 
        lockdep_assert_held(&mvm->mutex);
 
+       if (WARN_ON_ONCE(mvm->snif_sta.sta_id == IWL_MVM_INVALID_STA))
+               return -EINVAL;
+
        iwl_mvm_disable_txq(mvm, NULL, mvm->snif_queue, IWL_MAX_TID_COUNT, 0);
        ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id);
        if (ret)
@@ -2071,6 +2074,9 @@ int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm)
 
        lockdep_assert_held(&mvm->mutex);
 
+       if (WARN_ON_ONCE(mvm->aux_sta.sta_id == IWL_MVM_INVALID_STA))
+               return -EINVAL;
+
        iwl_mvm_disable_txq(mvm, NULL, mvm->aux_queue, IWL_MAX_TID_COUNT, 0);
        ret = iwl_mvm_rm_sta_common(mvm, mvm->aux_sta.sta_id);
        if (ret)
index a983c215df310776ffe67f3b3ffa203eab609bfc..3712adc3ccc2511d46bcc855efbfba41c487d8e6 100644 (file)
@@ -773,6 +773,7 @@ iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes,
 
        next = skb_gso_segment(skb, netdev_flags);
        skb_shinfo(skb)->gso_size = mss;
+       skb_shinfo(skb)->gso_type = ipv4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
        if (WARN_ON_ONCE(IS_ERR(next)))
                return -EINVAL;
        else if (next)
@@ -795,6 +796,8 @@ iwl_mvm_tx_tso_segment(struct sk_buff *skb, unsigned int num_subframes,
 
                if (tcp_payload_len > mss) {
                        skb_shinfo(tmp)->gso_size = mss;
+                       skb_shinfo(tmp)->gso_type = ipv4 ? SKB_GSO_TCPV4 :
+                                                          SKB_GSO_TCPV6;
                } else {
                        if (qos) {
                                u8 *qc;
index 36bf414a388af5101060d9b6a2b3189fa82df52f..5b5134dd49af8d5ee36a954412466e480c4e92d3 100644 (file)
@@ -75,6 +75,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
                                 const struct fw_img *fw)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
+                     u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
+                                     CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
+                     u32_encode_bits(250,
+                                     CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
+                     CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
+                     u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
+                                     CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
+                     u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
        struct iwl_context_info_gen3 *ctxt_info_gen3;
        struct iwl_prph_scratch *prph_scratch;
        struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl;
@@ -189,8 +198,10 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
        /* Allocate IML */
        iml_img = dma_alloc_coherent(trans->dev, trans->iml_len,
                                     &trans_pcie->iml_dma_addr, GFP_KERNEL);
-       if (!iml_img)
-               return -ENOMEM;
+       if (!iml_img) {
+               ret = -ENOMEM;
+               goto err_free_ctxt_info;
+       }
 
        memcpy(iml_img, trans->iml, trans->iml_len);
 
@@ -206,23 +217,19 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
        iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
                    CSR_AUTO_FUNC_BOOT_ENA);
 
-       if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
-               /*
-                * The firmware initializes this again later (to a smaller
-                * value), but for the boot process initialize the LTR to
-                * ~250 usec.
-                */
-               u32 val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
-                         u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
-                                         CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
-                         u32_encode_bits(250,
-                                         CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
-                         CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
-                         u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
-                                         CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
-                         u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
-
-               iwl_write32(trans, CSR_LTR_LONG_VAL_AD, val);
+       /*
+        * To workaround hardware latency issues during the boot process,
+        * initialize the LTR to ~250 usec (see ltr_val above).
+        * The firmware initializes this again later (to a smaller value).
+        */
+       if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 ||
+            trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) &&
+           !trans->trans_cfg->integrated) {
+               iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val);
+       } else if (trans->trans_cfg->integrated &&
+                  trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
+               iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL);
+               iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val);
        }
 
        if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
@@ -232,6 +239,11 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
 
        return 0;
 
+err_free_ctxt_info:
+       dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3),
+                         trans_pcie->ctxt_info_gen3,
+                         trans_pcie->ctxt_info_dma_addr);
+       trans_pcie->ctxt_info_gen3 = NULL;
 err_free_prph_info:
        dma_free_coherent(trans->dev,
                          sizeof(*prph_info),
@@ -294,6 +306,9 @@ int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
                return ret;
        }
 
+       if (WARN_ON(prph_sc_ctrl->pnvm_cfg.pnvm_size))
+               return -EBUSY;
+
        prph_sc_ctrl->pnvm_cfg.pnvm_base_addr =
                cpu_to_le64(trans_pcie->pnvm_dram.physical);
        prph_sc_ctrl->pnvm_cfg.pnvm_size =
index 965982612e740894f5f27dea7d8fc38d4d654c11..ed3f5b7aa71e9b63914061b175349b4ed17a963d 100644 (file)
@@ -910,6 +910,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
                      IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY,
                      IWL_CFG_ANY, IWL_CFG_ANY,
                      iwl_qu_b0_hr1_b0, iwl_ax101_name),
+       _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
+                     IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP,
+                     IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,
+                     IWL_CFG_ANY, IWL_CFG_ANY,
+                     iwl_qu_b0_hr_b0, iwl_ax203_name),
 
        /* Qu C step */
        _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
@@ -917,6 +922,11 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
                      IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY,
                      IWL_CFG_ANY, IWL_CFG_ANY,
                      iwl_qu_c0_hr1_b0, iwl_ax101_name),
+       _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
+                     IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP,
+                     IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,
+                     IWL_CFG_ANY, IWL_CFG_ANY,
+                     iwl_qu_c0_hr_b0, iwl_ax203_name),
 
        /* QuZ */
        _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
index 285e0d586021061d46d4f6c7dc5f41802e1013c0..ab93a848a46675d7d92242591f8663e71f7dd7e7 100644 (file)
@@ -2107,7 +2107,8 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
 
        while (offs < dwords) {
                /* limit the time we spin here under lock to 1/2s */
-               ktime_t timeout = ktime_add_us(ktime_get(), 500 * USEC_PER_MSEC);
+               unsigned long end = jiffies + HZ / 2;
+               bool resched = false;
 
                if (iwl_trans_grab_nic_access(trans, &flags)) {
                        iwl_write32(trans, HBUS_TARG_MEM_RADDR,
@@ -2118,14 +2119,15 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
                                                        HBUS_TARG_MEM_RDAT);
                                offs++;
 
-                               /* calling ktime_get is expensive so
-                                * do it once in 128 reads
-                                */
-                               if (offs % 128 == 0 && ktime_after(ktime_get(),
-                                                                  timeout))
+                               if (time_after(jiffies, end)) {
+                                       resched = true;
                                        break;
+                               }
                        }
                        iwl_trans_release_nic_access(trans, &flags);
+
+                       if (resched)
+                               cond_resched();
                } else {
                        return -EBUSY;
                }
index 5dda0015522dd92f53d3df4c36dad16fd2afb45f..83f4964f3cb29d6b43ffddacf3d75c0b5e3806a8 100644 (file)
@@ -201,6 +201,11 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_txq *txq = trans->txqs.txq[txq_id];
 
+       if (!txq) {
+               IWL_ERR(trans, "Trying to free a queue that wasn't allocated?\n");
+               return;
+       }
+
        spin_lock_bh(&txq->lock);
        while (txq->write_ptr != txq->read_ptr) {
                IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
index 27eea909e32da6df2a75a0fa7c9a2da037b075e3..7ff1bb0ccc9cd5aec1bbf077014883180d6c0aee 100644 (file)
@@ -142,26 +142,25 @@ void iwl_txq_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
         * idx is bounded by n_window
         */
        int idx = iwl_txq_get_cmd_index(txq, txq->read_ptr);
+       struct sk_buff *skb;
 
        lockdep_assert_held(&txq->lock);
 
+       if (!txq->entries)
+               return;
+
        iwl_txq_gen2_tfd_unmap(trans, &txq->entries[idx].meta,
                               iwl_txq_get_tfd(trans, txq, idx));
 
-       /* free SKB */
-       if (txq->entries) {
-               struct sk_buff *skb;
-
-               skb = txq->entries[idx].skb;
+       skb = txq->entries[idx].skb;
 
-               /* Can be called from irqs-disabled context
-                * If skb is not NULL, it means that the whole queue is being
-                * freed and that the queue is not empty - free the skb
-                */
-               if (skb) {
-                       iwl_op_mode_free_skb(trans->op_mode, skb);
-                       txq->entries[idx].skb = NULL;
-               }
+       /* Can be called from irqs-disabled context
+        * If skb is not NULL, it means that the whole queue is being
+        * freed and that the queue is not empty - free the skb
+        */
+       if (skb) {
+               iwl_op_mode_free_skb(trans->op_mode, skb);
+               txq->entries[idx].skb = NULL;
        }
 }
 
@@ -841,10 +840,8 @@ void iwl_txq_gen2_unmap(struct iwl_trans *trans, int txq_id)
                        int idx = iwl_txq_get_cmd_index(txq, txq->read_ptr);
                        struct sk_buff *skb = txq->entries[idx].skb;
 
-                       if (WARN_ON_ONCE(!skb))
-                               continue;
-
-                       iwl_txq_free_tso_page(trans, skb);
+                       if (!WARN_ON_ONCE(!skb))
+                               iwl_txq_free_tso_page(trans, skb);
                }
                iwl_txq_gen2_free_tfd(trans, txq);
                txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr);
@@ -1494,28 +1491,28 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
         */
        int rd_ptr = txq->read_ptr;
        int idx = iwl_txq_get_cmd_index(txq, rd_ptr);
+       struct sk_buff *skb;
 
        lockdep_assert_held(&txq->lock);
 
+       if (!txq->entries)
+               return;
+
        /* We have only q->n_window txq->entries, but we use
         * TFD_QUEUE_SIZE_MAX tfds
         */
        iwl_txq_gen1_tfd_unmap(trans, &txq->entries[idx].meta, txq, rd_ptr);
 
        /* free SKB */
-       if (txq->entries) {
-               struct sk_buff *skb;
-
-               skb = txq->entries[idx].skb;
+       skb = txq->entries[idx].skb;
 
-               /* Can be called from irqs-disabled context
-                * If skb is not NULL, it means that the whole queue is being
-                * freed and that the queue is not empty - free the skb
-                */
-               if (skb) {
-                       iwl_op_mode_free_skb(trans->op_mode, skb);
-                       txq->entries[idx].skb = NULL;
-               }
+       /* Can be called from irqs-disabled context
+        * If skb is not NULL, it means that the whole queue is being
+        * freed and that the queue is not empty - free the skb
+        */
+       if (skb) {
+               iwl_op_mode_free_skb(trans->op_mode, skb);
+               txq->entries[idx].skb = NULL;
        }
 }
 
index a44b7766dec6434ba8220853b98102d46b13700b..c13547841a4e9b14d2ac39badf59bd800b564519 100644 (file)
@@ -231,7 +231,7 @@ mt7615_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
                        int cmd, int *seq)
 {
        struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
-       enum mt76_txq_id qid;
+       enum mt76_mcuq_id qid;
 
        mt7615_mcu_fill_msg(dev, skb, cmd, seq);
        if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
index 13d77f8fca86664217c9299319cbea9f1e413ce8..9fb506f2ace6d8d84effb3ba443537d282c697b6 100644 (file)
@@ -83,7 +83,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
 {
        struct mt76_queue *q = &dev->q_rx[qid];
        struct mt76_sdio *sdio = &dev->sdio;
-       int len = 0, err, i, order;
+       int len = 0, err, i;
        struct page *page;
        u8 *buf;
 
@@ -96,8 +96,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
        if (len > sdio->func->cur_blksize)
                len = roundup(len, sdio->func->cur_blksize);
 
-       order = get_order(len);
-       page = __dev_alloc_pages(GFP_KERNEL, order);
+       page = __dev_alloc_pages(GFP_KERNEL, get_order(len));
        if (!page)
                return -ENOMEM;
 
@@ -106,7 +105,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
        err = sdio_readsb(sdio->func, buf, MCR_WRDR(qid), len);
        if (err < 0) {
                dev_err(dev->dev, "sdio read data failed:%d\n", err);
-               __free_pages(page, order);
+               put_page(page);
                return err;
        }
 
@@ -123,7 +122,7 @@ static int mt7663s_rx_run_queue(struct mt76_dev *dev, enum mt76_rxq_id qid,
                if (q->queued + i + 1 == q->ndesc)
                        break;
        }
-       __free_pages(page, order);
+       put_page(page);
 
        spin_lock_bh(&q->lock);
        q->head = (q->head + i) % q->ndesc;
index 5fdd1a6d32ee1273d84b602ae9d253b908294b65..e211a2bd4d3c00330ba38adc7d2cf4aebf0cda7f 100644 (file)
@@ -256,7 +256,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
        struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
        struct mt7915_mcu_txd *mcu_txd;
        u8 seq, pkt_fmt, qidx;
-       enum mt76_txq_id txq;
+       enum mt76_mcuq_id qid;
        __le32 *txd;
        u32 val;
 
@@ -268,18 +268,18 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
                seq = ++dev->mt76.mcu.msg_seq & 0xf;
 
        if (cmd == -MCU_CMD_FW_SCATTER) {
-               txq = MT_MCUQ_FWDL;
+               qid = MT_MCUQ_FWDL;
                goto exit;
        }
 
        mcu_txd = (struct mt7915_mcu_txd *)skb_push(skb, sizeof(*mcu_txd));
 
        if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) {
-               txq = MT_MCUQ_WA;
+               qid = MT_MCUQ_WA;
                qidx = MT_TX_MCU_PORT_RX_Q0;
                pkt_fmt = MT_TX_TYPE_CMD;
        } else {
-               txq = MT_MCUQ_WM;
+               qid = MT_MCUQ_WM;
                qidx = MT_TX_MCU_PORT_RX_Q0;
                pkt_fmt = MT_TX_TYPE_CMD;
        }
@@ -326,7 +326,7 @@ exit:
        if (wait_seq)
                *wait_seq = seq;
 
-       return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);
+       return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);
 }
 
 static void
index 5f99054f535b4d6ae3da175462136da2f4eb024b..af7d1ecb777c0a51fccb375179b7847096172bc8 100644 (file)
@@ -152,8 +152,7 @@ mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e)
 
        if (new_p) {
                /* we have one extra ref from the allocator */
-               __free_pages(e->p, MT_RX_ORDER);
-
+               put_page(e->p);
                e->p = new_p;
        }
 }
@@ -310,7 +309,6 @@ static int mt7601u_dma_submit_tx(struct mt7601u_dev *dev,
        }
 
        e = &q->e[q->end];
-       e->skb = skb;
        usb_fill_bulk_urb(e->urb, usb_dev, snd_pipe, skb->data, skb->len,
                          mt7601u_complete_tx, q);
        ret = usb_submit_urb(e->urb, GFP_ATOMIC);
@@ -328,6 +326,7 @@ static int mt7601u_dma_submit_tx(struct mt7601u_dev *dev,
 
        q->end = (q->end + 1) % q->entries;
        q->used++;
+       e->skb = skb;
 
        if (q->used >= q->entries)
                ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb));
index 8caf9b34734dc75d6abf16cfdd68d0ef0f515551..f13eb4ded95fad0ddf6076ed29f7c63f5ca67984 100644 (file)
@@ -3829,7 +3829,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
                }
        }
 
-       list_add_tail(&ns->siblings, &head->list);
+       list_add_tail_rcu(&ns->siblings, &head->list);
        ns->head = head;
        mutex_unlock(&ctrl->subsys->lock);
        return 0;
index 9ac762b28811293d0895eba568bbd00fd8848fc0..282b7a4ea9a9a7a85c999dfb8e58e0f438ef6d41 100644 (file)
@@ -221,7 +221,7 @@ static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head,
        }
 
        for (ns = nvme_next_ns(head, old);
-            ns != old;
+            ns && ns != old;
             ns = nvme_next_ns(head, ns)) {
                if (nvme_path_is_disabled(ns))
                        continue;
index 856aa31931c140b48ee4066820e9c301de5eb219..6bad4d4dcdf073a13c4b71af5a7e5a97cf7b1173 100644 (file)
@@ -3242,6 +3242,8 @@ static const struct pci_device_id nvme_id_table[] = {
        { PCI_DEVICE(0x144d, 0xa822),   /* Samsung PM1725a */
                .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY |
                                NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+       { PCI_DEVICE(0x1987, 0x5016),   /* Phison E16 */
+               .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, },
        { PCI_DEVICE(0x1d1d, 0x1f1f),   /* LighNVM qemu device */
                .driver_data = NVME_QUIRK_LIGHTNVM, },
        { PCI_DEVICE(0x1d1d, 0x2807),   /* CNEX WL */
@@ -3257,6 +3259,10 @@ static const struct pci_device_id nvme_id_table[] = {
                .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
        { PCI_DEVICE(0x15b7, 0x2001),   /*  Sandisk Skyhawk */
                .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x1d97, 0x2263),   /* SPCC */
+               .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+       { PCI_DEVICE(0x2646, 0x2263),   /* KINGSTON A2000 NVMe SSD  */
+               .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
        { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001),
                .driver_data = NVME_QUIRK_SINGLE_VECTOR },
        { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
index dc1f0f6471896e3dfd3f38dee4084184bc5d588c..aacf06f0b4312539c0d295d96ce5a2d7542c7c17 100644 (file)
@@ -305,7 +305,7 @@ static void nvmet_tcp_map_pdu_iovec(struct nvmet_tcp_cmd *cmd)
        length = cmd->pdu_len;
        cmd->nr_mapped = DIV_ROUND_UP(length, PAGE_SIZE);
        offset = cmd->rbytes_done;
-       cmd->sg_idx = DIV_ROUND_UP(offset, PAGE_SIZE);
+       cmd->sg_idx = offset / PAGE_SIZE;
        sg_offset = offset % PAGE_SIZE;
        sg = &cmd->req.sg[cmd->sg_idx];
 
@@ -318,6 +318,7 @@ static void nvmet_tcp_map_pdu_iovec(struct nvmet_tcp_cmd *cmd)
                length -= iov_len;
                sg = sg_next(sg);
                iov++;
+               sg_offset = 0;
        }
 
        iov_iter_kvec(&cmd->recv_msg.msg_iter, READ, cmd->iov,
index aedfaaafd3e7edb73a4468cba26cf2c177ea1164..1122daa8e273648ce1b30e92d5f0d43254e04381 100644 (file)
@@ -162,9 +162,11 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
        mask = DMA_BIT_MASK(ilog2(end) + 1);
        dev->coherent_dma_mask &= mask;
        *dev->dma_mask &= mask;
-       /* ...but only set bus limit if we found valid dma-ranges earlier */
-       if (!ret)
+       /* ...but only set bus limit and range map if we found valid dma-ranges earlier */
+       if (!ret) {
                dev->bus_dma_limit = end;
+               dev->dma_range_map = map;
+       }
 
        coherent = of_dma_is_coherent(np);
        dev_dbg(dev, "device is%sdma coherent\n",
@@ -172,6 +174,9 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 
        iommu = of_iommu_configure(dev, np, id);
        if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+               /* Don't touch range map if it wasn't set from a valid dma-ranges */
+               if (!ret)
+                       dev->dma_range_map = NULL;
                kfree(map);
                return -EPROBE_DEFER;
        }
@@ -181,7 +186,6 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 
        arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
 
-       dev->dma_range_map = map;
        return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure_id);
index b9fecc25d21316f8d7c1076d2d126305c58db82c..790393d1e31896d9d18f33e2f872c18f3e794e8e 100644 (file)
@@ -1558,7 +1558,6 @@ int pci_save_state(struct pci_dev *dev)
                return i;
 
        pci_save_ltr_state(dev);
-       pci_save_aspm_l1ss_state(dev);
        pci_save_dpc_state(dev);
        pci_save_aer_state(dev);
        pci_save_ptm_state(dev);
@@ -1665,7 +1664,6 @@ void pci_restore_state(struct pci_dev *dev)
         * LTR itself (in the PCIe capability).
         */
        pci_restore_ltr_state(dev);
-       pci_restore_aspm_l1ss_state(dev);
 
        pci_restore_pcie_state(dev);
        pci_restore_pasid_state(dev);
@@ -3353,11 +3351,6 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
        if (error)
                pci_err(dev, "unable to allocate suspend buffer for LTR\n");
 
-       error = pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_L1SS,
-                                           2 * sizeof(u32));
-       if (error)
-               pci_err(dev, "unable to allocate suspend buffer for ASPM-L1SS\n");
-
        pci_allocate_vc_save_buffers(dev);
 }
 
index 5c59365092fa44da2cff9985194642d7ee67cfdf..a7bdf0b1d45db8de894ef0f4a20b9d155c17e122 100644 (file)
@@ -582,15 +582,11 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev);
 void pcie_aspm_exit_link_state(struct pci_dev *pdev);
 void pcie_aspm_pm_state_change(struct pci_dev *pdev);
 void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
-void pci_save_aspm_l1ss_state(struct pci_dev *dev);
-void pci_restore_aspm_l1ss_state(struct pci_dev *dev);
 #else
 static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
 static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
 static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { }
 static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { }
-static inline void pci_save_aspm_l1ss_state(struct pci_dev *dev) { }
-static inline void pci_restore_aspm_l1ss_state(struct pci_dev *dev) { }
 #endif
 
 #ifdef CONFIG_PCIE_ECRC
index a08e7d6dc248807dc5064aa682c62e7e4ab7b13d..ac0557a305aff383f7a0d9e7ea4112904081f351 100644 (file)
@@ -734,50 +734,6 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
                                PCI_L1SS_CTL1_L1SS_MASK, val);
 }
 
-void pci_save_aspm_l1ss_state(struct pci_dev *dev)
-{
-       int aspm_l1ss;
-       struct pci_cap_saved_state *save_state;
-       u32 *cap;
-
-       if (!pci_is_pcie(dev))
-               return;
-
-       aspm_l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS);
-       if (!aspm_l1ss)
-               return;
-
-       save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS);
-       if (!save_state)
-               return;
-
-       cap = (u32 *)&save_state->cap.data[0];
-       pci_read_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL1, cap++);
-       pci_read_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL2, cap++);
-}
-
-void pci_restore_aspm_l1ss_state(struct pci_dev *dev)
-{
-       int aspm_l1ss;
-       struct pci_cap_saved_state *save_state;
-       u32 *cap;
-
-       if (!pci_is_pcie(dev))
-               return;
-
-       aspm_l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS);
-       if (!aspm_l1ss)
-               return;
-
-       save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS);
-       if (!save_state)
-               return;
-
-       cap = (u32 *)&save_state->cap.data[0];
-       pci_write_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL1, *cap++);
-       pci_write_config_dword(dev, aspm_l1ss + PCI_L1SS_CTL2, *cap++);
-}
-
 static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
 {
        pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL,
index dc6dd531c99642b1544db039336a91669967903d..cb81010ba1a21b108e76fd248ed8bb3ac79c8cb2 100644 (file)
@@ -419,13 +419,17 @@ static int init_bios_attributes(int attr_type, const char *guid)
                return retval;
        /* need to use specific instance_id and guid combination to get right data */
        obj = get_wmiobj_pointer(instance_id, guid);
-       if (!obj)
+       if (!obj || obj->type != ACPI_TYPE_PACKAGE)
                return -ENODEV;
        elements = obj->package.elements;
 
        mutex_lock(&wmi_priv.mutex);
        while (elements) {
                /* sanity checking */
+               if (elements[ATTR_NAME].type != ACPI_TYPE_STRING) {
+                       pr_debug("incorrect element type\n");
+                       goto nextobj;
+               }
                if (strlen(elements[ATTR_NAME].string.pointer) == 0) {
                        pr_debug("empty attribute found\n");
                        goto nextobj;
index 18bf8aeb5f870c699f930572848c5dfab75b442d..e94e59283ecb9f5f601f005f5359d35c60522be1 100644 (file)
@@ -32,6 +32,10 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
 MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
 
+static int enable_tablet_mode_sw = -1;
+module_param(enable_tablet_mode_sw, int, 0444);
+MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting (-1=auto, 0=no, 1=yes)");
+
 #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
 #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
 
@@ -654,10 +658,12 @@ static int __init hp_wmi_input_setup(void)
        }
 
        /* Tablet mode */
-       val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
-       if (!(val < 0)) {
-               __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
-               input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
+       if (enable_tablet_mode_sw > 0) {
+               val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
+               if (val >= 0) {
+                       __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
+                       input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
+               }
        }
 
        err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
index ca03d8e70bd1359f586e82aaa75878ecf58f75c7..67a768fe5b2a308eee0a88f267a192e99a68dd73 100644 (file)
@@ -1813,13 +1813,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
 {
        struct regulator_dev *r;
        struct device *dev = rdev->dev.parent;
-       int ret;
+       int ret = 0;
 
        /* No supply to resolve? */
        if (!rdev->supply_name)
                return 0;
 
-       /* Supply already resolved? */
+       /* Supply already resolved? (fast-path without locking contention) */
        if (rdev->supply)
                return 0;
 
@@ -1829,7 +1829,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
 
                /* Did the lookup explicitly defer for us? */
                if (ret == -EPROBE_DEFER)
-                       return ret;
+                       goto out;
 
                if (have_full_constraints()) {
                        r = dummy_regulator_rdev;
@@ -1837,15 +1837,18 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
                } else {
                        dev_err(dev, "Failed to resolve %s-supply for %s\n",
                                rdev->supply_name, rdev->desc->name);
-                       return -EPROBE_DEFER;
+                       ret = -EPROBE_DEFER;
+                       goto out;
                }
        }
 
        if (r == rdev) {
                dev_err(dev, "Supply for %s (%s) resolved to itself\n",
                        rdev->desc->name, rdev->supply_name);
-               if (!have_full_constraints())
-                       return -EINVAL;
+               if (!have_full_constraints()) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                r = dummy_regulator_rdev;
                get_device(&r->dev);
        }
@@ -1859,7 +1862,8 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
        if (r->dev.parent && r->dev.parent != rdev->dev.parent) {
                if (!device_is_bound(r->dev.parent)) {
                        put_device(&r->dev);
-                       return -EPROBE_DEFER;
+                       ret = -EPROBE_DEFER;
+                       goto out;
                }
        }
 
@@ -1867,15 +1871,32 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
        ret = regulator_resolve_supply(r);
        if (ret < 0) {
                put_device(&r->dev);
-               return ret;
+               goto out;
+       }
+
+       /*
+        * Recheck rdev->supply with rdev->mutex lock held to avoid a race
+        * between rdev->supply null check and setting rdev->supply in
+        * set_supply() from concurrent tasks.
+        */
+       regulator_lock(rdev);
+
+       /* Supply just resolved by a concurrent task? */
+       if (rdev->supply) {
+               regulator_unlock(rdev);
+               put_device(&r->dev);
+               goto out;
        }
 
        ret = set_supply(rdev, r);
        if (ret < 0) {
+               regulator_unlock(rdev);
                put_device(&r->dev);
-               return ret;
+               goto out;
        }
 
+       regulator_unlock(rdev);
+
        /*
         * In set_machine_constraints() we may have turned this regulator on
         * but we couldn't propagate to the supply if it hadn't been resolved
@@ -1886,11 +1907,12 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
                if (ret < 0) {
                        _regulator_put(rdev->supply);
                        rdev->supply = NULL;
-                       return ret;
+                       goto out;
                }
        }
 
-       return 0;
+out:
+       return ret;
 }
 
 /* Internal regulator request function */
index 51e80bc70d42325d14aea0baa72dff39b1113f48..68a9ac6f2fe1776a1f3d2206f5a2145f815f51b0 100644 (file)
@@ -805,6 +805,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
 
        spin_lock_irq(&rtc_lock);
 
+       /* Ensure that the RTC is accessible. Bit 0-6 must be 0! */
+       if ((CMOS_READ(RTC_VALID) & 0x7f) != 0) {
+               spin_unlock_irq(&rtc_lock);
+               dev_warn(dev, "not accessible\n");
+               retval = -ENXIO;
+               goto cleanup1;
+       }
+
        if (!(flags & CMOS_RTC_FLAGS_NOFREQ)) {
                /* force periodic irq to CMOS reset default of 1024Hz;
                 *
index 972a5b9a629d3bfd992bac180e623927b4144adb..f83c13818af3b6d207ae73226ef07a2b351118ea 100644 (file)
@@ -21,6 +21,13 @@ unsigned int mc146818_get_time(struct rtc_time *time)
 
 again:
        spin_lock_irqsave(&rtc_lock, flags);
+       /* Ensure that the RTC is accessible. Bit 0-6 must be 0! */
+       if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x7f) != 0)) {
+               spin_unlock_irqrestore(&rtc_lock, flags);
+               memset(time, 0xff, sizeof(*time));
+               return 0;
+       }
+
        /*
         * Check whether there is an update in progress during which the
         * readout is unspecified. The maximum update time is ~2ms. Poll
index 16bb135c20aa525de5581e73537f153ccd1358cb..03d27ee9cac65e62102fbbb9d0637b77164f9d8e 100644 (file)
@@ -1874,18 +1874,26 @@ void dasd_path_create_kobjects(struct dasd_device *device)
 }
 EXPORT_SYMBOL(dasd_path_create_kobjects);
 
-/*
- * As we keep kobjects for the lifetime of a device, this function must not be
- * called anywhere but in the context of offlining a device.
- */
-void dasd_path_remove_kobj(struct dasd_device *device, int chp)
+static void dasd_path_remove_kobj(struct dasd_device *device, int chp)
 {
        if (device->path[chp].in_sysfs) {
                kobject_put(&device->path[chp].kobj);
                device->path[chp].in_sysfs = false;
        }
 }
-EXPORT_SYMBOL(dasd_path_remove_kobj);
+
+/*
+ * As we keep kobjects for the lifetime of a device, this function must not be
+ * called anywhere but in the context of offlining a device.
+ */
+void dasd_path_remove_kobjects(struct dasd_device *device)
+{
+       int i;
+
+       for (i = 0; i < 8; i++)
+               dasd_path_remove_kobj(device, i);
+}
+EXPORT_SYMBOL(dasd_path_remove_kobjects);
 
 int dasd_add_sysfs_files(struct ccw_device *cdev)
 {
index 3caa1ee5f4b0ab03fc35de01f9662c67aedbe3c0..65eb87cbbb9b2d553aa85d0c039f98391623a584 100644 (file)
@@ -1036,7 +1036,6 @@ static void dasd_eckd_clear_conf_data(struct dasd_device *device)
                device->path[i].ssid = 0;
                device->path[i].chpid = 0;
                dasd_path_notoper(device, i);
-               dasd_path_remove_kobj(device, i);
        }
 }
 
@@ -2173,6 +2172,7 @@ out_err2:
        device->block = NULL;
 out_err1:
        dasd_eckd_clear_conf_data(device);
+       dasd_path_remove_kobjects(device);
        kfree(device->private);
        device->private = NULL;
        return rc;
@@ -2191,6 +2191,7 @@ static void dasd_eckd_uncheck_device(struct dasd_device *device)
        private->vdsneq = NULL;
        private->gneq = NULL;
        dasd_eckd_clear_conf_data(device);
+       dasd_path_remove_kobjects(device);
 }
 
 static struct dasd_ccw_req *
index 3bc008f9136cc7d8c739514e96b6c259a0887c4d..b8a04c42d1d2e4926c4e166f909ad14527050e22 100644 (file)
@@ -858,7 +858,7 @@ int dasd_add_sysfs_files(struct ccw_device *);
 void dasd_remove_sysfs_files(struct ccw_device *);
 void dasd_path_create_kobj(struct dasd_device *, int);
 void dasd_path_create_kobjects(struct dasd_device *);
-void dasd_path_remove_kobj(struct dasd_device *, int);
+void dasd_path_remove_kobjects(struct dasd_device *);
 
 struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
 struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *);
index be2520cc010bef249509eca4505e114026507331..7dc72cb718b0e2866226eefcde6a4832b99cbeb3 100644 (file)
@@ -71,15 +71,11 @@ static int vfio_ap_queue_dev_probe(struct ap_device *apdev)
 static void vfio_ap_queue_dev_remove(struct ap_device *apdev)
 {
        struct vfio_ap_queue *q;
-       int apid, apqi;
 
        mutex_lock(&matrix_dev->lock);
        q = dev_get_drvdata(&apdev->device);
+       vfio_ap_mdev_reset_queue(q, 1);
        dev_set_drvdata(&apdev->device, NULL);
-       apid = AP_QID_CARD(q->apqn);
-       apqi = AP_QID_QUEUE(q->apqn);
-       vfio_ap_mdev_reset_queue(apid, apqi, 1);
-       vfio_ap_irq_disable(q);
        kfree(q);
        mutex_unlock(&matrix_dev->lock);
 }
index e0bde85187451bb4c66c61049a8541937fe83b36..41fc2e4135fe18714aba0a9e39748fe826886067 100644 (file)
@@ -25,6 +25,7 @@
 #define VFIO_AP_MDEV_NAME_HWVIRT "VFIO AP Passthrough Device"
 
 static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev);
+static struct vfio_ap_queue *vfio_ap_find_queue(int apqn);
 
 static int match_apqn(struct device *dev, const void *data)
 {
@@ -49,20 +50,15 @@ static struct vfio_ap_queue *vfio_ap_get_queue(
                                        int apqn)
 {
        struct vfio_ap_queue *q;
-       struct device *dev;
 
        if (!test_bit_inv(AP_QID_CARD(apqn), matrix_mdev->matrix.apm))
                return NULL;
        if (!test_bit_inv(AP_QID_QUEUE(apqn), matrix_mdev->matrix.aqm))
                return NULL;
 
-       dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL,
-                                &apqn, match_apqn);
-       if (!dev)
-               return NULL;
-       q = dev_get_drvdata(dev);
-       q->matrix_mdev = matrix_mdev;
-       put_device(dev);
+       q = vfio_ap_find_queue(apqn);
+       if (q)
+               q->matrix_mdev = matrix_mdev;
 
        return q;
 }
@@ -119,13 +115,18 @@ static void vfio_ap_wait_for_irqclear(int apqn)
  */
 static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q)
 {
-       if (q->saved_isc != VFIO_AP_ISC_INVALID && q->matrix_mdev)
+       if (!q)
+               return;
+       if (q->saved_isc != VFIO_AP_ISC_INVALID &&
+           !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm))) {
                kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc);
-       if (q->saved_pfn && q->matrix_mdev)
+               q->saved_isc = VFIO_AP_ISC_INVALID;
+       }
+       if (q->saved_pfn && !WARN_ON(!q->matrix_mdev)) {
                vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev),
                                 &q->saved_pfn, 1);
-       q->saved_pfn = 0;
-       q->saved_isc = VFIO_AP_ISC_INVALID;
+               q->saved_pfn = 0;
+       }
 }
 
 /**
@@ -144,7 +145,7 @@ static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q)
  * Returns if ap_aqic function failed with invalid, deconfigured or
  * checkstopped AP.
  */
-struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q)
+static struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q)
 {
        struct ap_qirq_ctrl aqic_gisa = {};
        struct ap_queue_status status;
@@ -1037,19 +1038,14 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
 {
        struct ap_matrix_mdev *m;
 
-       mutex_lock(&matrix_dev->lock);
-
        list_for_each_entry(m, &matrix_dev->mdev_list, node) {
-               if ((m != matrix_mdev) && (m->kvm == kvm)) {
-                       mutex_unlock(&matrix_dev->lock);
+               if ((m != matrix_mdev) && (m->kvm == kvm))
                        return -EPERM;
-               }
        }
 
        matrix_mdev->kvm = kvm;
        kvm_get_kvm(kvm);
        kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
-       mutex_unlock(&matrix_dev->lock);
 
        return 0;
 }
@@ -1083,79 +1079,118 @@ static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb,
        return NOTIFY_DONE;
 }
 
+static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)
+{
+       kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
+       matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
+       vfio_ap_mdev_reset_queues(matrix_mdev->mdev);
+       kvm_put_kvm(matrix_mdev->kvm);
+       matrix_mdev->kvm = NULL;
+}
+
 static int vfio_ap_mdev_group_notifier(struct notifier_block *nb,
                                       unsigned long action, void *data)
 {
-       int ret;
+       int ret, notify_rc = NOTIFY_OK;
        struct ap_matrix_mdev *matrix_mdev;
 
        if (action != VFIO_GROUP_NOTIFY_SET_KVM)
                return NOTIFY_OK;
 
        matrix_mdev = container_of(nb, struct ap_matrix_mdev, group_notifier);
+       mutex_lock(&matrix_dev->lock);
 
        if (!data) {
-               matrix_mdev->kvm = NULL;
-               return NOTIFY_OK;
+               if (matrix_mdev->kvm)
+                       vfio_ap_mdev_unset_kvm(matrix_mdev);
+               goto notify_done;
        }
 
        ret = vfio_ap_mdev_set_kvm(matrix_mdev, data);
-       if (ret)
-               return NOTIFY_DONE;
+       if (ret) {
+               notify_rc = NOTIFY_DONE;
+               goto notify_done;
+       }
 
        /* If there is no CRYCB pointer, then we can't copy the masks */
-       if (!matrix_mdev->kvm->arch.crypto.crycbd)
-               return NOTIFY_DONE;
+       if (!matrix_mdev->kvm->arch.crypto.crycbd) {
+               notify_rc = NOTIFY_DONE;
+               goto notify_done;
+       }
 
        kvm_arch_crypto_set_masks(matrix_mdev->kvm, matrix_mdev->matrix.apm,
                                  matrix_mdev->matrix.aqm,
                                  matrix_mdev->matrix.adm);
 
-       return NOTIFY_OK;
+notify_done:
+       mutex_unlock(&matrix_dev->lock);
+       return notify_rc;
 }
 
-static void vfio_ap_irq_disable_apqn(int apqn)
+static struct vfio_ap_queue *vfio_ap_find_queue(int apqn)
 {
        struct device *dev;
-       struct vfio_ap_queue *q;
+       struct vfio_ap_queue *q = NULL;
 
        dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL,
                                 &apqn, match_apqn);
        if (dev) {
                q = dev_get_drvdata(dev);
-               vfio_ap_irq_disable(q);
                put_device(dev);
        }
+
+       return q;
 }
 
-int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi,
+int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q,
                             unsigned int retry)
 {
        struct ap_queue_status status;
+       int ret;
        int retry2 = 2;
-       int apqn = AP_MKQID(apid, apqi);
 
-       do {
-               status = ap_zapq(apqn);
-               switch (status.response_code) {
-               case AP_RESPONSE_NORMAL:
-                       while (!status.queue_empty && retry2--) {
-                               msleep(20);
-                               status = ap_tapq(apqn, NULL);
-                       }
-                       WARN_ON_ONCE(retry2 <= 0);
-                       return 0;
-               case AP_RESPONSE_RESET_IN_PROGRESS:
-               case AP_RESPONSE_BUSY:
+       if (!q)
+               return 0;
+
+retry_zapq:
+       status = ap_zapq(q->apqn);
+       switch (status.response_code) {
+       case AP_RESPONSE_NORMAL:
+               ret = 0;
+               break;
+       case AP_RESPONSE_RESET_IN_PROGRESS:
+               if (retry--) {
                        msleep(20);
-                       break;
-               default:
-                       /* things are really broken, give up */
-                       return -EIO;
+                       goto retry_zapq;
                }
-       } while (retry--);
+               ret = -EBUSY;
+               break;
+       case AP_RESPONSE_Q_NOT_AVAIL:
+       case AP_RESPONSE_DECONFIGURED:
+       case AP_RESPONSE_CHECKSTOPPED:
+               WARN_ON_ONCE(status.irq_enabled);
+               ret = -EBUSY;
+               goto free_resources;
+       default:
+               /* things are really broken, give up */
+               WARN(true, "PQAP/ZAPQ completed with invalid rc (%x)\n",
+                    status.response_code);
+               return -EIO;
+       }
+
+       /* wait for the reset to take effect */
+       while (retry2--) {
+               if (status.queue_empty && !status.irq_enabled)
+                       break;
+               msleep(20);
+               status = ap_tapq(q->apqn, NULL);
+       }
+       WARN_ON_ONCE(retry2 <= 0);
 
-       return -EBUSY;
+free_resources:
+       vfio_ap_free_aqic_resources(q);
+
+       return ret;
 }
 
 static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev)
@@ -1163,13 +1198,15 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev)
        int ret;
        int rc = 0;
        unsigned long apid, apqi;
+       struct vfio_ap_queue *q;
        struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
 
        for_each_set_bit_inv(apid, matrix_mdev->matrix.apm,
                             matrix_mdev->matrix.apm_max + 1) {
                for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm,
                                     matrix_mdev->matrix.aqm_max + 1) {
-                       ret = vfio_ap_mdev_reset_queue(apid, apqi, 1);
+                       q = vfio_ap_find_queue(AP_MKQID(apid, apqi));
+                       ret = vfio_ap_mdev_reset_queue(q, 1);
                        /*
                         * Regardless whether a queue turns out to be busy, or
                         * is not operational, we need to continue resetting
@@ -1177,7 +1214,6 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev)
                         */
                        if (ret)
                                rc = ret;
-                       vfio_ap_irq_disable_apqn(AP_MKQID(apid, apqi));
                }
        }
 
@@ -1222,13 +1258,8 @@ static void vfio_ap_mdev_release(struct mdev_device *mdev)
        struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
 
        mutex_lock(&matrix_dev->lock);
-       if (matrix_mdev->kvm) {
-               kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
-               matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
-               vfio_ap_mdev_reset_queues(mdev);
-               kvm_put_kvm(matrix_mdev->kvm);
-               matrix_mdev->kvm = NULL;
-       }
+       if (matrix_mdev->kvm)
+               vfio_ap_mdev_unset_kvm(matrix_mdev);
        mutex_unlock(&matrix_dev->lock);
 
        vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
index f46dde56b4644fc9965406a067775806d722a220..28e9d998976820deac127d45ed48c53a1c3d998f 100644 (file)
@@ -88,11 +88,6 @@ struct ap_matrix_mdev {
        struct mdev_device *mdev;
 };
 
-extern int vfio_ap_mdev_register(void);
-extern void vfio_ap_mdev_unregister(void);
-int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi,
-                            unsigned int retry);
-
 struct vfio_ap_queue {
        struct ap_matrix_mdev *matrix_mdev;
        unsigned long saved_pfn;
@@ -100,5 +95,10 @@ struct vfio_ap_queue {
 #define VFIO_AP_ISC_INVALID 0xff
        unsigned char saved_isc;
 };
-struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q);
+
+int vfio_ap_mdev_register(void);
+void vfio_ap_mdev_unregister(void);
+int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q,
+                            unsigned int retry);
+
 #endif /* _VFIO_AP_PRIVATE_H_ */
index 1cb82fa6a60e4c40d6e1c9d35287c274dc286fd0..39d147e251bf4f2e103a9b003b2fcf4a025b880a 100644 (file)
@@ -559,6 +559,9 @@ __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                return -ENODEV;
        }
 
+       if (!vport->phba->sli4_hba.nvmels_wq)
+               return -ENOMEM;
+
        /*
         * there are two dma buf in the request, actually there is one and
         * the second one is just the start address + cmd size.
index f80abe28f35a4da7630a5fbc572e03c7b9a733c1..0e0fe5b094966bb6cc5b5411d3ba2064faabe1a6 100644 (file)
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(ql2xfulldump_on_mpifail,
 int ql2xenforce_iocb_limit = 1;
 module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(ql2xenforce_iocb_limit,
-                "Enforce IOCB throttling, to avoid FW congestion. (default: 0)");
+                "Enforce IOCB throttling, to avoid FW congestion. (default: 1)");
 
 /*
  * CT6 CTX allocation cache
index c4472b68b7c2a2397d4bd037ff8b85697a845900..698d21f505165b2b0ef11838e40b553b9f5ec2b0 100644 (file)
@@ -271,8 +271,21 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs)
        return soc_dev;
 }
 
+static const struct of_device_id at91_soc_allowed_list[] __initconst = {
+       { .compatible = "atmel,at91rm9200", },
+       { .compatible = "atmel,at91sam9", },
+       { .compatible = "atmel,sama5", },
+       { .compatible = "atmel,samv7", },
+       { }
+};
+
 static int __init atmel_soc_device_init(void)
 {
+       struct device_node *np = of_find_node_by_path("/");
+
+       if (!of_match_node(at91_soc_allowed_list, np))
+               return 0;
+
        at91_soc_init(socs);
 
        return 0;
index a9370f4aacca97b1e00c5bb56e7d84fda8d932b5..05812f8ae73406f3f706efc953a5878af82659b3 100644 (file)
@@ -13,7 +13,7 @@ config SOC_IMX8M
        depends on ARCH_MXC || COMPILE_TEST
        default ARCH_MXC && ARM64
        select SOC_BUS
-       select ARM_GIC_V3 if ARCH_MXC
+       select ARM_GIC_V3 if ARCH_MXC && ARCH_MULTI_V7
        help
          If you say yes here you get support for the NXP i.MX8M family
          support, it will provide the SoC info like SoC family,
index 7c6b009b6f6cfdb2b00e9a0dfd1f3669ce361b41..7a7c38282e114cdc85fb9ee109aade42baf15f42 100644 (file)
@@ -8,6 +8,7 @@ config LITEX
 config LITEX_SOC_CONTROLLER
        tristate "Enable LiteX SoC Controller driver"
        depends on OF || COMPILE_TEST
+       depends on HAS_IOMEM
        select LITEX
        help
          This option enables the SoC Controller Driver which verifies
index e9925c8487d741f29c6f25cd9ee004619a335859..d90e4a264b6f6bfa4ada206c7a7f14bde14856a3 100644 (file)
@@ -23,12 +23,7 @@ static const char * const sunxi_mbus_devices[] = {
        "allwinner,sun7i-a20-display-engine",
        "allwinner,sun8i-a23-display-engine",
        "allwinner,sun8i-a33-display-engine",
-       "allwinner,sun8i-a83t-display-engine",
-       "allwinner,sun8i-h3-display-engine",
-       "allwinner,sun8i-r40-display-engine",
-       "allwinner,sun8i-v3s-display-engine",
        "allwinner,sun9i-a80-display-engine",
-       "allwinner,sun50i-a64-display-engine",
 
        /*
         * And now we have the regular devices connected to the MBUS
index 77f0051358f1c19c68407cb7f0913c720cf3ea53..bf1468e5bccbaa50c44d3ce81b59e37ab7b057e2 100644 (file)
@@ -860,6 +860,7 @@ static int omap_prm_reset_init(struct platform_device *pdev,
        const struct omap_rst_map *map;
        struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev);
        char buf[32];
+       u32 v;
 
        /*
         * Check if we have controllable resets. If either rstctrl is non-zero
@@ -907,6 +908,16 @@ static int omap_prm_reset_init(struct platform_device *pdev,
                map++;
        }
 
+       /* Quirk handling to assert rst_map_012 bits on reset and avoid errors */
+       if (prm->data->rstmap == rst_map_012) {
+               v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
+               if ((v & reset->mask) != reset->mask) {
+                       dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v);
+                       writel_relaxed(reset->mask, reset->prm->base +
+                                      reset->prm->data->rstctrl);
+               }
+       }
+
        return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
 }
 
index cbc4c28c1541cba3370661b2e7015a15c04b19be..62ea0c9e321b4c1e7e095ed6f70091ae775c5e5b 100644 (file)
@@ -254,7 +254,8 @@ static int altera_spi_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev,
                                "Invalid number of chipselect: %hu\n",
                                pdata->num_chipselect);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto exit;
                }
 
                master->num_chipselect = pdata->num_chipselect;
index 859910ec8d9f6b649a9de491d830f6b718d82f1e..8cb4d923aeaab3b9c67332f86b7fa72dc924b484 100644 (file)
@@ -682,6 +682,7 @@ static const struct of_device_id spidev_dt_ids[] = {
        { .compatible = "lwn,bk4" },
        { .compatible = "dh,dhcom-board" },
        { .compatible = "menlo,m53cpld" },
+       { .compatible = "cisco,spi-petra" },
        {},
 };
 MODULE_DEVICE_TABLE(of, spidev_dt_ids);
index b668a82d40ad4606b21832aa1f86dcfd225892e3..f5fbdbc4ffdb183b3bf00a27e7c6b95a25668953 100644 (file)
@@ -367,7 +367,7 @@ hantro_reset_raw_fmt(struct hantro_ctx *ctx)
 
        hantro_reset_fmt(raw_fmt, raw_vpu_fmt);
        raw_fmt->width = encoded_fmt->width;
-       raw_fmt->width = encoded_fmt->width;
+       raw_fmt->height = encoded_fmt->height;
        if (ctx->is_encoder)
                hantro_set_fmt_out(ctx, raw_fmt);
        else
index 781c84a9b1b79e39d10f4f47bab7e5e099e23851..de7442d4834dcab1237dc7f9558021c6871c1551 100644 (file)
@@ -203,7 +203,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
                position = cedrus_buf->codec.h264.position;
 
                sram_array[i] |= position << 1;
-               if (ref_list[i].fields & V4L2_H264_BOTTOM_FIELD_REF)
+               if (ref_list[i].fields == V4L2_H264_BOTTOM_FIELD_REF)
                        sram_array[i] |= BIT(0);
        }
 
index ab5a8627d3712e07ae3163ecbaf7d14544b35467..f798b0c744a4fc028cb6833b4795ca49b6673cc2 100644 (file)
@@ -20,9 +20,9 @@ enum country_code_type_t {
        COUNTRY_CODE_MAX
 };
 
-int rtw_regd_init(struct adapter *padapter,
-       void (*reg_notifier)(struct wiphy *wiphy,
-               struct regulatory_request *request));
+void rtw_regd_init(struct wiphy *wiphy,
+                  void (*reg_notifier)(struct wiphy *wiphy,
+                                       struct regulatory_request *request));
 void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
 
 
index bf1417236161859e1f0029862ab8f77c2efc0563..11032316c53dcc3bcf086161e48468ae7a0bf8b4 100644 (file)
@@ -3211,9 +3211,6 @@ void rtw_cfg80211_init_wiphy(struct adapter *padapter)
                        rtw_cfg80211_init_ht_capab(&bands->ht_cap, NL80211_BAND_2GHZ, rf_type);
        }
 
-       /* init regulary domain */
-       rtw_regd_init(padapter, rtw_reg_notifier);
-
        /* copy mac_addr to wiphy */
        memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
 
@@ -3328,6 +3325,9 @@ int rtw_wdev_alloc(struct adapter *padapter, struct device *dev)
        *((struct adapter **)wiphy_priv(wiphy)) = padapter;
        rtw_cfg80211_preinit_wiphy(padapter, wiphy);
 
+       /* init regulary domain */
+       rtw_regd_init(wiphy, rtw_reg_notifier);
+
        ret = wiphy_register(wiphy);
        if (ret < 0) {
                DBG_8192C("Couldn't register wiphy device\n");
index b2208e5f190ad3f92d929956e65aa0456420ed0d..301ffff12e82ba590e74e971d1a8796fb0239df7 100644 (file)
@@ -339,8 +339,6 @@ static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct
 
        padapter = rtw_netdev_priv(pnetdev);
 
-       rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj));
-
        /* 3 3. init driver special setting, interface, OS and hardware relative */
 
        /* 4 3.1 set hardware operation functions */
@@ -378,6 +376,8 @@ static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct
                goto free_hal_data;
        }
 
+       rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj));
+
        /* 3 8. get WLan MAC address */
        /*  set mac addr */
        rtw_macaddr_cfg(&psdio->func->dev, padapter->eeprompriv.mac_addr);
index 578b9f734231e0ce0a81d8c1d3045eb728ce3773..2833fc6901e6e4ad46f6ab0c96b4bb988d0d58f2 100644 (file)
@@ -139,15 +139,11 @@ static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg,
        _rtw_reg_apply_flags(wiphy);
 }
 
-int rtw_regd_init(struct adapter *padapter,
-                 void (*reg_notifier)(struct wiphy *wiphy,
-                                      struct regulatory_request *request))
+void rtw_regd_init(struct wiphy *wiphy,
+                  void (*reg_notifier)(struct wiphy *wiphy,
+                                       struct regulatory_request *request))
 {
-       struct wiphy *wiphy = padapter->rtw_wdev->wiphy;
-
        _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier);
-
-       return 0;
 }
 
 void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
index 893d1b406c29254ca0bb33fa19b4bcadd0253192..1a9c50401bdb55b1c1a63552b81187bf517da616 100644 (file)
@@ -896,7 +896,7 @@ int iscsit_setup_np(
        else
                len = sizeof(struct sockaddr_in);
        /*
-        * Set SO_REUSEADDR, and disable Nagel Algorithm with TCP_NODELAY.
+        * Set SO_REUSEADDR, and disable Nagle Algorithm with TCP_NODELAY.
         */
        if (np->np_network_transport == ISCSI_TCP)
                tcp_sock_set_nodelay(sock->sk);
index c981757ba0d4052733484c89a566be15255c08fc..780d7c4fd75653db9a7d81713eebeb32c94ccd0b 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/tee_drv.h>
 #include <linux/types.h>
@@ -148,7 +149,8 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
                         */
                        optee_cq_wait_for_completion(&optee->call_queue, &w);
                } else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
-                       might_sleep();
+                       if (need_resched())
+                               cond_resched();
                        param.a0 = res.a0;
                        param.a1 = res.a1;
                        param.a2 = res.a2;
index a5f988a9f9482bd54eef3f96cce4928c42ee02a5..b5442f979b4d0170950d9ded3d3dbe9e3066d6da 100644 (file)
@@ -56,7 +56,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
         * managed with the xHCI and the SuperSpeed hub so we create the
         * link from xHCI instead.
         */
-       while (!dev_is_pci(dev))
+       while (dev && !dev_is_pci(dev))
                dev = dev->parent;
 
        if (!dev)
index 319d68c8a5df32b62eb7fec1e7f518910f971ea0..219e85756171be8ecd75132001271252c2d28ac9 100644 (file)
@@ -2081,9 +2081,6 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
        return 0;
 }
 
-extern ssize_t redirected_tty_write(struct file *, const char __user *,
-                                                       size_t, loff_t *);
-
 /**
  *     job_control             -       check job control
  *     @tty: tty
@@ -2105,7 +2102,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
        /* NOTE: not yet done after every sleep pending a thorough
           check of the logic of this change. -- jlc */
        /* don't stop on /dev/console */
-       if (file->f_op->write == redirected_tty_write)
+       if (file->f_op->write_iter == redirected_tty_write)
                return 0;
 
        return __tty_check_change(tty, SIGTTIN);
@@ -2309,7 +2306,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
        ssize_t retval = 0;
 
        /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
-       if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
+       if (L_TOSTOP(tty) && file->f_op->write_iter != redirected_tty_write) {
                retval = tty_check_change(tty);
                if (retval)
                        return retval;
index 4a208a95e9219ba34f6b539d0e84af2d9556ea69..816e709afa5612941fa1241cf21c768710f51282 100644 (file)
@@ -144,10 +144,8 @@ DEFINE_MUTEX(tty_mutex);
 
 static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
 static ssize_t tty_write(struct kiocb *, struct iov_iter *);
-ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *);
 static __poll_t tty_poll(struct file *, poll_table *);
 static int tty_open(struct inode *, struct file *);
-long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 #ifdef CONFIG_COMPAT
 static long tty_compat_ioctl(struct file *file, unsigned int cmd,
                                unsigned long arg);
@@ -1028,9 +1026,8 @@ void tty_write_message(struct tty_struct *tty, char *msg)
  *     write method will not be invoked in parallel for each device.
  */
 
-static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)
+static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_iter *from)
 {
-       struct file *file = iocb->ki_filp;
        struct tty_struct *tty = file_tty(file);
        struct tty_ldisc *ld;
        ssize_t ret;
@@ -1053,6 +1050,11 @@ static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)
        return ret;
 }
 
+static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)
+{
+       return file_tty_write(iocb->ki_filp, iocb, from);
+}
+
 ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter)
 {
        struct file *p = NULL;
@@ -1062,9 +1064,13 @@ ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter)
                p = get_file(redirect);
        spin_unlock(&redirect_lock);
 
+       /*
+        * We know the redirected tty is just another tty, we can can
+        * call file_tty_write() directly with that file pointer.
+        */
        if (p) {
                ssize_t res;
-               res = vfs_iocb_iter_write(p, iocb, iter);
+               res = file_tty_write(p, iocb, iter);
                fput(p);
                return res;
        }
@@ -2310,6 +2316,12 @@ static int tioccons(struct file *file)
                        fput(f);
                return 0;
        }
+       if (file->f_op->write_iter != tty_write)
+               return -ENOTTY;
+       if (!(file->f_mode & FMODE_WRITE))
+               return -EBADF;
+       if (!(file->f_mode & FMODE_CAN_WRITE))
+               return -EINVAL;
        spin_lock(&redirect_lock);
        if (redirect) {
                spin_unlock(&redirect_lock);
index 134dc2005ce97de81ee1787510d4772395da8ef4..c9f6e975828852f09206ca11ed84c0fb6582e21c 100644 (file)
@@ -1329,14 +1329,17 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
        if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
                return -EINVAL;
 
-       alts = usblp->protocol[protocol].alt_setting;
-       if (alts < 0)
-               return -EINVAL;
-       r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
-       if (r < 0) {
-               printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
-                       alts, usblp->ifnum);
-               return r;
+       /* Don't unnecessarily set the interface if there's a single alt. */
+       if (usblp->intf->num_altsetting > 1) {
+               alts = usblp->protocol[protocol].alt_setting;
+               if (alts < 0)
+                       return -EINVAL;
+               r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
+               if (r < 0) {
+                       printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
+                               alts, usblp->ifnum);
+                       return r;
+               }
        }
 
        usblp->bidir = (usblp->protocol[protocol].epread != NULL);
index 0a0d11151cfb88cb6ecbd7e9264f26e75de148d6..ad4c94366dadfd4051c8459f4db0bd566fd18b04 100644 (file)
@@ -1543,7 +1543,6 @@ static void dwc2_hsotg_complete_oursetup(struct usb_ep *ep,
 static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
                                            u32 windex)
 {
-       struct dwc2_hsotg_ep *ep;
        int dir = (windex & USB_DIR_IN) ? 1 : 0;
        int idx = windex & 0x7F;
 
@@ -1553,12 +1552,7 @@ static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
        if (idx > hsotg->num_of_eps)
                return NULL;
 
-       ep = index_to_ep(hsotg, idx, dir);
-
-       if (idx && ep->dir_in != dir)
-               return NULL;
-
-       return ep;
+       return index_to_ep(hsotg, idx, dir);
 }
 
 /**
index 841daec70b6efd808b1407da9a4ba561eb98c660..3101f0dcf6ae853260c2f3abc6c78a61b1b1d89f 100644 (file)
@@ -1758,7 +1758,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
                if (PMSG_IS_AUTO(msg))
                        break;
 
-               ret = dwc3_core_init(dwc);
+               ret = dwc3_core_init_for_resume(dwc);
                if (ret)
                        return ret;
 
index 30313b233680d6a875928846d8fa8bd5eb7b1c25..99c7fc0d1d597369b819d98c238d63b1009f2f6c 100644 (file)
@@ -403,8 +403,10 @@ static int eth_bind(struct usb_composite_dev *cdev)
                struct usb_descriptor_header *usb_desc;
 
                usb_desc = usb_otg_descriptor_alloc(gadget);
-               if (!usb_desc)
+               if (!usb_desc) {
+                       status = -ENOMEM;
                        goto fail1;
+               }
                usb_otg_descriptor_init(gadget, usb_desc);
                otg_desc[0] = usb_desc;
                otg_desc[1] = NULL;
index 6497185ec4e7ab822cec2651385f64b1981fcdcb..bfd8e77788e29fe1c051b4f3f8ef14c772cb5dae 100644 (file)
@@ -999,8 +999,10 @@ static int ast_vhub_of_parse_str_desc(struct ast_vhub *vhub,
                str_array[offset].s = NULL;
 
                ret = ast_vhub_str_alloc_add(vhub, &lang_str);
-               if (ret)
+               if (ret) {
+                       of_node_put(child);
                        break;
+               }
        }
 
        return ret;
index 45c54d56ecbd55fd8241983c2c3ce42d76ffb809..b45e5bf0899798efbda164feab120da4c424fd30 100644 (file)
@@ -200,6 +200,8 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
 
        sch_ep->sch_tt = tt;
        sch_ep->ep = ep;
+       INIT_LIST_HEAD(&sch_ep->endpoint);
+       INIT_LIST_HEAD(&sch_ep->tt_endpoint);
 
        return sch_ep;
 }
@@ -373,6 +375,7 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
                                        sch_ep->bw_budget_table[j];
                }
        }
+       sch_ep->allocated = used;
 }
 
 static int check_sch_tt(struct usb_device *udev,
@@ -541,6 +544,22 @@ static int check_sch_bw(struct usb_device *udev,
        return 0;
 }
 
+static void destroy_sch_ep(struct usb_device *udev,
+       struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
+{
+       /* only release ep bw check passed by check_sch_bw() */
+       if (sch_ep->allocated)
+               update_bus_bw(sch_bw, sch_ep, 0);
+
+       list_del(&sch_ep->endpoint);
+
+       if (sch_ep->sch_tt) {
+               list_del(&sch_ep->tt_endpoint);
+               drop_tt(udev);
+       }
+       kfree(sch_ep);
+}
+
 static bool need_bw_sch(struct usb_host_endpoint *ep,
        enum usb_device_speed speed, int has_tt)
 {
@@ -583,6 +602,8 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 
        mtk->sch_array = sch_array;
 
+       INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(xhci_mtk_sch_init);
@@ -601,19 +622,14 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
        struct xhci_ep_ctx *ep_ctx;
        struct xhci_slot_ctx *slot_ctx;
        struct xhci_virt_device *virt_dev;
-       struct mu3h_sch_bw_info *sch_bw;
        struct mu3h_sch_ep_info *sch_ep;
-       struct mu3h_sch_bw_info *sch_array;
        unsigned int ep_index;
-       int bw_index;
-       int ret = 0;
 
        xhci = hcd_to_xhci(hcd);
        virt_dev = xhci->devs[udev->slot_id];
        ep_index = xhci_get_endpoint_index(&ep->desc);
        slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
        ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
-       sch_array = mtk->sch_array;
 
        xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n",
                __func__, usb_endpoint_type(&ep->desc), udev->speed,
@@ -632,35 +648,13 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
                return 0;
        }
 
-       bw_index = get_bw_index(xhci, udev, ep);
-       sch_bw = &sch_array[bw_index];
-
        sch_ep = create_sch_ep(udev, ep, ep_ctx);
        if (IS_ERR_OR_NULL(sch_ep))
                return -ENOMEM;
 
        setup_sch_info(udev, ep_ctx, sch_ep);
 
-       ret = check_sch_bw(udev, sch_bw, sch_ep);
-       if (ret) {
-               xhci_err(xhci, "Not enough bandwidth!\n");
-               if (is_fs_or_ls(udev->speed))
-                       drop_tt(udev);
-
-               kfree(sch_ep);
-               return -ENOSPC;
-       }
-
-       list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
-
-       ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
-               | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
-       ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
-               | EP_BREPEAT(sch_ep->repeat));
-
-       xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n",
-                       sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode,
-                       sch_ep->offset, sch_ep->repeat);
+       list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list);
 
        return 0;
 }
@@ -675,7 +669,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
        struct xhci_virt_device *virt_dev;
        struct mu3h_sch_bw_info *sch_array;
        struct mu3h_sch_bw_info *sch_bw;
-       struct mu3h_sch_ep_info *sch_ep;
+       struct mu3h_sch_ep_info *sch_ep, *tmp;
        int bw_index;
 
        xhci = hcd_to_xhci(hcd);
@@ -694,17 +688,79 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
        bw_index = get_bw_index(xhci, udev, ep);
        sch_bw = &sch_array[bw_index];
 
-       list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
+       list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) {
                if (sch_ep->ep == ep) {
-                       update_bus_bw(sch_bw, sch_ep, 0);
-                       list_del(&sch_ep->endpoint);
-                       if (is_fs_or_ls(udev->speed)) {
-                               list_del(&sch_ep->tt_endpoint);
-                               drop_tt(udev);
-                       }
-                       kfree(sch_ep);
+                       destroy_sch_ep(udev, sch_bw, sch_ep);
                        break;
                }
        }
 }
 EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);
+
+int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+{
+       struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+       struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
+       struct mu3h_sch_bw_info *sch_bw;
+       struct mu3h_sch_ep_info *sch_ep, *tmp;
+       int bw_index, ret;
+
+       xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
+
+       list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) {
+               bw_index = get_bw_index(xhci, udev, sch_ep->ep);
+               sch_bw = &mtk->sch_array[bw_index];
+
+               ret = check_sch_bw(udev, sch_bw, sch_ep);
+               if (ret) {
+                       xhci_err(xhci, "Not enough bandwidth!\n");
+                       return -ENOSPC;
+               }
+       }
+
+       list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
+               struct xhci_ep_ctx *ep_ctx;
+               struct usb_host_endpoint *ep = sch_ep->ep;
+               unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
+
+               bw_index = get_bw_index(xhci, udev, ep);
+               sch_bw = &mtk->sch_array[bw_index];
+
+               list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
+
+               ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
+               ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
+                       | EP_BCSCOUNT(sch_ep->cs_count)
+                       | EP_BBM(sch_ep->burst_mode));
+               ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
+                       | EP_BREPEAT(sch_ep->repeat));
+
+               xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n",
+                       sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode,
+                       sch_ep->offset, sch_ep->repeat);
+       }
+
+       return xhci_check_bandwidth(hcd, udev);
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwidth);
+
+void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+{
+       struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+       struct mu3h_sch_bw_info *sch_bw;
+       struct mu3h_sch_ep_info *sch_ep, *tmp;
+       int bw_index;
+
+       xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
+
+       list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
+               bw_index = get_bw_index(xhci, udev, sch_ep->ep);
+               sch_bw = &mtk->sch_array[bw_index];
+               destroy_sch_ep(udev, sch_bw, sch_ep);
+       }
+
+       xhci_reset_bandwidth(hcd, udev);
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_reset_bandwidth);
index 8f321f39ab960f169f4fbca420eb3381e3ae206e..fe010cc61f19bbc3180c6ff29876a09dca1a92a0 100644 (file)
@@ -347,6 +347,8 @@ static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable)
 static int xhci_mtk_setup(struct usb_hcd *hcd);
 static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
        .reset = xhci_mtk_setup,
+       .check_bandwidth = xhci_mtk_check_bandwidth,
+       .reset_bandwidth = xhci_mtk_reset_bandwidth,
 };
 
 static struct hc_driver __read_mostly xhci_mtk_hc_driver;
index a93cfe8179049d5d6518d27c4d504aaf13c1b918..cbb09dfea62e0f8be63a5ac4eac18c972c85ed7a 100644 (file)
@@ -59,6 +59,7 @@ struct mu3h_sch_bw_info {
  * @ep_type: endpoint type
  * @maxpkt: max packet size of endpoint
  * @ep: address of usb_host_endpoint struct
+ * @allocated: the bandwidth is aready allocated from bus_bw
  * @offset: which uframe of the interval that transfer should be
  *             scheduled first time within the interval
  * @repeat: the time gap between two uframes that transfers are
@@ -86,6 +87,7 @@ struct mu3h_sch_ep_info {
        u32 ep_type;
        u32 maxpkt;
        void *ep;
+       bool allocated;
        /*
         * mtk xHCI scheduling information put into reserved DWs
         * in ep context
@@ -131,6 +133,7 @@ struct xhci_hcd_mtk {
        struct device *dev;
        struct usb_hcd *hcd;
        struct mu3h_sch_bw_info *sch_array;
+       struct list_head bw_ep_chk_list;
        struct mu3c_ippc_regs __iomem *ippc_regs;
        bool has_ippc;
        int num_u2_ports;
@@ -166,6 +169,8 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
                struct usb_host_endpoint *ep);
 void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
                struct usb_host_endpoint *ep);
+int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
+void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
 
 #else
 static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd,
@@ -179,6 +184,16 @@ static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd,
 {
 }
 
+static inline int xhci_mtk_check_bandwidth(struct usb_hcd *hcd,
+               struct usb_device *udev)
+{
+       return 0;
+}
+
+static inline void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd,
+               struct usb_device *udev)
+{
+}
 #endif
 
 #endif         /* _XHCI_MTK_H_ */
index 60651a50770f93aa9e652e4ddbd127169cceba7a..8ca1a235d1645144824e1cdd129926f699f4a298 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/mbus.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/phy/phy.h>
 
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
@@ -74,6 +75,47 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
        return 0;
 }
 
+int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd)
+{
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+       struct device *dev = hcd->self.controller;
+       struct phy *phy;
+       int ret;
+
+       /* Old bindings miss the PHY handle */
+       phy = of_phy_get(dev->of_node, "usb3-phy");
+       if (IS_ERR(phy) && PTR_ERR(phy) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+       else if (IS_ERR(phy))
+               goto phy_out;
+
+       ret = phy_init(phy);
+       if (ret)
+               goto phy_put;
+
+       ret = phy_set_mode(phy, PHY_MODE_USB_HOST_SS);
+       if (ret)
+               goto phy_exit;
+
+       ret = phy_power_on(phy);
+       if (ret == -EOPNOTSUPP) {
+               /* Skip initializatin of XHCI PHY when it is unsupported by firmware */
+               dev_warn(dev, "PHY unsupported by firmware\n");
+               xhci->quirks |= XHCI_SKIP_PHY_INIT;
+       }
+       if (ret)
+               goto phy_exit;
+
+       phy_power_off(phy);
+phy_exit:
+       phy_exit(phy);
+phy_put:
+       of_phy_put(phy);
+phy_out:
+
+       return 0;
+}
+
 int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
index 3be021793cc8b07fcab2529214e57599c6f20d2d..01bf3fcb3eca5da04cbb7017e11cc176e2bf6eb3 100644 (file)
@@ -12,6 +12,7 @@ struct usb_hcd;
 
 #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
 int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
+int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd);
 int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd);
 #else
 static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
@@ -19,6 +20,11 @@ static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
        return 0;
 }
 
+static inline int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd)
+{
+       return 0;
+}
+
 static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
 {
        return 0;
index 4d34f6005381e6eb1b9dab31dd2e5ec9180ab5e4..c1edcc9b13cece07c9dc0e00c27a7f0848f4875c 100644 (file)
@@ -44,6 +44,16 @@ static void xhci_priv_plat_start(struct usb_hcd *hcd)
                priv->plat_start(hcd);
 }
 
+static int xhci_priv_plat_setup(struct usb_hcd *hcd)
+{
+       struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
+
+       if (!priv->plat_setup)
+               return 0;
+
+       return priv->plat_setup(hcd);
+}
+
 static int xhci_priv_init_quirk(struct usb_hcd *hcd)
 {
        struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
@@ -111,6 +121,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = {
 };
 
 static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
+       .plat_setup = xhci_mvebu_a3700_plat_setup,
        .init_quirk = xhci_mvebu_a3700_init_quirk,
 };
 
@@ -330,7 +341,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
 
        hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
        xhci->shared_hcd->tpl_support = hcd->tpl_support;
-       if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))
+
+       if (priv) {
+               ret = xhci_priv_plat_setup(hcd);
+               if (ret)
+                       goto disable_usb_phy;
+       }
+
+       if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)))
                hcd->skip_phy_initialization = 1;
 
        if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK))
index 1fb149d1fbcea319d712ccc9af6857e54c9cc6f8..561d0b7bce0980c10d821c96c338a2c1f909d26a 100644 (file)
@@ -13,6 +13,7 @@
 struct xhci_plat_priv {
        const char *firmware_name;
        unsigned long long quirks;
+       int (*plat_setup)(struct usb_hcd *);
        void (*plat_start)(struct usb_hcd *);
        int (*init_quirk)(struct usb_hcd *);
        int (*suspend_quirk)(struct usb_hcd *);
index cf0c93a90200f8c487dbd0e3fa728c7c552d40d4..89c3be9917f6610374b3647e81429b2e04e32753 100644 (file)
@@ -699,11 +699,16 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
        dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
                         DMA_FROM_DEVICE);
        /* for in tranfers we need to copy the data from bounce to sg */
-       len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
-                            seg->bounce_len, seg->bounce_offs);
-       if (len != seg->bounce_len)
-               xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n",
-                               len, seg->bounce_len);
+       if (urb->num_sgs) {
+               len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
+                                          seg->bounce_len, seg->bounce_offs);
+               if (len != seg->bounce_len)
+                       xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n",
+                                 len, seg->bounce_len);
+       } else {
+               memcpy(urb->transfer_buffer + seg->bounce_offs, seg->bounce_buf,
+                      seg->bounce_len);
+       }
        seg->bounce_len = 0;
        seg->bounce_offs = 0;
 }
@@ -3277,12 +3282,16 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len,
 
        /* create a max max_pkt sized bounce buffer pointed to by last trb */
        if (usb_urb_dir_out(urb)) {
-               len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
-                                  seg->bounce_buf, new_buff_len, enqd_len);
-               if (len != new_buff_len)
-                       xhci_warn(xhci,
-                               "WARN Wrong bounce buffer write length: %zu != %d\n",
-                               len, new_buff_len);
+               if (urb->num_sgs) {
+                       len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
+                                                seg->bounce_buf, new_buff_len, enqd_len);
+                       if (len != new_buff_len)
+                               xhci_warn(xhci, "WARN Wrong bounce buffer write length: %zu != %d\n",
+                                         len, new_buff_len);
+               } else {
+                       memcpy(seg->bounce_buf, urb->transfer_buffer + enqd_len, new_buff_len);
+               }
+
                seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
                                                 max_pkt, DMA_TO_DEVICE);
        } else {
index e86940571b4cf1ec7153ad15a0f22a2a2510544e..345a221028c6f254d8095867a8c85fb1f62c9e0d 100644 (file)
@@ -2985,7 +2985,7 @@ static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci,
  * else should be touching the xhci->devs[slot_id] structure, so we
  * don't need to take the xhci->lock for manipulating that.
  */
-static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 {
        int i;
        int ret = 0;
@@ -3083,7 +3083,7 @@ command_cleanup:
        return ret;
 }
 
-static void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 {
        struct xhci_hcd *xhci;
        struct xhci_virt_device *virt_dev;
@@ -5510,6 +5510,10 @@ void xhci_init_driver(struct hc_driver *drv,
                        drv->reset = over->reset;
                if (over->start)
                        drv->start = over->start;
+               if (over->check_bandwidth)
+                       drv->check_bandwidth = over->check_bandwidth;
+               if (over->reset_bandwidth)
+                       drv->reset_bandwidth = over->reset_bandwidth;
        }
 }
 EXPORT_SYMBOL_GPL(xhci_init_driver);
index 25e57bc9c3cc6b655b7ec1d4c1dfa54a80eaec85..07ff95016f119abff7c268095d6f4eee897e1e2c 100644 (file)
@@ -1920,6 +1920,8 @@ struct xhci_driver_overrides {
        size_t extra_priv_size;
        int (*reset)(struct usb_hcd *hcd);
        int (*start)(struct usb_hcd *hcd);
+       int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
+       void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
 };
 
 #define        XHCI_CFC_DELAY          10
@@ -2074,6 +2076,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
 void xhci_shutdown(struct usb_hcd *hcd);
 void xhci_init_driver(struct hc_driver *drv,
                      const struct xhci_driver_overrides *over);
+int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
+void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
 int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
 int xhci_ext_cap_init(struct xhci_hcd *xhci);
 
index ac9a81ae821642e01d96b2151ca13384c7111cf3..e6fa13701808247542ea6905a0659b194f466fd8 100644 (file)
@@ -126,6 +126,7 @@ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
                }
 
                usbhs_pipe_clear_without_sequence(pipe, 0, 0);
+               usbhs_pipe_running(pipe, 0);
 
                __usbhsf_pkt_del(pkt);
        }
index fbb10dfc56e3184a44277a16a5dc7c1d074a2127..7bec1e730b2093147feda765c189f5cfc349a5b1 100644 (file)
@@ -61,6 +61,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
        { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
        { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */
+       { USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */
        { USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */
        { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */
        { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */
@@ -201,6 +202,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
        { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */
        { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
+       { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */
        { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
        { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
        { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
index 3fe959104311b4019497b288194647afe1aba653..2049e66f34a3fd1c73c832ffd1866b0864869544 100644 (file)
@@ -425,6 +425,8 @@ static void option_instat_callback(struct urb *urb);
 #define CINTERION_PRODUCT_AHXX_2RMNET          0x0084
 #define CINTERION_PRODUCT_AHXX_AUDIO           0x0085
 #define CINTERION_PRODUCT_CLS8                 0x00b0
+#define CINTERION_PRODUCT_MV31_MBIM            0x00b3
+#define CINTERION_PRODUCT_MV31_RMNET           0x00b7
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID                     0x0b3c
@@ -1914,6 +1916,10 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_MBIM, 0xff),
+         .driver_info = RSVD(3)},
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff),
+         .driver_info = RSVD(0)},
        { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
          .driver_info = RSVD(4) },
        { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),
index 5c92a576edae8ec1cd74a9f427b79f9b0908994f..08f742fd24099e4f5e616c4818336dfe9fd26ded 100644 (file)
@@ -15,6 +15,7 @@ struct mlx5_vdpa_direct_mr {
        struct sg_table sg_head;
        int log_size;
        int nsg;
+       int nent;
        struct list_head list;
        u64 offset;
 };
index 4b6195666c589512329f4a5886cf2ba9c7486bf2..d300f799efcd1f982a41a550c61efc964cfb04e6 100644 (file)
@@ -25,17 +25,6 @@ static int get_octo_len(u64 len, int page_shift)
        return (npages + 1) / 2;
 }
 
-static void fill_sg(struct mlx5_vdpa_direct_mr *mr, void *in)
-{
-       struct scatterlist *sg;
-       __be64 *pas;
-       int i;
-
-       pas = MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
-       for_each_sg(mr->sg_head.sgl, sg, mr->nsg, i)
-               (*pas) = cpu_to_be64(sg_dma_address(sg));
-}
-
 static void mlx5_set_access_mode(void *mkc, int mode)
 {
        MLX5_SET(mkc, mkc, access_mode_1_0, mode & 0x3);
@@ -45,10 +34,18 @@ static void mlx5_set_access_mode(void *mkc, int mode)
 static void populate_mtts(struct mlx5_vdpa_direct_mr *mr, __be64 *mtt)
 {
        struct scatterlist *sg;
+       int nsg = mr->nsg;
+       u64 dma_addr;
+       u64 dma_len;
+       int j = 0;
        int i;
 
-       for_each_sg(mr->sg_head.sgl, sg, mr->nsg, i)
-               mtt[i] = cpu_to_be64(sg_dma_address(sg));
+       for_each_sg(mr->sg_head.sgl, sg, mr->nent, i) {
+               for (dma_addr = sg_dma_address(sg), dma_len = sg_dma_len(sg);
+                    nsg && dma_len;
+                    nsg--, dma_addr += BIT(mr->log_size), dma_len -= BIT(mr->log_size))
+                       mtt[j++] = cpu_to_be64(dma_addr);
+       }
 }
 
 static int create_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr *mr)
@@ -64,7 +61,6 @@ static int create_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct
                return -ENOMEM;
 
        MLX5_SET(create_mkey_in, in, uid, mvdev->res.uid);
-       fill_sg(mr, in);
        mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
        MLX5_SET(mkc, mkc, lw, !!(mr->perm & VHOST_MAP_WO));
        MLX5_SET(mkc, mkc, lr, !!(mr->perm & VHOST_MAP_RO));
@@ -276,8 +272,8 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
 done:
        mr->log_size = log_entity_size;
        mr->nsg = nsg;
-       err = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0);
-       if (!err)
+       mr->nent = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0);
+       if (!mr->nent)
                goto err_map;
 
        err = create_direct_mr(mvdev, mr);
index 88dde3455bfd99ddc585eeba97cdf434a4dd43a6..b5fe6d2ad22f5133b6d27142f5440785a2852c36 100644 (file)
@@ -87,6 +87,7 @@ struct mlx5_vq_restore_info {
        u64 device_addr;
        u64 driver_addr;
        u16 avail_index;
+       u16 used_index;
        bool ready;
        struct vdpa_callback cb;
        bool restore;
@@ -121,6 +122,7 @@ struct mlx5_vdpa_virtqueue {
        u32 virtq_id;
        struct mlx5_vdpa_net *ndev;
        u16 avail_idx;
+       u16 used_idx;
        int fw_state;
 
        /* keep last in the struct */
@@ -804,6 +806,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
 
        obj_context = MLX5_ADDR_OF(create_virtio_net_q_in, in, obj_context);
        MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx);
+       MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx);
        MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3,
                 get_features_12_3(ndev->mvdev.actual_features));
        vq_ctx = MLX5_ADDR_OF(virtio_net_q_object, obj_context, virtio_q_context);
@@ -1022,6 +1025,7 @@ static int connect_qps(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *m
 struct mlx5_virtq_attr {
        u8 state;
        u16 available_index;
+       u16 used_index;
 };
 
 static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq,
@@ -1052,6 +1056,7 @@ static int query_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueu
        memset(attr, 0, sizeof(*attr));
        attr->state = MLX5_GET(virtio_net_q_object, obj_context, state);
        attr->available_index = MLX5_GET(virtio_net_q_object, obj_context, hw_available_index);
+       attr->used_index = MLX5_GET(virtio_net_q_object, obj_context, hw_used_index);
        kfree(out);
        return 0;
 
@@ -1535,6 +1540,16 @@ static void teardown_virtqueues(struct mlx5_vdpa_net *ndev)
        }
 }
 
+static void clear_virtqueues(struct mlx5_vdpa_net *ndev)
+{
+       int i;
+
+       for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--) {
+               ndev->vqs[i].avail_idx = 0;
+               ndev->vqs[i].used_idx = 0;
+       }
+}
+
 /* TODO: cross-endian support */
 static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
 {
@@ -1610,6 +1625,7 @@ static int save_channel_info(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqu
                return err;
 
        ri->avail_index = attr.available_index;
+       ri->used_index = attr.used_index;
        ri->ready = mvq->ready;
        ri->num_ent = mvq->num_ent;
        ri->desc_addr = mvq->desc_addr;
@@ -1654,6 +1670,7 @@ static void restore_channels_info(struct mlx5_vdpa_net *ndev)
                        continue;
 
                mvq->avail_idx = ri->avail_index;
+               mvq->used_idx = ri->used_index;
                mvq->ready = ri->ready;
                mvq->num_ent = ri->num_ent;
                mvq->desc_addr = ri->desc_addr;
@@ -1768,6 +1785,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
        if (!status) {
                mlx5_vdpa_info(mvdev, "performing device reset\n");
                teardown_driver(ndev);
+               clear_virtqueues(ndev);
                mlx5_vdpa_destroy_mr(&ndev->mvdev);
                ndev->mvdev.status = 0;
                ndev->mvdev.mlx_features = 0;
index c8f0282bb64975b34f44459c0565156293b0ea64..18ffd0551b5429cbe3fc7ca4f431f45d0bad478e 100644 (file)
@@ -714,6 +714,23 @@ static bool xs_hvm_defer_init_for_callback(void)
 #endif
 }
 
+static int xenbus_probe_thread(void *unused)
+{
+       DEFINE_WAIT(w);
+
+       /*
+        * We actually just want to wait for *any* trigger of xb_waitq,
+        * and run xenbus_probe() the moment it occurs.
+        */
+       prepare_to_wait(&xb_waitq, &w, TASK_INTERRUPTIBLE);
+       schedule();
+       finish_wait(&xb_waitq, &w);
+
+       DPRINTK("probing");
+       xenbus_probe();
+       return 0;
+}
+
 static int __init xenbus_probe_initcall(void)
 {
        /*
@@ -725,6 +742,20 @@ static int __init xenbus_probe_initcall(void)
             !xs_hvm_defer_init_for_callback()))
                xenbus_probe();
 
+       /*
+        * For XS_LOCAL, spawn a thread which will wait for xenstored
+        * or a xenstore-stubdom to be started, then probe. It will be
+        * triggered when communication starts happening, by waiting
+        * on xb_waitq.
+        */
+       if (xen_store_domain_type == XS_LOCAL) {
+               struct task_struct *probe_task;
+
+               probe_task = kthread_run(xenbus_probe_thread, NULL,
+                                        "xenbus_probe");
+               if (IS_ERR(probe_task))
+                       return PTR_ERR(probe_task);
+       }
        return 0;
 }
 device_initcall(xenbus_probe_initcall);
index accdd8970e7c0cbaa67bf8eba097302c9b6274cd..b2975256dadbdf3abe4a1f1c784f83ec6d7ba8c2 100644 (file)
@@ -193,7 +193,7 @@ static int __init afs_init(void)
                goto error_cache;
 #endif
 
-       ret = register_pernet_subsys(&afs_net_ops);
+       ret = register_pernet_device(&afs_net_ops);
        if (ret < 0)
                goto error_net;
 
@@ -213,7 +213,7 @@ static int __init afs_init(void)
 error_proc:
        afs_fs_exit();
 error_fs:
-       unregister_pernet_subsys(&afs_net_ops);
+       unregister_pernet_device(&afs_net_ops);
 error_net:
 #ifdef CONFIG_AFS_FSCACHE
        fscache_unregister_netfs(&afs_cache_netfs);
@@ -244,7 +244,7 @@ static void __exit afs_exit(void)
 
        proc_remove(afs_proc_symlink);
        afs_fs_exit();
-       unregister_pernet_subsys(&afs_net_ops);
+       unregister_pernet_device(&afs_net_ops);
 #ifdef CONFIG_AFS_FSCACHE
        fscache_unregister_netfs(&afs_cache_netfs);
 #endif
index 3b8963e228a1ba82c0ac117d3a00892fc6b83abf..235b5042672e9f15cd137c22965eaa3aae9f3f61 100644 (file)
@@ -130,7 +130,15 @@ EXPORT_SYMBOL(truncate_bdev_range);
 
 static void set_init_blocksize(struct block_device *bdev)
 {
-       bdev->bd_inode->i_blkbits = blksize_bits(bdev_logical_block_size(bdev));
+       unsigned int bsize = bdev_logical_block_size(bdev);
+       loff_t size = i_size_read(bdev->bd_inode);
+
+       while (bsize < PAGE_SIZE) {
+               if (size & bsize)
+                       break;
+               bsize <<= 1;
+       }
+       bdev->bd_inode->i_blkbits = blksize_bits(bsize);
 }
 
 int set_blocksize(struct block_device *bdev, int size)
index 0886e81e554020daf145ba6a0b0044e6aeb5fc54..48ebc106a606c73582ef009ca6c9bcb19ef5a50b 100644 (file)
@@ -673,7 +673,15 @@ static noinline void caching_thread(struct btrfs_work *work)
                wake_up(&caching_ctl->wait);
        }
 
-       if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
+       /*
+        * If we are in the transaction that populated the free space tree we
+        * can't actually cache from the free space tree as our commit root and
+        * real root are the same, so we could change the contents of the blocks
+        * while caching.  Instead do the slow caching in this case, and after
+        * the transaction has committed we will be safe.
+        */
+       if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
+           !(test_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags)))
                ret = load_free_space_tree(caching_ctl);
        else
                ret = load_extent_tree_free(caching_ctl);
index e6e37591f1ded91a97c6046b1b021ecdfcab1e7c..4debdbdde2abbc264bf62c1a65fe31e22c9f3008 100644 (file)
@@ -563,6 +563,9 @@ enum {
 
        /* Indicate that we need to cleanup space cache v1 */
        BTRFS_FS_CLEANUP_SPACE_CACHE_V1,
+
+       /* Indicate that we can't trust the free space tree for caching yet */
+       BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED,
 };
 
 /*
index 30b1a630dc2f88b13d1612d5ec8f1dc4cf3f4ad7..0c335dae5af7adca7987ec8c7fcb5343c9a6f6f9 100644 (file)
@@ -2602,8 +2602,6 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
        struct btrfs_block_group *cache;
        int ret;
 
-       btrfs_add_excluded_extent(trans->fs_info, bytenr, num_bytes);
-
        cache = btrfs_lookup_block_group(trans->fs_info, bytenr);
        if (!cache)
                return -EINVAL;
@@ -2615,11 +2613,19 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
         * the pinned extents.
         */
        btrfs_cache_block_group(cache, 1);
+       /*
+        * Make sure we wait until the cache is completely built in case it is
+        * missing or is invalid and therefore needs to be rebuilt.
+        */
+       ret = btrfs_wait_block_group_cache_done(cache);
+       if (ret)
+               goto out;
 
        pin_down_extent(trans, cache, bytenr, num_bytes, 0);
 
        /* remove us from the free space cache (if we're there at all) */
        ret = btrfs_remove_free_space(cache, bytenr, num_bytes);
+out:
        btrfs_put_block_group(cache);
        return ret;
 }
@@ -2629,50 +2635,22 @@ static int __exclude_logged_extent(struct btrfs_fs_info *fs_info,
 {
        int ret;
        struct btrfs_block_group *block_group;
-       struct btrfs_caching_control *caching_ctl;
 
        block_group = btrfs_lookup_block_group(fs_info, start);
        if (!block_group)
                return -EINVAL;
 
-       btrfs_cache_block_group(block_group, 0);
-       caching_ctl = btrfs_get_caching_control(block_group);
-
-       if (!caching_ctl) {
-               /* Logic error */
-               BUG_ON(!btrfs_block_group_done(block_group));
-               ret = btrfs_remove_free_space(block_group, start, num_bytes);
-       } else {
-               /*
-                * We must wait for v1 caching to finish, otherwise we may not
-                * remove our space.
-                */
-               btrfs_wait_space_cache_v1_finished(block_group, caching_ctl);
-               mutex_lock(&caching_ctl->mutex);
-
-               if (start >= caching_ctl->progress) {
-                       ret = btrfs_add_excluded_extent(fs_info, start,
-                                                       num_bytes);
-               } else if (start + num_bytes <= caching_ctl->progress) {
-                       ret = btrfs_remove_free_space(block_group,
-                                                     start, num_bytes);
-               } else {
-                       num_bytes = caching_ctl->progress - start;
-                       ret = btrfs_remove_free_space(block_group,
-                                                     start, num_bytes);
-                       if (ret)
-                               goto out_lock;
+       btrfs_cache_block_group(block_group, 1);
+       /*
+        * Make sure we wait until the cache is completely built in case it is
+        * missing or is invalid and therefore needs to be rebuilt.
+        */
+       ret = btrfs_wait_block_group_cache_done(block_group);
+       if (ret)
+               goto out;
 
-                       num_bytes = (start + num_bytes) -
-                               caching_ctl->progress;
-                       start = caching_ctl->progress;
-                       ret = btrfs_add_excluded_extent(fs_info, start,
-                                                       num_bytes);
-               }
-out_lock:
-               mutex_unlock(&caching_ctl->mutex);
-               btrfs_put_caching_control(caching_ctl);
-       }
+       ret = btrfs_remove_free_space(block_group, start, num_bytes);
+out:
        btrfs_put_block_group(block_group);
        return ret;
 }
@@ -2863,9 +2841,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
                        mutex_unlock(&fs_info->unused_bg_unpin_mutex);
                        break;
                }
-               if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags))
-                       clear_extent_bits(&fs_info->excluded_extents, start,
-                                         end, EXTENT_UPTODATE);
 
                if (btrfs_test_opt(fs_info, DISCARD_SYNC))
                        ret = btrfs_discard_extent(fs_info, start,
index e33a65bd9a0c281a83bc824dcd5160209583c3f2..a33bca94d133ecb6022df27da5e2655f58c93fc3 100644 (file)
@@ -1150,6 +1150,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
                return PTR_ERR(trans);
 
        set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
+       set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
        free_space_root = btrfs_create_tree(trans,
                                            BTRFS_FREE_SPACE_TREE_OBJECTID);
        if (IS_ERR(free_space_root)) {
@@ -1171,11 +1172,18 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
        btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
        btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
        clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
+       ret = btrfs_commit_transaction(trans);
 
-       return btrfs_commit_transaction(trans);
+       /*
+        * Now that we've committed the transaction any reading of our commit
+        * root will be safe, so we can cache from the free space tree now.
+        */
+       clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
+       return ret;
 
 abort:
        clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
+       clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
        btrfs_abort_transaction(trans, ret);
        btrfs_end_transaction(trans);
        return ret;
index 0a6de859eb2226a2283076659fffe4afd22dd32b..d6c24c8ad7499b6e16a07d2d7332feee9baf573a 100644 (file)
@@ -433,7 +433,7 @@ static struct btrfs_device *__alloc_device(struct btrfs_fs_info *fs_info)
 
        atomic_set(&dev->reada_in_flight, 0);
        atomic_set(&dev->dev_stats_ccnt, 0);
-       btrfs_device_data_ordered_init(dev, fs_info);
+       btrfs_device_data_ordered_init(dev);
        INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
        INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
        extent_io_tree_init(fs_info, &dev->alloc_state,
index 1997a4649a66cfc62c364af9bc64d76d17508845..c43663d9c22e0d7fad622434a0ccdc70bdf57ce5 100644 (file)
@@ -39,10 +39,10 @@ struct btrfs_io_geometry {
 #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
 #include <linux/seqlock.h>
 #define __BTRFS_NEED_DEVICE_DATA_ORDERED
-#define btrfs_device_data_ordered_init(device, info)                           \
-       seqcount_mutex_init(&device->data_seqcount, &info->chunk_mutex)
+#define btrfs_device_data_ordered_init(device) \
+       seqcount_init(&device->data_seqcount)
 #else
-#define btrfs_device_data_ordered_init(device, info) do { } while (0)
+#define btrfs_device_data_ordered_init(device) do { } while (0)
 #endif
 
 #define BTRFS_DEV_STATE_WRITEABLE      (0)
@@ -76,8 +76,7 @@ struct btrfs_device {
        blk_status_t last_flush_error;
 
 #ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED
-       /* A seqcount_t with associated chunk_mutex (for lockdep) */
-       seqcount_mutex_t data_seqcount;
+       seqcount_t data_seqcount;
 #endif
 
        /* the internal btrfs device id */
@@ -168,9 +167,11 @@ btrfs_device_get_##name(const struct btrfs_device *dev)                    \
 static inline void                                                     \
 btrfs_device_set_##name(struct btrfs_device *dev, u64 size)            \
 {                                                                      \
+       preempt_disable();                                              \
        write_seqcount_begin(&dev->data_seqcount);                      \
        dev->name = size;                                               \
        write_seqcount_end(&dev->data_seqcount);                        \
+       preempt_enable();                                               \
 }
 #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPTION)
 #define BTRFS_DEVICE_GETSET_FUNCS(name)                                        \
index e4c6ae47a79617851ded589594d93dfc7a55975a..6b1ce4efb591c04e932611574eabfd15bd0de3c1 100644 (file)
@@ -133,8 +133,9 @@ cifs_build_devname(char *nodename, const char *prepath)
  * Caller is responsible for freeing returned value if it is not error.
  */
 char *cifs_compose_mount_options(const char *sb_mountdata,
-                                  const char *fullpath,
-                                  const struct dfs_info3_param *ref)
+                                const char *fullpath,
+                                const struct dfs_info3_param *ref,
+                                char **devname)
 {
        int rc;
        char *name;
@@ -231,7 +232,10 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
        strcat(mountdata, "ip=");
        strcat(mountdata, srvIP);
 
-       kfree(name);
+       if (devname)
+               *devname = name;
+       else
+               kfree(name);
 
        /*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/
        /*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/
@@ -278,7 +282,7 @@ static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt,
 
        /* strip first '\' from fullpath */
        mountdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
-                                              fullpath + 1, NULL);
+                                              fullpath + 1, NULL, NULL);
        if (IS_ERR(mountdata)) {
                kfree(devname);
                return (struct vfsmount *)mountdata;
index ce0d0037fd0afdce968408243ea7bcb4fbebc446..e46da536ed339eee61e963d4693992ae19158845 100644 (file)
@@ -822,7 +822,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
                goto out;
        }
 
-       rc = cifs_setup_volume_info(cifs_sb->ctx);
+       rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC);
        if (rc) {
                root = ERR_PTR(rc);
                goto out;
index 340ff81ee87bfdc6e3c29eb5f0198eaede82caf7..32f7a013402ee8be098e3fe1a600a4709821ae29 100644 (file)
@@ -78,7 +78,8 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
                                     int add_treename);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 extern char *cifs_compose_mount_options(const char *sb_mountdata,
-               const char *fullpath, const struct dfs_info3_param *ref);
+               const char *fullpath, const struct dfs_info3_param *ref,
+               char **devname);
 /* extern void renew_parental_timestamps(struct dentry *direntry);*/
 extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
                                        struct TCP_Server_Info *server);
@@ -89,6 +90,7 @@ extern void cifs_wake_up_task(struct mid_q_entry *mid);
 extern int cifs_handle_standard(struct TCP_Server_Info *server,
                                struct mid_q_entry *mid);
 extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx);
+extern int smb3_parse_opt(const char *options, const char *key, char **val);
 extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
 extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
 extern int cifs_call_async(struct TCP_Server_Info *server,
@@ -549,7 +551,7 @@ extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
                        unsigned char *p24);
 
 extern int
-cifs_setup_volume_info(struct smb3_fs_context *ctx);
+cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname);
 
 extern struct TCP_Server_Info *
 cifs_find_tcp_session(struct smb3_fs_context *ctx);
index c8ef24bac94fc7015df7358f52a2478ec8355f74..10fe6d6d2dee49b068c84ee977092451974e399f 100644 (file)
@@ -2972,17 +2972,20 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
        rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb),
                            ref_path, &referral, NULL);
        if (!rc) {
+               char *fake_devname = NULL;
+
                mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
-                                                  full_path + 1, &referral);
+                                                  full_path + 1, &referral,
+                                                  &fake_devname);
                free_dfs_info_param(&referral);
 
                if (IS_ERR(mdata)) {
                        rc = PTR_ERR(mdata);
                        mdata = NULL;
                } else {
-                       smb3_cleanup_fs_context_contents(ctx);
-                       rc = cifs_setup_volume_info(ctx);
+                       rc = cifs_setup_volume_info(ctx, mdata, fake_devname);
                }
+               kfree(fake_devname);
                kfree(cifs_sb->ctx->mount_options);
                cifs_sb->ctx->mount_options = mdata;
        }
@@ -3036,6 +3039,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
        struct dfs_info3_param ref = {0};
        char *mdata = NULL;
        struct smb3_fs_context fake_ctx = {NULL};
+       char *fake_devname = NULL;
 
        cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path);
 
@@ -3044,16 +3048,18 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
                return rc;
 
        mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
-                                          full_path + 1, &ref);
+                                          full_path + 1, &ref,
+                                          &fake_devname);
        free_dfs_info_param(&ref);
 
        if (IS_ERR(mdata)) {
                rc = PTR_ERR(mdata);
                mdata = NULL;
        } else
-               rc = cifs_setup_volume_info(&fake_ctx);
+               rc = cifs_setup_volume_info(&fake_ctx, mdata, fake_devname);
 
        kfree(mdata);
+       kfree(fake_devname);
 
        if (!rc) {
                /*
@@ -3122,10 +3128,24 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_
  * we should pass a clone of the original context?
  */
 int
-cifs_setup_volume_info(struct smb3_fs_context *ctx)
+cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname)
 {
        int rc = 0;
 
+       smb3_parse_devname(devname, ctx);
+
+       if (mntopts) {
+               char *ip;
+
+               cifs_dbg(FYI, "%s: mntopts=%s\n", __func__, mntopts);
+               rc = smb3_parse_opt(mntopts, "ip", &ip);
+               if (!rc && !cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip,
+                                                strlen(ip))) {
+                       cifs_dbg(VFS, "%s: failed to convert ip address\n", __func__);
+                       return -EINVAL;
+               }
+       }
+
        if (ctx->nullauth) {
                cifs_dbg(FYI, "Anonymous login\n");
                kfree(ctx->username);
index 0fdb0de7ff861b89e90ebc43b40921f79411eef2..4950ab0486aeeac4b85b2029d4e1440297b31529 100644 (file)
@@ -1417,7 +1417,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
        int rc;
        struct cache_entry *ce;
        struct dfs_info3_param ref = {0};
-       char *mdata = NULL;
+       char *mdata = NULL, *devname = NULL;
        struct TCP_Server_Info *server;
        struct cifs_ses *ses;
        struct smb3_fs_context ctx = {NULL};
@@ -1444,7 +1444,8 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
 
        up_read(&htable_rw_lock);
 
-       mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref);
+       mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref,
+                                          &devname);
        free_dfs_info_param(&ref);
 
        if (IS_ERR(mdata)) {
@@ -1453,7 +1454,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
                goto out;
        }
 
-       rc = cifs_setup_volume_info(&ctx);
+       rc = cifs_setup_volume_info(&ctx, NULL, devname);
 
        if (rc) {
                ses = ERR_PTR(rc);
@@ -1472,6 +1473,7 @@ out:
        smb3_cleanup_fs_context_contents(&ctx);
        kfree(mdata);
        kfree(rpath);
+       kfree(devname);
 
        return ses;
 }
index 68900f1629bffa97d243d645c73777157a59d414..97ac363b5df169db6c8f594b6bc3080c7473280f 100644 (file)
@@ -737,6 +737,7 @@ static int
 cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
 {
        struct inode *inode;
+       int rc;
 
        if (flags & LOOKUP_RCU)
                return -ECHILD;
@@ -746,8 +747,25 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
                if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode)))
                        CIFS_I(inode)->time = 0; /* force reval */
 
-               if (cifs_revalidate_dentry(direntry))
-                       return 0;
+               rc = cifs_revalidate_dentry(direntry);
+               if (rc) {
+                       cifs_dbg(FYI, "cifs_revalidate_dentry failed with rc=%d", rc);
+                       switch (rc) {
+                       case -ENOENT:
+                       case -ESTALE:
+                               /*
+                                * Those errors mean the dentry is invalid
+                                * (file was deleted or recreated)
+                                */
+                               return 0;
+                       default:
+                               /*
+                                * Otherwise some unexpected error happened
+                                * report it as-is to VFS layer
+                                */
+                               return rc;
+                       }
+               }
                else {
                        /*
                         * If the inode wasn't known to be a dfs entry when
index 076bcadc756a751ffaa43b55a107404b33b203fa..5111aadfdb6b6e14e86cebba2c59dd5af5de1cb7 100644 (file)
@@ -175,8 +175,10 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
        fsparam_flag_no("exec", Opt_ignore),
        fsparam_flag_no("dev", Opt_ignore),
        fsparam_flag_no("mand", Opt_ignore),
+       fsparam_flag_no("auto", Opt_ignore),
        fsparam_string("cred", Opt_ignore),
        fsparam_string("credentials", Opt_ignore),
+       fsparam_string("prefixpath", Opt_ignore),
        {}
 };
 
@@ -399,6 +401,37 @@ cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3)
        return 0;
 }
 
+int smb3_parse_opt(const char *options, const char *key, char **val)
+{
+       int rc = -ENOENT;
+       char *opts, *orig, *p;
+
+       orig = opts = kstrdup(options, GFP_KERNEL);
+       if (!opts)
+               return -ENOMEM;
+
+       while ((p = strsep(&opts, ","))) {
+               char *nval;
+
+               if (!*p)
+                       continue;
+               if (strncasecmp(p, key, strlen(key)))
+                       continue;
+               nval = strchr(p, '=');
+               if (nval) {
+                       if (nval == p)
+                               continue;
+                       *nval++ = 0;
+                       *val = kstrndup(nval, strlen(nval), GFP_KERNEL);
+                       rc = !*val ? -ENOMEM : 0;
+                       goto out;
+               }
+       }
+out:
+       kfree(orig);
+       return rc;
+}
+
 /*
  * Parse a devname into substrings and populate the ctx->UNC and ctx->prepath
  * fields with the result. Returns 0 on success and an error otherwise
@@ -531,7 +564,7 @@ static int smb3_fs_context_validate(struct fs_context *fc)
 
        if (ctx->rdma && ctx->vals->protocol_id < SMB30_PROT_ID) {
                cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n");
-               return -1;
+               return -EOPNOTSUPP;
        }
 
 #ifndef CONFIG_KEYS
@@ -554,7 +587,7 @@ static int smb3_fs_context_validate(struct fs_context *fc)
        /* make sure UNC has a share name */
        if (strlen(ctx->UNC) < 3 || !strchr(ctx->UNC + 3, '\\')) {
                cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n");
-               return -1;
+               return -ENOENT;
        }
 
        if (!ctx->got_ip) {
@@ -568,7 +601,7 @@ static int smb3_fs_context_validate(struct fs_context *fc)
                if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr,
                                          &ctx->UNC[2], len)) {
                        pr_err("Unable to determine destination address\n");
-                       return -1;
+                       return -EHOSTUNREACH;
                }
        }
 
@@ -1263,7 +1296,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
        return 0;
 
  cifs_parse_mount_err:
-       return 1;
+       return -EINVAL;
 }
 
 int smb3_init_fs_context(struct fs_context *fc)
index d85edf5d1429418728d9fa44fac2a2d9a6df7684..a5a9e33c0d739dbe1c80c97c12e9e4a4b4c1d390 100644 (file)
@@ -286,7 +286,7 @@ struct smb2_negotiate_req {
        __le32 NegotiateContextOffset; /* SMB3.1.1 only. MBZ earlier */
        __le16 NegotiateContextCount;  /* SMB3.1.1 only. MBZ earlier */
        __le16 Reserved2;
-       __le16 Dialects[1]; /* One dialect (vers=) at a time for now */
+       __le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
 } __packed;
 
 /* Dialects */
index 95ef26b555b911c620a5c357bea82bb25e3c8f11..4a2b836eb0177024627b252b11d81e802bd0851f 100644 (file)
@@ -666,10 +666,22 @@ wait_for_compound_request(struct TCP_Server_Info *server, int num,
 
        if (*credits < num) {
                /*
-                * Return immediately if not too many requests in flight since
-                * we will likely be stuck on waiting for credits.
+                * If the server is tight on resources or just gives us less
+                * credits for other reasons (e.g. requests are coming out of
+                * order and the server delays granting more credits until it
+                * processes a missing mid) and we exhausted most available
+                * credits there may be situations when we try to send
+                * a compound request but we don't have enough credits. At this
+                * point the client needs to decide if it should wait for
+                * additional credits or fail the request. If at least one
+                * request is in flight there is a high probability that the
+                * server will return enough credits to satisfy this compound
+                * request.
+                *
+                * Return immediately if no requests in flight since we will be
+                * stuck on waiting for credits.
                 */
-               if (server->in_flight < num - *credits) {
+               if (server->in_flight == 0) {
                        spin_unlock(&server->req_lock);
                        trace_smb3_insufficient_credits(server->CurrentMid,
                                        server->hostname, scredits, sin_flight);
index e23752d9a79f3d255345177db1b66950ae8e6607..58d0f7187997950d55a32bdc9911e147adf1f7a1 100644 (file)
@@ -1016,15 +1016,19 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
 {
        int rc;
        struct dentry *lower_dentry;
+       struct inode *lower_inode;
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) {
+       lower_inode = d_inode(lower_dentry);
+       if (!(lower_inode->i_opflags & IOP_XATTR)) {
                rc = -EOPNOTSUPP;
                goto out;
        }
-       rc = vfs_setxattr(lower_dentry, name, value, size, flags);
+       inode_lock(lower_inode);
+       rc = __vfs_setxattr_locked(lower_dentry, name, value, size, flags, NULL);
+       inode_unlock(lower_inode);
        if (!rc && inode)
-               fsstack_copy_attr_all(inode, d_inode(lower_dentry));
+               fsstack_copy_attr_all(inode, lower_inode);
 out:
        return rc;
 }
index b5c109703daaf9ff2f4384c1f53e15ee1c5f3e55..21c20fd5f9ee75a096241df596ec9ed45292eaa5 100644 (file)
@@ -735,9 +735,10 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
 
                mutex_unlock(&hugetlb_fault_mutex_table[hash]);
 
+               set_page_huge_active(page);
                /*
                 * unlock_page because locked by add_to_page_cache()
-                * page_put due to reference from alloc_huge_page()
+                * put_page() due to reference from alloc_huge_page()
                 */
                unlock_page(page);
                put_page(page);
index c07913ec0ccac43aa0f765ab9734c6ef1fab84c6..1f68105a41ed996622a4c35dbcb6e97e55e00922 100644 (file)
@@ -1026,6 +1026,7 @@ static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec,
                             const struct iovec *fast_iov,
                             struct iov_iter *iter, bool force);
 static void io_req_drop_files(struct io_kiocb *req);
+static void io_req_task_queue(struct io_kiocb *req);
 
 static struct kmem_cache *req_cachep;
 
@@ -1069,8 +1070,12 @@ static bool io_match_task(struct io_kiocb *head,
 {
        struct io_kiocb *req;
 
-       if (task && head->task != task)
+       if (task && head->task != task) {
+               /* in terms of cancelation, always match if req task is dead */
+               if (head->task->flags & PF_EXITING)
+                       return true;
                return false;
+       }
        if (!files)
                return true;
 
@@ -1630,18 +1635,11 @@ static void __io_queue_deferred(struct io_ring_ctx *ctx)
        do {
                struct io_defer_entry *de = list_first_entry(&ctx->defer_list,
                                                struct io_defer_entry, list);
-               struct io_kiocb *link;
 
                if (req_need_defer(de->req, de->seq))
                        break;
                list_del_init(&de->list);
-               /* punt-init is done before queueing for defer */
-               link = __io_queue_async_work(de->req);
-               if (link) {
-                       __io_queue_linked_timeout(link);
-                       /* drop submission reference */
-                       io_put_req_deferred(link, 1);
-               }
+               io_req_task_queue(de->req);
                kfree(de);
        } while (!list_empty(&ctx->defer_list));
 }
@@ -1775,12 +1773,13 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force,
        struct io_kiocb *req, *tmp;
        struct io_uring_cqe *cqe;
        unsigned long flags;
-       bool all_flushed;
+       bool all_flushed, posted;
        LIST_HEAD(list);
 
        if (!force && __io_cqring_events(ctx) == rings->cq_ring_entries)
                return false;
 
+       posted = false;
        spin_lock_irqsave(&ctx->completion_lock, flags);
        list_for_each_entry_safe(req, tmp, &ctx->cq_overflow_list, compl.list) {
                if (!io_match_task(req, tsk, files))
@@ -1800,6 +1799,7 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force,
                        WRITE_ONCE(ctx->rings->cq_overflow,
                                   ctx->cached_cq_overflow);
                }
+               posted = true;
        }
 
        all_flushed = list_empty(&ctx->cq_overflow_list);
@@ -1809,9 +1809,11 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force,
                ctx->rings->sq_flags &= ~IORING_SQ_CQ_OVERFLOW;
        }
 
-       io_commit_cqring(ctx);
+       if (posted)
+               io_commit_cqring(ctx);
        spin_unlock_irqrestore(&ctx->completion_lock, flags);
-       io_cqring_ev_posted(ctx);
+       if (posted)
+               io_cqring_ev_posted(ctx);
 
        while (!list_empty(&list)) {
                req = list_first_entry(&list, struct io_kiocb, compl.list);
@@ -2203,6 +2205,9 @@ static void __io_req_task_submit(struct io_kiocb *req)
        else
                __io_req_task_cancel(req, -EFAULT);
        mutex_unlock(&ctx->uring_lock);
+
+       if (ctx->flags & IORING_SETUP_SQPOLL)
+               io_sq_thread_drop_mm_files();
 }
 
 static void io_req_task_submit(struct callback_head *cb)
@@ -6458,7 +6463,8 @@ static struct file *io_file_get(struct io_submit_state *state,
                file = __io_file_get(state, fd);
        }
 
-       if (file && file->f_op == &io_uring_fops) {
+       if (file && file->f_op == &io_uring_fops &&
+           !(req->flags & REQ_F_INFLIGHT)) {
                io_req_init_async(req);
                req->flags |= REQ_F_INFLIGHT;
 
@@ -7266,14 +7272,18 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
                                                TASK_INTERRUPTIBLE);
                /* make sure we run task_work before checking for signals */
                ret = io_run_task_work_sig();
-               if (ret > 0)
+               if (ret > 0) {
+                       finish_wait(&ctx->wait, &iowq.wq);
                        continue;
+               }
                else if (ret < 0)
                        break;
                if (io_should_wake(&iowq))
                        break;
-               if (test_bit(0, &ctx->cq_check_overflow))
+               if (test_bit(0, &ctx->cq_check_overflow)) {
+                       finish_wait(&ctx->wait, &iowq.wq);
                        continue;
+               }
                if (uts) {
                        timeout = schedule_timeout(timeout);
                        if (timeout == 0) {
@@ -8865,30 +8875,31 @@ static void io_cancel_defer_files(struct io_ring_ctx *ctx,
        }
 }
 
+static int io_uring_count_inflight(struct io_ring_ctx *ctx,
+                                  struct task_struct *task,
+                                  struct files_struct *files)
+{
+       struct io_kiocb *req;
+       int cnt = 0;
+
+       spin_lock_irq(&ctx->inflight_lock);
+       list_for_each_entry(req, &ctx->inflight_list, inflight_entry)
+               cnt += io_match_task(req, task, files);
+       spin_unlock_irq(&ctx->inflight_lock);
+       return cnt;
+}
+
 static void io_uring_cancel_files(struct io_ring_ctx *ctx,
                                  struct task_struct *task,
                                  struct files_struct *files)
 {
        while (!list_empty_careful(&ctx->inflight_list)) {
                struct io_task_cancel cancel = { .task = task, .files = files };
-               struct io_kiocb *req;
                DEFINE_WAIT(wait);
-               bool found = false;
+               int inflight;
 
-               spin_lock_irq(&ctx->inflight_lock);
-               list_for_each_entry(req, &ctx->inflight_list, inflight_entry) {
-                       if (!io_match_task(req, task, files))
-                               continue;
-                       found = true;
-                       break;
-               }
-               if (found)
-                       prepare_to_wait(&task->io_uring->wait, &wait,
-                                       TASK_UNINTERRUPTIBLE);
-               spin_unlock_irq(&ctx->inflight_lock);
-
-               /* We need to keep going until we don't find a matching req */
-               if (!found)
+               inflight = io_uring_count_inflight(ctx, task, files);
+               if (!inflight)
                        break;
 
                io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, &cancel, true);
@@ -8897,7 +8908,11 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx,
                io_cqring_overflow_flush(ctx, true, task, files);
                /* cancellations _may_ trigger task work */
                io_run_task_work();
-               schedule();
+
+               prepare_to_wait(&task->io_uring->wait, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               if (inflight == io_uring_count_inflight(ctx, task, files))
+                       schedule();
                finish_wait(&task->io_uring->wait, &wait);
        }
 }
@@ -8955,8 +8970,6 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx,
        struct task_struct *task = current;
 
        if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) {
-               /* for SQPOLL only sqo_task has task notes */
-               WARN_ON_ONCE(ctx->sqo_task != current);
                io_disable_sqo_submit(ctx);
                task = ctx->sq_data->thread;
                atomic_inc(&task->io_uring->in_idle);
@@ -8966,19 +8979,12 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx,
        io_cancel_defer_files(ctx, task, files);
        io_cqring_overflow_flush(ctx, true, task, files);
 
+       io_uring_cancel_files(ctx, task, files);
        if (!files)
                __io_uring_cancel_task_requests(ctx, task);
-       else
-               io_uring_cancel_files(ctx, task, files);
 
        if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) {
                atomic_dec(&task->io_uring->in_idle);
-               /*
-                * If the files that are going away are the ones in the thread
-                * identity, clear them out.
-                */
-               if (task->io_uring->identity->files == files)
-                       task->io_uring->identity->files = NULL;
                io_sq_thread_unpark(ctx->sq_data);
        }
 }
@@ -9116,16 +9122,15 @@ void __io_uring_task_cancel(void)
                prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE);
 
                /*
-                * If we've seen completions, retry. This avoids a race where
-                * a completion comes in before we did prepare_to_wait().
+                * If we've seen completions, retry without waiting. This
+                * avoids a race where a completion comes in before we did
+                * prepare_to_wait().
                 */
-               if (inflight != tctx_inflight(tctx))
-                       continue;
-               schedule();
+               if (inflight == tctx_inflight(tctx))
+                       schedule();
                finish_wait(&tctx->wait, &wait);
        } while (1);
 
-       finish_wait(&tctx->wait, &wait);
        atomic_dec(&tctx->in_idle);
 
        io_uring_remove_task_files(tctx);
@@ -9136,6 +9141,9 @@ static int io_uring_flush(struct file *file, void *data)
        struct io_uring_task *tctx = current->io_uring;
        struct io_ring_ctx *ctx = file->private_data;
 
+       if (fatal_signal_pending(current) || (current->flags & PF_EXITING))
+               io_uring_cancel_task_requests(ctx, NULL);
+
        if (!tctx)
                return 0;
 
index 4f274f21c4abcb9c2d96bc4088c3f1f4003258f0..af64b4e6fd1ff2162ee837b4f64baf0f3621fb19 100644 (file)
@@ -324,6 +324,21 @@ pnfs_grab_inode_layout_hdr(struct pnfs_layout_hdr *lo)
        return NULL;
 }
 
+/*
+ * Compare 2 layout stateid sequence ids, to see which is newer,
+ * taking into account wraparound issues.
+ */
+static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
+{
+       return (s32)(s1 - s2) > 0;
+}
+
+static void pnfs_barrier_update(struct pnfs_layout_hdr *lo, u32 newseq)
+{
+       if (pnfs_seqid_is_newer(newseq, lo->plh_barrier))
+               lo->plh_barrier = newseq;
+}
+
 static void
 pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode,
                         u32 seq)
@@ -335,6 +350,7 @@ pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode,
        if (seq != 0) {
                WARN_ON_ONCE(lo->plh_return_seq != 0 && lo->plh_return_seq != seq);
                lo->plh_return_seq = seq;
+               pnfs_barrier_update(lo, seq);
        }
 }
 
@@ -639,15 +655,6 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
        return rv;
 }
 
-/*
- * Compare 2 layout stateid sequence ids, to see which is newer,
- * taking into account wraparound issues.
- */
-static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
-{
-       return (s32)(s1 - s2) > 0;
-}
-
 static bool
 pnfs_should_free_range(const struct pnfs_layout_range *lseg_range,
                 const struct pnfs_layout_range *recall_range)
@@ -984,8 +991,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
                new_barrier = be32_to_cpu(new->seqid);
        else if (new_barrier == 0)
                return;
-       if (pnfs_seqid_is_newer(new_barrier, lo->plh_barrier))
-               lo->plh_barrier = new_barrier;
+       pnfs_barrier_update(lo, new_barrier);
 }
 
 static bool
@@ -994,7 +1000,7 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo,
 {
        u32 seqid = be32_to_cpu(stateid->seqid);
 
-       return !pnfs_seqid_is_newer(seqid, lo->plh_barrier);
+       return !pnfs_seqid_is_newer(seqid, lo->plh_barrier) && lo->plh_barrier;
 }
 
 /* lget is set to 1 if called from inside send_layoutget call chain */
@@ -1183,20 +1189,17 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
                return false;
        set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
        pnfs_get_layout_hdr(lo);
+       nfs4_stateid_copy(stateid, &lo->plh_stateid);
+       *cred = get_cred(lo->plh_lc_cred);
        if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) {
-               nfs4_stateid_copy(stateid, &lo->plh_stateid);
-               *cred = get_cred(lo->plh_lc_cred);
                if (lo->plh_return_seq != 0)
                        stateid->seqid = cpu_to_be32(lo->plh_return_seq);
                if (iomode != NULL)
                        *iomode = lo->plh_return_iomode;
                pnfs_clear_layoutreturn_info(lo);
-               return true;
-       }
-       nfs4_stateid_copy(stateid, &lo->plh_stateid);
-       *cred = get_cred(lo->plh_lc_cred);
-       if (iomode != NULL)
+       } else if (iomode != NULL)
                *iomode = IOMODE_ANY;
+       pnfs_barrier_update(lo, be32_to_cpu(stateid->seqid));
        return true;
 }
 
@@ -1909,6 +1912,11 @@ static void nfs_layoutget_end(struct pnfs_layout_hdr *lo)
                wake_up_var(&lo->plh_outstanding);
 }
 
+static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo)
+{
+       return test_bit(NFS_LAYOUT_FIRST_LAYOUTGET, &lo->plh_flags);
+}
+
 static void pnfs_clear_first_layoutget(struct pnfs_layout_hdr *lo)
 {
        unsigned long *bitlock = &lo->plh_flags;
@@ -2383,23 +2391,34 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
                goto out_forget;
        }
 
-       if (!pnfs_layout_is_valid(lo)) {
-               /* We have a completely new layout */
-               pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true);
-       } else if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
+       if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
                /* existing state ID, make sure the sequence number matches. */
                if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
+                       if (!pnfs_layout_is_valid(lo) &&
+                           pnfs_is_first_layoutget(lo))
+                               lo->plh_barrier = 0;
                        dprintk("%s forget reply due to sequence\n", __func__);
                        goto out_forget;
                }
                pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, false);
-       } else {
+       } else if (pnfs_layout_is_valid(lo)) {
                /*
                 * We got an entirely new state ID.  Mark all segments for the
                 * inode invalid, and retry the layoutget
                 */
-               pnfs_mark_layout_stateid_invalid(lo, &free_me);
+               struct pnfs_layout_range range = {
+                       .iomode = IOMODE_ANY,
+                       .length = NFS4_MAX_UINT64,
+               };
+               pnfs_set_plh_return_info(lo, IOMODE_ANY, 0);
+               pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs,
+                                               &range, 0);
                goto out_forget;
+       } else {
+               /* We have a completely new layout */
+               if (!pnfs_is_first_layoutget(lo))
+                       goto out_forget;
+               pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true);
        }
 
        pnfs_get_lseg(lseg);
index e5b616c93e11b673d870a880d5d6233f20da536a..0fed532efa68d127adc8cbcc5755056495c45caf 100644 (file)
@@ -84,6 +84,14 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old,
 
                if (ovl_is_private_xattr(sb, name))
                        continue;
+
+               error = security_inode_copy_up_xattr(name);
+               if (error < 0 && error != -EOPNOTSUPP)
+                       break;
+               if (error == 1) {
+                       error = 0;
+                       continue; /* Discard */
+               }
 retry:
                size = vfs_getxattr(old, name, value, value_size);
                if (size == -ERANGE)
@@ -107,13 +115,6 @@ retry:
                        goto retry;
                }
 
-               error = security_inode_copy_up_xattr(name);
-               if (error < 0 && error != -EOPNOTSUPP)
-                       break;
-               if (error == 1) {
-                       error = 0;
-                       continue; /* Discard */
-               }
                error = vfs_setxattr(new, name, value, size, 0);
                if (error) {
                        if (error != -EOPNOTSUPP || ovl_must_copy_xattr(name))
index 28a075b5f5b2eb2e2391d8b341d3844723ed48b9..d1efa3a5a5032e6ce216342170e952c6222ec04f 100644 (file)
@@ -992,8 +992,8 @@ static char *ovl_get_redirect(struct dentry *dentry, bool abs_redirect)
 
                buflen -= thislen;
                memcpy(&buf[buflen], name, thislen);
-               tmp = dget_dlock(d->d_parent);
                spin_unlock(&d->d_lock);
+               tmp = dget_parent(d);
 
                dput(d);
                d = tmp;
index bd9dd38347aed87ed263d5df56ffcd3e658ea562..077d3ad343f689f4f517b804e2bfc848082a4d2b 100644 (file)
@@ -398,8 +398,9 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
        const struct cred *old_cred;
        int ret;
 
-       if (!ovl_should_sync(OVL_FS(file_inode(file)->i_sb)))
-               return 0;
+       ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb));
+       if (ret <= 0)
+               return ret;
 
        ret = ovl_real_fdget_meta(file, &real, !datasync);
        if (ret)
index d739e14c6814df6a38c004e96124a749b8948fe1..cf41bcb664bc74505b7b313c59ccfc21a492835f 100644 (file)
@@ -352,7 +352,9 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
                goto out;
 
        if (!value && !upperdentry) {
+               old_cred = ovl_override_creds(dentry->d_sb);
                err = vfs_getxattr(realdentry, name, NULL, 0);
+               revert_creds(old_cred);
                if (err < 0)
                        goto out_drop_write;
        }
index b487e48c7fd4276d22caf17a56e75f5f298a8cdf..cb4e2d60ecf9ceb2a4aeceecca1748d3002008eb 100644 (file)
@@ -324,6 +324,7 @@ int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct dentry *dentry);
 bool ovl_is_metacopy_dentry(struct dentry *dentry);
 char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry,
                             int padding);
+int ovl_sync_status(struct ovl_fs *ofs);
 
 static inline bool ovl_is_impuredir(struct super_block *sb,
                                    struct dentry *dentry)
index fbd5e27ce66bd3aad0c44e406ed943c016c1ea32..63efee554f69a7c1e862650d8f7b388576fda2cd 100644 (file)
@@ -81,6 +81,8 @@ struct ovl_fs {
        atomic_long_t last_ino;
        /* Whiteout dentry cache */
        struct dentry *whiteout;
+       /* r/o snapshot of upperdir sb's only taken on volatile mounts */
+       errseq_t errseq;
 };
 
 static inline struct vfsmount *ovl_upper_mnt(struct ovl_fs *ofs)
index 01620ebae1bd4e0f1a03a9bd05e8f28c9c5afb80..f404a78e6b607bf1d2b854506ebb3f72cd8af8d2 100644 (file)
@@ -865,7 +865,7 @@ struct file *ovl_dir_real_file(const struct file *file, bool want_upper)
 
        struct ovl_dir_file *od = file->private_data;
        struct dentry *dentry = file->f_path.dentry;
-       struct file *realfile = od->realfile;
+       struct file *old, *realfile = od->realfile;
 
        if (!OVL_TYPE_UPPER(ovl_path_type(dentry)))
                return want_upper ? NULL : realfile;
@@ -874,29 +874,20 @@ struct file *ovl_dir_real_file(const struct file *file, bool want_upper)
         * Need to check if we started out being a lower dir, but got copied up
         */
        if (!od->is_upper) {
-               struct inode *inode = file_inode(file);
-
                realfile = READ_ONCE(od->upperfile);
                if (!realfile) {
                        struct path upperpath;
 
                        ovl_path_upper(dentry, &upperpath);
                        realfile = ovl_dir_open_realfile(file, &upperpath);
+                       if (IS_ERR(realfile))
+                               return realfile;
 
-                       inode_lock(inode);
-                       if (!od->upperfile) {
-                               if (IS_ERR(realfile)) {
-                                       inode_unlock(inode);
-                                       return realfile;
-                               }
-                               smp_store_release(&od->upperfile, realfile);
-                       } else {
-                               /* somebody has beaten us to it */
-                               if (!IS_ERR(realfile))
-                                       fput(realfile);
-                               realfile = od->upperfile;
+                       old = cmpxchg_release(&od->upperfile, NULL, realfile);
+                       if (old) {
+                               fput(realfile);
+                               realfile = old;
                        }
-                       inode_unlock(inode);
                }
        }
 
@@ -909,8 +900,9 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,
        struct file *realfile;
        int err;
 
-       if (!ovl_should_sync(OVL_FS(file->f_path.dentry->d_sb)))
-               return 0;
+       err = ovl_sync_status(OVL_FS(file->f_path.dentry->d_sb));
+       if (err <= 0)
+               return err;
 
        realfile = ovl_dir_real_file(file, true);
        err = PTR_ERR_OR_ZERO(realfile);
index 2bd570cbe8a4591f58610f9ede56e713b3eb2aa8..d58b8f2bf9d0a45b4745e6feb776f7651c6362be 100644 (file)
@@ -264,11 +264,20 @@ static int ovl_sync_fs(struct super_block *sb, int wait)
        struct super_block *upper_sb;
        int ret;
 
-       if (!ovl_upper_mnt(ofs))
-               return 0;
+       ret = ovl_sync_status(ofs);
+       /*
+        * We have to always set the err, because the return value isn't
+        * checked in syncfs, and instead indirectly return an error via
+        * the sb's writeback errseq, which VFS inspects after this call.
+        */
+       if (ret < 0) {
+               errseq_set(&sb->s_wb_err, -EIO);
+               return -EIO;
+       }
+
+       if (!ret)
+               return ret;
 
-       if (!ovl_should_sync(ofs))
-               return 0;
        /*
         * Not called for sync(2) call or an emergency sync (SB_I_SKIP_SYNC).
         * All the super blocks will be iterated, including upper_sb.
@@ -1923,6 +1932,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        unsigned int numlower;
        int err;
 
+       err = -EIO;
+       if (WARN_ON(sb->s_user_ns != current_user_ns()))
+               goto out;
+
        sb->s_d_op = &ovl_dentry_operations;
 
        err = -ENOMEM;
@@ -1989,6 +2002,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_op = &ovl_super_operations;
 
        if (ofs->config.upperdir) {
+               struct super_block *upper_sb;
+
                if (!ofs->config.workdir) {
                        pr_err("missing 'workdir'\n");
                        goto out_err;
@@ -1998,6 +2013,16 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
                if (err)
                        goto out_err;
 
+               upper_sb = ovl_upper_mnt(ofs)->mnt_sb;
+               if (!ovl_should_sync(ofs)) {
+                       ofs->errseq = errseq_sample(&upper_sb->s_wb_err);
+                       if (errseq_check(&upper_sb->s_wb_err, ofs->errseq)) {
+                               err = -EIO;
+                               pr_err("Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n");
+                               goto out_err;
+                       }
+               }
+
                err = ovl_get_workdir(sb, ofs, &upperpath);
                if (err)
                        goto out_err;
@@ -2005,9 +2030,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
                if (!ofs->workdir)
                        sb->s_flags |= SB_RDONLY;
 
-               sb->s_stack_depth = ovl_upper_mnt(ofs)->mnt_sb->s_stack_depth;
-               sb->s_time_gran = ovl_upper_mnt(ofs)->mnt_sb->s_time_gran;
-
+               sb->s_stack_depth = upper_sb->s_stack_depth;
+               sb->s_time_gran = upper_sb->s_time_gran;
        }
        oe = ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers);
        err = PTR_ERR(oe);
index 6569031af3cdd4ca0fed5cf035161a7f1a33248c..9826b003f1d2702132c4cd12920230723b02416d 100644 (file)
@@ -962,3 +962,30 @@ err_free:
        kfree(buf);
        return ERR_PTR(res);
 }
+
+/*
+ * ovl_sync_status() - Check fs sync status for volatile mounts
+ *
+ * Returns 1 if this is not a volatile mount and a real sync is required.
+ *
+ * Returns 0 if syncing can be skipped because mount is volatile, and no errors
+ * have occurred on the upperdir since the mount.
+ *
+ * Returns -errno if it is a volatile mount, and the error that occurred since
+ * the last mount. If the error code changes, it'll return the latest error
+ * code.
+ */
+
+int ovl_sync_status(struct ovl_fs *ofs)
+{
+       struct vfsmount *mnt;
+
+       if (ovl_should_sync(ofs))
+               return 1;
+
+       mnt = ovl_upper_mnt(ofs);
+       if (!mnt)
+               return 0;
+
+       return errseq_check(&mnt->mnt_sb->s_wb_err, ofs->errseq);
+}
index c5989cfd564d45c7b6e7690af69a1e8effe1fdcd..39c96845a72fb15e19844248d206e81ccf448001 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1206,6 +1206,7 @@ const struct file_operations pipefifo_fops = {
        .unlocked_ioctl = pipe_ioctl,
        .release        = pipe_release,
        .fasync         = pipe_fasync,
+       .splice_write   = iter_file_splice_write,
 };
 
 /*
index f5e92fe9151c389a9e55a2c6f857eb91279a2fdb..bd1c39907b924a4f0ab5ad1db20a4d3002f11a88 100644 (file)
@@ -783,6 +783,7 @@ drm_dp_mst_detect_port(struct drm_connector *connector,
 
 struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
 
+int drm_dp_get_vc_payload_bw(int link_rate, int link_lane_count);
 
 int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc);
 
index 3c3e16c0aadbfd585c0ed0fcd8e9db296a69a1d8..dc605c4bc22491cb3b302008619db20e99386e64 100644 (file)
@@ -2,9 +2,8 @@
 #ifndef __DT_APQ8016_LPASS_H
 #define __DT_APQ8016_LPASS_H
 
-#define MI2S_PRIMARY   0
-#define MI2S_SECONDARY 1
-#define MI2S_TERTIARY  2
-#define MI2S_QUATERNARY        3
+#include <dt-bindings/sound/qcom,lpass.h>
+
+/* NOTE: Use qcom,lpass.h to define any AIF ID's for LPASS */
 
 #endif /* __DT_APQ8016_LPASS_H */
diff --git a/include/dt-bindings/sound/qcom,lpass.h b/include/dt-bindings/sound/qcom,lpass.h
new file mode 100644 (file)
index 0000000..7b0b80b
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_QCOM_LPASS_H
+#define __DT_QCOM_LPASS_H
+
+#define MI2S_PRIMARY   0
+#define MI2S_SECONDARY 1
+#define MI2S_TERTIARY  2
+#define MI2S_QUATERNARY        3
+#define MI2S_QUINARY   4
+
+#define LPASS_DP_RX    5
+
+#define LPASS_MCLK0    0
+
+#endif /* __DT_QCOM_LPASS_H */
index 56ecaafd2dc682d05ef88164b4ba4057b6b15ab8..5c1ee8b36b1972c6c025778a69b9c625834d7f58 100644 (file)
@@ -2,10 +2,8 @@
 #ifndef __DT_SC7180_LPASS_H
 #define __DT_SC7180_LPASS_H
 
-#define MI2S_PRIMARY   0
-#define MI2S_SECONDARY 1
-#define LPASS_DP_RX    2
+#include <dt-bindings/sound/qcom,lpass.h>
 
-#define LPASS_MCLK0    0
+/* NOTE: Use qcom,lpass.h to define any AIF ID's for LPASS */
 
 #endif /* __DT_APQ8016_LPASS_H */
index ebca2ef022127519ce9ec2c5c58cbe33b6a198af..b5807f23caf80458a6238d286c4deec6fd21fe07 100644 (file)
@@ -770,6 +770,8 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
 }
 #endif
 
+void set_page_huge_active(struct page *page);
+
 #else  /* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 
index b3f0e2018c6238a67a2b1cda397c3dab00689755..efa96263b81b3053d3dc1ec460e019ffb841ec64 100644 (file)
@@ -616,7 +616,10 @@ static inline void dev_iommu_fwspec_set(struct device *dev,
 
 static inline void *dev_iommu_priv_get(struct device *dev)
 {
-       return dev->iommu->priv;
+       if (dev->iommu)
+               return dev->iommu->priv;
+       else
+               return NULL;
 }
 
 static inline void dev_iommu_priv_set(struct device *dev, void *priv)
index fe1ae73ff8b574a8ee31e03b07f06cb6d5ca2473..0aea9e2a2a01d18d4036997967518d56774f371e 100644 (file)
@@ -333,6 +333,13 @@ static inline void *kasan_reset_tag(const void *addr)
        return (void *)arch_kasan_reset_tag(addr);
 }
 
+/**
+ * kasan_report - print a report about a bad memory access detected by KASAN
+ * @addr: address of the bad access
+ * @size: size of the bad access
+ * @is_write: whether the bad access is a write or a read
+ * @ip: instruction pointer for the accessibility check or the bad access itself
+ */
 bool kasan_report(unsigned long addr, size_t size,
                bool is_write, unsigned long ip);
 
index b3a36b0cfc81a3742b9c588b0efa8bb1b9ec8389..1883a4a9f16a7fc70bf533cd2206d046c6722b14 100644 (file)
@@ -266,7 +266,7 @@ extern void kprobes_inc_nmissed_count(struct kprobe *p);
 extern bool arch_within_kprobe_blacklist(unsigned long addr);
 extern int arch_populate_kprobe_blacklist(void);
 extern bool arch_kprobe_on_func_entry(unsigned long offset);
-extern bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset);
+extern int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset);
 
 extern bool within_kprobe_blacklist(unsigned long addr);
 extern int kprobe_add_ksym_blacklist(unsigned long entry);
index 5bcfbd972e9709234926b9b7148df45f3092f2f0..dbf8506decca0f5e4f6527b7a070a1c3c8335f43 100644 (file)
  * Objtool generates debug info for both FUNC & CODE, but needs special
  * annotations for each CODE's start (to describe the actual stack frame).
  *
+ * Objtool requires that all code must be contained in an ELF symbol. Symbol
+ * names that have a  .L prefix do not emit symbol table entries. .L
+ * prefixed symbols can be used within a code region, but should be avoided for
+ * denoting a range of code via ``SYM_*_START/END`` annotations.
+ *
  * ALIAS -- does not generate debug info -- the aliased function will
  */
 
index f93bfe7473aa7c15e3da3630fffd5786bf21ed3f..4672e12f1aa52cfb7daa2a87824e9715247d36fd 100644 (file)
@@ -1209,22 +1209,4 @@ static inline bool mlx5_is_roce_enabled(struct mlx5_core_dev *dev)
        return val.vbool;
 }
 
-/**
- * mlx5_core_net - Provide net namespace of the mlx5_core_dev
- * @dev: mlx5 core device
- *
- * mlx5_core_net() returns the net namespace of mlx5 core device.
- * This can be called only in below described limited context.
- * (a) When a devlink instance for mlx5_core is registered and
- *     when devlink reload operation is disabled.
- *     or
- * (b) during devlink reload reload_down() and reload_up callbacks
- *     where it is ensured that devlink instance's net namespace is
- *     stable.
- */
-static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev)
-{
-       return devlink_net(priv_to_devlink(dev));
-}
-
 #endif /* MLX5_DRIVER_H */
index 2024944fd2f78197792fc3020c04485477e56de0..20e84a84fb779ac549bca8c76bdd36a2df2522ef 100644 (file)
@@ -331,6 +331,12 @@ regulator_get_exclusive(struct device *dev, const char *id)
        return ERR_PTR(-ENODEV);
 }
 
+static inline struct regulator *__must_check
+devm_regulator_get_exclusive(struct device *dev, const char *id)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline struct regulator *__must_check
 regulator_get_optional(struct device *dev, const char *id)
 {
@@ -486,6 +492,11 @@ static inline int regulator_get_voltage(struct regulator *regulator)
        return -EINVAL;
 }
 
+static inline int regulator_sync_voltage(struct regulator *regulator)
+{
+       return -EINVAL;
+}
+
 static inline int regulator_is_supported_voltage(struct regulator *regulator,
                                   int min_uV, int max_uV)
 {
@@ -578,6 +589,25 @@ static inline int devm_regulator_unregister_notifier(struct regulator *regulator
        return 0;
 }
 
+static inline int regulator_suspend_enable(struct regulator_dev *rdev,
+                                          suspend_state_t state)
+{
+       return -EINVAL;
+}
+
+static inline int regulator_suspend_disable(struct regulator_dev *rdev,
+                                           suspend_state_t state)
+{
+       return -EINVAL;
+}
+
+static inline int regulator_set_suspend_voltage(struct regulator *regulator,
+                                               int min_uV, int max_uV,
+                                               suspend_state_t state)
+{
+       return -EINVAL;
+}
+
 static inline void *regulator_get_drvdata(struct regulator *regulator)
 {
        return NULL;
index 19b6dea27367b500456deeda0586978ee6135c38..b26213ae8c1ab011ba757a81367ac865b042982b 100644 (file)
@@ -25,8 +25,7 @@ struct rpc_rqst;
 #define XDR_QUADLEN(l)         (((l) + 3) >> 2)
 
 /*
- * Generic opaque `network object.' At the kernel level, this type
- * is used only by lockd.
+ * Generic opaque `network object.'
  */
 #define XDR_MAX_NETOBJ         1024
 struct xdr_netobj {
index 0f21617f1a6689395d9caa86d8d2982ef9a3ea84..966ed898032746b58ad79caead930f66292a9148 100644 (file)
@@ -307,11 +307,13 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
                                                                        \
                it_func_ptr =                                           \
                        rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
-               do {                                                    \
-                       it_func = (it_func_ptr)->func;                  \
-                       __data = (it_func_ptr)->data;                   \
-                       ((void(*)(void *, proto))(it_func))(__data, args); \
-               } while ((++it_func_ptr)->func);                        \
+               if (it_func_ptr) {                                      \
+                       do {                                            \
+                               it_func = (it_func_ptr)->func;          \
+                               __data = (it_func_ptr)->data;           \
+                               ((void(*)(void *, proto))(it_func))(__data, args); \
+                       } while ((++it_func_ptr)->func);                \
+               }                                                       \
                return 0;                                               \
        }                                                               \
        DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
index c873f475f0a762da8205c7cb4be684d5a1cd5677..37803f3e6d49eb7581e7168ea9807d351bf29fe2 100644 (file)
@@ -421,6 +421,7 @@ extern void tty_kclose(struct tty_struct *tty);
 extern int tty_dev_name_to_number(const char *name, dev_t *number);
 extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout);
 extern void tty_ldisc_unlock(struct tty_struct *tty);
+extern ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *);
 #else
 static inline void tty_kref_put(struct tty_struct *tty)
 { }
index 80c0181c411dff2a2f165d8e26e774841f80f9a6..cedcda6593f6134b239e640c44d3dbb5e000e5a0 100644 (file)
@@ -24,7 +24,8 @@ struct notifier_block;                /* in notifier.h */
 #define VM_UNINITIALIZED       0x00000020      /* vm_struct is not fully initialized */
 #define VM_NO_GUARD            0x00000040      /* don't add guard page */
 #define VM_KASAN               0x00000080      /* has allocated kasan shadow memory */
-#define VM_MAP_PUT_PAGES       0x00000100      /* put pages and free array in vfree */
+#define VM_FLUSH_RESET_PERMS   0x00000100      /* reset direct map and flush TLB on unmap, can't be freed in atomic context */
+#define VM_MAP_PUT_PAGES       0x00000200      /* put pages and free array in vfree */
 
 /*
  * VM_KASAN is used slighly differently depending on CONFIG_KASAN_VMALLOC.
@@ -37,12 +38,6 @@ struct notifier_block;               /* in notifier.h */
  * determine which allocations need the module shadow freed.
  */
 
-/*
- * Memory with VM_FLUSH_RESET_PERMS cannot be freed in an interrupt or with
- * vfree_atomic().
- */
-#define VM_FLUSH_RESET_PERMS   0x00000100      /* Reset direct map and flush TLB on unmap */
-
 /* bits [20..32] reserved for arch specific ioremap internals */
 
 /*
index be36cbdcc1bd22ad10ec2f7ec559b0789c666dcc..3eb202259e8ccd617d6b51875bc66917e0588436 100644 (file)
@@ -520,7 +520,7 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
                        u32 width, u32 height);
 
 /**
- * v4l2_get_link_rate - Get link rate from transmitter
+ * v4l2_get_link_freq - Get link rate from transmitter
  *
  * @handler: The transmitter's control handler
  * @mul: The multiplier between pixel rate and link frequency. Bits per pixel on
@@ -537,7 +537,7 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
  *     -ENOENT: Link frequency or pixel rate control not found
  *     -EINVAL: Invalid link frequency value
  */
-s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul,
+s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul,
                       unsigned int div);
 
 static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
index ccc3d1f020b0ca480994a05fff675d590059241e..eee73442a1ba1c2628ae605eb0b3c86cebbe80e6 100644 (file)
@@ -92,6 +92,7 @@ struct lapb_cb {
        unsigned short          n2, n2count;
        unsigned short          t1, t2;
        struct timer_list       t1timer, t2timer;
+       bool                    t1timer_stop, t2timer_stop;
 
        /* Internal control information */
        struct sk_buff_head     write_queue;
@@ -103,6 +104,7 @@ struct lapb_cb {
        struct lapb_frame       frmr_data;
        unsigned char           frmr_type;
 
+       spinlock_t              lock;
        refcount_t              refcnt;
 };
 
index f4af8362d2348475031143630d559e39796515ec..4b6ecf532623898ab9c9e2436e3a5c202f624b0f 100644 (file)
@@ -721,6 +721,8 @@ void *nft_set_elem_init(const struct nft_set *set,
                        const struct nft_set_ext_tmpl *tmpl,
                        const u32 *key, const u32 *key_end, const u32 *data,
                        u64 timeout, u64 expiration, gfp_t gfp);
+int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
+                           struct nft_expr *expr_array[]);
 void nft_set_elem_destroy(const struct nft_set *set, void *elem,
                          bool destroy_expr);
 
index 639e465a108f4476c5d9dbbf45f7b425b250ee7d..5b490b5591df58fda9400d68cebe2c183cba7e73 100644 (file)
@@ -1143,7 +1143,7 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
        old = *pold;
        *pold = new;
        if (old != NULL)
-               qdisc_tree_flush_backlog(old);
+               qdisc_purge_queue(old);
        sch_tree_unlock(sch);
 
        return old;
index 78d13c88720fda50e3f1880ac741cea1985ef3e9..25bbada379c46add16fb7239733bd6571f10f680 100644 (file)
@@ -630,6 +630,7 @@ static inline void tcp_clear_xmit_timers(struct sock *sk)
 
 unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
 unsigned int tcp_current_mss(struct sock *sk);
+u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when);
 
 /* Bound MSS / TSO packet size with the half of the window */
 static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
@@ -2060,7 +2061,7 @@ void tcp_mark_skb_lost(struct sock *sk, struct sk_buff *skb);
 void tcp_newreno_mark_lost(struct sock *sk, bool snd_una_advanced);
 extern s32 tcp_rack_skb_timeout(struct tcp_sock *tp, struct sk_buff *skb,
                                u32 reo_wnd);
-extern void tcp_rack_mark_lost(struct sock *sk);
+extern bool tcp_rack_mark_lost(struct sock *sk);
 extern void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq,
                             u64 xmit_time);
 extern void tcp_rack_reo_timeout(struct sock *sk);
index 877832bed4713a011a514a2f6f522728c8c89e20..01351ba25b874d261ace47151919cf7d8466b288 100644 (file)
@@ -178,7 +178,7 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
 int udp_gro_complete(struct sk_buff *skb, int nhoff, udp_lookup_t lookup);
 
 struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
-                                 netdev_features_t features);
+                                 netdev_features_t features, bool is_ipv6);
 
 static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb)
 {
index 2336bf9243e185cd0e8b84b4afe3add26faf59b6..2e1200d17d0cbe5e8a5ef23ffbe1b7f4e17a94f2 100644 (file)
@@ -229,7 +229,7 @@ typedef int (*snd_pcm_hw_rule_func_t)(struct snd_pcm_hw_params *params,
 struct snd_pcm_hw_rule {
        unsigned int cond;
        int var;
-       int deps[4];
+       int deps[5];
 
        snd_pcm_hw_rule_func_t func;
        void *private;
index 9744773de5ffa71203ca31672ddd3b4e449d90f3..bd4424de56ff57944617e3ef3ceb7bed7b2fb66a 100644 (file)
@@ -71,90 +71,4 @@ enum br_mrp_sub_tlv_header_type {
        BR_MRP_SUB_TLV_HEADER_TEST_AUTO_MGR = 0x3,
 };
 
-struct br_mrp_tlv_hdr {
-       __u8 type;
-       __u8 length;
-};
-
-struct br_mrp_sub_tlv_hdr {
-       __u8 type;
-       __u8 length;
-};
-
-struct br_mrp_end_hdr {
-       struct br_mrp_tlv_hdr hdr;
-};
-
-struct br_mrp_common_hdr {
-       __be16 seq_id;
-       __u8 domain[MRP_DOMAIN_UUID_LENGTH];
-};
-
-struct br_mrp_ring_test_hdr {
-       __be16 prio;
-       __u8 sa[ETH_ALEN];
-       __be16 port_role;
-       __be16 state;
-       __be16 transitions;
-       __be32 timestamp;
-};
-
-struct br_mrp_ring_topo_hdr {
-       __be16 prio;
-       __u8 sa[ETH_ALEN];
-       __be16 interval;
-};
-
-struct br_mrp_ring_link_hdr {
-       __u8 sa[ETH_ALEN];
-       __be16 port_role;
-       __be16 interval;
-       __be16 blocked;
-};
-
-struct br_mrp_sub_opt_hdr {
-       __u8 type;
-       __u8 manufacture_data[MRP_MANUFACTURE_DATA_LENGTH];
-};
-
-struct br_mrp_test_mgr_nack_hdr {
-       __be16 prio;
-       __u8 sa[ETH_ALEN];
-       __be16 other_prio;
-       __u8 other_sa[ETH_ALEN];
-};
-
-struct br_mrp_test_prop_hdr {
-       __be16 prio;
-       __u8 sa[ETH_ALEN];
-       __be16 other_prio;
-       __u8 other_sa[ETH_ALEN];
-};
-
-struct br_mrp_oui_hdr {
-       __u8 oui[MRP_OUI_LENGTH];
-};
-
-struct br_mrp_in_test_hdr {
-       __be16 id;
-       __u8 sa[ETH_ALEN];
-       __be16 port_role;
-       __be16 state;
-       __be16 transitions;
-       __be32 timestamp;
-};
-
-struct br_mrp_in_topo_hdr {
-       __u8 sa[ETH_ALEN];
-       __be16 id;
-       __be16 interval;
-};
-
-struct br_mrp_in_link_hdr {
-       __u8 sa[ETH_ALEN];
-       __be16 port_role;
-       __be16 id;
-       __be16 interval;
-};
-
 #endif
index 6e449e78426054c86f919ab7a19adb27ef2c888c..36e3efb81b014c4cd4fd03b021c38b2744c949f5 100644 (file)
 #define RKISP1_CIF_ISP_CTK_COEFF_MAX            0x100
 #define RKISP1_CIF_ISP_CTK_OFFSET_MAX           0x800
 
-#define RKISP1_CIF_ISP_AE_MEAN_MAX              25
-#define RKISP1_CIF_ISP_HIST_BIN_N_MAX           16
+#define RKISP1_CIF_ISP_AE_MEAN_MAX_V10         25
+#define RKISP1_CIF_ISP_AE_MEAN_MAX_V12         81
+#define RKISP1_CIF_ISP_AE_MEAN_MAX             RKISP1_CIF_ISP_AE_MEAN_MAX_V12
+
+#define RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10      16
+#define RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12      32
+#define RKISP1_CIF_ISP_HIST_BIN_N_MAX          RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12
+
 #define RKISP1_CIF_ISP_AFM_MAX_WINDOWS          3
 #define RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE       17
 
@@ -86,7 +92,9 @@
  * Gamma out
  */
 /* Maximum number of color samples supported */
-#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES       17
+#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10   17
+#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12   34
+#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES       RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12
 
 /*
  * Lens shade correction
 /*
  * Histogram calculation
  */
-/* Last 3 values unused. */
-#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 28
+#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10 25
+#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12 81
+#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE     RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12
 
 /*
  * Defect Pixel Cluster Correction
 #define RKISP1_CIF_ISP_STAT_AFM           (1U << 2)
 #define RKISP1_CIF_ISP_STAT_HIST          (1U << 3)
 
+/**
+ * enum rkisp1_cif_isp_version - ISP variants
+ *
+ * @RKISP1_V10: used at least in rk3288 and rk3399
+ * @RKISP1_V11: declared in the original vendor code, but not used
+ * @RKISP1_V12: used at least in rk3326 and px30
+ * @RKISP1_V13: used at least in rk1808
+ */
+enum rkisp1_cif_isp_version {
+       RKISP1_V10 = 10,
+       RKISP1_V11,
+       RKISP1_V12,
+       RKISP1_V13,
+};
+
 enum rkisp1_cif_isp_histogram_mode {
        RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE,
        RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
@@ -510,6 +534,15 @@ enum rkisp1_cif_isp_goc_mode {
  *
  * @mode: goc mode (from enum rkisp1_cif_isp_goc_mode)
  * @gamma_y: gamma out curve y-axis for all color components
+ *
+ * The number of entries of @gamma_y depends on the hardware revision
+ * as is reported by the hw_revision field of the struct media_device_info
+ * that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
+ *
+ * Versions <= V11 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10
+ * entries, versions >= V12 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12
+ * entries. RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES is equal to the maximum
+ * of the two.
  */
 struct rkisp1_cif_isp_goc_config {
        __u32 mode;
@@ -524,6 +557,15 @@ struct rkisp1_cif_isp_goc_config {
  *                       skipped
  * @meas_window: coordinates of the measure window
  * @hist_weight: weighting factor for sub-windows
+ *
+ * The number of entries of @hist_weight depends on the hardware revision
+ * as is reported by the hw_revision field of the struct media_device_info
+ * that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
+ *
+ * Versions <= V11 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10
+ * entries, versions >= V12 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12
+ * entries. RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE is equal to the maximum
+ * of the two.
  */
 struct rkisp1_cif_isp_hst_config {
        __u32 mode;
@@ -811,7 +853,15 @@ struct rkisp1_cif_isp_bls_meas_val {
  * @exp_mean: Mean luminance value of block xx
  * @bls_val:  BLS measured values
  *
- * Image is divided into 5x5 blocks.
+ * The number of entries of @exp_mean depends on the hardware revision
+ * as is reported by the hw_revision field of the struct media_device_info
+ * that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
+ *
+ * Versions <= V11 have RKISP1_CIF_ISP_AE_MEAN_MAX_V10 entries,
+ * versions >= V12 have RKISP1_CIF_ISP_AE_MEAN_MAX_V12 entries.
+ * RKISP1_CIF_ISP_AE_MEAN_MAX is equal to the maximum of the two.
+ *
+ * Image is divided into 5x5 blocks on V10 and 9x9 blocks on V12.
  */
 struct rkisp1_cif_isp_ae_stat {
        __u8 exp_mean[RKISP1_CIF_ISP_AE_MEAN_MAX];
@@ -844,13 +894,29 @@ struct rkisp1_cif_isp_af_stat {
 /**
  * struct rkisp1_cif_isp_hist_stat - statistics histogram data
  *
- * @hist_bins: measured bin counters
+ * @hist_bins: measured bin counters. Each bin is a 20 bits unsigned fixed point
+ *            type. Bits 0-4 are the fractional part and bits 5-19 are the
+ *            integer part.
+ *
+ * The window of the measurements area is divided to 5x5 sub-windows for
+ * V10/V11 and to 9x9 sub-windows for V12. The histogram is then computed for
+ * each sub-window independently and the final result is a weighted average of
+ * the histogram measurements on all sub-windows. The window of the
+ * measurements area and the weight of each sub-window are configurable using
+ * struct @rkisp1_cif_isp_hst_config.
+ *
+ * The histogram contains 16 bins in V10/V11 and 32 bins in V12/V13.
+ *
+ * The number of entries of @hist_bins depends on the hardware revision
+ * as is reported by the hw_revision field of the struct media_device_info
+ * that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
  *
- * Measurement window divided into 25 sub-windows, set
- * with ISP_HIST_XXX
+ * Versions <= V11 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10 entries,
+ * versions >= V12 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 entries.
+ * RKISP1_CIF_ISP_HIST_BIN_N_MAX is equal to the maximum of the two.
  */
 struct rkisp1_cif_isp_hist_stat {
-       __u16 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
+       __u32 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
 };
 
 /**
index 1dccb55cf8c647baa1ffda34b9ff442259e8efea..708adddf9f1389c039d7f94f05bef00714034213 100644 (file)
@@ -28,10 +28,10 @@ struct ipv6_rpl_sr_hdr {
                pad:4,
                reserved1:16;
 #elif defined(__BIG_ENDIAN_BITFIELD)
-       __u32   reserved:20,
+       __u32   cmpri:4,
+               cmpre:4,
                pad:4,
-               cmpri:4,
-               cmpre:4;
+               reserved:20;
 #else
 #error  "Please fix <asm/byteorder.h>"
 #endif
index 00850b98078a27495401c2045a8596d14e02c112..a38454d9e0f54eaf85af7a23c8e35554d7421430 100644 (file)
@@ -176,7 +176,7 @@ struct v4l2_subdev_capability {
 };
 
 /* The v4l2 sub-device video device node is registered in read-only mode. */
-#define V4L2_SUBDEV_CAP_RO_SUBDEV              BIT(0)
+#define V4L2_SUBDEV_CAP_RO_SUBDEV              0x00000001
 
 /* Backwards compatibility define --- to be removed */
 #define v4l2_subdev_edid v4l2_edid
index f8b638c73371d86287df15e70a2cafd16944d050..901a4fd72c09f8710a913274a1146c86a456b9ce 100644 (file)
@@ -133,6 +133,13 @@ enum pvrdma_wc_flags {
        PVRDMA_WC_FLAGS_MAX             = PVRDMA_WC_WITH_NETWORK_HDR_TYPE,
 };
 
+enum pvrdma_network_type {
+       PVRDMA_NETWORK_IB,
+       PVRDMA_NETWORK_ROCE_V1 = PVRDMA_NETWORK_IB,
+       PVRDMA_NETWORK_IPV4,
+       PVRDMA_NETWORK_IPV6
+};
+
 struct pvrdma_alloc_ucontext_resp {
        __u32 qp_tab_size;
        __u32 reserved;
index b77c60f8b963d4ae43140cce57b4c19af2e28732..29ad6832502880b8485f5cb76bd4348e7894e0de 100644 (file)
@@ -76,7 +76,6 @@ config CC_HAS_ASM_INLINE
 
 config CONSTRUCTORS
        bool
-       depends on !UML
 
 config IRQ_WORK
        bool
index 8a992d73e6fb7027e0b7b642b3935d81cb518fec..3711cdaafed2fb47ea655f98dd860c588d10fe1e 100644 (file)
@@ -198,7 +198,8 @@ struct task_struct init_task
        .lockdep_recursion = 0,
 #endif
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-       .ret_stack      = NULL,
+       .ret_stack              = NULL,
+       .tracing_graph_pause    = ATOMIC_INIT(0),
 #endif
 #if defined(CONFIG_TRACING) && defined(CONFIG_PREEMPTION)
        .trace_recursion = 0,
index c68d784376ca1058d58e3a6dfb664420c6ded461..a626e78dbf0611df73be6e5f20ce464c8b110d38 100644 (file)
@@ -1066,7 +1066,13 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
 /* Call all constructor functions linked into the kernel. */
 static void __init do_ctors(void)
 {
-#ifdef CONFIG_CONSTRUCTORS
+/*
+ * For UML, the constructors have already been called by the
+ * normal setup code as it's just a normal ELF binary, so we
+ * cannot do it again - but we do need CONFIG_CONSTRUCTORS
+ * even on UML for modules.
+ */
+#if defined(CONFIG_CONSTRUCTORS) && !defined(CONFIG_UML)
        ctor_fn_t *fn = (ctor_fn_t *) __ctors_start;
 
        for (; fn < (ctor_fn_t *) __ctors_end; fn++)
index 2f0597320b6d279871834c2deea3a662736b7373..6639640523c0bb1afb6a51d9e3e141fc30d8be8a 100644 (file)
@@ -125,8 +125,12 @@ static int bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key,
 
        fd = *(int *)key;
        f = fget_raw(fd);
-       if (!f || !inode_storage_ptr(f->f_inode))
+       if (!f)
+               return -EBADF;
+       if (!inode_storage_ptr(f->f_inode)) {
+               fput(f);
                return -EBADF;
+       }
 
        sdata = bpf_local_storage_update(f->f_inode,
                                         (struct bpf_local_storage_map *)map,
index 70e5e0b6d69d0d591b1cfd9c7ff516bc927c0fcf..1622a44d1617e16d97a4a2470280696ba7e47812 100644 (file)
@@ -149,7 +149,11 @@ BTF_ID(func, bpf_lsm_file_ioctl)
 BTF_ID(func, bpf_lsm_file_lock)
 BTF_ID(func, bpf_lsm_file_open)
 BTF_ID(func, bpf_lsm_file_receive)
+
+#ifdef CONFIG_SECURITY_NETWORK
 BTF_ID(func, bpf_lsm_inet_conn_established)
+#endif /* CONFIG_SECURITY_NETWORK */
+
 BTF_ID(func, bpf_lsm_inode_create)
 BTF_ID(func, bpf_lsm_inode_free_security)
 BTF_ID(func, bpf_lsm_inode_getattr)
@@ -166,7 +170,11 @@ BTF_ID(func, bpf_lsm_inode_symlink)
 BTF_ID(func, bpf_lsm_inode_unlink)
 BTF_ID(func, bpf_lsm_kernel_module_request)
 BTF_ID(func, bpf_lsm_kernfs_init_security)
+
+#ifdef CONFIG_KEYS
 BTF_ID(func, bpf_lsm_key_free)
+#endif /* CONFIG_KEYS */
+
 BTF_ID(func, bpf_lsm_mmap_file)
 BTF_ID(func, bpf_lsm_netlink_send)
 BTF_ID(func, bpf_lsm_path_notify)
@@ -181,6 +189,8 @@ BTF_ID(func, bpf_lsm_sb_show_options)
 BTF_ID(func, bpf_lsm_sb_statfs)
 BTF_ID(func, bpf_lsm_sb_umount)
 BTF_ID(func, bpf_lsm_settime)
+
+#ifdef CONFIG_SECURITY_NETWORK
 BTF_ID(func, bpf_lsm_socket_accept)
 BTF_ID(func, bpf_lsm_socket_bind)
 BTF_ID(func, bpf_lsm_socket_connect)
@@ -195,6 +205,8 @@ BTF_ID(func, bpf_lsm_socket_recvmsg)
 BTF_ID(func, bpf_lsm_socket_sendmsg)
 BTF_ID(func, bpf_lsm_socket_shutdown)
 BTF_ID(func, bpf_lsm_socket_socketpair)
+#endif /* CONFIG_SECURITY_NETWORK */
+
 BTF_ID(func, bpf_lsm_syslog)
 BTF_ID(func, bpf_lsm_task_alloc)
 BTF_ID(func, bpf_lsm_task_getsecid)
index 96555a8a2c545435aee44fd2fe4bbc37532357c5..6aa9e10c6335a220315eb2d7ee48676f03670bcb 100644 (file)
@@ -1442,6 +1442,11 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
                        goto out;
                }
 
+               if (ctx.optlen < 0) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+
                if (copy_from_user(ctx.optval, optval,
                                   min(ctx.optlen, max_optlen)) != 0) {
                        ret = -EFAULT;
@@ -1459,7 +1464,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
                goto out;
        }
 
-       if (ctx.optlen > max_optlen) {
+       if (ctx.optlen > max_optlen || ctx.optlen < 0) {
                ret = -EFAULT;
                goto out;
        }
index 23ee310b6eb49c7404667e5f9c94cadbabf0d005..1951332dd15f5c420eccdcd8754620a04dac39d6 100644 (file)
@@ -4,8 +4,11 @@ LIBBPF_SRCS = $(srctree)/tools/lib/bpf/
 LIBBPF_A = $(obj)/libbpf.a
 LIBBPF_OUT = $(abspath $(obj))
 
+# Although not in use by libbpf's Makefile, set $(O) so that the "dummy" test
+# in tools/scripts/Makefile.include always succeeds when building the kernel
+# with $(O) pointing to a relative path, as in "make O=build bindeb-pkg".
 $(LIBBPF_A):
-       $(Q)$(MAKE) -C $(LIBBPF_SRCS) OUTPUT=$(LIBBPF_OUT)/ $(LIBBPF_OUT)/libbpf.a
+       $(Q)$(MAKE) -C $(LIBBPF_SRCS) O=$(LIBBPF_OUT)/ OUTPUT=$(LIBBPF_OUT)/ $(LIBBPF_OUT)/libbpf.a
 
 userccflags += -I $(srctree)/tools/include/ -I $(srctree)/tools/include/uapi \
        -I $(srctree)/tools/lib/ -Wno-unused-result
index b1496e744c687f399cdd02a3e62d86bebe8c0f2c..1b1b8ff875cb3bbd26caef07aa55bc3a1026b431 100644 (file)
@@ -147,8 +147,10 @@ static int do_map_benchmark(struct map_benchmark_data *map)
        atomic64_set(&map->sum_sq_unmap, 0);
        atomic64_set(&map->loops, 0);
 
-       for (i = 0; i < threads; i++)
+       for (i = 0; i < threads; i++) {
+               get_task_struct(tsk[i]);
                wake_up_process(tsk[i]);
+       }
 
        msleep_interruptible(map->bparam.seconds * 1000);
 
@@ -183,6 +185,8 @@ static int do_map_benchmark(struct map_benchmark_data *map)
        }
 
 out:
+       for (i = 0; i < threads; i++)
+               put_task_struct(tsk[i]);
        put_device(map->dev);
        kfree(tsk);
        return ret;
index 378341642f94cd0dfe96f2f6ec554d2109344824..6dd82be60df81698dbe8e20a73a03d653b0bd04c 100644 (file)
@@ -222,7 +222,7 @@ static inline bool report_single_step(unsigned long work)
  */
 static inline bool report_single_step(unsigned long work)
 {
-       if (!(work & SYSCALL_WORK_SYSCALL_EMU))
+       if (work & SYSCALL_WORK_SYSCALL_EMU)
                return false;
 
        return !!(current_thread_info()->flags & _TIF_SINGLESTEP);
index c47d1015d75919b5436dfaab60c75d31aa14aa68..45a13eb8894e5667481965f219e275b6bd3e30e2 100644 (file)
@@ -763,6 +763,29 @@ static struct futex_pi_state *alloc_pi_state(void)
        return pi_state;
 }
 
+static void pi_state_update_owner(struct futex_pi_state *pi_state,
+                                 struct task_struct *new_owner)
+{
+       struct task_struct *old_owner = pi_state->owner;
+
+       lockdep_assert_held(&pi_state->pi_mutex.wait_lock);
+
+       if (old_owner) {
+               raw_spin_lock(&old_owner->pi_lock);
+               WARN_ON(list_empty(&pi_state->list));
+               list_del_init(&pi_state->list);
+               raw_spin_unlock(&old_owner->pi_lock);
+       }
+
+       if (new_owner) {
+               raw_spin_lock(&new_owner->pi_lock);
+               WARN_ON(!list_empty(&pi_state->list));
+               list_add(&pi_state->list, &new_owner->pi_state_list);
+               pi_state->owner = new_owner;
+               raw_spin_unlock(&new_owner->pi_lock);
+       }
+}
+
 static void get_pi_state(struct futex_pi_state *pi_state)
 {
        WARN_ON_ONCE(!refcount_inc_not_zero(&pi_state->refcount));
@@ -785,17 +808,11 @@ static void put_pi_state(struct futex_pi_state *pi_state)
         * and has cleaned up the pi_state already
         */
        if (pi_state->owner) {
-               struct task_struct *owner;
                unsigned long flags;
 
                raw_spin_lock_irqsave(&pi_state->pi_mutex.wait_lock, flags);
-               owner = pi_state->owner;
-               if (owner) {
-                       raw_spin_lock(&owner->pi_lock);
-                       list_del_init(&pi_state->list);
-                       raw_spin_unlock(&owner->pi_lock);
-               }
-               rt_mutex_proxy_unlock(&pi_state->pi_mutex, owner);
+               pi_state_update_owner(pi_state, NULL);
+               rt_mutex_proxy_unlock(&pi_state->pi_mutex);
                raw_spin_unlock_irqrestore(&pi_state->pi_mutex.wait_lock, flags);
        }
 
@@ -941,7 +958,8 @@ static inline void exit_pi_state_list(struct task_struct *curr) { }
  *     FUTEX_OWNER_DIED bit. See [4]
  *
  * [10] There is no transient state which leaves owner and user space
- *     TID out of sync.
+ *     TID out of sync. Except one error case where the kernel is denied
+ *     write access to the user address, see fixup_pi_state_owner().
  *
  *
  * Serialization and lifetime rules:
@@ -1521,26 +1539,15 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_
                        ret = -EINVAL;
        }
 
-       if (ret)
-               goto out_unlock;
-
-       /*
-        * This is a point of no return; once we modify the uval there is no
-        * going back and subsequent operations must not fail.
-        */
-
-       raw_spin_lock(&pi_state->owner->pi_lock);
-       WARN_ON(list_empty(&pi_state->list));
-       list_del_init(&pi_state->list);
-       raw_spin_unlock(&pi_state->owner->pi_lock);
-
-       raw_spin_lock(&new_owner->pi_lock);
-       WARN_ON(!list_empty(&pi_state->list));
-       list_add(&pi_state->list, &new_owner->pi_state_list);
-       pi_state->owner = new_owner;
-       raw_spin_unlock(&new_owner->pi_lock);
-
-       postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q);
+       if (!ret) {
+               /*
+                * This is a point of no return; once we modified the uval
+                * there is no going back and subsequent operations must
+                * not fail.
+                */
+               pi_state_update_owner(pi_state, new_owner);
+               postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q);
+       }
 
 out_unlock:
        raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
@@ -2323,18 +2330,13 @@ static void unqueue_me_pi(struct futex_q *q)
        spin_unlock(q->lock_ptr);
 }
 
-static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
-                               struct task_struct *argowner)
+static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+                                 struct task_struct *argowner)
 {
        struct futex_pi_state *pi_state = q->pi_state;
-       u32 uval, curval, newval;
        struct task_struct *oldowner, *newowner;
-       u32 newtid;
-       int ret, err = 0;
-
-       lockdep_assert_held(q->lock_ptr);
-
-       raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
+       u32 uval, curval, newval, newtid;
+       int err = 0;
 
        oldowner = pi_state->owner;
 
@@ -2368,14 +2370,12 @@ retry:
                         * We raced against a concurrent self; things are
                         * already fixed up. Nothing to do.
                         */
-                       ret = 0;
-                       goto out_unlock;
+                       return 0;
                }
 
                if (__rt_mutex_futex_trylock(&pi_state->pi_mutex)) {
-                       /* We got the lock after all, nothing to fix. */
-                       ret = 0;
-                       goto out_unlock;
+                       /* We got the lock. pi_state is correct. Tell caller. */
+                       return 1;
                }
 
                /*
@@ -2402,8 +2402,7 @@ retry:
                         * We raced against a concurrent self; things are
                         * already fixed up. Nothing to do.
                         */
-                       ret = 0;
-                       goto out_unlock;
+                       return 1;
                }
                newowner = argowner;
        }
@@ -2433,22 +2432,9 @@ retry:
         * We fixed up user space. Now we need to fix the pi_state
         * itself.
         */
-       if (pi_state->owner != NULL) {
-               raw_spin_lock(&pi_state->owner->pi_lock);
-               WARN_ON(list_empty(&pi_state->list));
-               list_del_init(&pi_state->list);
-               raw_spin_unlock(&pi_state->owner->pi_lock);
-       }
+       pi_state_update_owner(pi_state, newowner);
 
-       pi_state->owner = newowner;
-
-       raw_spin_lock(&newowner->pi_lock);
-       WARN_ON(!list_empty(&pi_state->list));
-       list_add(&pi_state->list, &newowner->pi_state_list);
-       raw_spin_unlock(&newowner->pi_lock);
-       raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
-
-       return 0;
+       return argowner == current;
 
        /*
         * In order to reschedule or handle a page fault, we need to drop the
@@ -2469,17 +2455,16 @@ handle_err:
 
        switch (err) {
        case -EFAULT:
-               ret = fault_in_user_writeable(uaddr);
+               err = fault_in_user_writeable(uaddr);
                break;
 
        case -EAGAIN:
                cond_resched();
-               ret = 0;
+               err = 0;
                break;
 
        default:
                WARN_ON_ONCE(1);
-               ret = err;
                break;
        }
 
@@ -2489,17 +2474,44 @@ handle_err:
        /*
         * Check if someone else fixed it for us:
         */
-       if (pi_state->owner != oldowner) {
-               ret = 0;
-               goto out_unlock;
-       }
+       if (pi_state->owner != oldowner)
+               return argowner == current;
 
-       if (ret)
-               goto out_unlock;
+       /* Retry if err was -EAGAIN or the fault in succeeded */
+       if (!err)
+               goto retry;
 
-       goto retry;
+       /*
+        * fault_in_user_writeable() failed so user state is immutable. At
+        * best we can make the kernel state consistent but user state will
+        * be most likely hosed and any subsequent unlock operation will be
+        * rejected due to PI futex rule [10].
+        *
+        * Ensure that the rtmutex owner is also the pi_state owner despite
+        * the user space value claiming something different. There is no
+        * point in unlocking the rtmutex if current is the owner as it
+        * would need to wait until the next waiter has taken the rtmutex
+        * to guarantee consistent state. Keep it simple. Userspace asked
+        * for this wreckaged state.
+        *
+        * The rtmutex has an owner - either current or some other
+        * task. See the EAGAIN loop above.
+        */
+       pi_state_update_owner(pi_state, rt_mutex_owner(&pi_state->pi_mutex));
 
-out_unlock:
+       return err;
+}
+
+static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+                               struct task_struct *argowner)
+{
+       struct futex_pi_state *pi_state = q->pi_state;
+       int ret;
+
+       lockdep_assert_held(q->lock_ptr);
+
+       raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
+       ret = __fixup_pi_state_owner(uaddr, q, argowner);
        raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
        return ret;
 }
@@ -2523,8 +2535,6 @@ static long futex_wait_restart(struct restart_block *restart);
  */
 static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
 {
-       int ret = 0;
-
        if (locked) {
                /*
                 * Got the lock. We might not be the anticipated owner if we
@@ -2535,8 +2545,8 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
                 * stable state, anything else needs more attention.
                 */
                if (q->pi_state->owner != current)
-                       ret = fixup_pi_state_owner(uaddr, q, current);
-               return ret ? ret : locked;
+                       return fixup_pi_state_owner(uaddr, q, current);
+               return 1;
        }
 
        /*
@@ -2547,23 +2557,17 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
         * Another speculative read; pi_state->owner == current is unstable
         * but needs our attention.
         */
-       if (q->pi_state->owner == current) {
-               ret = fixup_pi_state_owner(uaddr, q, NULL);
-               return ret;
-       }
+       if (q->pi_state->owner == current)
+               return fixup_pi_state_owner(uaddr, q, NULL);
 
        /*
         * Paranoia check. If we did not take the lock, then we should not be
-        * the owner of the rt_mutex.
+        * the owner of the rt_mutex. Warn and establish consistent state.
         */
-       if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) {
-               printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p "
-                               "pi-state %p\n", ret,
-                               q->pi_state->pi_mutex.owner,
-                               q->pi_state->owner);
-       }
+       if (WARN_ON_ONCE(rt_mutex_owner(&q->pi_state->pi_mutex) == current))
+               return fixup_pi_state_owner(uaddr, q, current);
 
-       return ret;
+       return 0;
 }
 
 /**
@@ -2771,7 +2775,6 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags,
                         ktime_t *time, int trylock)
 {
        struct hrtimer_sleeper timeout, *to;
-       struct futex_pi_state *pi_state = NULL;
        struct task_struct *exiting = NULL;
        struct rt_mutex_waiter rt_waiter;
        struct futex_hash_bucket *hb;
@@ -2907,23 +2910,8 @@ no_block:
        if (res)
                ret = (res < 0) ? res : 0;
 
-       /*
-        * If fixup_owner() faulted and was unable to handle the fault, unlock
-        * it and return the fault to userspace.
-        */
-       if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) {
-               pi_state = q.pi_state;
-               get_pi_state(pi_state);
-       }
-
        /* Unqueue and drop the lock */
        unqueue_me_pi(&q);
-
-       if (pi_state) {
-               rt_mutex_futex_unlock(&pi_state->pi_mutex);
-               put_pi_state(pi_state);
-       }
-
        goto out;
 
 out_unlock_put_key:
@@ -3183,7 +3171,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
                                 u32 __user *uaddr2)
 {
        struct hrtimer_sleeper timeout, *to;
-       struct futex_pi_state *pi_state = NULL;
        struct rt_mutex_waiter rt_waiter;
        struct futex_hash_bucket *hb;
        union futex_key key2 = FUTEX_KEY_INIT;
@@ -3261,16 +3248,17 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
                if (q.pi_state && (q.pi_state->owner != current)) {
                        spin_lock(q.lock_ptr);
                        ret = fixup_pi_state_owner(uaddr2, &q, current);
-                       if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) {
-                               pi_state = q.pi_state;
-                               get_pi_state(pi_state);
-                       }
                        /*
                         * Drop the reference to the pi state which
                         * the requeue_pi() code acquired for us.
                         */
                        put_pi_state(q.pi_state);
                        spin_unlock(q.lock_ptr);
+                       /*
+                        * Adjust the return value. It's either -EFAULT or
+                        * success (1) but the caller expects 0 for success.
+                        */
+                       ret = ret < 0 ? ret : 0;
                }
        } else {
                struct rt_mutex *pi_mutex;
@@ -3301,25 +3289,10 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
                if (res)
                        ret = (res < 0) ? res : 0;
 
-               /*
-                * If fixup_pi_state_owner() faulted and was unable to handle
-                * the fault, unlock the rt_mutex and return the fault to
-                * userspace.
-                */
-               if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) {
-                       pi_state = q.pi_state;
-                       get_pi_state(pi_state);
-               }
-
                /* Unqueue and drop the lock. */
                unqueue_me_pi(&q);
        }
 
-       if (pi_state) {
-               rt_mutex_futex_unlock(&pi_state->pi_mutex);
-               put_pi_state(pi_state);
-       }
-
        if (ret == -EINTR) {
                /*
                 * We've already been requeued, but cannot restart by calling
index 3110c77230c7f7729b7a4488680ee0003e1797f0..f62de2dea8a3178cbf5bdc4ae697f69a946cb038 100644 (file)
@@ -4,7 +4,7 @@ menu "GCOV-based kernel profiling"
 config GCOV_KERNEL
        bool "Enable gcov-based kernel profiling"
        depends on DEBUG_FS
-       select CONSTRUCTORS if !UML
+       select CONSTRUCTORS
        default n
        help
        This option enables gcov-based code profiling (e.g. for code coverage
index 4f8efc278aa75bc22fc4387e11fe6b8d48548135..aa919585c24b4adb914433fcfdd06999b3a212e6 100644 (file)
@@ -1134,7 +1134,6 @@ int kernel_kexec(void)
 
 #ifdef CONFIG_KEXEC_JUMP
        if (kexec_image->preserve_context) {
-               lock_system_sleep();
                pm_prepare_console();
                error = freeze_processes();
                if (error) {
@@ -1197,7 +1196,6 @@ int kernel_kexec(void)
                thaw_processes();
  Restore_console:
                pm_restore_console();
-               unlock_system_sleep();
        }
 #endif
 
index f7fb5d135930fa46e8f57a85ce67b856a6e23347..d5a3eb74a6574aade1fb23c3959a7ababee96d66 100644 (file)
@@ -1954,28 +1954,48 @@ bool __weak arch_kprobe_on_func_entry(unsigned long offset)
        return !offset;
 }
 
-bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
+/**
+ * kprobe_on_func_entry() -- check whether given address is function entry
+ * @addr: Target address
+ * @sym:  Target symbol name
+ * @offset: The offset from the symbol or the address
+ *
+ * This checks whether the given @addr+@offset or @sym+@offset is on the
+ * function entry address or not.
+ * This returns 0 if it is the function entry, or -EINVAL if it is not.
+ * And also it returns -ENOENT if it fails the symbol or address lookup.
+ * Caller must pass @addr or @sym (either one must be NULL), or this
+ * returns -EINVAL.
+ */
+int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
 {
        kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset);
 
        if (IS_ERR(kp_addr))
-               return false;
+               return PTR_ERR(kp_addr);
 
-       if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) ||
-                                               !arch_kprobe_on_func_entry(offset))
-               return false;
+       if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset))
+               return -ENOENT;
 
-       return true;
+       if (!arch_kprobe_on_func_entry(offset))
+               return -EINVAL;
+
+       return 0;
 }
 
 int register_kretprobe(struct kretprobe *rp)
 {
-       int ret = 0;
+       int ret;
        struct kretprobe_instance *inst;
        int i;
        void *addr;
 
-       if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset))
+       ret = kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset);
+       if (ret)
+               return ret;
+
+       /* If only rp->kp.addr is specified, check reregistering kprobes */
+       if (rp->kp.addr && check_kprobe_rereg(&rp->kp))
                return -EINVAL;
 
        if (kretprobe_blacklist_size) {
index cfdd5b93264d7e17ca120aa3d5fafe139a2c33f9..2f8cd616d3b29aa93498db95e426acd4abbb153b 100644 (file)
@@ -1716,8 +1716,7 @@ void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
  * possible because it belongs to the pi_state which is about to be freed
  * and it is not longer visible to other tasks.
  */
-void rt_mutex_proxy_unlock(struct rt_mutex *lock,
-                          struct task_struct *proxy_owner)
+void rt_mutex_proxy_unlock(struct rt_mutex *lock)
 {
        debug_rt_mutex_proxy_unlock(lock);
        rt_mutex_set_owner(lock, NULL);
index d1d62f942be2285a7e11588201ac199dc700a805..ca6fb489007b6baced167ea52ccc998179b18eec 100644 (file)
@@ -133,8 +133,7 @@ enum rtmutex_chainwalk {
 extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock);
 extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
                                       struct task_struct *proxy_owner);
-extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
-                                 struct task_struct *proxy_owner);
+extern void rt_mutex_proxy_unlock(struct rt_mutex *lock);
 extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter);
 extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock,
                                     struct rt_mutex_waiter *waiter,
index c73f2e295167d141cdc68fd77cc8ac60eb371226..72e33054a2e1b72d7b9c529d59105a51ea9dc9e6 100644 (file)
@@ -497,10 +497,10 @@ static int swap_writer_finish(struct swap_map_handle *handle,
                unsigned int flags, int error)
 {
        if (!error) {
-               flush_swap_writer(handle);
                pr_info("S");
                error = mark_swapfiles(handle, flags);
                pr_cont("|\n");
+               flush_swap_writer(handle);
        }
 
        if (error)
index 6639a0cfe0aca6591a1934fbaef32efc2da788d3..5a95c688621fa5483b2031efd703180b1edda573 100644 (file)
@@ -1398,7 +1398,7 @@ static size_t record_print_text(struct printk_record *r, bool syslog,
         * not counted in the return value.
         */
        if (buf_size > 0)
-               text[len] = 0;
+               r->text_buf[len] = 0;
 
        return len;
 }
index 73edb9e4f3548e0331ea0d38c351750a05a418d9..29a6ebeebc9e1eb75f803046c92cb7fef97c418d 100644 (file)
@@ -394,7 +394,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
                }
 
                if (t->ret_stack == NULL) {
-                       atomic_set(&t->tracing_graph_pause, 0);
                        atomic_set(&t->trace_overrun, 0);
                        t->curr_ret_stack = -1;
                        t->curr_ret_depth = -1;
@@ -489,7 +488,6 @@ static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack);
 static void
 graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack)
 {
-       atomic_set(&t->tracing_graph_pause, 0);
        atomic_set(&t->trace_overrun, 0);
        t->ftrace_timestamp = 0;
        /* make curr_ret_stack visible before we add the ret_stack */
index d06aab4dcbb8f41fe9929197b509bfad94f6e99b..6756379b661fee56125f1ea81e8106ddbb1f6887 100644 (file)
@@ -562,6 +562,8 @@ static int __irqsoff_tracer_init(struct trace_array *tr)
        /* non overwrite screws up the latency tracers */
        set_tracer_flag(tr, TRACE_ITER_OVERWRITE, 1);
        set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, 1);
+       /* without pause, we will produce garbage if another latency occurs */
+       set_tracer_flag(tr, TRACE_ITER_PAUSE_ON_TRACE, 1);
 
        tr->max_latency = 0;
        irqsoff_trace = tr;
@@ -583,11 +585,13 @@ static void __irqsoff_tracer_reset(struct trace_array *tr)
 {
        int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT;
        int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE;
+       int pause_flag = save_flags & TRACE_ITER_PAUSE_ON_TRACE;
 
        stop_irqsoff_tracer(tr, is_graph(tr));
 
        set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, lat_flag);
        set_tracer_flag(tr, TRACE_ITER_OVERWRITE, overwrite_flag);
+       set_tracer_flag(tr, TRACE_ITER_PAUSE_ON_TRACE, pause_flag);
        ftrace_reset_array_ops(tr);
 
        irqsoff_busy = false;
index e6fba1798771b401eaf97d08b2c4d5926eb81995..56c7fbff7bd7f7186bef4f9a5506063767b578aa 100644 (file)
@@ -221,9 +221,9 @@ bool trace_kprobe_on_func_entry(struct trace_event_call *call)
 {
        struct trace_kprobe *tk = trace_kprobe_primary_from_call(call);
 
-       return tk ? kprobe_on_func_entry(tk->rp.kp.addr,
+       return tk ? (kprobe_on_func_entry(tk->rp.kp.addr,
                        tk->rp.kp.addr ? NULL : tk->rp.kp.symbol_name,
-                       tk->rp.kp.addr ? 0 : tk->rp.kp.offset) : false;
+                       tk->rp.kp.addr ? 0 : tk->rp.kp.offset) == 0) : false;
 }
 
 bool trace_kprobe_error_injectable(struct trace_event_call *call)
@@ -828,9 +828,11 @@ static int trace_kprobe_create(int argc, const char *argv[])
                }
                if (is_return)
                        flags |= TPARG_FL_RETURN;
-               if (kprobe_on_func_entry(NULL, symbol, offset))
+               ret = kprobe_on_func_entry(NULL, symbol, offset);
+               if (ret == 0)
                        flags |= TPARG_FL_FENTRY;
-               if (offset && is_return && !(flags & TPARG_FL_FENTRY)) {
+               /* Defer the ENOENT case until register kprobe */
+               if (ret == -EINVAL && is_return) {
                        trace_probe_log_err(0, BAD_RETPROBE);
                        goto parse_error;
                }
index 3e3352f3d0da7b9e9f764bf7eb106463872f0a3e..bec38c64d6a624fe5680cff59bdc1a0b9dc7d803 100644 (file)
@@ -427,3 +427,34 @@ void __ubsan_handle_load_invalid_value(void *_data, void *val)
        ubsan_epilogue();
 }
 EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
+
+void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
+                                        unsigned long align,
+                                        unsigned long offset);
+void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
+                                        unsigned long align,
+                                        unsigned long offset)
+{
+       struct alignment_assumption_data *data = _data;
+       unsigned long real_ptr;
+
+       if (suppress_report(&data->location))
+               return;
+
+       ubsan_prologue(&data->location, "alignment-assumption");
+
+       if (offset)
+               pr_err("assumption of %lu byte alignment (with offset of %lu byte) for pointer of type %s failed",
+                      align, offset, data->type->type_name);
+       else
+               pr_err("assumption of %lu byte alignment for pointer of type %s failed",
+                      align, data->type->type_name);
+
+       real_ptr = ptr - offset;
+       pr_err("%saddress is %lu aligned, misalignment offset is %lu bytes",
+              offset ? "offset " : "", BIT(real_ptr ? __ffs(real_ptr) : 0),
+              real_ptr & (align - 1));
+
+       ubsan_epilogue();
+}
+EXPORT_SYMBOL(__ubsan_handle_alignment_assumption);
index 7b56c09473a98e7fcff4c8e6640459d1d178c49c..9a0b71c5ff9fbf45492c0043f24a8578f06acaf6 100644 (file)
@@ -78,6 +78,12 @@ struct invalid_value_data {
        struct type_descriptor *type;
 };
 
+struct alignment_assumption_data {
+       struct source_location location;
+       struct source_location assumption_location;
+       struct type_descriptor *type;
+};
+
 #if defined(CONFIG_ARCH_SUPPORTS_INT128)
 typedef __int128 s_max;
 typedef unsigned __int128 u_max;
index e5acb9714436307f3ecc3e42b53301f2c8c92475..190ccdaa6c192f641a456c15bd6623b85178abce 100644 (file)
@@ -1342,7 +1342,7 @@ fast_isolate_freepages(struct compact_control *cc)
 {
        unsigned int limit = min(1U, freelist_scan_limit(cc) >> 1);
        unsigned int nr_scanned = 0;
-       unsigned long low_pfn, min_pfn, high_pfn = 0, highest = 0;
+       unsigned long low_pfn, min_pfn, highest = 0;
        unsigned long nr_isolated = 0;
        unsigned long distance;
        struct page *page = NULL;
@@ -1387,6 +1387,7 @@ fast_isolate_freepages(struct compact_control *cc)
                struct page *freepage;
                unsigned long flags;
                unsigned int order_scanned = 0;
+               unsigned long high_pfn = 0;
 
                if (!area->nr_free)
                        continue;
index 5c9d564317a5c5eb2e7f5c4edc6e5e3571bd9c2d..aa0e0fb046700a0b5a468abfe57f91ca01970829 100644 (file)
@@ -835,6 +835,7 @@ noinline int __add_to_page_cache_locked(struct page *page,
        XA_STATE(xas, &mapping->i_pages, offset);
        int huge = PageHuge(page);
        int error;
+       bool charged = false;
 
        VM_BUG_ON_PAGE(!PageLocked(page), page);
        VM_BUG_ON_PAGE(PageSwapBacked(page), page);
@@ -848,6 +849,7 @@ noinline int __add_to_page_cache_locked(struct page *page,
                error = mem_cgroup_charge(page, current->mm, gfp);
                if (error)
                        goto error;
+               charged = true;
        }
 
        gfp &= GFP_RECLAIM_MASK;
@@ -896,6 +898,8 @@ unlock:
 
        if (xas_error(&xas)) {
                error = xas_error(&xas);
+               if (charged)
+                       mem_cgroup_uncharge(page);
                goto error;
        }
 
index 9237976abe72b7a7aa6afe50fce36c0b34007939..91ca9b103ee527283f0dc2cef8816d43beb9c6bc 100644 (file)
@@ -2202,7 +2202,7 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
 {
        spinlock_t *ptl;
        struct mmu_notifier_range range;
-       bool was_locked = false;
+       bool do_unlock_page = false;
        pmd_t _pmd;
 
        mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, vma->vm_mm,
@@ -2218,7 +2218,6 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
        VM_BUG_ON(freeze && !page);
        if (page) {
                VM_WARN_ON_ONCE(!PageLocked(page));
-               was_locked = true;
                if (page != pmd_page(*pmd))
                        goto out;
        }
@@ -2227,19 +2226,29 @@ repeat:
        if (pmd_trans_huge(*pmd)) {
                if (!page) {
                        page = pmd_page(*pmd);
-                       if (unlikely(!trylock_page(page))) {
-                               get_page(page);
-                               _pmd = *pmd;
-                               spin_unlock(ptl);
-                               lock_page(page);
-                               spin_lock(ptl);
-                               if (unlikely(!pmd_same(*pmd, _pmd))) {
-                                       unlock_page(page);
+                       /*
+                        * An anonymous page must be locked, to ensure that a
+                        * concurrent reuse_swap_page() sees stable mapcount;
+                        * but reuse_swap_page() is not used on shmem or file,
+                        * and page lock must not be taken when zap_pmd_range()
+                        * calls __split_huge_pmd() while i_mmap_lock is held.
+                        */
+                       if (PageAnon(page)) {
+                               if (unlikely(!trylock_page(page))) {
+                                       get_page(page);
+                                       _pmd = *pmd;
+                                       spin_unlock(ptl);
+                                       lock_page(page);
+                                       spin_lock(ptl);
+                                       if (unlikely(!pmd_same(*pmd, _pmd))) {
+                                               unlock_page(page);
+                                               put_page(page);
+                                               page = NULL;
+                                               goto repeat;
+                                       }
                                        put_page(page);
-                                       page = NULL;
-                                       goto repeat;
                                }
-                               put_page(page);
+                               do_unlock_page = true;
                        }
                }
                if (PageMlocked(page))
@@ -2249,7 +2258,7 @@ repeat:
        __split_huge_pmd_locked(vma, pmd, range.start, freeze);
 out:
        spin_unlock(ptl);
-       if (!was_locked && page)
+       if (do_unlock_page)
                unlock_page(page);
        /*
         * No need to double call mmu_notifier->invalidate_range() callback.
index 18f6ee3179002a7f218dfafb4e7724685ff1c215..4bdb58ab14cbbd659a1f9ca2e531a995fed03077 100644 (file)
@@ -79,6 +79,21 @@ DEFINE_SPINLOCK(hugetlb_lock);
 static int num_fault_mutexes;
 struct mutex *hugetlb_fault_mutex_table ____cacheline_aligned_in_smp;
 
+static inline bool PageHugeFreed(struct page *head)
+{
+       return page_private(head + 4) == -1UL;
+}
+
+static inline void SetPageHugeFreed(struct page *head)
+{
+       set_page_private(head + 4, -1UL);
+}
+
+static inline void ClearPageHugeFreed(struct page *head)
+{
+       set_page_private(head + 4, 0);
+}
+
 /* Forward declaration */
 static int hugetlb_acct_memory(struct hstate *h, long delta);
 
@@ -1028,6 +1043,7 @@ static void enqueue_huge_page(struct hstate *h, struct page *page)
        list_move(&page->lru, &h->hugepage_freelists[nid]);
        h->free_huge_pages++;
        h->free_huge_pages_node[nid]++;
+       SetPageHugeFreed(page);
 }
 
 static struct page *dequeue_huge_page_node_exact(struct hstate *h, int nid)
@@ -1044,6 +1060,7 @@ static struct page *dequeue_huge_page_node_exact(struct hstate *h, int nid)
 
                list_move(&page->lru, &h->hugepage_activelist);
                set_page_refcounted(page);
+               ClearPageHugeFreed(page);
                h->free_huge_pages--;
                h->free_huge_pages_node[nid]--;
                return page;
@@ -1344,12 +1361,11 @@ struct hstate *size_to_hstate(unsigned long size)
  */
 bool page_huge_active(struct page *page)
 {
-       VM_BUG_ON_PAGE(!PageHuge(page), page);
-       return PageHead(page) && PagePrivate(&page[1]);
+       return PageHeadHuge(page) && PagePrivate(&page[1]);
 }
 
 /* never called for tail page */
-static void set_page_huge_active(struct page *page)
+void set_page_huge_active(struct page *page)
 {
        VM_BUG_ON_PAGE(!PageHeadHuge(page), page);
        SetPagePrivate(&page[1]);
@@ -1505,6 +1521,7 @@ static void prep_new_huge_page(struct hstate *h, struct page *page, int nid)
        spin_lock(&hugetlb_lock);
        h->nr_huge_pages++;
        h->nr_huge_pages_node[nid]++;
+       ClearPageHugeFreed(page);
        spin_unlock(&hugetlb_lock);
 }
 
@@ -1755,6 +1772,7 @@ int dissolve_free_huge_page(struct page *page)
 {
        int rc = -EBUSY;
 
+retry:
        /* Not to disrupt normal path by vainly holding hugetlb_lock */
        if (!PageHuge(page))
                return 0;
@@ -1771,6 +1789,26 @@ int dissolve_free_huge_page(struct page *page)
                int nid = page_to_nid(head);
                if (h->free_huge_pages - h->resv_huge_pages == 0)
                        goto out;
+
+               /*
+                * We should make sure that the page is already on the free list
+                * when it is dissolved.
+                */
+               if (unlikely(!PageHugeFreed(head))) {
+                       spin_unlock(&hugetlb_lock);
+                       cond_resched();
+
+                       /*
+                        * Theoretically, we should return -EBUSY when we
+                        * encounter this race. In fact, we have a chance
+                        * to successfully dissolve the page if we do a
+                        * retry. Because the race window is quite small.
+                        * If we seize this opportunity, it is an optimization
+                        * for increasing the success rate of dissolving page.
+                        */
+                       goto retry;
+               }
+
                /*
                 * Move PageHWPoison flag from head page to the raw error page,
                 * which makes any subpages rather than the error page reusable.
@@ -2009,13 +2047,16 @@ retry:
 
        /* Free the needed pages to the hugetlb pool */
        list_for_each_entry_safe(page, tmp, &surplus_list, lru) {
+               int zeroed;
+
                if ((--needed) < 0)
                        break;
                /*
                 * This page is now managed by the hugetlb allocator and has
                 * no users -- drop the buddy allocator's reference.
                 */
-               VM_BUG_ON_PAGE(!put_page_testzero(page), page);
+               zeroed = put_page_testzero(page);
+               VM_BUG_ON_PAGE(!zeroed, page);
                enqueue_huge_page(h, page);
        }
 free:
@@ -5555,9 +5596,9 @@ bool isolate_huge_page(struct page *page, struct list_head *list)
 {
        bool ret = true;
 
-       VM_BUG_ON_PAGE(!PageHead(page), page);
        spin_lock(&hugetlb_lock);
-       if (!page_huge_active(page) || !get_page_unless_zero(page)) {
+       if (!PageHeadHuge(page) || !page_huge_active(page) ||
+           !get_page_unless_zero(page)) {
                ret = false;
                goto unlock;
        }
index cc4d9e1d49b1d046d579863ec36461152f4a2d12..8c706e7652f2b1fa026b7da658382cdcc4b8b8ea 100644 (file)
@@ -209,7 +209,7 @@ bool check_memory_region(unsigned long addr, size_t size, bool write,
 
 static inline bool addr_has_metadata(const void *addr)
 {
-       return true;
+       return (is_vmalloc_addr(addr) || virt_addr_valid(addr));
 }
 
 #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
index 1eaaec1e7687cc0c15c5d19ecee92e201875dadf..8d9b5f1e70409e1ea0ba95b3c576185cb80def05 100644 (file)
@@ -275,14 +275,6 @@ __memblock_find_range_top_down(phys_addr_t start, phys_addr_t end,
  *
  * Find @size free area aligned to @align in the specified range and node.
  *
- * When allocation direction is bottom-up, the @start should be greater
- * than the end of the kernel image. Otherwise, it will be trimmed. The
- * reason is that we want the bottom-up allocation just near the kernel
- * image so it is highly likely that the allocated memory and the kernel
- * will reside in the same node.
- *
- * If bottom-up allocation failed, will try to allocate memory top-down.
- *
  * Return:
  * Found address on success, 0 on failure.
  */
@@ -291,8 +283,6 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
                                        phys_addr_t end, int nid,
                                        enum memblock_flags flags)
 {
-       phys_addr_t kernel_end, ret;
-
        /* pump up @end */
        if (end == MEMBLOCK_ALLOC_ACCESSIBLE ||
            end == MEMBLOCK_ALLOC_KASAN)
@@ -301,40 +291,13 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
        /* avoid allocating the first page */
        start = max_t(phys_addr_t, start, PAGE_SIZE);
        end = max(start, end);
-       kernel_end = __pa_symbol(_end);
-
-       /*
-        * try bottom-up allocation only when bottom-up mode
-        * is set and @end is above the kernel image.
-        */
-       if (memblock_bottom_up() && end > kernel_end) {
-               phys_addr_t bottom_up_start;
-
-               /* make sure we will allocate above the kernel */
-               bottom_up_start = max(start, kernel_end);
 
-               /* ok, try bottom-up allocation first */
-               ret = __memblock_find_range_bottom_up(bottom_up_start, end,
-                                                     size, align, nid, flags);
-               if (ret)
-                       return ret;
-
-               /*
-                * we always limit bottom-up allocation above the kernel,
-                * but top-down allocation doesn't have the limit, so
-                * retrying top-down allocation may succeed when bottom-up
-                * allocation failed.
-                *
-                * bottom-up allocation is expected to be fail very rarely,
-                * so we use WARN_ONCE() here to see the stack trace if
-                * fail happens.
-                */
-               WARN_ONCE(IS_ENABLED(CONFIG_MEMORY_HOTREMOVE),
-                         "memblock: bottom-up allocation failed, memory hotremove may be affected\n");
-       }
-
-       return __memblock_find_range_top_down(start, end, size, align, nid,
-                                             flags);
+       if (memblock_bottom_up())
+               return __memblock_find_range_bottom_up(start, end, size, align,
+                                                      nid, flags);
+       else
+               return __memblock_find_range_top_down(start, end, size, align,
+                                                     nid, flags);
 }
 
 /**
index c0efe921bca5c608fbaf385ddccd1e85319be7ab..20ca887ea76943c97236872c2b046ffa7647a613 100644 (file)
@@ -1280,6 +1280,12 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
                return -ENOSYS;
        }
 
+       if (page_count(hpage) == 1) {
+               /* page was freed from under us. So we are done. */
+               putback_active_hugepage(hpage);
+               return MIGRATEPAGE_SUCCESS;
+       }
+
        new_hpage = get_new_page(hpage, private);
        if (!new_hpage)
                return -ENOMEM;
index 783913e41f65df5b283e2fa2e9766b969bd6f23b..519a60d5b6f7d5017c788ced10c9fcca6637dd65 100644 (file)
@@ -7080,26 +7080,23 @@ void __init free_area_init_memoryless_node(int nid)
  * Initialize all valid struct pages in the range [spfn, epfn) and mark them
  * PageReserved(). Return the number of struct pages that were initialized.
  */
-static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn,
-                                        int zone, int nid)
+static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn)
 {
-       unsigned long pfn, zone_spfn, zone_epfn;
+       unsigned long pfn;
        u64 pgcnt = 0;
 
-       zone_spfn = arch_zone_lowest_possible_pfn[zone];
-       zone_epfn = arch_zone_highest_possible_pfn[zone];
-
-       spfn = clamp(spfn, zone_spfn, zone_epfn);
-       epfn = clamp(epfn, zone_spfn, zone_epfn);
-
        for (pfn = spfn; pfn < epfn; pfn++) {
                if (!pfn_valid(ALIGN_DOWN(pfn, pageblock_nr_pages))) {
                        pfn = ALIGN_DOWN(pfn, pageblock_nr_pages)
                                + pageblock_nr_pages - 1;
                        continue;
                }
-
-               __init_single_page(pfn_to_page(pfn), pfn, zone, nid);
+               /*
+                * Use a fake node/zone (0) for now. Some of these pages
+                * (in memblock.reserved but not in memblock.memory) will
+                * get re-initialized via reserve_bootmem_region() later.
+                */
+               __init_single_page(pfn_to_page(pfn), pfn, 0, 0);
                __SetPageReserved(pfn_to_page(pfn));
                pgcnt++;
        }
@@ -7108,64 +7105,51 @@ static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn,
 }
 
 /*
- * Only struct pages that correspond to ranges defined by memblock.memory
- * are zeroed and initialized by going through __init_single_page() during
- * memmap_init().
- *
- * But, there could be struct pages that correspond to holes in
- * memblock.memory. This can happen because of the following reasons:
- * - phyiscal memory bank size is not necessarily the exact multiple of the
- *   arbitrary section size
- * - early reserved memory may not be listed in memblock.memory
- * - memory layouts defined with memmap= kernel parameter may not align
- *   nicely with memmap sections
+ * Only struct pages that are backed by physical memory are zeroed and
+ * initialized by going through __init_single_page(). But, there are some
+ * struct pages which are reserved in memblock allocator and their fields
+ * may be accessed (for example page_to_pfn() on some configuration accesses
+ * flags). We must explicitly initialize those struct pages.
  *
- * Explicitly initialize those struct pages so that:
- * - PG_Reserved is set
- * - zone link is set accorging to the architecture constrains
- * - node is set to node id of the next populated region except for the
- *   trailing hole where last node id is used
+ * This function also addresses a similar issue where struct pages are left
+ * uninitialized because the physical address range is not covered by
+ * memblock.memory or memblock.reserved. That could happen when memblock
+ * layout is manually configured via memmap=, or when the highest physical
+ * address (max_pfn) does not end on a section boundary.
  */
-static void __init init_zone_unavailable_mem(int zone)
+static void __init init_unavailable_mem(void)
 {
-       unsigned long start, end;
-       int i, nid;
-       u64 pgcnt;
-       unsigned long next = 0;
+       phys_addr_t start, end;
+       u64 i, pgcnt;
+       phys_addr_t next = 0;
 
        /*
-        * Loop through holes in memblock.memory and initialize struct
-        * pages corresponding to these holes
+        * Loop through unavailable ranges not covered by memblock.memory.
         */
        pgcnt = 0;
-       for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, &nid) {
+       for_each_mem_range(i, &start, &end) {
                if (next < start)
-                       pgcnt += init_unavailable_range(next, start, zone, nid);
+                       pgcnt += init_unavailable_range(PFN_DOWN(next),
+                                                       PFN_UP(start));
                next = end;
        }
 
        /*
-        * Last section may surpass the actual end of memory (e.g. we can
-        * have 1Gb section and 512Mb of RAM pouplated).
-        * Make sure that memmap has a well defined state in this case.
+        * Early sections always have a fully populated memmap for the whole
+        * section - see pfn_valid(). If the last section has holes at the
+        * end and that section is marked "online", the memmap will be
+        * considered initialized. Make sure that memmap has a well defined
+        * state.
         */
-       end = round_up(max_pfn, PAGES_PER_SECTION);
-       pgcnt += init_unavailable_range(next, end, zone, nid);
+       pgcnt += init_unavailable_range(PFN_DOWN(next),
+                                       round_up(max_pfn, PAGES_PER_SECTION));
 
        /*
         * Struct pages that do not have backing memory. This could be because
         * firmware is using some of this memory, or for some other reasons.
         */
        if (pgcnt)
-               pr_info("Zone %s: zeroed struct page in unavailable ranges: %lld pages", zone_names[zone], pgcnt);
-}
-
-static void __init init_unavailable_mem(void)
-{
-       int zone;
-
-       for (zone = 0; zone < ZONE_MOVABLE; zone++)
-               init_zone_unavailable_mem(zone);
+               pr_info("Zeroed struct page in unavailable ranges: %lld pages", pgcnt);
 }
 #else
 static inline void __init init_unavailable_mem(void)
index 69742ab9a21d3271eadf2ddb0ddd322f197c7544..7ecbbbe5bc0c1fe65e3fc52b881205b18189b771 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5625,10 +5625,8 @@ static int sysfs_slab_add(struct kmem_cache *s)
 
        s->kobj.kset = kset;
        err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name);
-       if (err) {
-               kobject_put(&s->kobj);
+       if (err)
                goto out;
-       }
 
        err = sysfs_create_group(&s->kobj, &slab_attr_group);
        if (err)
index 1883118aae55b015e33b3702a3611bc5a60f8357..32a48e5418dac67af8daf4dcf9b4312ab89c321f 100644 (file)
@@ -88,4 +88,33 @@ int br_mrp_switchdev_send_in_test(struct net_bridge *br, struct br_mrp *mrp,
 int br_mrp_ring_port_open(struct net_device *dev, u8 loc);
 int br_mrp_in_port_open(struct net_device *dev, u8 loc);
 
+/* MRP protocol data units */
+struct br_mrp_tlv_hdr {
+       __u8 type;
+       __u8 length;
+};
+
+struct br_mrp_common_hdr {
+       __be16 seq_id;
+       __u8 domain[MRP_DOMAIN_UUID_LENGTH];
+};
+
+struct br_mrp_ring_test_hdr {
+       __be16 prio;
+       __u8 sa[ETH_ALEN];
+       __be16 port_role;
+       __be16 state;
+       __be16 transitions;
+       __be32 timestamp;
+} __attribute__((__packed__));
+
+struct br_mrp_in_test_hdr {
+       __be16 id;
+       __u8 sa[ETH_ALEN];
+       __be16 port_role;
+       __be16 state;
+       __be16 transitions;
+       __be32 timestamp;
+} __attribute__((__packed__));
+
 #endif /* _BR_PRIVATE_MRP_H */
index 277ed854aef1c362df96bedfa19b07ef1b6d6b80..6d2d557442dc69b403cdbf98b4b8f5d593287121 100644 (file)
@@ -1245,13 +1245,14 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
        old    = neigh->nud_state;
        err    = -EPERM;
 
-       if (!(flags & NEIGH_UPDATE_F_ADMIN) &&
-           (old & (NUD_NOARP | NUD_PERMANENT)))
-               goto out;
        if (neigh->dead) {
                NL_SET_ERR_MSG(extack, "Neighbor entry is now dead");
+               new = old;
                goto out;
        }
+       if (!(flags & NEIGH_UPDATE_F_ADMIN) &&
+           (old & (NUD_NOARP | NUD_PERMANENT)))
+               goto out;
 
        ext_learn_change = neigh_update_ext_learned(neigh, flags, &notify);
 
index 4cac31d22a502077b959e7d734d24be7a57467f7..2193ae529e752623123dfbbaeb19f6962ec4d64e 100644 (file)
@@ -1035,7 +1035,7 @@ source_ok:
                        fld.saddr = dnet_select_source(dev_out, 0,
                                                       RT_SCOPE_HOST);
                        if (!fld.daddr)
-                               goto out;
+                               goto done;
                }
                fld.flowidn_oif = LOOPBACK_IFINDEX;
                res.type = RTN_LOCAL;
index 7dc92ce5a1340ebe379d9d7dae2111ba5961edaf..a9c30a608e35da7a823f959bebe75911430f3c28 100644 (file)
@@ -217,7 +217,10 @@ struct hsr_priv {
        u8 net_id;              /* for PRP, it occupies most significant 3 bits
                                 * of lan_id
                                 */
-       unsigned char           sup_multicast_addr[ETH_ALEN];
+       unsigned char           sup_multicast_addr[ETH_ALEN] __aligned(sizeof(u16));
+                               /* Align to u16 boundary to avoid unaligned access
+                                * in ether_addr_equal
+                                */
 #ifdef CONFIG_DEBUG_FS
        struct dentry *node_tbl_root;
 #endif
index 64594aa755f0549081185575c5108e753f50749c..76a420c76f16e701d36e0ffe235fc19e0ccd8235 100644 (file)
@@ -317,7 +317,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
        }
 
        dev->needed_headroom = t_hlen + hlen;
-       mtu -= (dev->hard_header_len + t_hlen);
+       mtu -= t_hlen;
 
        if (mtu < IPV4_MIN_MTU)
                mtu = IPV4_MIN_MTU;
@@ -347,7 +347,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
        nt = netdev_priv(dev);
        t_hlen = nt->hlen + sizeof(struct iphdr);
        dev->min_mtu = ETH_MIN_MTU;
-       dev->max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen;
+       dev->max_mtu = IP_MAX_MTU - t_hlen;
        ip_tunnel_add(itn, nt);
        return nt;
 
@@ -488,11 +488,10 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
        int mtu;
 
        tunnel_hlen = md ? tunnel_hlen : tunnel->hlen;
-       pkt_size = skb->len - tunnel_hlen - dev->hard_header_len;
+       pkt_size = skb->len - tunnel_hlen;
 
        if (df)
-               mtu = dst_mtu(&rt->dst) - dev->hard_header_len
-                                       - sizeof(struct iphdr) - tunnel_hlen;
+               mtu = dst_mtu(&rt->dst) - (sizeof(struct iphdr) + tunnel_hlen);
        else
                mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
 
@@ -972,7 +971,7 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
        int t_hlen = tunnel->hlen + sizeof(struct iphdr);
-       int max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen;
+       int max_mtu = IP_MAX_MTU - t_hlen;
 
        if (new_mtu < ETH_MIN_MTU)
                return -EINVAL;
@@ -1149,10 +1148,9 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
 
        mtu = ip_tunnel_bind_dev(dev);
        if (tb[IFLA_MTU]) {
-               unsigned int max = IP_MAX_MTU - dev->hard_header_len - nt->hlen;
+               unsigned int max = IP_MAX_MTU - (nt->hlen + sizeof(struct iphdr));
 
-               mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU,
-                           (unsigned int)(max - sizeof(struct iphdr)));
+               mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU, max);
        }
 
        err = dev_set_mtu(dev, mtu);
index a7dfca0a38cd7a0cdbe0a1c6d9b17866a33ebdc1..9b44caa4b956221a8d911fa8d0d8a6c51bad5829 100644 (file)
@@ -2859,7 +2859,8 @@ static void tcp_identify_packet_loss(struct sock *sk, int *ack_flag)
        } else if (tcp_is_rack(sk)) {
                u32 prior_retrans = tp->retrans_out;
 
-               tcp_rack_mark_lost(sk);
+               if (tcp_rack_mark_lost(sk))
+                       *ack_flag &= ~FLAG_SET_XMIT_TIMER;
                if (prior_retrans > tp->retrans_out)
                        *ack_flag |= FLAG_LOST_RETRANS;
        }
@@ -3392,8 +3393,8 @@ static void tcp_ack_probe(struct sock *sk)
        } else {
                unsigned long when = tcp_probe0_when(sk, TCP_RTO_MAX);
 
-               tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0,
-                                    when, TCP_RTO_MAX);
+               when = tcp_clamp_probe0_to_user_timeout(sk, when);
+               tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, when, TCP_RTO_MAX);
        }
 }
 
@@ -3816,9 +3817,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
 
        if (tp->tlp_high_seq)
                tcp_process_tlp_ack(sk, ack, flag);
-       /* If needed, reset TLP/RTO timer; RACK may later override this. */
-       if (flag & FLAG_SET_XMIT_TIMER)
-               tcp_set_xmit_timer(sk);
 
        if (tcp_ack_is_dubious(sk, flag)) {
                if (!(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP))) {
@@ -3831,6 +3829,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
                                      &rexmit);
        }
 
+       /* If needed, reset TLP/RTO timer when RACK doesn't set. */
+       if (flag & FLAG_SET_XMIT_TIMER)
+               tcp_set_xmit_timer(sk);
+
        if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP))
                sk_dst_confirm(sk);
 
index ab458697881eda4503d6f223480deadf754d2d22..8478cf749821ade9c1abf52406634ed15be03a25 100644 (file)
@@ -4099,6 +4099,8 @@ void tcp_send_probe0(struct sock *sk)
                 */
                timeout = TCP_RESOURCE_PROBE_INTERVAL;
        }
+
+       timeout = tcp_clamp_probe0_to_user_timeout(sk, timeout);
        tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, timeout, TCP_RTO_MAX);
 }
 
index 177307a3081f9583e5e488e1a1d73035fb4bc3fd..6f1b4ac7fe99c4b256d45e23f7b96509dd597e77 100644 (file)
@@ -96,13 +96,13 @@ static void tcp_rack_detect_loss(struct sock *sk, u32 *reo_timeout)
        }
 }
 
-void tcp_rack_mark_lost(struct sock *sk)
+bool tcp_rack_mark_lost(struct sock *sk)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        u32 timeout;
 
        if (!tp->rack.advanced)
-               return;
+               return false;
 
        /* Reset the advanced flag to avoid unnecessary queue scanning */
        tp->rack.advanced = 0;
@@ -112,6 +112,7 @@ void tcp_rack_mark_lost(struct sock *sk)
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_REO_TIMEOUT,
                                          timeout, inet_csk(sk)->icsk_rto);
        }
+       return !!timeout;
 }
 
 /* Record the most recently (re)sent time among the (s)acked packets
index faa92948441ba28a821034f18a6e4cc252da2c99..4ef08079ccfa9d0e68f046b3cb329e7e3efdf1ff 100644 (file)
@@ -40,6 +40,24 @@ static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk)
        return min_t(u32, icsk->icsk_rto, msecs_to_jiffies(remaining));
 }
 
+u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when)
+{
+       struct inet_connection_sock *icsk = inet_csk(sk);
+       u32 remaining;
+       s32 elapsed;
+
+       if (!icsk->icsk_user_timeout || !icsk->icsk_probes_tstamp)
+               return when;
+
+       elapsed = tcp_jiffies32 - icsk->icsk_probes_tstamp;
+       if (unlikely(elapsed < 0))
+               elapsed = 0;
+       remaining = msecs_to_jiffies(icsk->icsk_user_timeout) - elapsed;
+       remaining = max_t(u32, remaining, TCP_TIMEOUT_MIN);
+
+       return min_t(u32, remaining, when);
+}
+
 /**
  *  tcp_write_err() - close socket and save error info
  *  @sk:  The socket the error has appeared on.
index ff39e94781bfb825a6d24d7642424458550e6a12..cfc872689b9976d793ba5b893338ed323bf17c65 100644 (file)
@@ -187,8 +187,67 @@ out_unlock:
 }
 EXPORT_SYMBOL(skb_udp_tunnel_segment);
 
+static void __udpv4_gso_segment_csum(struct sk_buff *seg,
+                                    __be32 *oldip, __be32 *newip,
+                                    __be16 *oldport, __be16 *newport)
+{
+       struct udphdr *uh;
+       struct iphdr *iph;
+
+       if (*oldip == *newip && *oldport == *newport)
+               return;
+
+       uh = udp_hdr(seg);
+       iph = ip_hdr(seg);
+
+       if (uh->check) {
+               inet_proto_csum_replace4(&uh->check, seg, *oldip, *newip,
+                                        true);
+               inet_proto_csum_replace2(&uh->check, seg, *oldport, *newport,
+                                        false);
+               if (!uh->check)
+                       uh->check = CSUM_MANGLED_0;
+       }
+       *oldport = *newport;
+
+       csum_replace4(&iph->check, *oldip, *newip);
+       *oldip = *newip;
+}
+
+static struct sk_buff *__udpv4_gso_segment_list_csum(struct sk_buff *segs)
+{
+       struct sk_buff *seg;
+       struct udphdr *uh, *uh2;
+       struct iphdr *iph, *iph2;
+
+       seg = segs;
+       uh = udp_hdr(seg);
+       iph = ip_hdr(seg);
+
+       if ((udp_hdr(seg)->dest == udp_hdr(seg->next)->dest) &&
+           (udp_hdr(seg)->source == udp_hdr(seg->next)->source) &&
+           (ip_hdr(seg)->daddr == ip_hdr(seg->next)->daddr) &&
+           (ip_hdr(seg)->saddr == ip_hdr(seg->next)->saddr))
+               return segs;
+
+       while ((seg = seg->next)) {
+               uh2 = udp_hdr(seg);
+               iph2 = ip_hdr(seg);
+
+               __udpv4_gso_segment_csum(seg,
+                                        &iph2->saddr, &iph->saddr,
+                                        &uh2->source, &uh->source);
+               __udpv4_gso_segment_csum(seg,
+                                        &iph2->daddr, &iph->daddr,
+                                        &uh2->dest, &uh->dest);
+       }
+
+       return segs;
+}
+
 static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb,
-                                             netdev_features_t features)
+                                             netdev_features_t features,
+                                             bool is_ipv6)
 {
        unsigned int mss = skb_shinfo(skb)->gso_size;
 
@@ -198,11 +257,11 @@ static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb,
 
        udp_hdr(skb)->len = htons(sizeof(struct udphdr) + mss);
 
-       return skb;
+       return is_ipv6 ? skb : __udpv4_gso_segment_list_csum(skb);
 }
 
 struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
-                                 netdev_features_t features)
+                                 netdev_features_t features, bool is_ipv6)
 {
        struct sock *sk = gso_skb->sk;
        unsigned int sum_truesize = 0;
@@ -214,7 +273,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
        __be16 newlen;
 
        if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)
-               return __udp_gso_segment_list(gso_skb, features);
+               return __udp_gso_segment_list(gso_skb, features, is_ipv6);
 
        mss = skb_shinfo(gso_skb)->gso_size;
        if (gso_skb->len <= sizeof(*uh) + mss)
@@ -328,7 +387,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
                goto out;
 
        if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4)
-               return __udp_gso_segment(skb, features);
+               return __udp_gso_segment(skb, features, false);
 
        mss = skb_shinfo(skb)->gso_size;
        if (unlikely(skb->len <= mss))
index c7bd7b1a04c13fb2379edcadfa99152e09d11ba3..faa823c242923ff36ebd4b048bdb2d84728df0e7 100644 (file)
@@ -42,7 +42,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
                        goto out;
 
                if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4)
-                       return __udp_gso_segment(skb, features);
+                       return __udp_gso_segment(skb, features, true);
 
                mss = skb_shinfo(skb)->gso_size;
                if (unlikely(skb->len <= mss))
index c12dbc51ef5fe93b4a11c4b8e2a413c5e2dd0c85..ef9b4ac03e7b74e5ddad0ca2d3d337583fc25fee 100644 (file)
@@ -2902,7 +2902,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
                        break;
                if (!aalg->pfkey_supported)
                        continue;
-               if (aalg_tmpl_set(t, aalg) && aalg->available)
+               if (aalg_tmpl_set(t, aalg))
                        sz += sizeof(struct sadb_comb);
        }
        return sz + sizeof(struct sadb_prop);
@@ -2920,7 +2920,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
                if (!ealg->pfkey_supported)
                        continue;
 
-               if (!(ealg_tmpl_set(t, ealg) && ealg->available))
+               if (!(ealg_tmpl_set(t, ealg)))
                        continue;
 
                for (k = 1; ; k++) {
@@ -2931,7 +2931,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
                        if (!aalg->pfkey_supported)
                                continue;
 
-                       if (aalg_tmpl_set(t, aalg) && aalg->available)
+                       if (aalg_tmpl_set(t, aalg))
                                sz += sizeof(struct sadb_comb);
                }
        }
index 40961889e9c01add01792690e61c16a04647cc4c..0511bbe4af7b4f6421de932a95bd72b55d4f8182 100644 (file)
@@ -122,6 +122,8 @@ static struct lapb_cb *lapb_create_cb(void)
 
        timer_setup(&lapb->t1timer, NULL, 0);
        timer_setup(&lapb->t2timer, NULL, 0);
+       lapb->t1timer_stop = true;
+       lapb->t2timer_stop = true;
 
        lapb->t1      = LAPB_DEFAULT_T1;
        lapb->t2      = LAPB_DEFAULT_T2;
@@ -129,6 +131,8 @@ static struct lapb_cb *lapb_create_cb(void)
        lapb->mode    = LAPB_DEFAULT_MODE;
        lapb->window  = LAPB_DEFAULT_WINDOW;
        lapb->state   = LAPB_STATE_0;
+
+       spin_lock_init(&lapb->lock);
        refcount_set(&lapb->refcnt, 1);
 out:
        return lapb;
@@ -178,11 +182,23 @@ int lapb_unregister(struct net_device *dev)
                goto out;
        lapb_put(lapb);
 
+       /* Wait for other refs to "lapb" to drop */
+       while (refcount_read(&lapb->refcnt) > 2)
+               usleep_range(1, 10);
+
+       spin_lock_bh(&lapb->lock);
+
        lapb_stop_t1timer(lapb);
        lapb_stop_t2timer(lapb);
 
        lapb_clear_queues(lapb);
 
+       spin_unlock_bh(&lapb->lock);
+
+       /* Wait for running timers to stop */
+       del_timer_sync(&lapb->t1timer);
+       del_timer_sync(&lapb->t2timer);
+
        __lapb_remove_cb(lapb);
 
        lapb_put(lapb);
@@ -201,6 +217,8 @@ int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms)
        if (!lapb)
                goto out;
 
+       spin_lock_bh(&lapb->lock);
+
        parms->t1      = lapb->t1 / HZ;
        parms->t2      = lapb->t2 / HZ;
        parms->n2      = lapb->n2;
@@ -219,6 +237,7 @@ int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms)
        else
                parms->t2timer = (lapb->t2timer.expires - jiffies) / HZ;
 
+       spin_unlock_bh(&lapb->lock);
        lapb_put(lapb);
        rc = LAPB_OK;
 out:
@@ -234,6 +253,8 @@ int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms)
        if (!lapb)
                goto out;
 
+       spin_lock_bh(&lapb->lock);
+
        rc = LAPB_INVALUE;
        if (parms->t1 < 1 || parms->t2 < 1 || parms->n2 < 1)
                goto out_put;
@@ -256,6 +277,7 @@ int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms)
 
        rc = LAPB_OK;
 out_put:
+       spin_unlock_bh(&lapb->lock);
        lapb_put(lapb);
 out:
        return rc;
@@ -270,6 +292,8 @@ int lapb_connect_request(struct net_device *dev)
        if (!lapb)
                goto out;
 
+       spin_lock_bh(&lapb->lock);
+
        rc = LAPB_OK;
        if (lapb->state == LAPB_STATE_1)
                goto out_put;
@@ -285,24 +309,18 @@ int lapb_connect_request(struct net_device *dev)
 
        rc = LAPB_OK;
 out_put:
+       spin_unlock_bh(&lapb->lock);
        lapb_put(lapb);
 out:
        return rc;
 }
 EXPORT_SYMBOL(lapb_connect_request);
 
-int lapb_disconnect_request(struct net_device *dev)
+static int __lapb_disconnect_request(struct lapb_cb *lapb)
 {
-       struct lapb_cb *lapb = lapb_devtostruct(dev);
-       int rc = LAPB_BADTOKEN;
-
-       if (!lapb)
-               goto out;
-
        switch (lapb->state) {
        case LAPB_STATE_0:
-               rc = LAPB_NOTCONNECTED;
-               goto out_put;
+               return LAPB_NOTCONNECTED;
 
        case LAPB_STATE_1:
                lapb_dbg(1, "(%p) S1 TX DISC(1)\n", lapb->dev);
@@ -310,12 +328,10 @@ int lapb_disconnect_request(struct net_device *dev)
                lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
                lapb->state = LAPB_STATE_0;
                lapb_start_t1timer(lapb);
-               rc = LAPB_NOTCONNECTED;
-               goto out_put;
+               return LAPB_NOTCONNECTED;
 
        case LAPB_STATE_2:
-               rc = LAPB_OK;
-               goto out_put;
+               return LAPB_OK;
        }
 
        lapb_clear_queues(lapb);
@@ -328,8 +344,22 @@ int lapb_disconnect_request(struct net_device *dev)
        lapb_dbg(1, "(%p) S3 DISC(1)\n", lapb->dev);
        lapb_dbg(0, "(%p) S3 -> S2\n", lapb->dev);
 
-       rc = LAPB_OK;
-out_put:
+       return LAPB_OK;
+}
+
+int lapb_disconnect_request(struct net_device *dev)
+{
+       struct lapb_cb *lapb = lapb_devtostruct(dev);
+       int rc = LAPB_BADTOKEN;
+
+       if (!lapb)
+               goto out;
+
+       spin_lock_bh(&lapb->lock);
+
+       rc = __lapb_disconnect_request(lapb);
+
+       spin_unlock_bh(&lapb->lock);
        lapb_put(lapb);
 out:
        return rc;
@@ -344,6 +374,8 @@ int lapb_data_request(struct net_device *dev, struct sk_buff *skb)
        if (!lapb)
                goto out;
 
+       spin_lock_bh(&lapb->lock);
+
        rc = LAPB_NOTCONNECTED;
        if (lapb->state != LAPB_STATE_3 && lapb->state != LAPB_STATE_4)
                goto out_put;
@@ -352,6 +384,7 @@ int lapb_data_request(struct net_device *dev, struct sk_buff *skb)
        lapb_kick(lapb);
        rc = LAPB_OK;
 out_put:
+       spin_unlock_bh(&lapb->lock);
        lapb_put(lapb);
 out:
        return rc;
@@ -364,7 +397,9 @@ int lapb_data_received(struct net_device *dev, struct sk_buff *skb)
        int rc = LAPB_BADTOKEN;
 
        if (lapb) {
+               spin_lock_bh(&lapb->lock);
                lapb_data_input(lapb, skb);
+               spin_unlock_bh(&lapb->lock);
                lapb_put(lapb);
                rc = LAPB_OK;
        }
@@ -435,6 +470,8 @@ static int lapb_device_event(struct notifier_block *this, unsigned long event,
        if (!lapb)
                return NOTIFY_DONE;
 
+       spin_lock_bh(&lapb->lock);
+
        switch (event) {
        case NETDEV_UP:
                lapb_dbg(0, "(%p) Interface up: %s\n", dev, dev->name);
@@ -454,7 +491,7 @@ static int lapb_device_event(struct notifier_block *this, unsigned long event,
                break;
        case NETDEV_GOING_DOWN:
                if (netif_carrier_ok(dev))
-                       lapb_disconnect_request(dev);
+                       __lapb_disconnect_request(lapb);
                break;
        case NETDEV_DOWN:
                lapb_dbg(0, "(%p) Interface down: %s\n", dev, dev->name);
@@ -489,6 +526,7 @@ static int lapb_device_event(struct notifier_block *this, unsigned long event,
                break;
        }
 
+       spin_unlock_bh(&lapb->lock);
        lapb_put(lapb);
        return NOTIFY_DONE;
 }
index 7a4d0715d1c32b842a7ba781da5f774d107ad92d..a966d29c772d9f09e73350718468e3e1a4331160 100644 (file)
@@ -82,7 +82,8 @@ void lapb_kick(struct lapb_cb *lapb)
                skb = skb_dequeue(&lapb->write_queue);
 
                do {
-                       if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+                       skbn = skb_copy(skb, GFP_ATOMIC);
+                       if (!skbn) {
                                skb_queue_head(&lapb->write_queue, skb);
                                break;
                        }
index baa247fe4ed057a13b3a1fb257bf5685570f35f4..0230b272b7d1db9ef1864f4f6a57948593f61346 100644 (file)
@@ -40,6 +40,7 @@ void lapb_start_t1timer(struct lapb_cb *lapb)
        lapb->t1timer.function = lapb_t1timer_expiry;
        lapb->t1timer.expires  = jiffies + lapb->t1;
 
+       lapb->t1timer_stop = false;
        add_timer(&lapb->t1timer);
 }
 
@@ -50,16 +51,19 @@ void lapb_start_t2timer(struct lapb_cb *lapb)
        lapb->t2timer.function = lapb_t2timer_expiry;
        lapb->t2timer.expires  = jiffies + lapb->t2;
 
+       lapb->t2timer_stop = false;
        add_timer(&lapb->t2timer);
 }
 
 void lapb_stop_t1timer(struct lapb_cb *lapb)
 {
+       lapb->t1timer_stop = true;
        del_timer(&lapb->t1timer);
 }
 
 void lapb_stop_t2timer(struct lapb_cb *lapb)
 {
+       lapb->t2timer_stop = true;
        del_timer(&lapb->t2timer);
 }
 
@@ -72,16 +76,31 @@ static void lapb_t2timer_expiry(struct timer_list *t)
 {
        struct lapb_cb *lapb = from_timer(lapb, t, t2timer);
 
+       spin_lock_bh(&lapb->lock);
+       if (timer_pending(&lapb->t2timer)) /* A new timer has been set up */
+               goto out;
+       if (lapb->t2timer_stop) /* The timer has been stopped */
+               goto out;
+
        if (lapb->condition & LAPB_ACK_PENDING_CONDITION) {
                lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
                lapb_timeout_response(lapb);
        }
+
+out:
+       spin_unlock_bh(&lapb->lock);
 }
 
 static void lapb_t1timer_expiry(struct timer_list *t)
 {
        struct lapb_cb *lapb = from_timer(lapb, t, t1timer);
 
+       spin_lock_bh(&lapb->lock);
+       if (timer_pending(&lapb->t1timer)) /* A new timer has been set up */
+               goto out;
+       if (lapb->t1timer_stop) /* The timer has been stopped */
+               goto out;
+
        switch (lapb->state) {
 
                /*
@@ -108,7 +127,7 @@ static void lapb_t1timer_expiry(struct timer_list *t)
                                lapb->state = LAPB_STATE_0;
                                lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
                                lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev);
-                               return;
+                               goto out;
                        } else {
                                lapb->n2count++;
                                if (lapb->mode & LAPB_EXTENDED) {
@@ -132,7 +151,7 @@ static void lapb_t1timer_expiry(struct timer_list *t)
                                lapb->state = LAPB_STATE_0;
                                lapb_disconnect_confirmation(lapb, LAPB_TIMEDOUT);
                                lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
-                               return;
+                               goto out;
                        } else {
                                lapb->n2count++;
                                lapb_dbg(1, "(%p) S2 TX DISC(1)\n", lapb->dev);
@@ -150,7 +169,7 @@ static void lapb_t1timer_expiry(struct timer_list *t)
                                lapb_stop_t2timer(lapb);
                                lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
                                lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
-                               return;
+                               goto out;
                        } else {
                                lapb->n2count++;
                                lapb_requeue_frames(lapb);
@@ -167,7 +186,7 @@ static void lapb_t1timer_expiry(struct timer_list *t)
                                lapb->state = LAPB_STATE_0;
                                lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
                                lapb_dbg(0, "(%p) S4 -> S0\n", lapb->dev);
-                               return;
+                               goto out;
                        } else {
                                lapb->n2count++;
                                lapb_transmit_frmr(lapb);
@@ -176,4 +195,7 @@ static void lapb_t1timer_expiry(struct timer_list *t)
        }
 
        lapb_start_t1timer(lapb);
+
+out:
+       spin_unlock_bh(&lapb->lock);
 }
index c9a8a2433e8ac51f9c63827887113b357ea23a95..48322e45e7ddb56f82a6c762fed757368cbdeb91 100644 (file)
@@ -125,8 +125,11 @@ int drv_sta_state(struct ieee80211_local *local,
        } else if (old_state == IEEE80211_STA_AUTH &&
                   new_state == IEEE80211_STA_ASSOC) {
                ret = drv_sta_add(local, sdata, &sta->sta);
-               if (ret == 0)
+               if (ret == 0) {
                        sta->uploaded = true;
+                       if (rcu_access_pointer(sta->sta.rates))
+                               drv_sta_rate_tbl_update(local, sdata, &sta->sta);
+               }
        } else if (old_state == IEEE80211_STA_ASSOC &&
                   new_state == IEEE80211_STA_AUTH) {
                drv_sta_remove(local, sdata, &sta->sta);
index 8bf9c0e974d6284390840970f0bdcecbd9476423..8e281c2e644d5ebc75aa4529e3bb996bea0c8fc1 100644 (file)
@@ -1078,6 +1078,7 @@ enum queue_stop_reason {
        IEEE80211_QUEUE_STOP_REASON_FLUSH,
        IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN,
        IEEE80211_QUEUE_STOP_REASON_RESERVE_TID,
+       IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE,
 
        IEEE80211_QUEUE_STOP_REASONS,
 };
index 3b9ec4ef81c3baa6d44261dd339e4fe6964b56d9..b31417f40bd56f4df116c7b91647275883eb86a8 100644 (file)
@@ -1617,6 +1617,10 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
        if (ret)
                return ret;
 
+       ieee80211_stop_vif_queues(local, sdata,
+                                 IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE);
+       synchronize_net();
+
        ieee80211_do_stop(sdata, false);
 
        ieee80211_teardown_sdata(sdata);
@@ -1639,6 +1643,8 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
        err = ieee80211_do_open(&sdata->wdev, false);
        WARN(err, "type change: do_open returned %d", err);
 
+       ieee80211_wake_vif_queues(local, sdata,
+                                 IEEE80211_QUEUE_STOP_REASON_IFTYPE_CHANGE);
        return ret;
 }
 
index 45927202c71c6e0664331e2347cb40c9ed1170c3..63652c39c8e07df537901b3f19a4e6d979d4c5a3 100644 (file)
@@ -960,7 +960,8 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
        if (old)
                kfree_rcu(old, rcu_head);
 
-       drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
+       if (sta->uploaded)
+               drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
 
        ieee80211_sta_set_expected_throughput(pubsta, sta_get_expected_throughput(sta));
 
index ae1cb2c6872245e03d7f9805cb4e46c2c6ad52b2..76747bfdaddd08ec02e207a0fb603976b443dafe 100644 (file)
@@ -133,16 +133,20 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
        }
 
        if (wide_bw_chansw_ie) {
+               u8 new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1;
                struct ieee80211_vht_operation vht_oper = {
                        .chan_width =
                                wide_bw_chansw_ie->new_channel_width,
                        .center_freq_seg0_idx =
                                wide_bw_chansw_ie->new_center_freq_seg0,
-                       .center_freq_seg1_idx =
-                               wide_bw_chansw_ie->new_center_freq_seg1,
+                       .center_freq_seg1_idx = new_seg1,
                        /* .basic_mcs_set doesn't matter */
                };
-               struct ieee80211_ht_operation ht_oper = {};
+               struct ieee80211_ht_operation ht_oper = {
+                       .operation_mode =
+                               cpu_to_le16(new_seg1 <<
+                                           IEEE80211_HT_OP_MODE_CCFS2_SHIFT),
+               };
 
                /* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT,
                 * to the previously parsed chandef
index 15c467f1a9dd9daf84b8d3b21f0f070924d06fb5..8d3aa97b52e71950ed34eacb9dc69d0cee1ab7ef 100644 (file)
@@ -5235,9 +5235,8 @@ static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
        kfree(elem);
 }
 
-static int nft_set_elem_expr_clone(const struct nft_ctx *ctx,
-                                  struct nft_set *set,
-                                  struct nft_expr *expr_array[])
+int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
+                           struct nft_expr *expr_array[])
 {
        struct nft_expr *expr;
        int err, i, k;
index 0b053f75cd6047c1ba619dc540b7cf544699786d..d164ef9e6843976b8abcfd65ce95f3a37ade2b35 100644 (file)
@@ -295,6 +295,12 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
                        err = -EOPNOTSUPP;
                        goto err_expr_free;
                }
+       } else if (set->num_exprs > 0) {
+               err = nft_set_elem_expr_clone(ctx, set, priv->expr_array);
+               if (err < 0)
+                       return err;
+
+               priv->num_exprs = set->num_exprs;
        }
 
        nft_set_ext_prepare(&priv->tmpl);
@@ -306,8 +312,10 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
                nft_dynset_ext_add_expr(priv);
 
        if (set->flags & NFT_SET_TIMEOUT) {
-               if (timeout || set->timeout)
+               if (timeout || set->timeout) {
+                       nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
                        nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
+               }
        }
 
        priv->timeout = timeout;
@@ -376,22 +384,25 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
                         nf_jiffies64_to_msecs(priv->timeout),
                         NFTA_DYNSET_PAD))
                goto nla_put_failure;
-       if (priv->num_exprs == 1) {
-               if (nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr_array[0]))
-                       goto nla_put_failure;
-       } else if (priv->num_exprs > 1) {
-               struct nlattr *nest;
-
-               nest = nla_nest_start_noflag(skb, NFTA_DYNSET_EXPRESSIONS);
-               if (!nest)
-                       goto nla_put_failure;
-
-               for (i = 0; i < priv->num_exprs; i++) {
-                       if (nft_expr_dump(skb, NFTA_LIST_ELEM,
-                                         priv->expr_array[i]))
+       if (priv->set->num_exprs == 0) {
+               if (priv->num_exprs == 1) {
+                       if (nft_expr_dump(skb, NFTA_DYNSET_EXPR,
+                                         priv->expr_array[0]))
                                goto nla_put_failure;
+               } else if (priv->num_exprs > 1) {
+                       struct nlattr *nest;
+
+                       nest = nla_nest_start_noflag(skb, NFTA_DYNSET_EXPRESSIONS);
+                       if (!nest)
+                               goto nla_put_failure;
+
+                       for (i = 0; i < priv->num_exprs; i++) {
+                               if (nft_expr_dump(skb, NFTA_LIST_ELEM,
+                                                 priv->expr_array[i]))
+                                       goto nla_put_failure;
+                       }
+                       nla_nest_end(skb, nest);
                }
-               nla_nest_end(skb, nest);
        }
        if (nla_put_be32(skb, NFTA_DYNSET_FLAGS, htonl(flags)))
                goto nla_put_failure;
index 573b38ad2f8ed91e1f46d12213d7890cf9ca2c6c..e161ef2d4720d523ea5ff62e598bafd99872db97 100644 (file)
@@ -852,6 +852,7 @@ static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
 
        if (!dev->polling) {
                device_unlock(&dev->dev);
+               nfc_put_device(dev);
                return -EINVAL;
        }
 
index 955c195ae14bcf5adbd0cc9c94989c890dc8d6da..9c7eb8455ba8eb275133f0d0bfc0b8d5a6fbdd70 100644 (file)
@@ -105,7 +105,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
        if (addr->target_idx > dev->target_next_idx - 1 ||
            addr->target_idx < dev->target_next_idx - dev->n_targets) {
                rc = -EINVAL;
-               goto error;
+               goto put_dev;
        }
 
        rc = nfc_activate_target(dev, addr->target_idx, addr->nfc_protocol);
index 1d0afb1dd77b5cfc78b46a88451b15c4f1a44069..6f1a50d50d06da3924370492bc829e4391fd3d9c 100644 (file)
@@ -565,6 +565,9 @@ int rds_rdma_extra_size(struct rds_rdma_args *args,
        if (args->nr_local == 0)
                return -EINVAL;
 
+       if (args->nr_local > UIO_MAXIOV)
+               return -EMSGSIZE;
+
        iov->iov = kcalloc(args->nr_local,
                           sizeof(struct rds_iovec),
                           GFP_KERNEL);
index 0a2f4817ec6cf2b8b2847aa26ccd7f16e4c6f10d..41671af6b33f91e9f77af4dc0c9d8f813247e4f3 100644 (file)
@@ -990,7 +990,7 @@ static int __init af_rxrpc_init(void)
                goto error_security;
        }
 
-       ret = register_pernet_subsys(&rxrpc_net_ops);
+       ret = register_pernet_device(&rxrpc_net_ops);
        if (ret)
                goto error_pernet;
 
@@ -1035,7 +1035,7 @@ error_key_type:
 error_sock:
        proto_unregister(&rxrpc_proto);
 error_proto:
-       unregister_pernet_subsys(&rxrpc_net_ops);
+       unregister_pernet_device(&rxrpc_net_ops);
 error_pernet:
        rxrpc_exit_security();
 error_security:
@@ -1057,7 +1057,7 @@ static void __exit af_rxrpc_exit(void)
        unregister_key_type(&key_type_rxrpc);
        sock_unregister(PF_RXRPC);
        proto_unregister(&rxrpc_proto);
-       unregister_pernet_subsys(&rxrpc_net_ops);
+       unregister_pernet_device(&rxrpc_net_ops);
        ASSERTCMP(atomic_read(&rxrpc_n_tx_skbs), ==, 0);
        ASSERTCMP(atomic_read(&rxrpc_n_rx_skbs), ==, 0);
 
index 382add72c66f6df606c552d4109fa3aa9bfcb6aa..1ae90fb979362b8a585b5a5f984de91ba871220e 100644 (file)
@@ -197,6 +197,7 @@ void rxrpc_discard_prealloc(struct rxrpc_sock *rx)
        tail = b->peer_backlog_tail;
        while (CIRC_CNT(head, tail, size) > 0) {
                struct rxrpc_peer *peer = b->peer_backlog[tail];
+               rxrpc_put_local(peer->local);
                kfree(peer);
                tail = (tail + 1) & (size - 1);
        }
index 4ecc2a9595674a783140cc22e862fe5e6c5dc34e..5f42aa5fc612850b526c160ab5e5c75416862676 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/uaccess.h>
 #include <linux/hashtable.h>
 
+#include "auth_gss_internal.h"
 #include "../netns.h"
 
 #include <trace/events/rpcgss.h>
@@ -125,35 +126,6 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
        clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
 }
 
-static const void *
-simple_get_bytes(const void *p, const void *end, void *res, size_t len)
-{
-       const void *q = (const void *)((const char *)p + len);
-       if (unlikely(q > end || q < p))
-               return ERR_PTR(-EFAULT);
-       memcpy(res, p, len);
-       return q;
-}
-
-static inline const void *
-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
-{
-       const void *q;
-       unsigned int len;
-
-       p = simple_get_bytes(p, end, &len, sizeof(len));
-       if (IS_ERR(p))
-               return p;
-       q = (const void *)((const char *)p + len);
-       if (unlikely(q > end || q < p))
-               return ERR_PTR(-EFAULT);
-       dest->data = kmemdup(p, len, GFP_NOFS);
-       if (unlikely(dest->data == NULL))
-               return ERR_PTR(-ENOMEM);
-       dest->len = len;
-       return q;
-}
-
 static struct gss_cl_ctx *
 gss_cred_get_ctx(struct rpc_cred *cred)
 {
diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h
new file mode 100644 (file)
index 0000000..f6d9631
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * linux/net/sunrpc/auth_gss/auth_gss_internal.h
+ *
+ * Internal definitions for RPCSEC_GSS client authentication
+ *
+ * Copyright (c) 2000 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ */
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/sunrpc/xdr.h>
+
+static inline const void *
+simple_get_bytes(const void *p, const void *end, void *res, size_t len)
+{
+       const void *q = (const void *)((const char *)p + len);
+       if (unlikely(q > end || q < p))
+               return ERR_PTR(-EFAULT);
+       memcpy(res, p, len);
+       return q;
+}
+
+static inline const void *
+simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
+{
+       const void *q;
+       unsigned int len;
+
+       p = simple_get_bytes(p, end, &len, sizeof(len));
+       if (IS_ERR(p))
+               return p;
+       q = (const void *)((const char *)p + len);
+       if (unlikely(q > end || q < p))
+               return ERR_PTR(-EFAULT);
+       if (len) {
+               dest->data = kmemdup(p, len, GFP_NOFS);
+               if (unlikely(dest->data == NULL))
+                       return ERR_PTR(-ENOMEM);
+       } else
+               dest->data = NULL;
+       dest->len = len;
+       return q;
+}
index ae9acf3a73898dea708cbb01fd7cc76e8815abc9..1c092b05c2bba01e8181a4140d58eee2f1b057b7 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/gss_krb5_enctypes.h>
 
+#include "auth_gss_internal.h"
+
 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
 # define RPCDBG_FACILITY       RPCDBG_AUTH
 #endif
@@ -143,35 +145,6 @@ get_gss_krb5_enctype(int etype)
        return NULL;
 }
 
-static const void *
-simple_get_bytes(const void *p, const void *end, void *res, int len)
-{
-       const void *q = (const void *)((const char *)p + len);
-       if (unlikely(q > end || q < p))
-               return ERR_PTR(-EFAULT);
-       memcpy(res, p, len);
-       return q;
-}
-
-static const void *
-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
-{
-       const void *q;
-       unsigned int len;
-
-       p = simple_get_bytes(p, end, &len, sizeof(len));
-       if (IS_ERR(p))
-               return p;
-       q = (const void *)((const char *)p + len);
-       if (unlikely(q > end || q < p))
-               return ERR_PTR(-EFAULT);
-       res->data = kmemdup(p, len, GFP_NOFS);
-       if (unlikely(res->data == NULL))
-               return ERR_PTR(-ENOMEM);
-       res->len = len;
-       return q;
-}
-
 static inline const void *
 get_key(const void *p, const void *end,
        struct krb5_ctx *ctx, struct crypto_sync_skcipher **res)
index c9766d07eb81a1cdee4cad8bfc4a393114543e6f..5a809c64dc7b9c5673969da158f1453e62a03d16 100644 (file)
@@ -1113,14 +1113,15 @@ static int svc_tcp_sendmsg(struct socket *sock, struct msghdr *msg,
                unsigned int offset, len, remaining;
                struct bio_vec *bvec;
 
-               bvec = xdr->bvec;
-               offset = xdr->page_base;
+               bvec = xdr->bvec + (xdr->page_base >> PAGE_SHIFT);
+               offset = offset_in_page(xdr->page_base);
                remaining = xdr->page_len;
                flags = MSG_MORE | MSG_SENDPAGE_NOTLAST;
                while (remaining > 0) {
                        if (remaining <= PAGE_SIZE && tail->iov_len == 0)
                                flags = 0;
-                       len = min(remaining, bvec->bv_len);
+
+                       len = min(remaining, bvec->bv_len - offset);
                        ret = kernel_sendpage(sock, bvec->bv_page,
                                              bvec->bv_offset + offset,
                                              len, flags);
index 23d8685453627c569cc9aa1af5297f6318df4cad..2c1ffc9ba2eb2567da09139aa204e9c6db8f2d20 100644 (file)
@@ -460,10 +460,11 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev,
        extack = switchdev_notifier_info_to_extack(&port_obj_info->info);
 
        if (check_cb(dev)) {
-               /* This flag is only checked if the return value is success. */
-               port_obj_info->handled = true;
-               return add_cb(dev, port_obj_info->obj, port_obj_info->trans,
-                             extack);
+               err = add_cb(dev, port_obj_info->obj, port_obj_info->trans,
+                            extack);
+               if (err != -EOPNOTSUPP)
+                       port_obj_info->handled = true;
+               return err;
        }
 
        /* Switch ports might be stacked under e.g. a LAG. Ignore the
@@ -515,9 +516,10 @@ static int __switchdev_handle_port_obj_del(struct net_device *dev,
        int err = -EOPNOTSUPP;
 
        if (check_cb(dev)) {
-               /* This flag is only checked if the return value is success. */
-               port_obj_info->handled = true;
-               return del_cb(dev, port_obj_info->obj);
+               err = del_cb(dev, port_obj_info->obj);
+               if (err != -EOPNOTSUPP)
+                       port_obj_info->handled = true;
+               return err;
        }
 
        /* Switch ports might be stacked under e.g. a LAG. Ignore the
@@ -568,9 +570,10 @@ static int __switchdev_handle_port_attr_set(struct net_device *dev,
        int err = -EOPNOTSUPP;
 
        if (check_cb(dev)) {
-               port_attr_info->handled = true;
-               return set_cb(dev, port_attr_info->attr,
-                             port_attr_info->trans);
+               err = set_cb(dev, port_attr_info->attr, port_attr_info->trans);
+               if (err != -EOPNOTSUPP)
+                       port_attr_info->handled = true;
+               return err;
        }
 
        /* Switch ports might be stacked under e.g. a LAG. Ignore the
index b12d3a32224280e838827fc7ee25f931d5c7d549..6894f21dc147557ed1540120b1045d6e9d9956f3 100644 (file)
@@ -1014,9 +1014,12 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
                        mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
 
        } else if (sock->type == SOCK_STREAM) {
-               const struct vsock_transport *transport = vsk->transport;
+               const struct vsock_transport *transport;
+
                lock_sock(sk);
 
+               transport = vsk->transport;
+
                /* Listening sockets that have connections in their accept
                 * queue can be read.
                 */
@@ -1099,10 +1102,11 @@ static int vsock_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
        err = 0;
        sk = sock->sk;
        vsk = vsock_sk(sk);
-       transport = vsk->transport;
 
        lock_sock(sk);
 
+       transport = vsk->transport;
+
        err = vsock_auto_bind(vsk);
        if (err)
                goto out;
@@ -1561,10 +1565,11 @@ static int vsock_stream_setsockopt(struct socket *sock,
        err = 0;
        sk = sock->sk;
        vsk = vsock_sk(sk);
-       transport = vsk->transport;
 
        lock_sock(sk);
 
+       transport = vsk->transport;
+
        switch (optname) {
        case SO_VM_SOCKETS_BUFFER_SIZE:
                COPY_IN(val);
@@ -1697,7 +1702,6 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 
        sk = sock->sk;
        vsk = vsock_sk(sk);
-       transport = vsk->transport;
        total_written = 0;
        err = 0;
 
@@ -1706,6 +1710,8 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 
        lock_sock(sk);
 
+       transport = vsk->transport;
+
        /* Callers should not provide a destination with stream sockets. */
        if (msg->msg_namelen) {
                err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
@@ -1840,11 +1846,12 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 
        sk = sock->sk;
        vsk = vsock_sk(sk);
-       transport = vsk->transport;
        err = 0;
 
        lock_sock(sk);
 
+       transport = vsk->transport;
+
        if (!transport || sk->sk_state != TCP_ESTABLISHED) {
                /* Recvmsg is supposed to return 0 if a peer performs an
                 * orderly shutdown. Differentiate between that case and when a
index 69102fda9ebd46343a0444d7206799223e24a0fd..76a80a41615befda05f5e62a8b5f2ba1a2253d04 100644 (file)
@@ -896,8 +896,9 @@ out:
 int call_commit_handler(struct net_device *dev)
 {
 #ifdef CONFIG_WIRELESS_EXT
-       if ((netif_running(dev)) &&
-          (dev->wireless_handlers->standard[0] != NULL))
+       if (netif_running(dev) &&
+           dev->wireless_handlers &&
+           dev->wireless_handlers->standard[0])
                /* Call the commit handler on the driver */
                return dev->wireless_handlers->standard[0](dev, NULL,
                                                           NULL, NULL);
index be6351e3f3cdfaa6c15d1b824907042d0365731d..1158cd0311d7d0efef498b9b8b6ffa3c8fd241a1 100644 (file)
@@ -660,7 +660,7 @@ resume:
                /* only the first xfrm gets the encap type */
                encap_type = 0;
 
-               if (async && x->repl->recheck(x, skb, seq)) {
+               if (x->repl->recheck(x, skb, seq)) {
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
                        goto drop_unlock;
                }
index d622c2548d2295c0893b1b5fcbd84862f95fb8ea..b74f28cabe24f245266f97f32428edc2cb68673b 100644 (file)
@@ -793,15 +793,22 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a,
                                  const xfrm_address_t *b,
                                  u8 prefixlen, u16 family)
 {
+       u32 ma, mb, mask;
        unsigned int pdw, pbi;
        int delta = 0;
 
        switch (family) {
        case AF_INET:
-               if (sizeof(long) == 4 && prefixlen == 0)
-                       return ntohl(a->a4) - ntohl(b->a4);
-               return (ntohl(a->a4) & ((~0UL << (32 - prefixlen)))) -
-                      (ntohl(b->a4) & ((~0UL << (32 - prefixlen))));
+               if (prefixlen == 0)
+                       return 0;
+               mask = ~0U << (32 - prefixlen);
+               ma = ntohl(a->a4) & mask;
+               mb = ntohl(b->a4) & mask;
+               if (ma < mb)
+                       delta = -1;
+               else if (ma > mb)
+                       delta = 1;
+               break;
        case AF_INET6:
                pdw = prefixlen >> 5;
                pbi = prefixlen & 0x1f;
@@ -812,10 +819,13 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a,
                                return delta;
                }
                if (pbi) {
-                       u32 mask = ~0u << (32 - pbi);
-
-                       delta = (ntohl(a->a6[pdw]) & mask) -
-                               (ntohl(b->a6[pdw]) & mask);
+                       mask = ~0U << (32 - pbi);
+                       ma = ntohl(a->a6[pdw]) & mask;
+                       mb = ntohl(b->a6[pdw]) & mask;
+                       if (ma < mb)
+                               delta = -1;
+                       else if (ma > mb)
+                               delta = 1;
                }
                break;
        default:
@@ -3078,8 +3088,8 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
                xflo.flags = flags;
 
                /* To accelerate a bit...  */
-               if ((dst_orig->flags & DST_NOXFRM) ||
-                   !net->xfrm.policy_count[XFRM_POLICY_OUT])
+               if (!if_id && ((dst_orig->flags & DST_NOXFRM) ||
+                              !net->xfrm.policy_count[XFRM_POLICY_OUT]))
                        goto nopol;
 
                xdst = xfrm_bundle_lookup(net, fl, family, dir, &xflo, if_id);
index b5418ec587fbd2cd6ca6896b8868b93f12e59ef3..9de3c03b94aa763ec76e2bb9c2fe17cd0b66152a 100644 (file)
@@ -3,6 +3,9 @@
 # scripts contains sources for various helper programs used throughout
 # the kernel for the build process.
 
+CRYPTO_LIBS = $(shell pkg-config --libs libcrypto 2> /dev/null || echo -lcrypto)
+CRYPTO_CFLAGS = $(shell pkg-config --cflags libcrypto 2> /dev/null)
+
 hostprogs-always-$(CONFIG_BUILD_BIN2C)                 += bin2c
 hostprogs-always-$(CONFIG_KALLSYMS)                    += kallsyms
 hostprogs-always-$(BUILD_C_RECORDMCOUNT)               += recordmcount
@@ -14,8 +17,9 @@ hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)   += insert-sys-cert
 
 HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
 HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
-HOSTLDLIBS_sign-file = -lcrypto
-HOSTLDLIBS_extract-cert = -lcrypto
+HOSTLDLIBS_sign-file = $(CRYPTO_LIBS)
+HOSTCFLAGS_extract-cert.o = $(CRYPTO_CFLAGS)
+HOSTLDLIBS_extract-cert = $(CRYPTO_LIBS)
 
 ifdef CONFIG_UNWINDER_ORC
 ifeq ($(ARCH),x86_64)
index 652e9542043f28ab995e5379e949d7578a26c673..dcd8d8750b8bf3b7204718c379edc5a71e31711b 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright 2004 Matt Mackall <mpm@selenic.com>
 #
index 92e888ed939f9833a3b17f32ae7d15813ec4c46f..1afe3af1cc09726c0e0c91c3803b0f8a020584b8 100755 (executable)
@@ -3390,13 +3390,6 @@ sub process {
                        }
                }
 
-# discourage the use of boolean for type definition attributes of Kconfig options
-               if ($realfile =~ /Kconfig/ &&
-                   $line =~ /^\+\s*\bboolean\b/) {
-                       WARN("CONFIG_TYPE_BOOLEAN",
-                            "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
-               }
-
                if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
                    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
                        my $flag = $1;
index 19963708bcf87712384eaedbba359e278cb78321..8ddb5d099029f717d9b3732f76d123c2a2315be5 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0
 #
 # Copyright (C) Google LLC, 2018
index fa7655c7cec0e8df222278d14c3e7ecb18113fc5..f754415af398b7eb97710931c1ce5761e664f879 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0
 #
 # Copyright (C) Google LLC, 2020
index 627eba5849b5ccf6a018cb1be1fd27341807fb62..d5da5fa05d1d3c264775dbb5c960bc3f69cd8684 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0
 #
 # diffconfig - a tool to compare .config files.
index 33487e99d83e5c0fe076c317f218a93fae3ada01..5c113cad5601742083addba09cb076b116933bc8 100755 (executable)
@@ -75,16 +75,12 @@ if arg_contain -S "$@"; then
        fi
 fi
 
-# For scripts/gcc-plugin.sh
+# To set GCC_PLUGINS
 if arg_contain -print-file-name=plugin "$@"; then
        plugin_dir=$(mktemp -d)
 
-       sed -n 's/.*#include "\(.*\)"/\1/p' $(dirname $0)/../gcc-plugins/gcc-common.h |
-       while read header
-       do
-               mkdir -p $plugin_dir/include/$(dirname $header)
-               touch $plugin_dir/include/$header
-       done
+       mkdir -p $plugin_dir/include
+       touch $plugin_dir/include/plugin-version.h
 
        echo $plugin_dir
        exit 0
index 0fdb31a790a810ff649701187076b815bad832d0..48d141e3ec56f280045a996f926a8213ace36dac 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0+
 #
 # This determines how many parallel tasks "make" is expecting, as it is
index 7ecd2ccba531bb4c46a01b4ecad7ea8078f29027..54ad86d13784995cfb8eb57bd0827204c6c36886 100644 (file)
@@ -112,6 +112,12 @@ static bool is_ignored_symbol(const char *name, char type)
                "__crc_",               /* modversions */
                "__efistub_",           /* arm64 EFI stub namespace */
                "__kvm_nvhe_",          /* arm64 non-VHE KVM namespace */
+               "__AArch64ADRPThunk_",  /* arm64 lld */
+               "__ARMV5PILongThunk_",  /* arm lld */
+               "__ARMV7PILongThunk_",
+               "__ThumbV7PILongThunk_",
+               "__LA25Thunk_",         /* mips lld */
+               "__microLA25Thunk_",
                NULL
        };
 
index fcd4acd4e9cbc10002fd72c91b0ce3677d11f01e..b520e407a8ebb6f4b72e3679d6672bd0f4db2026 100755 (executable)
@@ -35,7 +35,7 @@ fi
 
 # As a final fallback before giving up, check if $HOSTCC knows of a default
 # ncurses installation (e.g. from a vendor-specific sysroot).
-if echo '#include <ncurses.h>' | "${HOSTCC}" -E - >/dev/null 2>&1; then
+if echo '#include <ncurses.h>' | ${HOSTCC} -E - >/dev/null 2>&1; then
        echo cflags=\"-D_GNU_SOURCE\"
        echo libs=\"-lncurses\"
        exit 0
index bacc1111d871bc257c5f86bbf206430f64cb8d79..26c1cb725dcbe5c59197cc1e962a60d370a0deb6 100644 (file)
@@ -371,10 +371,11 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer,
 {
        int size, ret;
        kuid_t kroot;
+       u32 nsmagic, magic;
        uid_t root, mappedroot;
        char *tmpbuf = NULL;
        struct vfs_cap_data *cap;
-       struct vfs_ns_cap_data *nscap;
+       struct vfs_ns_cap_data *nscap = NULL;
        struct dentry *dentry;
        struct user_namespace *fs_ns;
 
@@ -396,46 +397,61 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer,
        fs_ns = inode->i_sb->s_user_ns;
        cap = (struct vfs_cap_data *) tmpbuf;
        if (is_v2header((size_t) ret, cap)) {
-               /* If this is sizeof(vfs_cap_data) then we're ok with the
-                * on-disk value, so return that.  */
-               if (alloc)
-                       *buffer = tmpbuf;
-               else
-                       kfree(tmpbuf);
-               return ret;
-       } else if (!is_v3header((size_t) ret, cap)) {
-               kfree(tmpbuf);
-               return -EINVAL;
+               root = 0;
+       } else if (is_v3header((size_t) ret, cap)) {
+               nscap = (struct vfs_ns_cap_data *) tmpbuf;
+               root = le32_to_cpu(nscap->rootid);
+       } else {
+               size = -EINVAL;
+               goto out_free;
        }
 
-       nscap = (struct vfs_ns_cap_data *) tmpbuf;
-       root = le32_to_cpu(nscap->rootid);
        kroot = make_kuid(fs_ns, root);
 
        /* If the root kuid maps to a valid uid in current ns, then return
         * this as a nscap. */
        mappedroot = from_kuid(current_user_ns(), kroot);
        if (mappedroot != (uid_t)-1 && mappedroot != (uid_t)0) {
+               size = sizeof(struct vfs_ns_cap_data);
                if (alloc) {
-                       *buffer = tmpbuf;
+                       if (!nscap) {
+                               /* v2 -> v3 conversion */
+                               nscap = kzalloc(size, GFP_ATOMIC);
+                               if (!nscap) {
+                                       size = -ENOMEM;
+                                       goto out_free;
+                               }
+                               nsmagic = VFS_CAP_REVISION_3;
+                               magic = le32_to_cpu(cap->magic_etc);
+                               if (magic & VFS_CAP_FLAGS_EFFECTIVE)
+                                       nsmagic |= VFS_CAP_FLAGS_EFFECTIVE;
+                               memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
+                               nscap->magic_etc = cpu_to_le32(nsmagic);
+                       } else {
+                               /* use allocated v3 buffer */
+                               tmpbuf = NULL;
+                       }
                        nscap->rootid = cpu_to_le32(mappedroot);
-               } else
-                       kfree(tmpbuf);
-               return size;
+                       *buffer = nscap;
+               }
+               goto out_free;
        }
 
        if (!rootid_owns_currentns(kroot)) {
-               kfree(tmpbuf);
-               return -EOPNOTSUPP;
+               size = -EOVERFLOW;
+               goto out_free;
        }
 
        /* This comes from a parent namespace.  Return as a v2 capability */
        size = sizeof(struct vfs_cap_data);
        if (alloc) {
-               *buffer = kmalloc(size, GFP_ATOMIC);
-               if (*buffer) {
-                       struct vfs_cap_data *cap = *buffer;
-                       __le32 nsmagic, magic;
+               if (nscap) {
+                       /* v3 -> v2 conversion */
+                       cap = kzalloc(size, GFP_ATOMIC);
+                       if (!cap) {
+                               size = -ENOMEM;
+                               goto out_free;
+                       }
                        magic = VFS_CAP_REVISION_2;
                        nsmagic = le32_to_cpu(nscap->magic_etc);
                        if (nsmagic & VFS_CAP_FLAGS_EFFECTIVE)
@@ -443,9 +459,12 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer,
                        memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
                        cap->magic_etc = cpu_to_le32(magic);
                } else {
-                       size = -ENOMEM;
+                       /* use unconverted v2 */
+                       tmpbuf = NULL;
                }
+               *buffer = cap;
        }
+out_free:
        kfree(tmpbuf);
        return size;
 }
index 9f3f8e953ff04ef7eb49b0928d1a09b918177c03..c4aac703dc224c0c58995239275fe2c515be445c 100644 (file)
@@ -382,8 +382,8 @@ retry:
                        continue;
 
                /*
-                * The 'deps' array includes maximum three dependencies
-                * to SNDRV_PCM_HW_PARAM_XXXs for this rule. The fourth
+                * The 'deps' array includes maximum four dependencies
+                * to SNDRV_PCM_HW_PARAM_XXXs for this rule. The fifth
                 * member of this array is a sentinel and should be
                 * negative value.
                 *
index 6a0d070c60c9ac489a9c1e9d35e1262e0b4bbe62..c4568617251723c41090a7a188d3d7013007c747 100644 (file)
@@ -307,6 +307,10 @@ static const struct config_entry config_table[] = {
                .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
                .device = 0xa0c8,
        },
+       {
+               .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+               .device = 0x43c8,
+       },
 #endif
 
 /* Elkhart Lake */
index ed5b6b894dc1941c5d6ca0426b9e24d6ab78889e..290645516313c6a034d9b6f4ebf9d6065261eb3e 100644 (file)
@@ -8006,6 +8006,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
+       SND_PCI_QUIRK(0x1043, 0x1982, "ASUS B1400CEPE", ALC256_FIXUP_ASUS_HPE),
        SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
        SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
index 834367dd54e1b651c8bc34588cb84224d2919b8d..a5c1a2c4eae4e6f2d53968d514696e371e759584 100644 (file)
@@ -1043,7 +1043,7 @@ static const struct hda_fixup via_fixups[] = {
 static const struct snd_pci_quirk vt2002p_fixups[] = {
        SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75),
        SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
-       SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", VIA_FIXUP_POWER_SAVE),
+       SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", VIA_FIXUP_POWER_SAVE),
        {}
 };
 
index deca8c7a0e8784b82458bc9b5d9d0d12adbd58e7..050a61fe9693f99171dee180db6cdd1eb95fccfe 100644 (file)
@@ -165,10 +165,24 @@ static int rn_acp_deinit(void __iomem *acp_base)
 
 static const struct dmi_system_id rn_acp_quirk_table[] = {
        {
-               /* Lenovo IdeaPad Flex 5 14ARE05, IdeaPad 5 15ARE05 */
+               /* Lenovo IdeaPad S340-14API */
                .matches = {
                        DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
-                       DMI_EXACT_MATCH(DMI_BOARD_NAME, "LNVNB161216"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81NB"),
+               }
+       },
+       {
+               /* Lenovo IdeaPad Flex 5 14ARE05 */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81X2"),
+               }
+       },
+       {
+               /* Lenovo IdeaPad 5 15ARE05 */
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81YQ"),
                }
        },
        {
index 1010c9ee2e836272055d689d9736da34689f9629..472caad17012e9f032563984528f084c03ea684d 100644 (file)
@@ -595,18 +595,10 @@ static struct snd_soc_dai_driver ak4497_dai = {
        .ops = &ak4458_dai_ops,
 };
 
-static void ak4458_power_off(struct ak4458_priv *ak4458)
+static void ak4458_reset(struct ak4458_priv *ak4458, bool active)
 {
        if (ak4458->reset_gpiod) {
-               gpiod_set_value_cansleep(ak4458->reset_gpiod, 0);
-               usleep_range(1000, 2000);
-       }
-}
-
-static void ak4458_power_on(struct ak4458_priv *ak4458)
-{
-       if (ak4458->reset_gpiod) {
-               gpiod_set_value_cansleep(ak4458->reset_gpiod, 1);
+               gpiod_set_value_cansleep(ak4458->reset_gpiod, active);
                usleep_range(1000, 2000);
        }
 }
@@ -620,7 +612,7 @@ static int ak4458_init(struct snd_soc_component *component)
        if (ak4458->mute_gpiod)
                gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
 
-       ak4458_power_on(ak4458);
+       ak4458_reset(ak4458, false);
 
        ret = snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
                            0x80, 0x80);   /* ACKS bit = 1; 10000000 */
@@ -650,7 +642,7 @@ static void ak4458_remove(struct snd_soc_component *component)
 {
        struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
 
-       ak4458_power_off(ak4458);
+       ak4458_reset(ak4458, true);
 }
 
 #ifdef CONFIG_PM
@@ -660,7 +652,7 @@ static int __maybe_unused ak4458_runtime_suspend(struct device *dev)
 
        regcache_cache_only(ak4458->regmap, true);
 
-       ak4458_power_off(ak4458);
+       ak4458_reset(ak4458, true);
 
        if (ak4458->mute_gpiod)
                gpiod_set_value_cansleep(ak4458->mute_gpiod, 0);
@@ -685,8 +677,8 @@ static int __maybe_unused ak4458_runtime_resume(struct device *dev)
        if (ak4458->mute_gpiod)
                gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
 
-       ak4458_power_off(ak4458);
-       ak4458_power_on(ak4458);
+       ak4458_reset(ak4458, true);
+       ak4458_reset(ak4458, false);
 
        regcache_cache_only(ak4458->regmap, false);
        regcache_mark_dirty(ak4458->regmap);
index dec8716aa8ef5ebe92410027b9996ddab5bbadd6..985b2dcecf138c18f6cc6f562e2dfadb119f48dc 100644 (file)
@@ -2031,11 +2031,14 @@ static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp,
                                             unsigned int alg)
 {
        struct wm_coeff_ctl *pos, *rslt = NULL;
+       const char *fw_txt = wm_adsp_fw_text[dsp->fw];
 
        list_for_each_entry(pos, &dsp->ctl_list, list) {
                if (!pos->subname)
                        continue;
                if (strncmp(pos->subname, name, pos->subname_len) == 0 &&
+                   strncmp(pos->fw_name, fw_txt,
+                           SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 0 &&
                                pos->alg_region.alg == alg &&
                                pos->alg_region.type == type) {
                        rslt = pos;
index ca968901ac96f39070c7164446162a268bfd5ba8..6d0d6ef711e0f3129019829d1f35e9e7348e69af 100644 (file)
@@ -67,6 +67,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
                .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
                                        SOF_RT715_DAI_ID_FIX),
        },
+       {
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E")
+               },
+               .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
+                                       SOF_RT715_DAI_ID_FIX |
+                                       SOF_SDW_FOUR_SPK),
+       },
        {
                .callback = sof_sdw_quirk_cb,
                .matches = {
index ae466cd592922a4a6cff1ed7117521a0bd186653..b824086203b9e14292e3db5165dc9ffb3987a665 100644 (file)
@@ -3619,19 +3619,20 @@ static void skl_tplg_complete(struct snd_soc_component *component)
 
        list_for_each_entry(dobj, &component->dobj_list, list) {
                struct snd_kcontrol *kcontrol = dobj->control.kcontrol;
-               struct soc_enum *se =
-                       (struct soc_enum *)kcontrol->private_value;
-               char **texts = dobj->control.dtexts;
+               struct soc_enum *se;
+               char **texts;
                char chan_text[4];
 
-               if (dobj->type != SND_SOC_DOBJ_ENUM ||
-                   dobj->control.kcontrol->put !=
-                   skl_tplg_multi_config_set_dmic)
+               if (dobj->type != SND_SOC_DOBJ_ENUM || !kcontrol ||
+                   kcontrol->put != skl_tplg_multi_config_set_dmic)
                        continue;
+
+               se = (struct soc_enum *)kcontrol->private_value;
+               texts = dobj->control.dtexts;
                sprintf(chan_text, "c%d", mach->mach_params.dmic_num);
 
                for (i = 0; i < se->items; i++) {
-                       struct snd_ctl_elem_value val;
+                       struct snd_ctl_elem_value val = {};
 
                        if (strstr(texts[i], chan_text)) {
                                val.value.enumerated.item[0] = i;
index 078e58f1ad0b27b2e49837dc145e674689ce9b08..cfbd0c65c7a389564ebed1fed50f8dd32413245e 100644 (file)
@@ -532,6 +532,7 @@ static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
                .dpcm_playback = 1,
                .ignore_suspend = 1,
                .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
+               .ignore = 1,
                .init = mt8183_da7219_max98357_hdmi_init,
                SND_SOC_DAILINK_REG(tdm),
        },
@@ -754,8 +755,10 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
                        }
                }
 
-               if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0)
+               if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
                        dai_link->codecs->of_node = hdmi_codec;
+                       dai_link->ignore = 0;
+               }
 
                if (!dai_link->platforms->name)
                        dai_link->platforms->of_node = platform_node;
index 8c8340854859aceadfd0da76b4733fadf6527946..1ce3eddbee13bd1ed9bfc4d4850adacc833d20a6 100644 (file)
@@ -515,6 +515,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = {
                .ignore_suspend = 1,
                .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
                .ops = &mt8183_mt6358_tdm_ops,
+               .ignore = 1,
                .init = mt8183_mt6358_ts3a227_max98357_hdmi_init,
                SND_SOC_DAILINK_REG(tdm),
        },
@@ -661,8 +662,10 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
                                                    SND_SOC_DAIFMT_CBM_CFM;
                }
 
-               if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0)
+               if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
                        dai_link->codecs->of_node = hdmi_codec;
+                       dai_link->ignore = 0;
+               }
 
                if (!dai_link->platforms->name)
                        dai_link->platforms->of_node = platform_node;
index 716fbb4126b5fc2f2b8fbf19bf7a38cf0f5429da..ae2c748eb19c40a490f84880820fc97093f5b895 100644 (file)
@@ -401,6 +401,53 @@ static const struct snd_soc_ops mt8192_mt6359_rt1015_rt5682_capture1_ops = {
        .startup = mt8192_mt6359_rt1015_rt5682_cap1_startup,
 };
 
+static int
+mt8192_mt6359_rt5682_startup(struct snd_pcm_substream *substream)
+{
+       static const unsigned int channels[] = {
+               1, 2
+       };
+       static const struct snd_pcm_hw_constraint_list constraints_channels = {
+               .count = ARRAY_SIZE(channels),
+               .list = channels,
+               .mask = 0,
+       };
+       static const unsigned int rates[] = {
+               48000
+       };
+       static const struct snd_pcm_hw_constraint_list constraints_rates = {
+               .count = ARRAY_SIZE(rates),
+               .list  = rates,
+               .mask = 0,
+       };
+
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       int ret;
+
+       ret = snd_pcm_hw_constraint_list(runtime, 0,
+                                        SNDRV_PCM_HW_PARAM_CHANNELS,
+                                        &constraints_channels);
+       if (ret < 0) {
+               dev_err(rtd->dev, "hw_constraint_list channels failed\n");
+               return ret;
+       }
+
+       ret = snd_pcm_hw_constraint_list(runtime, 0,
+                                        SNDRV_PCM_HW_PARAM_RATE,
+                                        &constraints_rates);
+       if (ret < 0) {
+               dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static const struct snd_soc_ops mt8192_mt6359_rt5682_ops = {
+       .startup = mt8192_mt6359_rt5682_startup,
+};
+
 /* FE */
 SND_SOC_DAILINK_DEFS(playback1,
                     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
@@ -648,6 +695,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = {
                            SND_SOC_DPCM_TRIGGER_PRE},
                .dynamic = 1,
                .dpcm_playback = 1,
+               .ops = &mt8192_mt6359_rt5682_ops,
                SND_SOC_DAILINK_REG(playback3),
        },
        {
@@ -721,6 +769,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = {
                            SND_SOC_DPCM_TRIGGER_PRE},
                .dynamic = 1,
                .dpcm_capture = 1,
+               .ops = &mt8192_mt6359_rt5682_ops,
                SND_SOC_DAILINK_REG(capture2),
        },
        {
index c5e99c2d89c7ed65b3ae4eacd69a449df5b37d4b..66b834312f330fdd8424d7caca8e93706ecb094a 100644 (file)
@@ -344,8 +344,30 @@ int asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai *dai)
 }
 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_probe);
 
+static int asoc_qcom_of_xlate_dai_name(struct snd_soc_component *component,
+                                  struct of_phandle_args *args,
+                                  const char **dai_name)
+{
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
+       struct lpass_variant *variant = drvdata->variant;
+       int id = args->args[0];
+       int ret = -EINVAL;
+       int i;
+
+       for (i = 0; i  < variant->num_dai; i++) {
+               if (variant->dai_driver[i].id == id) {
+                       *dai_name = variant->dai_driver[i].name;
+                       ret = 0;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
 static const struct snd_soc_component_driver lpass_cpu_comp_driver = {
        .name = "lpass-cpu",
+       .of_xlate_dai_name = asoc_qcom_of_xlate_dai_name,
 };
 
 static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
index 92f98b4df47ffb23b878108342c8c8c3c785c427..ef8a7984f232356c1f879abfb5b5efe04e725d44 100644 (file)
@@ -131,7 +131,7 @@ static struct lpass_variant ipq806x_data = {
        .micmode                = REG_FIELD_ID(0x0010, 4, 7, 5, 0x4),
        .micmono                = REG_FIELD_ID(0x0010, 3, 3, 5, 0x4),
        .wssrc                  = REG_FIELD_ID(0x0010, 2, 2, 5, 0x4),
-       .bitwidth               = REG_FIELD_ID(0x0010, 0, 0, 5, 0x4),
+       .bitwidth               = REG_FIELD_ID(0x0010, 0, 1, 5, 0x4),
 
        .rdma_dyncclk           = REG_FIELD_ID(0x6000, 12, 12, 4, 0x1000),
        .rdma_bursten           = REG_FIELD_ID(0x6000, 11, 11, 4, 0x1000),
index 405542832e99416737b62b2c47ccf980e8a6965b..baf72f124ea9b24603692bad3708821e744dfd87 100644 (file)
 #define        LPAIF_WRDMAPERCNT_REG(v, chan)  LPAIF_WRDMA_REG_ADDR(v, 0x14, (chan))
 
 #define LPAIF_INTFDMA_REG(v, chan, reg, dai_id)  \
-               ((v->dai_driver[dai_id].id ==  LPASS_DP_RX) ? \
+       ((dai_id ==  LPASS_DP_RX) ? \
                LPAIF_HDMI_RDMA##reg##_REG(v, chan) : \
                 LPAIF_RDMA##reg##_REG(v, chan))
 
index d1c248590f3ab6da7622dcf8d1909d74c340c88a..0074b7f2dbc107ba8376d7fe51b056fd54361551 100644 (file)
@@ -257,6 +257,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
                break;
        case MI2S_PRIMARY:
        case MI2S_SECONDARY:
+       case MI2S_TERTIARY:
+       case MI2S_QUATERNARY:
+       case MI2S_QUINARY:
                ret = regmap_fields_write(dmactl->intf, id,
                                                LPAIF_DMACTL_AUDINTF(dma_port));
                if (ret) {
@@ -507,6 +510,9 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
                        break;
                case MI2S_PRIMARY:
                case MI2S_SECONDARY:
+               case MI2S_TERTIARY:
+               case MI2S_QUATERNARY:
+               case MI2S_QUINARY:
                        reg_irqclr = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
                        val_irqclr = LPAIF_IRQ_ALL(ch);
 
@@ -559,6 +565,9 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
                        break;
                case MI2S_PRIMARY:
                case MI2S_SECONDARY:
+               case MI2S_TERTIARY:
+               case MI2S_QUATERNARY:
+               case MI2S_QUINARY:
                        reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST);
                        val_mask = LPAIF_IRQ_ALL(ch);
                        val_irqen = 0;
@@ -655,6 +664,9 @@ static irqreturn_t lpass_dma_interrupt_handler(
        break;
        case MI2S_PRIMARY:
        case MI2S_SECONDARY:
+       case MI2S_TERTIARY:
+       case MI2S_QUATERNARY:
+       case MI2S_QUINARY:
                map = drvdata->lpaif_map;
                reg = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
                val = 0;
index 85db650c2169d2356cf71b0eb3b8724d1fc72538..735c9dac28f2683abdb11b5e51f0d61483253682 100644 (file)
@@ -20,7 +20,7 @@
 #include "lpass.h"
 
 static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
-       [MI2S_PRIMARY] = {
+       {
                .id = MI2S_PRIMARY,
                .name = "Primary MI2S",
                .playback = {
@@ -44,9 +44,7 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
                },
                .probe  = &asoc_qcom_lpass_cpu_dai_probe,
                .ops    = &asoc_qcom_lpass_cpu_dai_ops,
-       },
-
-       [MI2S_SECONDARY] = {
+       }, {
                .id = MI2S_SECONDARY,
                .name = "Secondary MI2S",
                .playback = {
@@ -60,8 +58,7 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
                },
                .probe  = &asoc_qcom_lpass_cpu_dai_probe,
                .ops    = &asoc_qcom_lpass_cpu_dai_ops,
-       },
-       [LPASS_DP_RX] = {
+       }, {
                .id = LPASS_DP_RX,
                .name = "Hdmi",
                .playback = {
@@ -174,7 +171,7 @@ static struct lpass_variant sc7180_data = {
        .rdma_channels          = 5,
        .hdmi_rdma_reg_base             = 0x64000,
        .hdmi_rdma_reg_stride   = 0x1000,
-       .hdmi_rdma_channels             = 4,
+       .hdmi_rdma_channels             = 3,
        .dmactl_audif_start     = 1,
        .wrdma_reg_base         = 0x18000,
        .wrdma_reg_stride       = 0x1000,
index 0195372905ed3849ba4e0111a797dd5edbf5a0dd..2d68af0da34d877943946da18d8dda616544dbc4 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/compiler.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
-#include <dt-bindings/sound/sc7180-lpass.h>
+#include <dt-bindings/sound/qcom,lpass.h>
 #include "lpass-hdmi.h"
 
 #define LPASS_AHBIX_CLOCK_FREQUENCY            131072000
index 950c45008e245fbf2952bff0f9c986c95d40a8a3..22e7b4c9115b723f194c931f485bb102cfcc563e 100644 (file)
@@ -447,7 +447,7 @@ static void remove_dai(struct snd_soc_component *comp,
 {
        struct snd_soc_dai_driver *dai_drv =
                container_of(dobj, struct snd_soc_dai_driver, dobj);
-       struct snd_soc_dai *dai;
+       struct snd_soc_dai *dai, *_dai;
 
        if (pass != SOC_TPLG_PASS_PCM_DAI)
                return;
@@ -455,9 +455,9 @@ static void remove_dai(struct snd_soc_component *comp,
        if (dobj->ops && dobj->ops->dai_unload)
                dobj->ops->dai_unload(comp, dobj);
 
-       for_each_component_dais(comp, dai)
+       for_each_component_dais_safe(comp, dai, _dai)
                if (dai->driver == dai_drv)
-                       dai->driver = NULL;
+                       snd_soc_unregister_dai(dai);
 
        list_del(&dobj->list);
 }
@@ -902,7 +902,7 @@ static int soc_tplg_denum_create_values(struct soc_tplg *tplg, struct soc_enum *
                return -EINVAL;
 
        se->dobj.control.dvalues = devm_kcalloc(tplg->dev, le32_to_cpu(ec->items),
-                                          sizeof(u32),
+                                          sizeof(*se->dobj.control.dvalues),
                                           GFP_KERNEL);
        if (!se->dobj.control.dvalues)
                return -ENOMEM;
@@ -1742,7 +1742,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
        list_add(&dai_drv->dobj.list, &tplg->comp->dobj_list);
 
        /* register the DAI to the component */
-       dai = devm_snd_soc_register_dai(tplg->dev, tplg->comp, dai_drv, false);
+       dai = snd_soc_register_dai(tplg->comp, dai_drv, false);
        if (!dai)
                return -ENOMEM;
 
@@ -1750,6 +1750,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
        ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
        if (ret != 0) {
                dev_err(dai->dev, "Failed to create DAI widgets %d\n", ret);
+               snd_soc_unregister_dai(dai);
                return ret;
        }
 
index d306c370e5d164ac786f0760812927e8b17e2a08..4797a1cf8c805d5d063cba4544845cfdbb748c55 100644 (file)
@@ -355,7 +355,7 @@ config SND_SOC_SOF_HDA
 
 config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK
        bool "SOF support for SoundWire"
-       depends on SOUNDWIRE && ACPI
+       depends on ACPI
        help
          This adds support for SoundWire with Sound Open Firmware
          for Intel(R) platforms.
@@ -371,6 +371,7 @@ config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
 
 config SND_SOC_SOF_INTEL_SOUNDWIRE
        tristate
+       select SOUNDWIRE
        select SOUNDWIRE_INTEL
        help
          This option is not user-selectable but automagically handled by
index 2a369c2c65514c7c3b359d73eca2a0e2bce1994f..cc2e257087e4c37583b0eab45a0e8abbc9e9ddf8 100644 (file)
@@ -131,12 +131,13 @@ static int sof_acpi_probe(struct platform_device *pdev)
        if (!id)
                return -ENODEV;
 
-       ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
-       if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
-               dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
-               return -ENODEV;
+       if (IS_REACHABLE(CONFIG_SND_INTEL_DSP_CONFIG)) {
+               ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
+               if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
+                       dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
+                       return -ENODEV;
+               }
        }
-
        dev_dbg(dev, "ACPI DSP detected");
 
        sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL);
index 63b989e3ec409826a01ccd8a04295e7e323638b5..215711ac7450997138d542b952b50db2e3b028d9 100644 (file)
@@ -344,10 +344,12 @@ static int sof_pci_probe(struct pci_dev *pci,
        const struct snd_sof_dsp_ops *ops;
        int ret;
 
-       ret = snd_intel_dsp_driver_probe(pci);
-       if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
-               dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n");
-               return -ENODEV;
+       if (IS_REACHABLE(CONFIG_SND_INTEL_DSP_CONFIG)) {
+               ret = snd_intel_dsp_driver_probe(pci);
+               if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
+                       dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n");
+                       return -ENODEV;
+               }
        }
        dev_dbg(&pci->dev, "PCI DSP detected");
 
index 9ebc5d202c87398fa4e622acd58295d6bc356df3..e6ff317a678520a20ff5f6109886d5018fab9043 100644 (file)
@@ -466,6 +466,17 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,
        unsigned int nr_rates;
        int i, err;
 
+       /* performing the rate verification may lead to unexpected USB bus
+        * behavior afterwards by some unknown reason.  Do this only for the
+        * known devices.
+        */
+       switch (USB_ID_VENDOR(chip->usb_id)) {
+       case 0x07fd: /* MOTU */
+               break;
+       default:
+               return 0; /* don't perform the validation as default */
+       }
+
        table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL);
        if (!table)
                return -ENOMEM;
index 388e4492b81be44c5a0444a0ea5afeb4c80e7842..76efb1f8375e3c2ac9f7f5cc810a91d1f98d698a 100755 (executable)
@@ -203,7 +203,7 @@ multipath4_test()
        t0_rp12=$(link_stats_tx_packets_get $rp12)
        t0_rp13=$(link_stats_tx_packets_get $rp13)
 
-       ip vrf exec vrf-h1 $MZ -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \
+       ip vrf exec vrf-h1 $MZ $h1 -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \
                -d 1msec -t udp "sp=1024,dp=0-32768"
 
        t1_rp12=$(link_stats_tx_packets_get $rp12)
index 79a2099279621a7810b2718f76f2964012423fa0..464821c587a5e8cd073db1b64ab8f39267a669b2 100755 (executable)
@@ -178,7 +178,7 @@ multipath4_test()
        t0_rp12=$(link_stats_tx_packets_get $rp12)
        t0_rp13=$(link_stats_tx_packets_get $rp13)
 
-       ip vrf exec vrf-h1 $MZ -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \
+       ip vrf exec vrf-h1 $MZ $h1 -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \
               -d 1msec -t udp "sp=1024,dp=0-32768"
 
        t1_rp12=$(link_stats_tx_packets_get $rp12)
index 7a1bf94c5bd38bc9837b87911a082a1ef287eee8..bdf450eaf60cff25d7d36308e0ddc94838423bc7 100755 (executable)
@@ -202,7 +202,7 @@ check_xfrm() {
        # 1: iptables -m policy rule count != 0
        rval=$1
        ip=$2
-       lret=0
+       local lret=0
 
        ip netns exec ns1 ping -q -c 1 10.0.2.$ip > /dev/null
 
@@ -287,6 +287,47 @@ check_hthresh_repeat()
        return 0
 }
 
+# insert non-overlapping policies in a random order and check that
+# all of them can be fetched using the traffic selectors.
+check_random_order()
+{
+       local ns=$1
+       local log=$2
+
+       for i in $(seq 100); do
+               ip -net $ns xfrm policy flush
+               for j in $(seq 0 16 255 | sort -R); do
+                       ip -net $ns xfrm policy add dst $j.0.0.0/24 dir out priority 10 action allow
+               done
+               for j in $(seq 0 16 255); do
+                       if ! ip -net $ns xfrm policy get dst $j.0.0.0/24 dir out > /dev/null; then
+                               echo "FAIL: $log" 1>&2
+                               return 1
+                       fi
+               done
+       done
+
+       for i in $(seq 100); do
+               ip -net $ns xfrm policy flush
+               for j in $(seq 0 16 255 | sort -R); do
+                       local addr=$(printf "e000:0000:%02x00::/56" $j)
+                       ip -net $ns xfrm policy add dst $addr dir out priority 10 action allow
+               done
+               for j in $(seq 0 16 255); do
+                       local addr=$(printf "e000:0000:%02x00::/56" $j)
+                       if ! ip -net $ns xfrm policy get dst $addr dir out > /dev/null; then
+                               echo "FAIL: $log" 1>&2
+                               return 1
+                       fi
+               done
+       done
+
+       ip -net $ns xfrm policy flush
+
+       echo "PASS: $log"
+       return 0
+}
+
 #check for needed privileges
 if [ "$(id -u)" -ne 0 ];then
        echo "SKIP: Need root privileges"
@@ -438,6 +479,8 @@ check_exceptions "exceptions and block policies after htresh change to normal"
 
 check_hthresh_repeat "policies with repeated htresh change"
 
+check_random_order ns3 "policies inserted in random order"
+
 for i in 1 2 3 4;do ip netns del ns$i;done
 
 exit $ret
index fa9e3614d30edb150f6b8f7a071f0e351657dd08..8367d88ce39bf2b831d317c91ebb087cc034d096 100644 (file)
@@ -1292,6 +1292,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
                return -EINVAL;
        /* We can read the guest memory with __xxx_user() later on. */
        if ((mem->userspace_addr & (PAGE_SIZE - 1)) ||
+           (mem->userspace_addr != untagged_addr(mem->userspace_addr)) ||
             !access_ok((void __user *)(unsigned long)mem->userspace_addr,
                        mem->memory_size))
                return -EINVAL;